Skip to content

Instantly share code, notes, and snippets.

@cyphunk
Last active September 4, 2017 15:18
Show Gist options
  • Save cyphunk/78965be2425a201a80ffb177810448a2 to your computer and use it in GitHub Desktop.
Save cyphunk/78965be2425a201a80ffb177810448a2 to your computer and use it in GitHub Desktop.
LED Proxy for Cuckoo rice cooker in Cuckoo theatre sohw
#include "FastLED.h"
#define NUM_LEDS 8
#define DATA_PIN PIN_D6
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 120
#define HEARTBEAT_MILLIS 5000
#define HEARTBEAT_CHAR "A"
bool DEBUG = 0;
CRGB leds[NUM_LEDS];
String inputCmd = "";
boolean cmdComplete = false;
unsigned long previousMillis = 0;
void p(char *fmt, ... )
{
char tmp[128];
va_list args;
va_start (args, fmt );
vsnprintf(tmp, 128, fmt, args);
va_end (args);
Serial.print(tmp);
}
void setup() {
delay(3000); // 3 second delay for recovery
FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
for (int i = 0; i < NUM_LEDS; i++)
leds[i] = CRGB::Black;
FastLED.show();
//Serial.begin(230400);
Serial.begin(115200);
inputCmd.reserve(200);
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
unsigned char bytecount = 0;
while (Serial.available() && bytecount < 10) {
// get the new byte:
char inChar = (char)Serial.read();
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
// if (inChar == '\n') {
if (inChar == '\n' || inChar == '!') { // ! for puredata
cmdComplete = true;
}
else {
if (inChar == '_')
inputCmd += " ";
else
inputCmd += inChar;
}
bytecount++;
}
}
byte LED = 0, R = 0, G = 0, B = 0;
unsigned long LEDstate [8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned long newstate = 0;
int len = 0;
char * pch;
void processCommand(String command) {
if (command.substring(0, 4) == "led ") {
if (DEBUG) p("is led command.\n");
LED = (byte) command.substring(4, 5).toInt();
if (DEBUG) p("for LED %d\n", LED);
command.remove(0, 6);
// if (command.substring(0, 4) == "name") {
// command.remove(0, 5);
// if (DEBUG) p("has Color name: %s\n", command.c_str());
// // FastLED/pixeltypes.h:
// if (command == "white") newstate = CRGB::White;
// else if (command == "black") newstate = CRGB::Black;
// else if (command == "red") newstate = CRGB::Red;
// else if (command == "darkred") newstate = CRGB::DarkRed;
// else if (command == "lightred") newstate = CRGB::Pink;
// else if (command == "pink") newstate = CRGB::Pink;
//
// else if (command == "green") newstate = CRGB::Green;
// else if (command == "dakrgreen") newstate = CRGB::DarkGreen;
// else if (command == "lightgreen") newstate = CRGB::LightGreen;
// else if (command == "orange") newstate = CRGB::Orange;
// else if (command == "darkorange") newstate = CRGB::DarkOrange;
// else if (command == "lightorange") newstate = CRGB::OrangeRed;
//
// else if (command == "blue") newstate = CRGB::Blue;
// else if (command == "darkblue") newstate = CRGB::DarkBlue;
// else if (command == "lightblue") newstate = CRGB::LightBlue;
//
//
// else if (command == "cyan") newstate = CRGB::Cyan;
// else if (command == "darkcyan") newstate = CRGB::DarkCyan;
// else if (command == "lightcyan") newstate = CRGB::LightCyan;
// else if (command == "grey") newstate = CRGB::Grey;
// else if (command == "darkgrey") newstate = CRGB::DarkGrey;
// else if (command == "lightgrey") newstate = CRGB::LightGrey;
// else if (command == "gray") newstate = CRGB::Grey;
// else if (command == "darkgray") newstate = CRGB::DarkGrey;
// else if (command == "lightgray") newstate = CRGB::LightGrey;
//
// else if (command == "brown") newstate = CRGB::Brown;
// else if (command == "purple") newstate = CRGB::Purple;
// else if (command == "yellow") newstate = CRGB::Yellow;
// else if (command == "lime") newstate = CRGB::Lime;
// else if (command == "magenta") newstate = CRGB::Magenta;
// else if (command == "teal") newstate = CRGB::Teal;
// else if (command == "turquoise") newstate = CRGB::Turquoise;
// else if (command == "violet") newstate = CRGB::Violet;
// else {
// newstate = LEDstate[LED-1];
// if (DEBUG) p("unknown color: %s\n", command.c_str());
// }
// }
// else {
if (DEBUG) p("Assuming has RGB or 0|>0 state\n");
R = (byte) atoi(strtok((char*)command.c_str(), " ")) & 0xff;
pch = strtok(NULL, " ");
if (pch == NULL) {
if (DEBUG) p("Is on/off 0 or >0 state or white\n");
if (R > 0) newstate = CRGB::White;
else newstate = CRGB::Black;
}
else {
G = (byte) atoi(pch);
B = (byte) atoi(strtok(NULL, " ")) & 0xff;
newstate = (unsigned long)R << 16 | (unsigned long)G << 8 | B; // bloody hell
}
if (DEBUG) Serial.println(newstate); // printf has some issues it appears with %x and %lu
if (DEBUG || 1) Serial.println(newstate, HEX);
// }
if (LEDstate[LED-1] != newstate) {
if (DEBUG) p("Setting LED to 0x%08X %lu - ", ((unsigned long) newstate) & 0xffffff, ((unsigned long)newstate)& 0xffffff);
if (DEBUG) Serial.println(newstate);
LEDstate[LED-1] = newstate;
leds[LED-1] = newstate;
FastLED.show();
}
}
else if (command.substring(0, 5) == "debug") {
DEBUG = !DEBUG;
p("change debug state to: %s\n", DEBUG ? "true" : "false");
}
}
unsigned long currentMillis;
void loop() {
// send heartbeat
currentMillis = millis();
if (currentMillis - previousMillis >= HEARTBEAT_MILLIS) {
// save the last time you sent heartbeat
previousMillis = currentMillis;
Serial.println(HEARTBEAT_CHAR);
}
// process command
if (cmdComplete) {
processCommand(inputCmd);
// clear the string:
inputCmd = "";
cmdComplete = false;
}
serialEvent(); // teensy main.cpp doesn't have this after loop() call so, we call it
// Turn the LED on, then pause
// for (int i = 0; i < NUM_LEDS; i++)
// leds[i] = CRGB::White;
// FastLED.show();
// delay(500);
// // Now turn the LED off, then pause
// for (int i = 0; i < NUM_LEDS; i++)
// leds[i] = CRGB::Black;
// FastLED.show();
// delay(500);
}
#include "FastLED.h"
#define NUM_LEDS 8
#define DATA_PIN PIN_D6
#define BRIGHTNESS 96
#define FRAMES_PER_SECOND 120
#define HEARTBEAT_MILLIS 5000
#define HEARTBEAT_CHAR "A"
#define BUFFER_SIZE 128
#define COMMAND_LENGTH 11 // "1_#FFFFFF_!" this format is due to PureData blah:
// pure data translates 000000 to 0 in its pipeline. And it can't append ! gracefully
// and without _ it may send all chars or messages seperately slowing things down
bool DEBUG = 0;
CRGB leds[NUM_LEDS];
unsigned long previousMillis = 0;
void setup() {
delay(3000); // 3 second delay for recovery
FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
for (int i = 0; i < NUM_LEDS; i++)
leds[i] = CRGB::Black;
FastLED.show();
Serial.begin(230400);
}
char cmd[BUFFER_SIZE];
int queue = 0;
int offset;
bool reset_when_full = true; // reset buffer if any command must be dropped due to full unprocessed buffer
int errors = 0;
void serialEvent() {
// if reach end of buffer wait for commands to be processed
while (Serial.available() && offset < BUFFER_SIZE-COMMAND_LENGTH) {
// get the new byte:
char c = (char)Serial.read();
if (DEBUG) {Serial.print("c: ");Serial.println(c);}
if (c == 10 && c == 13)
continue;
else if (c == '_')
cmd[offset++] = ' ';
else
cmd[offset++] = c;
if (c == '!') { // ! for puredata
queue++;
processCommands_sm();
offset=0;
}
}
// if (queue > 0) {
// if (DEBUG) Serial.println("Buffer ready");
// processCommands();
// }
// if (offset >= BUFFER_SIZE)
// offset=0;
}
char _color[7];
void processCommands_sm() {
char led = 0;
unsigned long color;
led = cmd[0] - '0';
strncpy(_color, cmd+3, 6);
// Serial.println(_color);
_color[7] = '\0';
color = strtoul(_color, NULL, 16); // 0L on fail
leds[led-1] = CRGB(color);
FastLED.show();
}
void processCommands() {
char led = 0;
unsigned long color = 0;
char * _cmd = strtok(cmd, "!");
while (_cmd != NULL) {
if (DEBUG) {Serial.print("cmds: ");Serial.println(queue);}
if (DEBUG) {Serial.print("offset: ");Serial.println(offset);}
if (DEBUG) {Serial.print("cmd: ");Serial.println(_cmd);}
queue--;
if (_cmd == NULL) {
queue=0;
break;
}
led = _cmd[0] - '0';
_cmd+=3; //skip singled digit led number, "_" (or " ") and '#'
if (strlen(_cmd) == 7) {
color = strtoul(_cmd, NULL, 16); // 0L on fail
leds[led-1] = CRGB(color);
if (DEBUG) {Serial.print("set_led: ");Serial.print(led, DEC);Serial.print(" color: ");Serial.println(color, HEX);}
}
else {
errors++;
}
if (DEBUG) {Serial.print("use color: ");Serial.println(color, HEX);}
_cmd = strtok(NULL, "!");
}
queue=0;
offset=0;
FastLED.show();
}
unsigned long currentMillis;
void loop() {
serialEvent(); // teensy main.cpp doesn't have this after loop() call so, we call it
// // send heartbeat
// currentMillis = millis();
// if (currentMillis - previousMillis >= HEARTBEAT_MILLIS) {
// // save the last time you sent heartbeat
// previousMillis = currentMillis;
// Serial.println(HEARTBEAT_CHAR);
// }
}
// This script just attempts to rotate through some colors.
// Meant to test that the LED's are okay
#include "FastLED.h"
#define NUM_LEDS 8
#define DATA_PIN PIN_D6
#define BRIGHTNESS 96
CRGB leds[NUM_LEDS];
void setup() {
delay(3000); // 3 second delay for recovery
FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
for (int i = 0; i < NUM_LEDS; i++)
leds[i] = CRGB::Black;
FastLED.show();
Serial.begin(115200);
}
unsigned long currentMillis;
char * colors[] = { "FFFFFF\0", "FF0000\0", "00FF00\0", "0000FF\0" };
unsigned long color;
void loop() {
Serial.println("begin");
for (int c = 0; c<sizeof(colors)/sizeof(colors[0]); c++) {
Serial.print("color "); Serial.print(colors[c]);
Serial.print(" leds: ");
for (int led = 0; led<NUM_LEDS; led++) {
Serial.print(led,DEC);
color = strtoul(colors[c], NULL, 16); // 0L on fail
leds[led-1] = CRGB(color);
FastLED.show();
delay(200);
}
delay(500);
// turn off
for (int led = 0; led<NUM_LEDS; led++) {
leds[led-1] = CRGB::Black;
FastLED.show();
delay(100);
}
Serial.println(".");
delay(500);
}
delay(2000);
}
Attempting to program a Teensy2.0
Archlinux:
Arduino 1.8.2 + Teensduino 136 works for Teensy++2.0 but not Teensy2.0
OSX:
Arduino 1.8.2 + Teensduino 136 works for Teensy++2.0 but not Teensy2.0
Arduino 1.8.4 + Teensduino 138beta works for Teensy++2.0 but not Teensy2.0
Archlinux Teensy++2.0
[20792.125865] usb 3-1: new full-speed USB device number 121 using xhci_hcd
[20792.258271] cdc_acm 3-1:1.0: ttyACM0: USB ACM device
Bus 003 Device 121: ID 16c0:0483 Van Ooijen Technische Informatica Teensyduino Serial
Teensy2.0 already with blinky sketch loaded
[21005.421051] usb 3-1: new full-speed USB device number 127 using xhci_hcd
[21005.554511] hid-generic 0003:16C0:0486.003F: hiddev0,hidraw0: USB HID v1.11 Device [Teensyduino RawHID Device] on usb-0000:00:14.0-1/input0
[21005.555444] hid-generic 0003:16C0:0486.0040: hidraw1: USB HID v1.11 Device [Teensyduino RawHID Device] on usb-0000:00:14.0-1/input1
Bus 003 Device 127: ID 16c0:0486 Van Ooijen Technische Informatica Teensyduino RawHID
(results are same with or without teensy udev rules)
wget http://www.pjrc.com/teensy/49-teensy.rules
sudo cp 49-teensy.rules /etc/udev/rules.d/49-teensy.rules
sudo rm /etc/udev/rules.d/49-teensy.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
https://forum.pjrc.com/threads/45978-Cannot-program-Teensy-2-0-with-Arduino-gt-1-8-2-amp-Loader-gt-136?p=151603#post151603
#!/bin/bash
port=$(ls /dev/ttyACM* | tail -1)
echo using $port
stty -F $port 115200 raw
stty -F $port -echo
echo "test"
echo "led 1 1!" > $port
sleep 1
echo "led 1 0!" > $port
sleep 1
echo "debug!" > $port
iter=20
ii=7
for l in 1 2 3 4 5 6 7 8; do
echo "led $l 0!" > $port
sleep 0.1
done
echo "### TEST colors formats "
for i in 1 255_0_0 0_255_0 0_0_255 255_255_255 FFFFFF FF0000 00FF00 0000FF; do
#while [ 1 ] ; do
#for i in 1 255_255_255; do
echo color: $i
# one on at time
for l in 1 2 3 4 5 6 7 8; do
echo "led $l $i!" > $port
sleep 0.1
echo "led $l 0!" > $port
done
sleep 0.5
# all on
for l in 8 7 6 5 4 3 2 1; do
echo "led $l $i!" > $port
sleep 0.1
done
sleep 0.5
for l in 1 2 3 4 5 6 7 8; do
echo "led $l 0!" > $port
sleep 0.1
done
sleep 0.5
done
#done
sleep 2
echo "### TEST SPEED"
for i in 0.001 0.005 0.01 0.05 0.1 0.5; do
echo $i
mul=$(($iter*$ii))
ii=$(($ii-1))
while [ $mul -gt 0 ]; do
mul=$(($mul-1))
for l in 1 2 3 4 5 6 7 8; do
lp=$(($l-2))
if [ $lp -eq -1 ]; then
lp=7
fi
if [ $lp -eq -0 ]; then
lp=8
fi
echo "led $l 1!" > $port
echo "led $lp 0!" > $port
sleep $i
done
done
done
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment