Mercurial > code > home > repos > homeauto
changeset 37:8e55a6a9c425
add shiftbrites to bedroom arduino
Ignore-this: c0ce65f20b52679af58b9e31bcc3cf2e
author | drewp@bigasterisk.com |
---|---|
date | Sat, 25 Aug 2012 14:20:45 -0700 |
parents | 0ab069867c64 |
children | 8f00302ba2e4 |
files | service/bedroomArduino/bed/bed.pde service/bedroomArduino/bedroomArduino.py |
diffstat | 2 files changed, 111 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/service/bedroomArduino/bed/bed.pde Tue Aug 07 23:24:10 2012 -0700 +++ b/service/bedroomArduino/bed/bed.pde Sat Aug 25 14:20:45 2012 -0700 @@ -63,12 +63,66 @@ #define SWITCH_SELECT_B 9 #define SWITCH_SELECT_C 8 #define SPEAKER_CHOICE 13 +#define SHIFTBRITE_L 5 +#define SHIFTBRITE_D 11 +#define SHIFTBRITE_C 12 + +unsigned long SB_CommandPacket; +int SB_CommandMode; +int SB_BlueCommand; +int SB_RedCommand; +int SB_GreenCommand; + +#define LEDCHANS 5 +int vals[LEDCHANS * 3]; + +#define SHIFT(val) shiftOut(SHIFTBRITE_D, SHIFTBRITE_C, MSBFIRST, val) + +void SB_SendPacket() { + SB_CommandPacket = SB_CommandMode & B11; + SB_CommandPacket = (SB_CommandPacket << 10) | (SB_BlueCommand & 1023); + SB_CommandPacket = (SB_CommandPacket << 10) | (SB_RedCommand & 1023); + SB_CommandPacket = (SB_CommandPacket << 10) | (SB_GreenCommand & 1023); + + SHIFT(SB_CommandPacket >> 24); + SHIFT(SB_CommandPacket >> 16); + SHIFT(SB_CommandPacket >> 8); + SHIFT(SB_CommandPacket); + +} +void latch() { + delayMicroseconds(100); + digitalWrite(SHIFTBRITE_L, HIGH); // latch data into registers + delayMicroseconds(100); + digitalWrite(SHIFTBRITE_L, LOW); +} +void refresh() { + /* send all pixels */ + SB_CommandMode = B00; + for (int pixel=0; pixel < LEDCHANS; pixel++) { + SB_RedCommand = vals[pixel * 3 + 0]; + SB_GreenCommand = vals[pixel * 3 + 1]; + SB_BlueCommand = vals[pixel * 3 + 2]; + SB_SendPacket(); + } + latch(); +} +void setCurrent(unsigned char r, unsigned char g, unsigned char b) { + /* 127 = max */ + SB_CommandMode = B01; // Write to current control registers + SB_RedCommand = r; + SB_GreenCommand = g; + SB_BlueCommand = b; + SB_SendPacket(); + latch(); +} + void setup() { - + pinMode(2, INPUT); digitalWrite(2, LOW); -// PIR sensor DC-SS015 from http://www.gadgettown.com/Pyroelectric-Infrared-PIR-Motion-Sensor-Detector-Module-E2013.html +// PIR sensor DC-SS015 from http://www.gadgettown.com/Pyroelectric-Infrared-PIR-Motion-Sensor-Detector-Module-E2013.html but that didn't work well, so I got one from dealextreme that does. It's on analog 4 right now, not D2. pinMode(SWITCH_X, INPUT); digitalWrite(SWITCH_X, LOW); pinMode(SWITCH_Y, INPUT); digitalWrite(SWITCH_Y, LOW); @@ -77,7 +131,13 @@ pinMode(SWITCH_SELECT_B, OUTPUT); pinMode(SWITCH_SELECT_C, OUTPUT); pinMode(SPEAKER_CHOICE, OUTPUT); + pinMode(SHIFTBRITE_L, OUTPUT); + pinMode(SHIFTBRITE_D, OUTPUT); + pinMode(SHIFTBRITE_C, OUTPUT); + for (int i=0; i < LEDCHANS; i++) { + setCurrent(127, 127, 127); + } Serial.begin(115200); } @@ -88,7 +148,7 @@ void loop() { - unsigned char head, cmd, arg; + unsigned char head, cmd, arg, i; if (Serial.available() >= 3) { head = Serial.read(); @@ -131,14 +191,19 @@ Serial.print(", \"door\":"); Serial.print(digitalRead(SWITCH_Y)); - Serial.print("}\n"); + Serial.print(",\"led\":\"v2\"}\n"); } else if (cmd == 0x02) { // speaker digitalWrite(SPEAKER_CHOICE, arg); Serial.print("{\"speakerChoice\":"); Serial.print((int)arg); Serial.print("}\n"); + } else if (cmd == 0x03) { // set leds. arg is the number of data bytes coming + while (arg--) { + while (Serial.available() < 1) NULL; + SHIFT(Serial.read()); + } + latch(); + Serial.print("{\"ok\":1}\n"); } } } - -
--- a/service/bedroomArduino/bedroomArduino.py Tue Aug 07 23:24:10 2012 -0700 +++ b/service/bedroomArduino/bedroomArduino.py Sat Aug 25 14:20:45 2012 -0700 @@ -5,7 +5,7 @@ from __future__ import division -import cyclone.web, json, traceback, os, sys, time, logging +import cyclone.web, json, traceback, os, sys, time, logging, bitstring from twisted.internet import reactor, task from twisted.web.client import getPage sys.path.append("/my/proj/house/frontdoor") @@ -14,6 +14,9 @@ from cycloneerr import PrettyErrorHandler from logsetup import log +sys.path.append("/my/proj/pixel/shiftweb") +from shiftweb import hexFromRgb, rgbFromHex + sys.path.append("/my/site/magma") from stategraph import StateGraph from rdflib import Namespace @@ -34,11 +37,28 @@ def poll(self): self.ser.write("\x60\x01\x00") ret = self.ser.readJson() + ret['motion'] = int(ret['motion'] > 100) return ret def setSpeakerChoice(self, pillow): self.ser.write("\x60\x02" + chr(pillow)) - return self.ser.readJson() + return self.ser.readJson() + + def setLeds(self, colors): + """ + shift out this sequence of (r,g,b) triples of 10-bit ints + The nearest led gets color[0], etc. + """ + resetCurrent = "".join(bitstring.pack("0b01, uint:10, uint:10, uint:10", + 127, 127, 127).bytes + for loop in range(len(colors))) + out = "".join(bitstring.pack("0b00, uint:10, uint:10, uint:10", + b, r, g).bytes + for r,g,b in reversed(colors)) + out = resetCurrent + out + self.ser.write("\x60\x03" + chr(len(out)) + out) + msg = self.ser.readJson() + assert msg == {"ok":1}, msg class Index(PrettyErrorHandler, cyclone.web.RequestHandler): def get(self): @@ -56,6 +76,18 @@ ret = self.settings.arduino.setSpeakerChoice(int(self.get_argument('pillow'))) self.write(ret) +class Brite(PrettyErrorHandler, cyclone.web.RequestHandler): + def put(self, which): + which = int(which) + brites = self.settings.brites + if which + 1 > len(brites): + brites.extend([(0,0,0)] * (which + 1 - len(brites))) + brites[which] = rgbFromHex(self.request.body) + + self.settings.arduino.setLeds(brites) + self.set_header("Content-Type", "text/plain") + self.write("ok") + class GraphPage(PrettyErrorHandler, cyclone.web.RequestHandler): def get(self): self.set_header("Content-Type", "application/x-trig") @@ -75,7 +107,7 @@ self.period = period self.lastValues = None self.lastPollTime = 0 - self.lastMotion = False + self.lastMotion = None def assertIsCurrent(self): """raise an error if the poll data is not fresh""" @@ -91,8 +123,8 @@ except ValueError, e: print e else: - print newData - return + #print newData # for testing + self.lastPollTime = now self.lastValues = newData # for other data besides the blinks self.processMotion(newData['motion']) @@ -121,7 +153,7 @@ if __name__ == '__main__': config = { # to be read from a file - 'arduinoPort': '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A4001lVK-if00-port0', + 'arduinoPort': '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A4001nIu-if00-port0', 'servePort' : 9088, 'pollFrequency' : 6, 'boardName' : 'bedroom', # gets sent with updates @@ -142,5 +174,6 @@ (r"/", Index), (r"/graph", GraphPage), (r'/speakerChoice', SpeakerChoice), - ], arduino=ard, poller=p)) + (r'/brite/(\d+)', Brite), + ], arduino=ard, poller=p, brites=[])) reactor.run()