Browse Source

Merge branch 'feature/2019-update'

DarkMorford 5 years ago
parent
commit
2a05ab3b36
6 changed files with 194 additions and 54 deletions
  1. 11 5
      code/Pipfile.lock
  2. 28 2
      code/boot.py
  3. 13 0
      code/button.py
  4. 17 5
      code/config.json.tmpl
  5. 93 42
      code/main.py
  6. 32 0
      code/quadrature.py

+ 11 - 5
code/Pipfile.lock

@@ -31,10 +31,10 @@
         },
         "ecdsa": {
             "hashes": [
-                "sha256:163c80b064a763ea733870feb96f9dd9b92216cfcacd374837af18e4e8ec3d4d",
-                "sha256:9814e700890991abeceeb2242586024d4758c8fc18445b194a49bd62d85861db"
+                "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e",
+                "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe"
             ],
-            "version": "==0.13.3"
+            "version": "==0.14.1"
         },
         "esptool": {
             "hashes": [
@@ -45,8 +45,7 @@
         },
         "pyaes": {
             "hashes": [
-                "sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f",
-                "sha256:0b6ec2e5058000d89ae65252dd53f1c5e27936dfd750e27fc2a51df74fe3dde9"
+                "sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f"
             ],
             "version": "==1.6.1"
         },
@@ -63,6 +62,13 @@
                 "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544"
             ],
             "version": "==0.10.3"
+        },
+        "six": {
+            "hashes": [
+                "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
+                "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
+            ],
+            "version": "==1.13.0"
         }
     },
     "develop": {}

+ 28 - 2
code/boot.py

@@ -1,7 +1,33 @@
 # This file is executed on every boot (including wake-boot from deepsleep)
 #import esp
 #esp.osdebug(None)
+
+# Disable built-in WiFi access point
+import network
+wifi_ap = network.WLAN(network.AP_IF)
+wifi_ap.active(False)
+del wifi_ap
+del network
+
+# Load configuration data from file
+import ujson
+with open('config.json', encoding='utf8') as fd:
+    CONFIG = ujson.load(fd)
+del ujson
+
+# Define input handler
+import quadrature
+input_handler = quadrature.Encoder(CONFIG['pins']['encoder_A'], CONFIG['pins']['encoder_B'])
+del quadrature
+
+# Set up LED pins
+from machine import Pin, Signal
+led_red1 = Signal(CONFIG['pins']['led_1'], Pin.OUT, value=0, invert=False)
+led_red2 = Signal(CONFIG['pins']['led_2'], Pin.OUT, value=0, invert=False)
+led_green = Signal(CONFIG['pins']['led_3'], Pin.OUT, value=0, invert=False)
+del Pin, Signal
+
+# Clean up temporary setup variables
 import gc
-#import webrepl
-#webrepl.start()
 gc.collect()
+del gc

+ 13 - 0
code/button.py

@@ -0,0 +1,13 @@
+from machine import Pin
+
+class Button:
+    def __init__(self, pin):
+        self.trigger = pin
+        self.pressed = False
+        self.trigger.irq(self._cb, Pin.IRQ_FALLING)
+
+    def reset(self):
+        self.pressed = False
+
+    def _cb(self, pin):
+        self.pressed = True

+ 17 - 5
code/config.json.tmpl

@@ -1,7 +1,19 @@
 {
-	"wifi": {
-		"ssid": "LunarModule",
-		"password": "DesertBus"
-	},
-	"buttonId": 0
+  "pins": {
+    "encoder_A": 4,
+    "encoder_B": 5,
+    "led_1": 12,
+    "led_2": 13,
+    "led_3": 14,
+    "play_dat": 0
+  },
+  "logic": {
+    "sleep_time": 3,
+    "active_time": 60,
+    "wake_threshold": 25
+  },
+  "wifi": {
+    "ssid": "DesertBus",
+    "password": "iwantinternet"
+  }
 }

+ 93 - 42
code/main.py

@@ -1,54 +1,105 @@
-from machine import Pin, Signal
-LED_PIN = Signal(13, Pin.OUT, invert=False)
-BUTTON_PIN = Pin(0, Pin.IN)
+import button
+import machine
+from machine import Pin
+import network
+import urequests as requests
+import utime
 
-button_triggered = False
-def button_handler(pin):
-    global button_triggered
-    button_triggered = True
+BTN_IDLE = 0
+BTN_FWD_1 = 1
+BTN_FWD_2 = 2
+BTN_FWD_RDY = 3
+BTN_REV_1 = 4
+BTN_REV_2 = 5
+BTN_REV_RDY = 6
 
-# Turn off "ready" LED
-LED_PIN.off()
+def full_reset():
+    global current_state
+    led_red1.off()
+    led_red2.off()
+    led_green.off()
+    activity_timeout.deinit()
+    THE_BUTTON.reset()
+    current_state = BTN_IDLE
+    input_handler.reset()
+    input_handler.enable()
+    wifi.active(False)
 
