Last active
August 8, 2017 19:33
-
-
Save mherweg/54baf4cb1cfe5066ac396977d6cb84cd to your computer and use it in GitHub Desktop.
firmware for Wifi Enabled LED Display "redshift"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#include <avr/pgmspace.h> | |
const uint8_t CHARSET[][5] PROGMEM = { | |
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // 20 space | |
{ 0x00, 0x00, 0x5f, 0x00, 0x00 }, // 21 ! | |
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // 22 " | |
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // 23 # | |
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // 24 $ | |
{ 0x23, 0x13, 0x08, 0x64, 0x62 }, // 25 % | |
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // 26 & | |
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // 27 ' | |
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // 28 ( | |
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // 29 ) | |
{ 0x14, 0x08, 0x3e, 0x08, 0x14 }, // 2a * | |
{ 0x08, 0x08, 0x3e, 0x08, 0x08 }, // 2b + | |
{ 0x00, 0x50, 0x30, 0x00, 0x00 }, // 2c , | |
{ 0x08, 0x08, 0x08, 0x08, 0x08 }, // 2d - | |
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // 2e . | |
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // 2f / | |
{ 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 30 0 | |
{ 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 31 1 | |
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 32 2 | |
{ 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 33 3 | |
{ 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 34 4 | |
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 35 5 | |
{ 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 36 6 | |
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 37 7 | |
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 38 8 | |
{ 0x06, 0x49, 0x49, 0x29, 0x1e }, // 39 9 | |
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // 3a : | |
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // 3b ; | |
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // 3c < | |
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // 3d = | |
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // 3e > | |
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // 3f ? | |
{ 0x32, 0x49, 0x79, 0x41, 0x3e }, // 40 @ | |
{ 0x7e, 0x11, 0x11, 0x11, 0x7e }, // 41 A | |
{ 0x7f, 0x49, 0x49, 0x49, 0x36 }, // 42 B | |
{ 0x3e, 0x41, 0x41, 0x41, 0x22 }, // 43 C | |
{ 0x7f, 0x41, 0x41, 0x22, 0x1c }, // 44 D | |
{ 0x7f, 0x49, 0x49, 0x49, 0x41 }, // 45 E | |
{ 0x7f, 0x09, 0x09, 0x09, 0x01 }, // 46 F | |
{ 0x3e, 0x41, 0x49, 0x49, 0x7a }, // 47 G | |
{ 0x7f, 0x08, 0x08, 0x08, 0x7f }, // 48 H | |
{ 0x00, 0x41, 0x7f, 0x41, 0x00 }, // 49 I | |
{ 0x20, 0x40, 0x41, 0x3f, 0x01 }, // 4a J | |
{ 0x7f, 0x08, 0x14, 0x22, 0x41 }, // 4b K | |
{ 0x7f, 0x40, 0x40, 0x40, 0x40 }, // 4c L | |
{ 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // 4d M | |
{ 0x7f, 0x04, 0x08, 0x10, 0x7f }, // 4e N | |
{ 0x3e, 0x41, 0x41, 0x41, 0x3e }, // 4f O | |
{ 0x7f, 0x09, 0x09, 0x09, 0x06 }, // 50 P | |
{ 0x3e, 0x41, 0x51, 0x21, 0x5e }, // 51 Q | |
{ 0x7f, 0x09, 0x19, 0x29, 0x46 }, // 52 R | |
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // 53 S | |
{ 0x01, 0x01, 0x7f, 0x01, 0x01 }, // 54 T | |
{ 0x3f, 0x40, 0x40, 0x40, 0x3f }, // 55 U | |
{ 0x1f, 0x20, 0x40, 0x20, 0x1f }, // 56 V | |
{ 0x3f, 0x40, 0x38, 0x40, 0x3f }, // 57 W | |
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // 58 X | |
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // 59 Y | |
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // 5a Z | |
{ 0x00, 0x7f, 0x41, 0x41, 0x00 }, // 5b [ | |
{ 0x02, 0x04, 0x08, 0x10, 0x20 }, // 5c backslash | |
{ 0x00, 0x41, 0x41, 0x7f, 0x00 }, // 5d ] | |
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // 5e ^ | |
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // 5f _ | |
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // 60 ` | |
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // 61 a | |
{ 0x7f, 0x48, 0x44, 0x44, 0x38 }, // 62 b | |
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // 63 c | |
{ 0x38, 0x44, 0x44, 0x48, 0x7f }, // 64 d | |
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // 65 e | |
{ 0x08, 0x7e, 0x09, 0x01, 0x02 }, // 66 f | |
{ 0x0c, 0x52, 0x52, 0x52, 0x3e }, // 67 g | |
{ 0x7f, 0x08, 0x04, 0x04, 0x78 }, // 68 h | |
{ 0x00, 0x44, 0x7d, 0x40, 0x00 }, // 69 i | |
{ 0x20, 0x40, 0x44, 0x3d, 0x00 }, // 6a j | |
{ 0x7f, 0x10, 0x28, 0x44, 0x00 }, // 6b k | |
{ 0x00, 0x41, 0x7f, 0x40, 0x00 }, // 6c l | |
{ 0x7c, 0x04, 0x18, 0x04, 0x78 }, // 6d m | |
{ 0x7c, 0x08, 0x04, 0x04, 0x78 }, // 6e n | |
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // 6f o | |
{ 0x7c, 0x14, 0x14, 0x14, 0x08 }, // 70 p | |
{ 0x08, 0x14, 0x14, 0x18, 0x7c }, // 71 q | |
{ 0x7c, 0x08, 0x04, 0x04, 0x08 }, // 72 r | |
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // 73 s | |
{ 0x04, 0x3f, 0x44, 0x40, 0x20 }, // 74 t | |
{ 0x3c, 0x40, 0x40, 0x20, 0x7c }, // 75 u | |
{ 0x1c, 0x20, 0x40, 0x20, 0x1c }, // 76 v | |
{ 0x3c, 0x40, 0x30, 0x40, 0x3c }, // 77 w | |
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // 78 x | |
{ 0x0c, 0x50, 0x50, 0x50, 0x3c }, // 79 y | |
{ 0x44, 0x64, 0x54, 0x4c, 0x44 }, // 7a z | |
{ 0x00, 0x08, 0x36, 0x41, 0x00 }, // 7b { | |
{ 0x00, 0x00, 0x7f, 0x00, 0x00 }, // 7c | | |
{ 0x00, 0x41, 0x36, 0x08, 0x00 }, // 7d } | |
{ 0x10, 0x08, 0x08, 0x10, 0x08 }, // 7e ~ | |
{ 0x00, 0x00, 0x00, 0x00, 0x00 } // 7f | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ESP8266 MQTT | |
this sketch subscibes 2 MQTT topics: | |
inTopic = "huette/clubraum/000/redshift/actuators/frame | |
receive a binary MQTT message and update the whole display | |
currently: 8 pixel in one byte , 8 x 8 = 64 byte per frame(picture) | |
later versions: maybe 1 byte per pixel for different level of brightness | |
inTopic2 = huette/clubraum/000/redshift/actuators/set_pixel | |
receive a command (ascii) | |
possible commands: | |
0-512 #1 (set one pixel) | |
0-512 #0 (clear one pixel) | |
text Hello (display Text, max 10 letters) | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <WiFiUdp.h> | |
#include <ArduinoOTA.h> | |
#include <PubSubClient.h> | |
#include "nokia5110_chars.h" | |
#include "conf.h" | |
//war: | |
#define TAKT D5 // D1 | |
#define HIDE D6 // D2 | |
#define DATA D7 // D3 | |
#define DEBUG | |
#ifdef DEBUG | |
#define DEBUG_PRINT(x) Serial.print (x) | |
#define DEBUG_PRINTDEC(x) Serial.print (x, DEC) | |
#define DEBUG_PRINTLN(x) Serial.println (x) | |
#else | |
#define DEBUG_PRINT(x) | |
#define DEBUG_PRINTDEC(x) | |
#define DEBUG_PRINTLN(x) | |
#endif | |
#define BIT_S(var,b) ((var&(1<<b))?1:0) | |
// clear bit | |
#ifndef cbi | |
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) | |
#endif | |
// set bit | |
#ifndef sbi | |
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) | |
#endif | |
WiFiClient espClient; | |
PubSubClient client(espClient); | |
/* position */ | |
uint8_t cursor_x; | |
uint8_t cursor_y; | |
int r,g,b; | |
byte framebuffer[NUMPIXELS]; | |
String stringPixel, stringFrame, stringIntopic ; | |
// WIP | |
String scrolltext = " Hello World!"; | |
void setup() { | |
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output | |
pinMode(DATA, OUTPUT); | |
pinMode(HIDE, OUTPUT); | |
pinMode(TAKT, OUTPUT); | |
Serial.begin(115200); | |
setup_wifi(); | |
delay(500); | |
client.setServer(mqtt_server, 1883); | |
client.subscribe("inTopic"); | |
client.subscribe("inTopic2"); | |
client.setCallback(callback); | |
stringPixel = String(inTopic2); | |
stringFrame = String(inTopic); | |
ArduinoOTA.setHostname("redshift"); // give an name to our module | |
ArduinoOTA.begin(); // OTA initialization | |
} //setup | |
void setup_wifi() { | |
delay(10); | |
Serial.print("Connecting to "); | |
Serial.println(ssid); | |
WiFi.softAPdisconnect(true); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) { | |
framebuffer[8]=8; | |
show(); | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
framebuffer[8]=4; | |
show(); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
client.subscribe(inTopic); | |
client.setCallback(callback); | |
} //setup_wifi | |
void set_pixel(int x, int y,int color ){ | |
byte b_index , mybit; | |
b_index = x/8 + y*8; | |
mybit = x % 8; | |
// color= 0 = off, alles andere: on | |
if (color > 0) | |
sbi(framebuffer[b_index], mybit); | |
else | |
cbi(framebuffer[b_index], mybit); | |
//Serial.println(b_index); | |
//Serial.println(mybit); | |
//Serial.println(image[b_index]); | |
//Serial.println("-----"); | |
} // set_pixel(x,y,col) | |
// eindimensional, ueber alle Zeilen | |
void setPixelColor(int j, char r ){ | |
//nothing todo - it works on all lines | |
//int x=j%8; | |
//int y = j/8; | |
DEBUG_PRINT("setPixelColor:"); | |
DEBUG_PRINTDEC(j); | |
DEBUG_PRINT(" r:"); | |
DEBUG_PRINTDEC(r); | |
DEBUG_PRINTLN(""); | |
//DEBUG_PRINTDEC(y); | |
set_pixel( j, 0 , r ); | |
} | |
void shiftbyte(byte dat) // wird von show() benutzt | |
{ | |
unsigned char p; | |
int i; | |
p=0x01; | |
for(i=0;i<8;i++) | |
{ | |
if (dat & p) | |
digitalWrite(DATA, 1); | |
else | |
digitalWrite(DATA, 0); | |
digitalWrite(TAKT, 0); | |
digitalWrite(TAKT, 1); | |
p<<=1; | |
} | |
} | |
void show() | |
{ | |
int line,j; | |
int offset=0; | |
byte val; | |
digitalWrite(HIDE, 1) ; //hide | |
//for (line=0;line<8;line++) | |
for (line=8;line>=0;line--) | |
{ | |
//for(j=7;j>=0;j--) | |
// 8 bytes on each line | |
for(j=0;j<8;j++) | |
{ | |
//val=framebuffer[offset]-1; //show inverted | |
offset=line*8+j; | |
val=framebuffer[offset]; | |
shiftbyte(val); | |
} | |
} | |
digitalWrite(HIDE, 0); //show | |
} | |
void setpixel( byte* payload, unsigned int length){ | |
int splitat; | |
String s = ""; | |
for(int i = 0; i < length; i++) { | |
s += (char)payload[i]; | |
// Serial.println((char)payload[i]); | |
if (isWhitespace((char)payload[i])) { | |
splitat = i; | |
i = length; | |
} //if | |
} //for | |
String Numberstring = ""; | |
String Colorstring = ""; | |
for(int i = 0; i < splitat; i++) { | |
Numberstring += (char) payload[i]; | |
} | |
for (int i = (splitat + 1); i < length; i++) { | |
Colorstring += (char) payload[i]; | |
} | |
//Colorstring contains something like = "#00ff00" or "00ff00" | |
// you need to convert it to 0,255,0 and insert it to the two calls below | |
// Am ende Newline. | |
int intcolors=(int) strtol(&Colorstring[1],NULL,16); | |
int r = intcolors >> 16; | |
int g = intcolors >> 8 & 0xFF; | |
int b = intcolors & 0xFF; | |
Serial.print("Number:" + Numberstring + " Color:" + Colorstring + " intcolors:"); | |
//Serial.println(intcolors); | |
if(Numberstring == "text") { | |
//scrolltext = Colorstring; | |
//DEBUG_PRINT("scrolltext:"); | |
//DEBUG_PRINTLN(scrolltext); | |
//scrolltext(); | |
cursor_x=0; | |
cursor_y=0; | |
nokia_lcd_write_string(Colorstring.c_str() ,1); | |
show(); | |
} | |
if(Numberstring.toInt() == 255) { | |
for(int i = 0; i < NUMPIXELS; i++) { | |
if (r == 0) | |
framebuffer[i]=0; | |
else | |
framebuffer[i]=1; | |
} | |
show(); | |
} | |
else { | |
setPixelColor(Numberstring.toInt(), r ); | |
show(); // This sends the updated pixel color to the hardware. | |
} | |
} //setpixel | |
// ein Frame das binär via MQTT empfangen wurde | |
// wird in den Frambuffer geschrieben und 1x show() aufgerufen | |
// | |
void writeframe(byte* payload, unsigned int length){ | |
//Serial.print("TOPIC=frame"); | |
// 1 pixel = 1 bit , 1 byte = 8 pixel | |
//write bytes to framebuffer | |
for (int i = 0; i < (NUMPIXELS) ; i++) { | |
//Serial.print((char)payload[i]); | |
//Serial.print(" "); | |
framebuffer[i] = payload[i]; | |
} | |
// wenn 1 pixel = 1 byte dann das hier | |
//write frame to LEDs | |
// for(int i = 0; i < NUMPIXELS ; i++) { | |
//Serial.print(" "); | |
//Serial.print(j); | |
//Serial.print(":"); | |
//Serial.print(r); | |
// r = payload[i]; | |
// setPixelColor(i, r ); | |
// } | |
Serial.println(); | |
show(); | |
} //writeframe | |
void callback(char* topic, byte* payload, unsigned int length) { | |
//Serial.print("Message arrived ["); | |
//Serial.print(topic); | |
//Serial.print("] "); | |
//Serial.print("length:"); | |
//Serial.print( length ); | |
stringIntopic = String(topic); | |
if (stringIntopic == stringPixel ){ | |
//Serial.print("TOPIC=setpixel"); | |
setpixel(payload,length); | |
} | |
if (stringIntopic == stringFrame ){ | |
writeframe(payload,length); | |
} | |
} //callback | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!client.connected()) { | |
Serial.print("Attempting MQTT connection..."); | |
// Attempt to connect | |
if (client.connect(mqtt_client_id)) { | |
Serial.println("connected"); | |
// Once connected, publish an announcement... | |
client.publish(outTopic, "hello world"); | |
// ... and resubscribe | |
client.subscribe(inTopic); | |
client.subscribe(inTopic2); | |
} else { | |
Serial.print("failed, rc="); | |
Serial.print(client.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} //reconnect | |
void nokia_lcd_write_char(char code, uint8_t scale) | |
{ | |
register uint8_t x, y; | |
for (x = 0; x < 5*scale; x++) | |
for (y = 0; y < 7*scale; y++) | |
if (pgm_read_byte(&CHARSET[code-32][x/scale]) & (1 << y/scale)) | |
set_pixel(cursor_x + x, cursor_y + y, 1); | |
else | |
set_pixel(cursor_x + x, cursor_y + y, 0); | |
cursor_x += 5*scale + 1; | |
if (cursor_x >= 64) { | |
cursor_x = 0; | |
//cursor_y += 7*scale + 1; | |
cursor_y = 0; | |
} | |
if (cursor_y >= 10) { | |
cursor_x = 0; | |
cursor_y = 0; | |
} | |
} | |
void nokia_lcd_write_string(const char *str, uint8_t scale) | |
{ | |
while(*str) | |
nokia_lcd_write_char(*str++, scale); | |
} | |
void nokia_lcd_set_cursor(uint8_t x, uint8_t y) | |
{ | |
cursor_x = x; | |
cursor_y = y; | |
} | |
void loop() { | |
if (!client.connected()) { | |
reconnect(); | |
} | |
client.loop(); | |
ArduinoOTA.handle(); | |
delay(10); | |
// show(); | |
} //loop | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment