changeset 157:28c2db876548

busybox py and arduino Ignore-this: eea165c21e11600b5ac6787cbbb2239
author drewp@bigasterisk.com
date Mon, 19 Jan 2015 18:02:47 -0800
parents 08b398a0626b
children 75b1dc5c0bdc
files service/busyboxArduino/DFR_Key.cpp service/busyboxArduino/DFR_Key.h service/busyboxArduino/busybox.py service/busyboxArduino/main.ino service/busyboxArduino/makefile service/busyboxArduino/pydeps
diffstat 6 files changed, 372 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/busyboxArduino/DFR_Key.cpp	Mon Jan 19 18:02:47 2015 -0800
@@ -0,0 +1,62 @@
+// rewritten from distro version by drewp 2015-01-04
+
+#include "Arduino.h"
+#include "DFR_Key.h"
+
+static int DEFAULT_KEY_PIN = 0; 
+static int DEFAULT_THRESHOLD = 5;
+
+// Updated for my board
+static int UPKEY_ARV = 103; //that's read "analogue read value"
+static int DOWNKEY_ARV = 266;
+static int LEFTKEY_ARV = 426;
+static int RIGHTKEY_ARV = 0;
+static int SELKEY_ARV = 668;
+static int NOKEY_ARV = 1023;
+
+DFR_Key::DFR_Key()
+{	
+  _refreshRate = 10;
+  _keyPin = DEFAULT_KEY_PIN;
+  _threshold = DEFAULT_THRESHOLD;
+  _keyIn = NO_KEY;
+  _curInput = NO_KEY;
+  _curKey = NO_KEY;
+  _prevInput = NO_KEY;
+  _prevKey = NO_KEY;
+  _oldTime = 0;
+}
+
+int DFR_Key::getKey()
+{
+  if (millis() < _oldTime + _refreshRate) {
+    return SAMPLE_WAIT;
+  }
+
+  _prevInput = _curInput;
+  _curInput = analogRead(_keyPin);
+  _oldTime = millis();
+
+  if (_curInput != _prevInput) {
+    // We could be in the middle of a key change
+    return SAMPLE_WAIT;
+  }
+
+  _prevKey = _curKey;
+
+  int curLo = _curInput - _threshold;
+  int curHi = _curInput + _threshold;
+  if (      curHi > UPKEY_ARV    && curLo < UPKEY_ARV)    _curKey = UP_KEY;
+  else if ( curHi > DOWNKEY_ARV  && curLo < DOWNKEY_ARV)  _curKey = DOWN_KEY;
+  else if ( curHi > RIGHTKEY_ARV && curLo < RIGHTKEY_ARV) _curKey = RIGHT_KEY;
+  else if ( curHi > LEFTKEY_ARV  && curLo < LEFTKEY_ARV)  _curKey = LEFT_KEY;
+  else if ( curHi > SELKEY_ARV   && curLo < SELKEY_ARV)   _curKey = SELECT_KEY;
+  else                                                    _curKey = NO_KEY;      
+
+  return _curKey;
+}
+
+void DFR_Key::setRate(int rate)
+{
+  _refreshRate = rate;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/busyboxArduino/DFR_Key.h	Mon Jan 19 18:02:47 2015 -0800
@@ -0,0 +1,33 @@
+#ifndef DFR_Key_h
+#define DFR_Key_h
+
+#include "Arduino.h"
+
+#define SAMPLE_WAIT -1
+#define NO_KEY 0
+#define UP_KEY 3
+#define DOWN_KEY 4
+#define LEFT_KEY 2
+#define RIGHT_KEY 5
+#define SELECT_KEY 1
+
+class DFR_Key
+{
+  public:
+    DFR_Key();
+    int getKey();
+    void setRate(int);
+  private:
+    int _refreshRate;
+    int _keyPin;
+    int _threshold;
+    int _keyIn;
+    int _curInput;
+    int _curKey;
+    int _prevInput;
+    int _prevKey;
+    boolean _change;
+    unsigned long _oldTime;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/busyboxArduino/busybox.py	Mon Jan 19 18:02:47 2015 -0800
@@ -0,0 +1,96 @@
+from __future__ import division
+import serial, struct, json, sys
+
+from rdflib import Namespace, Literal
+sys.path.append("/my/site/magma")
+from stategraph import StateGraph
+import klein
+from twisted.internet import task
+import random, time
+
+import restkit
+reasoning = restkit.Resource("http://bang:9071/", timeout=1)
+ROOM = Namespace("http://projects.bigasterisk.com/room/")
+
+def sendOneShot(stmt):
+    try:
+        t1 = time.time()
+        print "post to reasoning", stmt
+        p = reasoning.post("oneShot",
+                           headers={"content-type": "text/n3"},
+                           payload=("%s %s %s ." %
+                                    tuple(n.n3() for n in stmt)))
+    except restkit.errors.RequestFailed:
+        print "oneShot failed"
+        return
+    print "posted in %.04f sec. %r" % (time.time() - t1,
+                                       p.body_string())
+    
+
+class Busybox(object):
+    def __init__(self, port='/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A4001lVK-if00-port0'):
+        self.serial = serial.Serial(port, baudrate=115200, timeout=.2)
+
+    def poll(self):
+        for tries in range(5):
+            self.serial.write('\x60\x00')
+            line = self.serial.readline()
+            if not line.startswith('{'):
+                continue
+            if tries > 0:
+                print "after %s tries" % tries
+            return json.loads(line)
+        return {'error': 'invalid response'}
+        
+    def writeMessage(self, row, col, text):
+        msg = struct.pack('BBBBB', 0x60, 0x01, row, col, len(text)) + text
+        self.serial.write(msg)
+
+    def setBacklight(self, level):
+        self.serial.write(struct.pack('BBB', 0x60, 0x02, level))
+
+sendOneShot((ROOM['greets'],
+             ROOM['change'],
+             ROOM['down']))
+
+bb = Busybox()
+words = open('/usr/share/dict/words').readlines()
+
+lastWordTime = 0
+last = None
+s1 = []
+
+def poll():
+    global lastWordTime, s1, last
+    now = time.time()
+    if now - lastWordTime > 1:
+        msg = '%15s' % random.choice(words).strip()[:15]
+        bb.writeMessage(1, 1, msg)
+        lastWordTime = now
+    last = bb.poll()
+    if 'slider1' in last:
+        s1 = s1[-5:] + [last['slider1']]
+        if len(s1) > 4:
+            median = sorted(s1)[2]
+            bb.setBacklight(min(255, median // 4))
+    if 'keyDown' in last:
+        keyNum = last['keyDown']
+        sendOneShot((ROOM['ariBed/button%s' % keyNum],
+                     ROOM['change'],
+                     ROOM['down']))
+
+
+@klein.route('/graph', methods=['GET'])
+def getGraph(request):
+    g = StateGraph(ROOM.busybox)
+    g.add((ROOM.busybox, ROOM.localHour, Literal('x')))
+    for attr in ['slider1', 'slider2', 'slider3', 'slider4']:
+        # needs: smoothing, exp curve correction
+        g.add((ROOM['busybox/%s' % attr], ROOM.value, Literal(round(last[attr] / 1021, 3))))
+    request.setHeader('Content-type', 'application/x-trig')
+    return g.asTrig()
+
+task.LoopingCall(poll).start(.05)
+        
+klein.run('0.0.0.0', port=9056)
+
--- a/service/busyboxArduino/main.ino	Mon Jan 19 18:02:27 2015 -0800
+++ b/service/busyboxArduino/main.ino	Mon Jan 19 18:02:47 2015 -0800
@@ -1,8 +1,11 @@
 #include <Arduino.h>
 #include <LiquidCrystal.h>
+#include "DFR_Key.h"
+#include "IRremote.h"
 
+// see http://www.dfrobot.com/image/data/DFR0009/LCDKeypad%20Shield%20V1.0%20SCH.pdf
 #define I2C_ADDR      0x27 // I2C address of PCF8574A
-#define BACKLIGHT_PIN 3
+#define BACKLIGHT_PIN 10
 #define En_pin        9
 #define Rw_pin        1
 #define Rs_pin        8
@@ -11,41 +14,175 @@
 #define D6_pin        6
 #define D7_pin        7
 
-LiquidCrystal twilcd(Rs_pin, Rw_pin, En_pin, D4_pin, D5_pin, D6_pin, D7_pin, BACKLIGHT_PIN, POSITIVE);
+LiquidCrystal lcd(Rs_pin, Rw_pin, En_pin, D4_pin, D5_pin, D6_pin, D7_pin, BACKLIGHT_PIN, POSITIVE);
+DFR_Key keypad;
 
 #define debugLed 13
 
+byte backlightStandard = 0;
+byte backlightCurrent = 0;
+byte backlightKeypressBoost = 30;
+
+int lastKey = -1;
+int lastUnsentKeydown = -1;
+uint16_t steps = 0;
+uint16_t stepDelayPerBrightnessFade = 2048;
+
+IRsend irsend;
+
+void sendnec(byte addr, byte cmd) {
+  uint32_t w = 0x00ff0000;
+  w |= (cmd << 8) & 0xff00;
+  w |= (~cmd) & 0xff;
+  irsend.sendNEC(w, 32);
+ delay(100);
+}
 
 void setup(void) {
-  int i;
   pinMode(debugLed, OUTPUT);
-
   Serial.begin(115200);
-  
-  twilcd.begin(16,2);
-  twilcd.setBacklight(HIGH);
-  twilcd.home();
-  //1234567890123456
-  //I2C/TWI BackPack
-  twilcd.print("hello world");
-  // ana read and display
-  while (1) {
-    while (Serial.available() <= 2) {
-    }
-    i = Serial.read();
-    if (i != 0x60) {
-      continue;
-    }
-    i = Serial.read(); // command
-    if (i == 0) { // set strip: 0x60 0x00 <numPixels * 3 bytes>
-      digitalWrite(debugLed, 1);
-      delay(1000);
-      digitalWrite(debugLed, 0);
-    } else {
-        // unknown command
-    }
+  keypad.setRate(10);
+  lcd.begin(16,2);
+
+
+  for (int i = 0; i < 1; i++) {
+    digitalWrite(debugLed,1);
+    /*
+44 key remote. command chart: http://blog.allgaiershops.com/2012/05/
+Up  Down Play Pwr
+0x3A 0xBA 0x82 0x02
+
+Red  Grn  Blu  Wht
+1A   9A   A2   22
+
+2A   AA   92   12
+
+0A   8A   B2   32
+
+38   B8   78   F8
+
+18   98   58   D8
+
+RUp  GUp  BUp  Quick
+28   A8   68   E8
+
+RDn  GDn  BDn  Slow
+08   88   48   C8
+
+DIY1 DIY2 DIY3 AUTO
+30   B0   70   F0
+
+DIY4 DIY5 DIY6 Flash
+10   90   50   D0
+
+JMP3 JMP7 Fade Fade7
+20   A0   60   E0
+      
+    irsend.sendNEC(0xff0002fd, 32);
+    irsend.sendNEC(0x00ff02fd, 32);
+    irsend.sendNEC(0x00ff40bf, 32);
+    irsend.sendNEC(0xff0040bf, 32);
+    */
+    delay(100);
+
+    // LED618 remote command byte (addr is ff)
+    // see https://github.com/alistairallan/RgbIrLed/blob/master/RgbIrLed.cpp#L44
+#define ON                0xE0
+#define OFF               0x60
+#define BRIGHTNESS_UP     0xA0
+#define BRIGHTNESS_DOWN   0x20
+#define FLASH             0xF0
+#define STROBE            0xE8
+#define FADE              0xD8
+#define SMOOTH            0xC8
+ 
+#define RED               0x90
+#define GREEN             0x10
+#define BLUE              0x50
+#define WHITE             0xD0
+ 
+#define ORANGE            0xB0
+#define YELLOW_DARK       0xA8
+#define YELLOW_MEDIUM     0x98
+#define YELLOW_LIGHT      0x88
+ 
+#define GREEN_LIGHT       0x30
+#define GREEN_BLUE1       0x28
+#define GREEN_BLUE2       0x18
+#define GREEN_BLUE3       0x08
+ 
+#define BLUE_RED          0x70
+#define PURPLE_DARK       0x68
+#define PURPLE_LIGHT      0x58
+#define PINK              0x48
+    sendnec(0xff, ON);
+    
+    digitalWrite(debugLed,0);
+    delay(100);
   }
 }
 
+
 void loop() {
+  while (Serial.available() <= 2) {
+    int localKey = keypad.getKey();
+    if (localKey != SAMPLE_WAIT) {
+      if (localKey != lastKey) {
+        if (lastKey == 0) {
+          backlightCurrent = min(255, backlightStandard +
+                                 backlightKeypressBoost);
+          lastUnsentKeydown = localKey;
+        }
+        lastKey = localKey;
+      }
+    }
+
+    if (backlightCurrent > backlightStandard) {
+      steps++;
+      if (steps % stepDelayPerBrightnessFade == 0) {
+        backlightCurrent--;
+      }
+    } else if (backlightCurrent < backlightStandard) {
+      backlightCurrent = backlightStandard;
+    }
+    lcd.setBacklight(backlightCurrent);
+  }
+  byte i = Serial.read();
+  if (i != 0x60) {
+    return;
+  }
+  i = Serial.read(); // command
+  if (i == 0) { // get status
+    Serial.print('{');
+    if (lastUnsentKeydown != -1) {
+      Serial.print("\"keyDown\":");
+      Serial.print(lastUnsentKeydown);
+      Serial.print(",");
+      lastUnsentKeydown = -1;
+    }
+    Serial.print("\"slider1\":"); Serial.print(analogRead(1));
+    Serial.print(",\"slider2\":"); Serial.print(analogRead(2));
+    Serial.print(",\"slider3\":"); Serial.print(analogRead(3));
+    Serial.print(",\"slider4\":"); Serial.print(analogRead(4));
+    Serial.print("}\n");
+  } else if (i == 1) { // write text
+    while (Serial.available() < 3) NULL;
+    byte row = Serial.read();
+    byte col = Serial.read();
+    byte nchars = Serial.read();
+    char buf[32];
+    char *p=buf;
+    while (nchars--) {
+      while (Serial.available() < 1) NULL;
+      *(p++) = Serial.read();
+    }
+    *p = 0;
+    lcd.setCursor(row, col);
+    lcd.print(buf);
+  } else if (i == 2) { // set backlight
+    while (Serial.available() < 1) NULL;
+    backlightStandard = Serial.read();
+  } else {
+    // unknown command
+  }
 }
--- a/service/busyboxArduino/makefile	Mon Jan 19 18:02:27 2015 -0800
+++ b/service/busyboxArduino/makefile	Mon Jan 19 18:02:47 2015 -0800
@@ -7,3 +7,8 @@
 
 setup:
 	ln -sf LiquidCrystal_V1.2.1/LiquidCrystal/LiquidCrystal.cpp LiquidCrystal.cpp
+	ln -sf IRremote/IRremote.cpp IRremote.cpp
+	ln -sf IRremote/IRremote.h IRremote.h
+	ln -sf IRremote/IRremoteInt.h IRremoteInt.h
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/busyboxArduino/pydeps	Mon Jan 19 18:02:47 2015 -0800
@@ -0,0 +1,12 @@
+SPARQLWrapper==1.6.4
+Twisted==14.0.2
+Werkzeug==0.9.6
+isodate==0.5.1
+klein==14.0.0
+pyserial==2.7
+python-dateutil==2.4.0
+rdflib==4.1.2
+restkit==4.2.2
+
+
+