]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_ctfws/commitdiff
Some miscellaneous work around the tree
authorNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 12 Aug 2018 01:06:40 +0000 (02:06 +0100)
committerNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 12 Aug 2018 14:24:14 +0000 (15:24 +0100)
Mostly changing messages on the LCD
 And some state-model plumbing to help
Explicitly disable wifi sleep in init2 hw bringup
Some debugging prints that should probably stick around

README.rst
ctfws-lcd.lua
ctfws.lua
init2.lua
init3.lua

index 83450964ef964b8510f4f9a9be3ff529553b38ab..41e36a71f01edef492b1ce35b5d26518c7f088d3 100644 (file)
@@ -2,7 +2,6 @@
 Capture The Flag With Stuff Glyph Module
 ########################################
 
-
 This is a hardware device designed to assist the `CMU KGB
 <http://www.cmukgb.org/>`_ game of `Capture The Flag With Stuff
 <http://www.cmukgb.org/activities/ctfws.php>`_.
@@ -98,6 +97,10 @@ One possible instantiation, just as a baseline:
 |   | TOTAL                                                       | 15.50 |
 +---+-------------------------------------------------------------+-------+
 
+We have found it necessary, on occasion, to add a 100-ohm resistor between
+power and ground to keep the USB power sticks from automagically turning
+off due to low draw.  It's not great, but it works.
+
 NodeMCU Pinout
 ==============
 
@@ -150,7 +153,7 @@ Steady state display::
 
     0         1         
     01234567890123456789
-    ROUND r/R :  MM:SS.s
+    JB#   n/N :  MM:SS.s
        NN⚑: R=NN Y=NN
     messagemessagemessag
     JAILBREAK :  MM:SS.s
@@ -159,7 +162,7 @@ Last round display::
 
     0         1         
     01234567890123456789
-    ROUND r/R :  MM:SS.s
+    GAME      :  MM:SS.s
        NN⚑: R=NN Y=NN
     messagemessagemessag
     GAME END  :  MM:SS.s
@@ -168,16 +171,16 @@ Game over::
 
     0         1         
     01234567890123456789
-         GAME OVER
+     CMUKGB CTFWS TIMER
        NN⚑: R=NN Y=NN
     messagemessagemessag
-         GAME OVER
+     GAME OVER @ MM:SS
 
 Game not configured::
 
     0         1         
     01234567890123456789
-     GAME NOT CONFIGURED
+     CMUKGB CTFWS TIMER
        
     messagemessagemessag
      GAME NOT CONFIGURED
index 6aa206f8ac52cb97fe369fc48542dbb58f4d6ead..338a189fc25ad88723ec4a5ee06e6962637f77d8 100644 (file)
@@ -29,6 +29,26 @@ local function drawDS(lcd, row, col, max, last, decisec)
   end
 end
 
+-- scroll a message msg across line lix using the timer t
+local function scroller(t, lix, msg)
+  local lcd = self.lcd
+  local mlen = #msg
+  if mlen <= 20
+   then lcd:put(lcd:locate(lix,(20-mlen)/2),msg)
+   else
+     -- inspired by lcd:run(), but corrected
+     local ix = 1
+     local function doscroll()
+       if     ix <= 20   then lcd:put(lcd:locate(lix,20-ix),msg:sub(1,ix))
+       elseif ix >  mlen then lcd:put(lcd:locate(lix,0),msg:sub(ix-19)," ")
+       else                   lcd:put(lcd:locate(lix,0),msg:sub(ix-19,ix))
+       end
+       if ix >= mlen + 20 then ix = 1 else ix = ix + 1 end
+     end
+     t:alarm(300, tmr.ALARM_AUTO, doscroll)
+  end
+end
+
 local function drawNoGame(lcd, msg)
   lcd:put(lcd:locate(0,0), " CMUKGB CTFWS TIMER ")
   lcd:put(lcd:locate(3,0), "                    ")
@@ -40,13 +60,10 @@ local function drawSteadyTopLine(self,rix,maxt,ela)
   local ctfws = self.ctfws
   if self.dl_elapsed == nil then
     lcd:put(lcd:locate(0,0), "                    ")
-    if rix == 0 then
-      lcd:put(lcd:locate(0,0), "SETUP    :")
-    else
-      if ctfws.rounds >= 10
-       then lcd:put(lcd:locate(0,0), string.format("JB# %2d/%2d :",rix,ctfws.rounds))
-       else lcd:put(lcd:locate(0,0), string.format("JB#   %d/%d :",rix,ctfws.rounds))
-      end
+    if     rix == 0            then lcd:put(lcd:locate(0,0), "SETUP     :")
+    elseif rix == ctfws.rounds then lcd:put(lcd:locate(0,0), "GAME      :")
+    elseif ctfws.rounds >= 11  then lcd:put(lcd:locate(0,0), string.format("JB# %2d/%2d :",rix,ctfws.rounds-1))
+    else                            lcd:put(lcd:locate(0,0), string.format("JB#   %d/%d :",rix,ctfws.rounds-1))
     end
   end
   drawDS(lcd,0,13,maxt,self.dl_elapsed,ela); self.dl_elapsed = ela
@@ -57,7 +74,7 @@ local function drawSteadyBotLine(self,rix,maxt,rem)
   if self.dl_remain == nil then
     lcd:put(lcd:locate(3,0), "                    ")
     if rix == 0 then
-      lcd:put(lcd:locate(3,0), "START IN :")
+      lcd:put(lcd:locate(3,0), "START IN  :")
     elseif rix < ctfws.rounds then
       lcd:put(lcd:locate(3,0), "JAILBREAK :")
     else
@@ -117,17 +134,14 @@ local function drawTimes(self)
 end
 
 local function drawFlags(self)
-  local lcd = self.lcd
-  local ctfws = self.ctfws
   if ctfws.flagsN then -- try not to blank a flagsmessage unless we have reason
+    self.ftmr:unregister()
     lcd:put(lcd:locate(1,0),"                    ")
   end
-  if ctfws.startT then
-    local str = string.format("%d\000: R=%s Y=%s",
-                               ctfws.flagsN, tostring(ctfws.flagsR), tostring(ctfws.flagsY))
-              :sub(1,20)
-    lcd:put(lcd:locate(1,(20-#str)/2), str)
-    attention(self,false)
+  if ctfws.startT
+   then scroller(self.ftmr, 1, string.format("%d\000: R=%s Y=%s",
+                               ctfws.flagsN, tostring(ctfws.flagsR), tostring(ctfws.flagsY)))
+        attention(self,false)
   end
 end
 
@@ -139,25 +153,13 @@ local function drawFlagsMessage(self, msg)
 end
 
 local function drawMessage(self, msg)
-  local lcd = self.lcd
-  local mlen = (msg and #msg) or 0
+  -- blank and stop scrolling
   self.mtmr:unregister()
   lcd:put(lcd:locate(2,0),"                    ")
+
   if not msg then return end
-  if mlen <= 20
-   then lcd:put(lcd:locate(2,(20-#msg)/2),msg)
-   else
-     -- inspired by lcd:run(), but corrected
-     local ix = 1
-     local function scroller()
-       if     ix <= 20   then lcd:put(lcd:locate(2,20-ix),msg:sub(1,ix))
-       elseif ix >  mlen then lcd:put(lcd:locate(2,0),msg:sub(ix-19)," ")
-       else                   lcd:put(lcd:locate(2,0),msg:sub(ix-19,ix))
-       end
-       if ix >= mlen + 20 then ix = 1 else ix = ix + 1 end
-     end
-     self.mtmr:alarm(300, tmr.ALARM_AUTO, scroller)
-  end
+
+  scroller(self.mtmr, 2, msg)
   attention(self,false)
 end
 
@@ -167,11 +169,12 @@ local function reset(self)
   self.dl_round   = nil
 end
 
-return function(ctfws, lcd, t)
+return function(ctfws, lcd, mt, ft)
   self = {}
   self.ctfws = ctfws
   self.lcd = lcd
-  self.mtmr = t
+  self.mtmr = mt
+  self.ftmr = ft
 
   self.attnState        = nil
 
index a7cd74200cf3e273c9478bcfbb7115346ac6363e..f9393778b14b2a2eed910c86c9167cbd6d295aee 100644 (file)
--- a/ctfws.lua
+++ b/ctfws.lua
@@ -3,8 +3,8 @@
 --   setupD  -- deciseconds for setup round
 --   roundD  -- deciseconds per round
 --   rounds* -- number of rounds of game play
---   startT* -- NTP seconds of game start
---   endT    -- NTP seconds of game end (if set)
+--   startT* -- POSIX seconds of game start
+--   endT    -- POSIX seconds of game end (if set)
 --
 --   flagsN* -- total flags
 --   flagsR* -- flags captured by the red team
@@ -21,8 +21,10 @@ local function times(self, nowf)
     return nil, "GAME NOT CONFIGURED!"
   end
 
+  -- Game declared over; show total elapsed time
   if self.endT and self.endT >= self.startT then
-    return nil, "GAME OVER"
+    local t = self.endT - self.startT
+    return nil, string.format("GAME OVER @ %02d:%02d", t/60, t%60)
   end
 
   local now_sec, now_usec = nowf()
@@ -62,9 +64,13 @@ local function deconfig(self)
   -- leave flagsN alone for end-of-game display logic
 end
 
+-- return whether or not a change took place, for duplicate message
+-- suppression
 local function setFlags(self, fr, fy)
+  if (self.flagsR == fr) and (self.flagsY == fy) then return false end
   self.flagsR = fr
   self.flagsY = fy
+  return true
 end
 
 local function setEndTime(self,t)
index 7ae5297f10f6b1bda3d3da0a462c9d71512cddde..ed70cace0a38b3477b86b7043c853ba8fde9b0f7 100644 (file)
--- a/init2.lua
+++ b/init2.lua
@@ -15,6 +15,7 @@ end
 
 -- Hardware initialization
 print("init2 hw")
+wifi.sta.sleeptype(wifi.NONE_SLEEP) -- don't power down radio
 gpio.mode(5,gpio.OUTPUT)   -- beeper on GPIO14
 i2c.setup(0,2,1,i2c.SLOW)  -- init i2c on GPIO4 and GPIO5
 lcd = dofile("lcd1602.lc")(ctfwshw.lcd or 0x27)
index 68916e21467d24530a89644498e118b1cd1581c9..8902a942bb2e7e8d3b94326b19f521ab7625e38f 100644 (file)
--- a/init3.lua
+++ b/init3.lua
@@ -1,3 +1,7 @@
+-- logging for debugging
+-- dprint = function(...) end -- OFF
+dprint = function(...) print(...) end -- ON
+
 -- common module initialization
 cron.schedule("*/5 * * * *", function(e) dofile("nwfnet-sntp.lc").dosntp(nil) end)
 nwfnet = require "nwfnet"
@@ -7,7 +11,8 @@ ctfws = dofile("ctfws.lc")()
 ctfws:setFlags(0,0)
 
 msg_tmr = tmr.create()
-ctfws_lcd = dofile("ctfws-lcd.lc")(ctfws, lcd, msg_tmr)
+flg_tmr = tmr.create()
+ctfws_lcd = dofile("ctfws-lcd.lc")(ctfws, lcd, msg_tmr, flg_tmr)
 ctfws_tmr = tmr.create()
 
 -- Draw the default display
@@ -29,6 +34,7 @@ local myBSSID = "00:00:00:00:00:00"
 
 local mqtt_reconn_cronentry
 local function mqtt_reconn()
+  dprint("Trying reconn...")
   mqtt_reconn_cronentry = cron.schedule("* * * * *", function(e)
     mqc:close(); dofile("nwfmqtt.lc").connect(mqc,"nwfmqtt.conf")
   end)
@@ -37,7 +43,7 @@ end
 
 local mqtt_beat_cronentry
 local function mqtt_beat()
-  mqtt_beat_cronentry = cron.schedule("*/5 * * * *", function(e) 
+  mqtt_beat_cronentry = cron.schedule("* * * * *", function(e)
     mqc:publish(mqttBootTopic,string.format("beat %d %s",rtctime.get(),myBSSID),1,1)
   end)
 end
@@ -70,6 +76,7 @@ function ctfws_start_tmr()
 end
 
 nwfnet.onmqtt["init"] = function(c,t,m)
+  dprint("MQTT", t, m)
   if t == "ctfws/game/config" then
     ctfws_tmr:unregister()
     if not m or m == "none"
@@ -91,19 +98,16 @@ nwfnet.onmqtt["init"] = function(c,t,m)
     ctfws_start_tmr() -- might have been unset; restart display if so
   elseif t == "ctfws/game/flags" then
    if not m or m == "" then
-     ctfws:setFlags("?","?")
-     ctfws_lcd:drawFlags()
+     if ctfws:setFlags("?","?") then ctfws_lcd:drawFlags() end
      return
    end
    local fr, fy = m:match("^%s*(%d+)%s+(%d+).*$")
    if fr ~= nil then
-     ctfws:setFlags(tonumber(fr),tonumber(fy))
-     ctfws_lcd:drawFlags()
+     if ctfws:setFlags(tonumber(fr),tonumber(fy)) then ctfws_lcd:drawFlags() end
      return
    end
    if m:match("^%s*%?.*$") then
-     ctfws:setFlags("?","?")
-     ctfws_lcd:drawFlags()
+     if ctfws:setFlags("?","?") then ctfws_lcd:drawFlags() end
    end
   elseif t:match("^ctfws/game/message") then
     boot_message_hack = nil
@@ -126,6 +130,7 @@ end
 -- network callbacks
 
 nwfnet.onnet["init"] = function(e,c)
+  dprint("NET", e)
   if     e == "mqttdscn" and c == mqc then
     if mqtt_beat_cronentry then mqtt_beat_cronentry:unschedule() mqtt_beat_cronentry = nil end
     if not mqtt_reconn_cronentry then mqtt_reconn() end
@@ -134,11 +139,13 @@ nwfnet.onnet["init"] = function(e,c)
     if mqtt_reconn_cronentry then mqtt_reconn_cronentry:unschedule() mqtt_reconn_cronentry = nil end
     if not mqtt_beat_cronentry then mqtt_beat() end
     mqc:publish(mqttBootTopic,"alive",1,1)
-    mqc:subscribe("ctfws/game/config",2)
-    mqc:subscribe("ctfws/game/endtime",2)
-    mqc:subscribe("ctfws/game/flags",2)
-    mqc:subscribe("ctfws/game/message",2)      -- broadcast messages
-    mqc:subscribe("ctfws/game/message/jail",2) -- jail-specific messages
+    mqc:subscribe({
+      ["ctfws/game/config"] = 2,
+      ["ctfws/game/endtime"] = 2,
+      ["ctfws/game/flags"] = 2,
+      ["ctfws/game/message"] = 2,      -- broadcast messages
+      ["ctfws/game/message/jail"] = 2, -- jail-specific messages
+    })
     ctfws_lcd:drawFlagsMessage("MQTT CONNECTED")
   elseif e == "wstagoip"              then
     if not mqtt_reconn_cronentry then mqtt_reconn() end