-# Read configuration from JSON file
-with open('config.json') as fd:
-    import ujson
-    config = ujson.load(fd)
+def check_forward_1(handler):
+    if handler.total_change > 100:
+        led_red2.on()
+        handler.reset()
+        return BTN_FWD_2
+    return BTN_FWD_1
 
-# Configure wireless networking
-import network
-wifi_host = network.WLAN(network.AP_IF)
-wifi_host.active(False)
+def check_forward_2(handler):
+    global button_triggered
+    if handler.total_change > 150 and wifi.isconnected():
+        led_green.on()
+        button_triggered = False
+        print('Button armed')
+        return BTN_FWD_RDY
+    return BTN_FWD_2
+
+def check_forward_trigger(handler):
+    if (THE_BUTTON.pressed):
+        # Ping overlay server
+        # requests.get('http://192.168.0.210:42069/rdp')
+        led_red1.off()
+        led_red2.off()
+        led_green.off()
+        activity_timeout.deinit()
+        machine.lightsleep(5)
+        THE_BUTTON.reset()
+        return BTN_IDLE
+    return BTN_FWD_RDY
 
-wifi_guest = network.WLAN(network.STA_IF)
-wifi_guest.active(True)
-if not wifi_guest.isconnected():
-    wifi_guest.connect(config['wifi']['ssid'], config['wifi']['password'])
-    while not wifi_guest.isconnected():
-        pass
-print(wifi_guest.ifconfig())
+def time_up(timer):
+    print('Timeout exceeded, resetting')
+    full_reset()
 
-# Set up interrupt handler
-BUTTON_PIN.irq(button_handler, Pin.IRQ_RISING)
+btn_pin = Pin(CONFIG['pins']['play_dat'], Pin.IN, Pin.PULL_UP)
+THE_BUTTON = button.Button(btn_pin)
 
-# Turn on "ready" LED
-LED_PIN.on()
+activity_timeout = machine.Timer(-1)
+current_state = BTN_IDLE
 
-# Enter main loop
-import time
+wifi = network.WLAN(network.STA_IF)
 while True:
-    if button_triggered:
-        import urequests as requests
+    while current_state == BTN_IDLE:
+        machine.lightsleep(CONFIG['logic']['sleep_time'] * 1000)
+        if input_handler.total_change > CONFIG['logic']['wake_threshold']:
+            print('Entering BTN_FWD_1')
+            current_state = BTN_FWD_1
 
-        LED_PIN.off()
+    led_red1.on()
+    wifi.active(True)
+    wifi.connect(CONFIG['wifi']['ssid'], CONFIG['wifi']['password'])
+    input_handler.disable()
+    start_time = utime.ticks_ms()
+    activity_timeout.init(mode=machine.Timer.ONE_SHOT, callback=time_up,
+                          period=CONFIG['logic']['active_time'] * 1000)
+    while current_state == BTN_FWD_1:
+        machine.lightsleep(100)
+        if utime.ticks_diff(utime.ticks_ms(), start_time) > 1500:
+            print('Entering BTN_FWD_2')
+            current_state = BTN_FWD_2
 
-        btn_id = config['buttonId']
-        endpoint = 'http://192.168.0.212:42069/rdp?id={0}'.format(btn_id)
-        res = requests.get(endpoint)
-#       print(res.status_code)
+    led_red2.on()
+    start_time = utime.ticks_ms()
+    while current_state == BTN_FWD_2:
+        machine.lightsleep(100)
+        if (utime.ticks_diff(utime.ticks_ms(), start_time) > 1500) and wifi.isconnected():
+            print('Entering BTN_FWD_RDY')
+            current_state = BTN_FWD_RDY
 
-        time.sleep(5)
-        button_triggered = False
-        LED_PIN.on()
-    else:
-        time.sleep(1)
+    led_green.on()
+    THE_BUTTON.reset()
+    while current_state == BTN_FWD_RDY:
+        machine.lightsleep(100)
+        if THE_BUTTON.pressed:
+            print('Launching dance party')
+            requests.get('http://192.168.0.210:42069/rdp')
+            current_state = BTN_IDLE
+
+    full_reset()

+ 32 - 0
code/quadrature.py

@@ -0,0 +1,32 @@
+from machine import Pin
+
+class Encoder:
+    _increment_grid = [[0, -1, 1, None],
+                       [1, 0, None, -1],
+                       [-1, None, 0, 1],
+                       [None, 1, -1, 0]]
+
+    @property
+    def total_change(self):
+        return self._total_change
+
+    def __init__(self, channel_a, channel_b):
+        self.channel_a = self._configure_channel(channel_a)
+        self.reset()
+
+    def disable(self):
+        self.channel_a.irq(None)
+
+    def enable(self):
+        self.channel_a.irq(self._irq_cb, trigger=Pin.IRQ_RISING)
+
+    def reset(self):
+        self._total_change = 0
+
+    def _irq_cb(self, input_pin):
+        self._total_change += 1
+
+    def _configure_channel(self, pin):
+        p = pin if isinstance(pin, Pin) else Pin(pin, Pin.IN, pull=Pin.PULL_UP)
+        p.irq(self._irq_cb, trigger=Pin.IRQ_RISING)
+        return p