I Let Everyone On The Internet Control My X-Mas Decoration
Control any of the 55 RGB LEDs on the tree, let Santa twerk for you, control a model railroad, or display custom text on an LED dot matrix.
Components and supplies
Level Shifter Board
8 channel relay board
LED dot matrix with MAX7219 control IC
Arduino MKR1000
Raspberry Pi 3 Model B
Arduino Mega 2560
Arduino Mega Proto Shield
5V, 5A (switching) power supply
WS2812 RGB LED
Arduino Nano R3
Tools and machines
Soldering iron (generic)
Jigsaw
Drill
Apps and platforms
openweathermap.org
timezonedb.com
TelegramBot Api
Project description
Code
dot_matrix_scrolling_text_test.ino
arduino
Code for the Arduino Nano to run the dot matrix.
1#include <MD_Parola.h> 2#include <MD_MAX72xx.h> 3#include <SPI.h> 4#include <Time.h> 5#include <TimeLib.h> 6#include "Parola_Fonts_data.h" 7 8#define MAX_DEVICES 8 9#define CLK_PIN 13 10#define DATA_PIN 11 11#define CS_PIN 10 12 13#define TIME 1 14#define TEXT 2 15#define WEATHER 3 16#define STATS 4 17 18#define NUM_TIMEZONES 8 19 20MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES); 21 22uint8_t scrollSpeed = 30; // default frame delay value 23textEffect_t scrollEffect = PA_SCROLL_LEFT; 24textPosition_t scrollAlign = PA_CENTER; 25uint16_t scrollPause = 0; // in milliseconds 26 27#define BUF_SIZE 100 28char curMessage[BUF_SIZE] = "www.steuermeinentannenbaum.de"; //{0x01}; 29char newMessage[BUF_SIZE]; 30String newMessageString = ""; 31bool newMessageAvailable = false, showClock = false; 32unsigned long lastNewMessageTime; 33byte dataByte = 0, zoneIndex, timeBuffer[3]; 34 35struct timeZonesStruct { 36 int GMT; 37 String name; 38}; 39 40timeZonesStruct timeZones[NUM_TIMEZONES] = { 41 {1, "Berlin"}, 42 {0, "UK"}, 43 { -8, "LA"}, 44 { -6, "Texas"}, 45 { -5, "NYC"}, 46 {11, "Sydney"}, 47 {9, "Tokyo"}, 48 {3, "Russia"} 49}; 50 51/* 52 void readSerial(void) 53 { 54 static char *cp = newMessage; 55 56 while (Serial1.available()) 57 { 58 cp = (char)Serial1.read(); 59 if ((*cp == '\ 60') || (cp - newMessage >= BUF_SIZE-2)) // end of message character or full buffer 61 { 62 cp = '\\0'; // end the string 63 // restart the index for next filling spree and flag we have a message waiting 64 cp = newMessage; 65 newMessageAvailable = true; 66 Serial.println(cp); 67 //Serial.flush(); 68 } 69 else // move char pointer to next position 70 cp++; 71 } 72 } 73*/ 74 75void readSerial(void) { 76 if (Serial.available()) { 77 if (dataByte == 0) dataByte = Serial.read(); 78 else if (dataByte == TEXT) { 79 newMessageString = Serial.readStringUntil('\ 80'); 81 newMessageString.toCharArray(newMessage, BUF_SIZE); 82 newMessageAvailable = true; 83 showClock = false; 84 lastNewMessageTime = millis(); 85 dataByte = 0; 86 } 87 else if (dataByte == TIME) { 88 Serial.readBytes(timeBuffer, 3); 89 setTime(timeBuffer[0], timeBuffer[1], timeBuffer[2], day(), month(), year()); 90 dataByte = 0; 91 } 92 } 93} 94 95 96 97void setup() 98{ 99 Serial.begin(9600); 100 101 randomSeed(analogRead(0)); 102 103 104 P.begin(); 105 P.setFont(ExtASCII); 106 P.displayClear(); 107 P.displaySuspend(false); 108 109 //P.setScrollSpacing(1); 110 111 lastNewMessageTime = millis(); 112 113 P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect); 114 115 //newMessage[0] = '\\0'; 116} 117 118void loop() 119{ 120 readSerial(); 121 122 if (millis() - lastNewMessageTime > 30000) showClock = true; 123 124 if (P.displayAnimate()) 125 { 126 if (showClock) { 127 P.setTextEffect(PA_SCROLL_DOWN, PA_SCROLL_DOWN); 128 P.setPause(5000); 129 130 newMessageString = timeZones[zoneIndex].name + ": "; 131 newMessageString += returnLocalTime(zoneIndex); 132 133 zoneIndex++; 134 if (zoneIndex >= NUM_TIMEZONES) zoneIndex = 0; 135 136 newMessageString.toCharArray(newMessage, BUF_SIZE); 137 strcpy(curMessage, newMessage); 138 newMessageString = ""; 139 140 P.displayReset(); 141 } 142 else if (newMessageAvailable) 143 { 144 P.setTextEffect(PA_SCROLL_LEFT, PA_SCROLL_LEFT); 145 P.setPause(0); 146 147 strcpy(curMessage, newMessage); 148 newMessageAvailable = false; 149 newMessageString = ""; 150 } 151 P.displayReset(); 152 } 153} 154 155String returnLocalTime(byte index) { 156 String temp; 157 int hourInt = hour() + timeZones[index].GMT; 158 159 if (hourInt < 0) hourInt = 24 + hourInt; 160 else if (hourInt > 23) hourInt -= 24; 161 162 if (hourInt < 10) temp += "0"; 163 temp += String(hourInt) + ":"; 164 if (minute() < 10) temp += "0"; 165 temp += String(minute()); 166 167 return temp; 168} 169 170
Telegram_Bot_xmas.ino
arduino
Code for the Arduino MKR1000.
1#define TEXT_SERIAL 1 2#define WATCHDOG 1 3#define DEBUG 0 4 5#include <Arduino.h> 6#include <Time.h> 7#include <TimeLib.h> 8#include <WiFi101.h> 9//#include <WiFiUdp.h> 10#include <SPI.h> 11#include <TelegramBot.h> 12//#include <time.h> 13//#include <RTCZero.h> 14 15#if TEXT_SERIAL 16#include <wiring_private.h> 17#endif 18 19#if WATCHDOG 20#include <Adafruit_SleepyDog.h> 21#endif 22 23#if TEXT_SERIAL 24Uart textSerial (&sercom3, 0, 1, SERCOM_RX_PAD_1, UART_TX_PAD_0); 25 26void SERCOM3_Handler() // Interrupt handler for SERCOM3 27{ 28 textSerial.IrqHandler(); 29} 30#endif 31 32#define ledPin 6 33#define RBUFFSIZE 1000 34 35#define MAX_MESSAGES 16 36 37#define TIME 1 38#define TEXT 2 39#define WEATHER 3 40#define STATS 4 41 42/* 43 #define BEER_NAME 0 44 #define BEER_ID 1 45*/ 46 47char responseBuffer[RBUFFSIZE]; 48int rbindex = 0; 49 50boolean startCapture; 51unsigned long lastTimeSentTime, lastTextSent, currentTime, lastClockSent; 52 53// Initialize Wifi connection 54 55const char ssid[] = ""; // network SSID 56const char pass[] = ""; // network key 57 58// Initialize Telegram BOT 59 60const char BotToken[] = ""; 61 62char server[] = "api.openweathermap.org"; 63 64String eingabe; //Nachrichten[128]; 65char Nachrichten[MAX_MESSAGES][100]; 66byte numMessages, messageIndex, sendMessageIndex; 67 68WiFiSSLClient client; 69WiFiClient clienthttp; 70 71TelegramBot bot(BotToken, client); 72 73//RTCZero rtc; 74 75//TelegramKeyboard keyboardStart; 76/* 77const char* row1Start[] = {"/help", "/wlan"}; 78const char* row2Start[] = {"/ip", "/signal"}; 79//const char* row3Start[] = {"/alloff"}; 80*/ 81 82time_t tClock = 0; 83 84 85void setup() { 86 87 delay(3000); 88 89#if TEXT_SERIAL 90 textSerial.begin(9600); // Begin Uart for sending text to LED matrix 91#endif 92 93 Serial.begin(9600); 94 95#if TEXT_SERIAL 96 pinPeripheral(0, PIO_SERCOM); // Assign pins 0 & 1 SERCOM functionality 97 pinPeripheral(1, PIO_SERCOM); 98#endif 99 100#if WATCHDOG 101 Watchdog.enable(10000); 102#endif 103 104 // attempt to connect to Wifi network: 105#if DEBUG 106 Serial.print(F("Verbine mit WLAN: ")); 107 Serial.println(ssid); 108#endif 109 110 while (WiFi.begin(ssid, pass) != WL_CONNECTED) { 111 delay(500); 112 } 113 114#if DEBUG 115 Serial.println(F("Mit WLAN verbunden.")); 116#endif 117/* 118 byte counterT = 0; 119 while (tClock == 0 && counterT < 6) { 120 delay(1000); 121 counterT++; 122 123 tClock = WiFi.getTime(); 124 125 } 126 Serial.println(tClock); 127 */ 128 getCurrentTime(); 129 130 if (tClock != 0) { 131 textSerial.write(TIME); 132 textSerial.write(hour(tClock)); 133 textSerial.write(minute(tClock)); 134 textSerial.write(second(tClock)); 135 } 136 tClock = 0; 137 138 lastClockSent = millis(); 139 140 bot.begin(); 141 142 pinMode(ledPin, OUTPUT); 143 digitalWrite(ledPin, LOW); 144/* 145 keyboardStart.addRow(row1Start, 2); 146 keyboardStart.addRow(row2Start, 2); 147 //keyboardStart.addRow(row3Start, 1); 148 */ 149 150 message m = bot.getUpdates(); 151} 152 153void loop() { 154#if WATCHDOG 155 Watchdog.reset(); 156#endif 157 158 if ( WiFi.status() != WL_CONNECTED) { 159 //WiFi.disconnect(); 160 while (WiFi.begin(ssid, pass) != WL_CONNECTED) { 161#if DEBUG 162 Serial.print("."); 163#endif 164 delay(1000); 165 } 166 } 167 currentTime = millis(); 168 169 if (numMessages > 0 && currentTime - lastTextSent > 20000) { 170 textSerial.write(TEXT); 171 textSerial.print(String(Nachrichten[sendMessageIndex])); 172 lastTextSent = currentTime; 173 sendMessageIndex++; 174 numMessages--; 175 if (sendMessageIndex >= MAX_MESSAGES) sendMessageIndex = 0; 176 } 177 178 if (currentTime - lastTextSent > 120000) { 179 textSerial.write(TEXT); 180 textSerial.print("To send custom text, open/download the 'Telegram' App and add: TannenbaumBot."); 181 lastTextSent = currentTime; 182 } 183 184 if (currentTime - lastClockSent > 600000) { 185 tClock = 0; 186 187 getCurrentTime(); 188 /* 189 byte counterT = 0; 190 while (tClock == 0 && counterT < 6) { 191 counterT++; 192 delay(500); 193 tClock = WiFi.getTime(); 194 } 195 */ 196 if (tClock != 0) { 197 textSerial.write(TIME); 198 textSerial.write(hour(tClock)); 199 textSerial.write(minute(tClock)); 200 textSerial.write(second(tClock)); 201 } 202 203 204 /* 205 textSerial.write(rtc.getHours()); 206 textSerial.write(rtc.getMinutes()); 207 textSerial.write(rtc.getSeconds()); 208 */ 209 210 lastClockSent = currentTime; 211 } 212 213 message m = bot.getUpdates(); 214 /* 215 if(millis() - lastTimeSentTime > 600000) { 216 textSerial.write(TIME); 217 textSerial.print(String(rtc.getEpoch()) + "\ 218"); 219 lastTimeSentTime = millis(); 220 } 221 */ 222 223 if (Serial.available() > 0) { 224 eingabe = Serial.readStringUntil('\ 225'); 226 if (!eingabe.equalsIgnoreCase("i")) { 227 bot.sendMessage("", eingabe); 228 eingabe = ""; 229 } 230 } 231 232 else if (eingabe.equalsIgnoreCase("i")) { 233 if (WL_CONNECTED) { 234 Serial.println(F("Mit WLAN verbunden")); 235 IPAddress ip = WiFi.localIP(); 236 Serial.print(F("IP Address: ")); 237 Serial.println(ip); 238 239 // print the received signal strength: 240 long rssi = WiFi.RSSI(); 241 Serial.print(F("signal strength (RSSI):")); 242 Serial.print(rssi); 243 Serial.println(F(" dBm")); 244 eingabe = ""; 245 } 246 else Serial.println(F("KEINE Verbindung zum WLAN")); 247 eingabe = ""; 248 } 249 250 if ( m.chat_id != 0 ) { 251 if (1) { // if a message is received from unique Chats m.sender.equals("xxxxx") 252 253 //Serial.println("Location: " + m.location.lon + ", " + m.location.lat); 254 //Serial.println("Name: " + m.first_name); 255 //Serial.println(m.chat_id); 256 //Serial.println(m.sender); 257 258#if DEBUG 259 time_t t = m.date.toInt(); 260 t = t + 1 * 60 * 60; 261 262 Serial.print(m.sender); 263 Serial.print(F(" hat um ")); 264 Serial.print(hour(t)); 265 Serial.print(":"); 266 Serial.print(minute(t)); 267 268 Serial.print(F(" folgendes gesendet: ")); 269 Serial.println(m.text); 270#endif 271 272 if (m.location.lon.length() != 0) { 273 bot.sendMessage(m.chat_id, "Requesting weather data..."); 274#if DEBUG 275 Serial.println(F("Verbinde zu api.openweathermap.org")); 276#endif 277 278 weatherHttpRequest(m.location.lat, m.location.lon, m.chat_id); 279 280 } 281 282 if (m.text.equalsIgnoreCase("/help")) { 283 bot.sendMessage(m.chat_id, "To send custom text, type: /text and your message. For example: '/text Santa rocks!'. To display the current weather in your area, simply send your location."); 284 285 286 } 287/* 288 else if (m.text.equalsIgnoreCase("/watchdog")) { 289 while (1); 290 } 291*/ 292 else if (m.text.equalsIgnoreCase("/start")) { 293 bot.sendMessage(m.chat_id, "Welcome " + m.first_name + "! Send /help for more information."); 294 295 } 296 297 else if (m.text.startsWith("/text") || m.text.startsWith("/Text")) { 298 m.text.remove(0, 6); 299 m.text += "\ 300"; 301 302 if (m.text.length() <= 2) { 303 bot.sendMessage(m.chat_id, "Sorry, your text is too short. Please send at least 2 characters."); 304 } 305 else if (m.text.length() >= 75) { 306 bot.sendMessage(m.chat_id, "Sorry, your text is too long. The maxmimal text length is 74 characters."); 307 } 308 else if (numMessages == MAX_MESSAGES) { 309 bot.sendMessage(m.chat_id, "Sorry, there are currently too many people sending messages to Santa. Try again later."); 310 } 311 else { 312 if (m.first_name.length() >= 21) m.first_name.remove(20); 313 eingabe = m.first_name + ": " + m.text; 314 eingabe.toCharArray(Nachrichten[messageIndex], 100); 315 eingabe = ""; 316 numMessages++; 317 messageIndex++; 318 if (messageIndex >= MAX_MESSAGES) messageIndex = 0; 319 bot.sendMessage(m.chat_id, "Your text is on position " + String(numMessages) + " in the pipeline. It will be displayed in approximately " + String((numMessages) * 20) + " seconds."); 320 } 321 322#if DEBUG 323 Serial.println("Der reine Text lautet: " + m.text); 324 325#endif 326 327 } 328 /* 329 else if (m.text.startsWith("/bierID")) { 330 m.text.remove(0, 7); 331 m.text.trim(); 332 beerHttpRequest(BEER_ID, m.text, m.chat_id); 333 } 334 335 else if (m.text.startsWith("/bier") || m.text.startsWith("/Bier")) { 336 m.text.remove(0, 6); 337 m.text.trim(); 338 beerHttpRequest(BEER_NAME, m.text, m.chat_id); 339 } 340 */ 341 /* 342 else if (m.text.equalsIgnoreCase("/wlan")) { 343 bot.sendMessage(m.chat_id, ssid); 344 345 } 346 else if (m.text.equalsIgnoreCase("/ip")) { 347 IPAddress ip = WiFi.localIP(); 348 bot.sendMessage(m.chat_id, String(ip[0]) + String(".") + \\ 349 String(ip[1]) + String(".") + \\ 350 String(ip[2]) + String(".") + \\ 351 String(ip[3])); 352 } 353 else if (m.text.equalsIgnoreCase("/signal")) { 354 long rssi = WiFi.RSSI(); 355 bot.sendMessage(m.chat_id, String(rssi) + " dBm"); 356 } 357 */ 358 } 359 360 else { 361 bot.sendMessage(m.chat_id, "Sie sind nicht befugt diesen Befehl zu verwenden."); 362 363 Serial.println(m.chat_id); 364 Serial.println(m.sender); 365 } 366 } 367} 368 369int findText(String needle, String haystack) { 370 int foundpos = -1; 371 for (int i = 0; i <= haystack.length() - needle.length(); i++) { 372 if (haystack.substring(i, needle.length() + i) == needle) { 373 foundpos = i; 374 } 375 } 376 return foundpos; 377} 378 379void weatherHttpRequest(String lat, String lon, String chatId) { 380 if (clienthttp.connect(server, 80)) { 381#if DEBUG 382 Serial.println(F("Verbunden zum Server")); 383#endif 384 385 clienthttp.println("GET /data/2.5/weather?lat=" + lat + "&lon=" + lon + "&APPID=**yourapikey** HTTP/1.1"); 386 clienthttp.println("Host: api.openweathermap.org"); 387 clienthttp.println("Connection: close"); 388 clienthttp.println(); 389 390 responseBuffer[0] = '\\0'; 391 rbindex = 0; 392 393 startCapture = false; 394 } 395 396 else { 397 bot.sendMessage(chatId, "Cannot connect to weather server."); 398 return; 399 } 400 401 char c; 402 unsigned long startTime = millis(); 403 while (clienthttp.connected() && millis() - startTime < 7000) { 404 if (clienthttp.available()) { 405 c = clienthttp.read(); 406 if (c == '{') { 407 startCapture = true; 408 } 409 if (startCapture && rbindex < RBUFFSIZE) { 410 responseBuffer[rbindex] = c; 411 rbindex++; 412 } 413 } 414 } 415 416 417 if (clienthttp.connected()) { 418 clienthttp.stop(); 419 clienthttp.flush(); 420#if DEBUG 421 Serial.println(F("Client won't disconnect")); 422#endif 423 bot.sendMessage(chatId, "Data couldn't be recieved."); 424 return; 425 } 426 427#if DEBUG 428 Serial.println(F("Received bytes.")); 429 //Serial.print(strlen(responseBuffer)); 430 Serial.println(F("Disconnecting.")); 431#endif 432 433 clienthttp.stop(); 434 clienthttp.flush(); 435 436 StaticJsonBuffer<RBUFFSIZE> jsonBuffer; 437 438 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 439 440 if (!root.success()) { 441#if DEBUG 442 Serial.println(F("parseObject() fehlgeschlagen")); 443#endif 444 445 bot.sendMessage(chatId, "Datenverarbeitung fehlgeschlagen."); 446 } 447 else { 448 char bufferw[20]; 449 char bufferc[30]; 450 root["weather"][0]["description"].prettyPrintTo(bufferw, sizeof(bufferw)); 451 root["name"].prettyPrintTo(bufferc, sizeof(bufferc)); 452 453#if DEBUG 454 Serial.println("Schnee: " + String((float)root["snow"]["3h"])); 455#endif 456 //bot.sendMessage(m.chat_id, "Aktuelle Wetter fr " + String(bufferc) + ":"); 457 textSerial.write(TEXT); 458 eingabe = "Current weather in " + String(bufferc) + ": " + String(bufferw) + " at " + String(((double)root["main"]["temp"]) - 273.15, 1) + " C"; 459 textSerial.print(eingabe); 460 lastTextSent = millis(); 461 eingabe = ""; 462 463 bot.sendMessage(chatId, "The current weather in your region will be displayed soon."); 464 465#if DEBUG 466 Serial.print(F("Aktuelle Temperatur: ")); 467 Serial.print(((double)root["main"]["temp"]) - 273.15); 468 Serial.println(F(" C")); 469 470 Serial.print(F("Beschreibung: ")); 471 Serial.println(bufferw); 472#endif 473 } 474} 475void getCurrentTime() { 476 if (clienthttp.connect("api.timezonedb.com", 80)) { 477 clienthttp.println("GET /v2/get-time-zone?key=**yourapikey**&format=json&by=zone&zone=Europe/London HTTP/1.1"); 478 clienthttp.println("Host: api.timezonedb.com"); 479 clienthttp.println("Connection: close"); 480 clienthttp.println(); 481 482 responseBuffer[0] = '\\0'; 483 rbindex = 0; 484 485 startCapture = false; 486 } 487 488 else { 489 Serial.println("Verbindung zum Zeitserver fehlgeschlagen"); 490 return; 491 } 492 493 char c; 494 unsigned long startTime = millis(); 495 496 while (clienthttp.connected() && millis() - startTime < 7000) { 497 if (clienthttp.available()) { 498 c = clienthttp.read(); 499 if (c == '{') { 500 startCapture = true; 501 } 502 if (startCapture && rbindex < RBUFFSIZE) { 503 responseBuffer[rbindex] = c; 504 rbindex++; 505 } 506 } 507 } 508 509 if (clienthttp.connected()) { 510 clienthttp.stop(); 511 clienthttp.flush(); 512 #if DEBUG 513 Serial.println(F("Client won't disconnect")); 514 #endif 515 return; 516 } 517 518 519 #if DEBUG 520 Serial.println(F("Received bytes.")); 521 //Serial.print(strlen(responseBuffer)); 522 Serial.println(F("Disconnecting.")); 523 #endif 524 525 clienthttp.stop(); 526 clienthttp.flush(); 527 528 StaticJsonBuffer<RBUFFSIZE> jsonBuffer; 529 530 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 531 532 if (!root.success()) { 533 #if DEBUG 534 Serial.println(F("parseObject() fehlgeschlagen")); 535 #endif 536 537 } 538 else { 539 tClock = root["timestamp"]; 540 Serial.println(tClock); 541 } 542} 543//wanted to implement the brewery db but couldn't make it work so fart 544/* 545 void beerHttpRequest(boolean type, String request, String chatId) { 546 if (clienthttp.connect("api.brewerydb.com", 80)) { 547 #if DEBUG 548 Serial.println(F("Verbunden zum Server")); 549 #endif 550 551 if (type == BEER_NAME) clienthttp.println("GET /v2/search?q=" + request + "&type=beer&key=**yourapikey**&format=json HTTP/1.1"); 552 else clienthttp.println("GET /v2/beer/" + request + "?key=**yourapikey**&format=json HTTP/1.1"); 553 clienthttp.println("Host: api.brewerydb.com"); 554 clienthttp.println("Connection: close"); 555 clienthttp.println(); 556 557 responseBuffer[0] = '\\0'; 558 rbindex = 0; 559 560 startCapture = false; 561 562 } 563 564 else { 565 bot.sendMessage(chatId, "Verbindung zur Brewery Databse nicht mglich."); 566 return; 567 } 568 569 char c; 570 unsigned long startTime = millis(); 571 572 while (clienthttp.connected() && millis() - startTime < 7000) { 573 if (clienthttp.available()) { 574 c = clienthttp.read(); 575 if (c == '{') { 576 startCapture = true; 577 } 578 if (startCapture && rbindex < RBUFFSIZE) { 579 responseBuffer[rbindex] = c; 580 rbindex++; 581 } 582 } 583 } 584 585 if (clienthttp.connected()) { 586 clienthttp.stop(); 587 clienthttp.flush(); 588 #if DEBUG 589 Serial.println(F("Client won't disconnect")); 590 #endif 591 bot.sendMessage(chatId, "Daten konnten nicht empfangen werden."); 592 return; 593 } 594 595 596 #if DEBUG 597 Serial.println(F("Received bytes.")); 598 //Serial.print(strlen(responseBuffer)); 599 Serial.println(F("Disconnecting.")); 600 #endif 601 602 clienthttp.stop(); 603 clienthttp.flush(); 604 605 StaticJsonBuffer<RBUFFSIZE> jsonBuffer; 606 607 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 608 609 if (!root.success()) { 610 #if DEBUG 611 Serial.println(F("parseObject() fehlgeschlagen")); 612 #endif 613 614 bot.sendMessage(chatId, "Datenverarbeitung fehlgeschlagen."); 615 } 616 else { 617 618 if (type == BEER_NAME) { 619 char bufferName[10][50]; // char bufferName[10][50]; 620 char bufferID[10][9]; //char bufferID[10][6]; 621 int results = root["totalResults"]; // int results = atoi(&root["totalResults"]); 622 if (results > 10) results = 10; 623 for (byte i = 0; i < results; i++) { 624 625 root["data"][i]["id"].prettyPrintTo(bufferID[i], sizeof(bufferID[i])); 626 root["data"][i]["name"].prettyPrintTo(bufferName[i], sizeof(bufferName[i])); 627 } 628 629 String beerMessage; 630 631 if (results > 0) { 632 beerMessage = "Hier die ersten " + String(results) + " Treffer. Meintest du:"; 633 for (byte i = 0; i < results; i++) { 634 beerMessage += '\ 635'; 636 beerMessage += String(bufferName[i]); 637 beerMessage += ": /bierID"; 638 String IDtemp = String(bufferID[i]); 639 IDtemp.remove(0, 1); 640 IDtemp.remove(6, 1); 641 beerMessage += IDtemp; 642 } 643 } 644 645 else beerMessage = "Zu diesem Suchbegriff gab es leider keine Treffer."; 646 647 bot.sendMessage(chatId, beerMessage); 648 #if DEBUG 649 Serial.println(F("test")); 650 #endif 651 } 652 else { 653 char bufferDescription[1000]; 654 char bufferStyle[50]; 655 656 if (root["data"]["description"] != NULL) { 657 root["data"]["description"].prettyPrintTo(bufferDescription, sizeof(bufferDescription)); 658 bot.sendMessage(chatId, bufferDescription); 659 #if DEBUG 660 Serial.println(bufferDescription); 661 #endif 662 } 663 if (root["data"]["style"]["description"] != NULL) { 664 root["data"]["style"]["description"].prettyPrintTo(bufferDescription, sizeof(bufferDescription)); 665 root["data"]["style"]["name"].prettyPrintTo(bufferStyle, sizeof(bufferStyle)); 666 667 bot.sendMessage(chatId, "Es handelt sich um ein: " + String(bufferStyle) + ".'\ 668'" + String(bufferDescription)); 669 #if DEBUG 670 Serial.println("Es handelt sich um ein: " + String(bufferStyle) + ".'\ 671'" + String(bufferDescription)); 672 #endif 673 } 674 } 675 } 676 } 677*/ 678 679
Serial_Data_Read.ino
arduino
Code for the "main" Arduino Mega. Reads data from pi and controls all LEDs and devices.
1#include "FastLED.h" 2#include "leds_lookup_table.h" 3#include <EEPROM.h> 4 5#define DEBUG 0 6 7#define READY_PIN 28 8#define SANTA_PIN 5 9#define TRAIN_PIN 39 //relay 3 10#define LIGHT_CHAIN_PIN 35 //relay 1 11#define SPOT_LIGHT_PIN 37 12#define FRONT_LIGHT_PIN 41 13#define LAP_COUNT_PIN 6 14 15 16#define NUM_LEDS 55 //number of total P9823's 17#define DATA_PIN 2 18#define FADE_DELAY 50 19#define FADE_TIME 2000 20#define CHANCE_SANTA_SOLO 20 //chance of a santa solo in percent 21 22#define PiSerial Serial1 23#define DebugSerial Serial 24 25//status bytes knnen werte von 1 bis 191 haben (0 = undefined) 26#define LED_START 1 27#define LED_END 55 28#define TEXT_EINGABE 124 29#define TWERKING_SANTA 69 30#define TRAIN 56 31#define LIGHT_CHAIN 57 32#define SPARKLING 58 33#define ANIMATIONS 59 34#define TREE_BLACKOUT 60 35 36//info/data bytes von 192 bis 254 37#define OFF 192 38#define ON 193 39#define FARBEN_START 194 40#define FARBEN_END 210 41 42#define DATA_ERROR 255 43 44struct ledStepStruct { 45 int rStep, gStep, bStep; 46 boolean fade; 47}; 48 49byte data[2], rndLED, hueTemp; 50char text[31]; 51boolean newText, santaFlag, trainFlag, lightChainFlag, sparklingFlag, sparkleOn, santaSoloFlag, pinActive = true; 52const unsigned int fadeSteps = FADE_TIME / FADE_DELAY; 53unsigned long currentMillis, lastFadeTime, santaTime, trainTime, lightChainTime, sparklingTime, lastSparkleTime, lastLapCount, currentTime, trainActionTime, lastTrainAction; 54unsigned int lapCounter; 55 56CRGB leds[NUM_LEDS], ledsAim[NUM_LEDS], ledBefore; 57 58ledStepStruct ledsStep[NUM_LEDS]; 59 60void setup() { 61 PiSerial.begin(9600); 62 63 DebugSerial.begin(9600); 64 65 pinMode(READY_PIN, OUTPUT); 66 pinMode(SANTA_PIN, OUTPUT); 67 pinMode(TRAIN_PIN, OUTPUT); 68 pinMode(LIGHT_CHAIN_PIN, OUTPUT); 69 pinMode(SPOT_LIGHT_PIN, OUTPUT); 70 pinMode(FRONT_LIGHT_PIN, OUTPUT); 71 pinMode(LAP_COUNT_PIN, INPUT_PULLUP); 72 73 74 FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS); 75 FastLED.setBrightness(70); 76 FastLED.clear(); 77 FastLED.show(); 78 79 digitalWrite(READY_PIN, HIGH); 80 digitalWrite(SANTA_PIN, LOW); 81 digitalWrite(TRAIN_PIN, LOW); 82 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 83 digitalWrite(SPOT_LIGHT_PIN, LOW); 84 digitalWrite(FRONT_LIGHT_PIN, HIGH); 85 86 lightChainFlag = true; 87 88 //lapCounter = 200; //add counts up to now, since eeprom wasnt' implemented yet 89 //EEPROM.put(0, lapCounter); 90 EEPROM.get(0, lapCounter); 91 92} 93 94void loop() { 95 96 handleSerialCommunication(); 97 handleData(); 98 handleColorFade(); 99 handleControl(); 100 handleSparkling(); 101 handleLapCount(); 102 103} 104 105void handleLapCount() { 106 currentTime = millis(); 107 if (!digitalRead(LAP_COUNT_PIN) && pinActive && currentTime - trainActionTime > 100) { 108 lapCounter++; 109 pinActive = false; 110 lastLapCount = currentTime; 111 PiSerial.print(lapCounter); 112 PiSerial.flush(); 113 EEPROM.put(0, lapCounter); 114 //Serial.println(lapCounter); 115 } 116 117 if (digitalRead(LAP_COUNT_PIN) && currentTime - lastLapCount > 2000) { 118 pinActive = true; 119 } 120} 121 122void handleSparkling() { 123 if (sparklingFlag) { 124 if (millis() - sparklingTime > 20000) { 125 sparklingFlag = false; 126 leds[rndLED] = ledBefore; 127 FastLED.show(); 128 sparkleOn = false; 129 } 130 else if (!sparkleOn && millis() - lastSparkleTime > 100) { 131 rndLED = random8(NUM_LEDS); 132 ledBefore = leds[rndLED]; 133 leds[rndLED] += CRGB::White; 134 FastLED.show(); 135 sparkleOn = true; 136 lastSparkleTime = millis(); 137 } 138 else if (sparkleOn && millis() - lastSparkleTime > 50) { 139 leds[rndLED] = ledBefore; 140 FastLED.show(); 141 sparkleOn = false; 142 lastSparkleTime = millis(); 143 } 144 } 145} 146 147void handleControl() { 148 if (santaFlag) { 149 if (santaTime == 0) { 150 digitalWrite(SANTA_PIN, HIGH); 151 santaTime = millis(); 152 } 153 else if (millis() - santaTime > 20000) { 154 digitalWrite(SANTA_PIN, LOW); 155 santaTime = 0; 156 santaFlag = false; 157 } 158 } 159 160 else if (santaSoloFlag) { 161 162 if (trainFlag) { 163 trainFlag = false; 164 digitalWrite(TRAIN_PIN, LOW); 165 } 166 if (lightChainFlag) { 167 digitalWrite(LIGHT_CHAIN_PIN, LOW); 168 } 169 FastLED.clear(); 170 FastLED.show(); 171 172 digitalWrite(FRONT_LIGHT_PIN, LOW); 173 FastLED.delay(1000); 174 digitalWrite(SPOT_LIGHT_PIN, HIGH); 175 FastLED.delay(500); 176 digitalWrite(SANTA_PIN, HIGH); 177 FastLED.delay(50); 178 digitalWrite(SANTA_PIN, LOW); 179 180 /* 181 for (int i; i < 500; i++) { 182 fill_rainbow(leds, NUM_LEDS, hueTemp, 1); 183 FastLED.show(); 184 hueTemp++; 185 FastLED.delay(25); 186 } 187 FastLED.clear(); 188 FastLED.show(); 189 */ 190 for ( int k = 0; k < 20; k++ ) { 191 triangle(); 192 } 193 194 195 digitalWrite(SPOT_LIGHT_PIN, LOW); 196 197 digitalWrite(SANTA_PIN, HIGH); 198 FastLED.delay(50); 199 digitalWrite(SANTA_PIN, LOW); 200 201 FastLED.delay(1000); 202 203 digitalWrite(FRONT_LIGHT_PIN, HIGH); 204 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 205 lightChainFlag = true; 206 207 for (byte i = 0; i < NUM_LEDS; i++) { 208 leds[i] = ledsAim[i]; 209 } 210 FastLED.show(); 211 santaSoloFlag = false; 212 digitalWrite(READY_PIN, HIGH); 213 } 214 215 if (trainFlag) { 216 if (millis() - trainTime > 30000) { 217 trainFlag = false; 218 digitalWrite(TRAIN_PIN, LOW); 219 } 220 } 221 222 if (!lightChainFlag) { 223 if (millis() - lightChainTime > 60000) { 224 lightChainFlag = true; 225 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 226 } 227 } 228} 229 230void handleColorFade() { 231 currentMillis = millis(); 232 if (currentMillis - lastFadeTime >= FADE_DELAY) { 233 234 for (byte i = 0; i < NUM_LEDS; i++) { 235 if (ledsStep[i].fade) { 236 ledsStep[i].fade = false; 237 if (leds[i].r != ledsAim[i].r) { 238 ledsStep[i].fade = true; 239 int rTemp = (int)leds[i].r + (int)ledsStep[i].rStep; 240 if ((ledsStep[i].rStep > 0 && rTemp > ledsAim[i].r) || (ledsStep[i].rStep < 0 && rTemp < ledsAim[i].r) || rTemp > 255 || rTemp < 0) leds[i].r = ledsAim[i].r; 241 else leds[i].r = rTemp; 242 243 if ((ledsStep[i].rStep > 0 && leds[i].r > ledsAim[i].r) || (ledsStep[i].rStep < 0 && leds[i].r < ledsAim[i].r)) leds[i].r = ledsAim[i].r; 244 } 245 if (leds[i].g != ledsAim[i].g) { 246 ledsStep[i].fade = true; 247 int gTemp = (int)leds[i].g + (int)ledsStep[i].gStep; 248 if ((ledsStep[i].gStep > 0 && gTemp > ledsAim[i].g) || (ledsStep[i].gStep < 0 && gTemp < ledsAim[i].g) || gTemp > 255 || gTemp < 0) leds[i].g = ledsAim[i].g; 249 else leds[i].g = gTemp; 250 } 251 if (leds[i].b != ledsAim[i].b) { 252 ledsStep[i].fade = true; 253 int bTemp = (int)leds[i].b + (int)ledsStep[i].bStep; 254 if ((ledsStep[i].bStep > 0 && bTemp > ledsAim[i].b) || (ledsStep[i].bStep < 0 && bTemp < ledsAim[i].b) || bTemp > 255 || bTemp < 0) leds[i].b = ledsAim[i].b; 255 else leds[i].b = bTemp; 256 } 257 258 } 259 } 260 FastLED.show(); 261 lastFadeTime = currentMillis; 262 } 263 264 265} 266 267void handleSerialCommunication() { 268 if (PiSerial.available() > 0) { //if there's any serial data 269 /* 270 if (data[0] == TEXT_EINGABE) { //if the upcoming data is a text; indicated by first data byte = 124 271 //inputString = PiSerial.readString(); 272 273 for (byte textIndex = 0; textIndex < (data[1] - 193); textIndex++) { //194 = textlnge 1, ..., 224 = textlnge 30 274 text[textIndex] = PiSerial.read(); 275 } 276 text[data[1] - 193] = '\\0'; 277 278 newText = true; //text saved 279 data[0] = 0; 280 data[1] = 0; 281 282 } 283 */ 284 //else if !!!!!!! wenn oben auskommentiert 285 286 if (PiSerial.peek() >= 1 && PiSerial.peek() <= 191) { //if first data byte is valid 287 PiSerial.readBytes(data, 2); 288 //if (data[0] == TEXT_EINGABE) digitalWrite(READY_PIN, LOW); 289#if DEBUG 290 DebugSerial.println("Empfangen: " + (String)data[0] + ", " + (String)data[1]); 291#endif 292 } 293 else { //else; first data byte is invalid (0 or greater than 191) 294 byte errorMessage = PiSerial.read(); 295 //PiSerial.print(DATA_ERROR); 296 //PiSerial.print(errorMessage); 297#if DEBUG 298 DebugSerial.print("DATA_ERROR: "); 299 DebugSerial.println(errorMessage); 300#endif 301 } 302 } 303} 304 305void handleData() { 306 if (data[0] >= LED_START && data[0] <= LED_END) { //if data is LED data 307 if (data[1] < OFF || data[1] > FARBEN_END) { //if second data byte has invalid color 308 //invalid color/data byte 309 //PiSerial.print(DATA_ERROR); 310 //PiSerial.print(data[1]); 311#if DEBUG 312 DebugSerial.print("DATA_ERROR_INVALID_COLOR: "); 313 DebugSerial.println(data[1]); 314#endif 315 316 } 317 else { //color value is valid 318 //led mit farbe (in data[1]) ansteuern 319 byte i = data[0] - 1; 320 321 if (data[1] == OFF) ledsAim[i] = CRGB::Black; 322 else if (data[1] == ON) ledsAim[i] = CRGB::White; //hier warmwei einfgen 323 else ledsAim[i].setHue((data[1] - 194) * 16); //set aim color for led to chosen value 324 325 setLEDFade(i); 326 327 } 328 data[0] = 0; 329 data[1] = 0; 330 } 331 332 else if (data[0] == TWERKING_SANTA) { 333 334 335 if (!santaFlag) { 336 digitalWrite(READY_PIN, LOW); 337 338 if (random8(100) > CHANCE_SANTA_SOLO - 1) { 339 santaFlag = true; 340 digitalWrite(READY_PIN, HIGH); 341 } 342 else santaSoloFlag = true; 343 } 344 345 data[0] = 0; 346 data[1] = 0; 347 348 } 349 350 else if ( data[0] == TRAIN) { 351 currentTime = millis(); 352 if (currentTime - lastTrainAction > 1000) { 353 if (data[1] == OFF && trainFlag) { 354 trainActionTime = currentTime; 355 lastTrainAction = trainActionTime; 356 digitalWrite(TRAIN_PIN, LOW); 357 trainFlag = false; 358 } 359 360 else if (data[1] == ON && !trainFlag) { 361 trainActionTime = currentTime; 362 lastTrainAction = trainActionTime; 363 digitalWrite(TRAIN_PIN, HIGH); 364 trainFlag = true; 365 trainTime = millis(); 366 } 367 } 368 data[0] = 0; 369 data[1] = 0; 370 371 372 } 373 374 else if (data[0] == LIGHT_CHAIN) { 375 if (data[1] == OFF && lightChainFlag) { 376 digitalWrite(LIGHT_CHAIN_PIN, LOW); 377 lightChainFlag = false; 378 lightChainTime = millis(); 379 } 380 381 else if (data[1] == ON && !lightChainFlag) { 382 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 383 lightChainFlag = true; 384 } 385 data[0] = 0; 386 data[1] = 0; 387 } 388 389 else if (data[0] == SPARKLING) { 390 if (data[1] == ON && !sparklingFlag) { 391 sparklingFlag = true; 392 sparklingTime = millis(); 393 } 394 395 else if (data[1] == OFF && sparklingFlag) { 396 sparklingFlag = false; 397 } 398 399 data[0] = 0; 400 data[1] = 0; 401 } 402 403 else if (data[0] == ANIMATIONS) { 404 digitalWrite(READY_PIN, LOW); 405 animations(); 406 digitalWrite(READY_PIN, HIGH); 407 data[0] = 0; 408 data[1] = 0; 409 } 410 411 else if (data[0] == TREE_BLACKOUT) { 412 413 for (byte i = 0; i < NUM_LEDS; i++) { 414 ledsAim[i] = CRGB::Black; 415 setLEDFade(i); 416 } 417 418 data[0] = 0; 419 data[1] = 0; 420 } 421 422 423 /* 424 if (newText) { //handle text entry 425 //inputString.toCharArray(text, 31); 426 427 #if DEBUG 428 DebugSerial.println(text); //debug 429 DebugSerial.flush(); 430 #endif 431 digitalWrite(READY_PIN, HIGH); 432 //text anzeigen 433 newText = false; 434 } 435 */ 436} 437 438void animations() { 439 fillSpiralCCW(); 440 fillSpiralCW(); 441 fillSpiralCCW(); 442 fillSpiralCW(); 443 444 for (byte i = 0; i < NUM_LEDS; i++) { 445 leds[i] = ledsAim[i]; 446 } 447 FastLED.show(); 448} 449 450void setLEDFade(byte i) { 451 if (leds[i] != ledsAim[i]) { 452 ledsStep[i].fade = true; 453 454 if (ledsAim[i].r != leds[i].r) { 455 ledsStep[i].rStep = ((int)ledsAim[i].r - (int)leds[i].r) / (int)fadeSteps; 456 if (ledsStep[i].rStep == 0) { 457 if (ledsAim[i].r > leds[i].r) ledsStep[i].rStep = 1; 458 else ledsStep[i].rStep = -1; 459 } 460#if DEBUG 461 DebugSerial.println("rStep: " + (String)ledsStep[i].rStep); //debug 462#endif 463 } 464 if (ledsAim[i].g != leds[i].g) { 465 ledsStep[i].gStep = ((int)ledsAim[i].g - (int)leds[i].g) / (int)fadeSteps; 466 if (ledsStep[i].gStep == 0) { 467 if (ledsAim[i].g > leds[i].g) ledsStep[i].gStep = 1; 468 else ledsStep[i].gStep = -1; 469 } 470#if DEBUG 471 DebugSerial.println("gStep: " + (String)ledsStep[i].gStep); //debug 472#endif 473 } 474 if (ledsAim[i].b != leds[i].b) { 475 ledsStep[i].bStep = ((int)ledsAim[i].b - (int)leds[i].b) / (int)fadeSteps; 476 if (ledsStep[i].bStep == 0) { 477 if (ledsAim[i].b > leds[i].b) ledsStep[i].bStep = 1; 478 else ledsStep[i].bStep = -1; 479 } 480#if DEBUG 481 DebugSerial.println("bStep: " + (String)ledsStep[i].bStep); //debug 482#endif 483 } 484 485 } 486} 487 488 489void fillSpiralCCW() { 490 491 FastLED.clear(); 492 FastLED.show(); 493 494 for (byte i = 0; i < (sizeof(spiralCCW) / sizeof(byte)); i++) { 495 leds[spiralCCW[i]].setHue(hueTemp); 496 FastLED.show(); 497 FastLED.delay(30); 498 hueTemp += 2; 499 } 500 501 for (byte i = (sizeof(spiralCCW) / sizeof(byte)) - 1; i > 0; i--) { 502 leds[spiralCCW[i]] = CRGB::Black; 503 FastLED.show(); 504 FastLED.delay(30); 505 } 506} 507 508void fillSpiralCW() { 509 510 FastLED.clear(); 511 FastLED.show(); 512 513 for (byte i = 0; i < (sizeof(spiralCW) / sizeof(byte)); i++) { 514 leds[spiralCW[i]].setHue(hueTemp); 515 FastLED.show(); 516 FastLED.delay(30); 517 hueTemp += 2; 518 } 519 520 for (byte i = (sizeof(spiralCW) / sizeof(byte)) - 1; i > 0; i--) { 521 leds[spiralCW[i]] = CRGB::Black; 522 FastLED.show(); 523 FastLED.delay(30); 524 } 525} 526 527 528void frameMarquee() { 529 FastLED.clear(); 530 FastLED.show(); 531 532 for (int j = 0; j < 400; j++) { 533 for (byte i = 0; i < (sizeof(frame) / sizeof(byte)); i++) { 534 leds[frame[i]].setHue(hueTemp); 535 hueTemp += 2; 536 } 537 hueTemp = 2 * j; 538 FastLED.show(); 539 FastLED.delay(40); 540 } 541 FastLED.clear(); 542 FastLED.show(); 543} 544 545void innerFrame() { 546 for (int j = 0; j < 15; j++) { 547 548 hueTemp += 40; 549 550 for (byte i = 0; i < (sizeof(frame) / sizeof(byte)); i++) { 551 leds[frame[i]].setHue(hueTemp); 552 } 553 FastLED.show(); 554 FastLED.delay(200); 555 556 for (byte i = 0; i < (sizeof(frame) / sizeof(byte)); i++) { 557 leds[frame[i]] = CRGB::Black; 558 } 559 560 hueTemp += 40; 561 562 for (byte i = 0; i < (sizeof(inner) / sizeof(byte)); i++) { 563 leds[inner[i]].setHue(hueTemp); 564 } 565 FastLED.show(); 566 FastLED.delay(200); 567 568 for (byte i = 0; i < (sizeof(inner) / sizeof(byte)); i++) { 569 leds[inner[i]] = CRGB::Black; 570 } 571 } 572 FastLED.clear(); 573 FastLED.show(); 574} 575 576void triangle() { 577 hueTemp += 16; 578 for (byte i = 0; i < (sizeof(triangle1) / sizeof(byte)); i++) { 579 leds[triangle1[i]].setHue(hueTemp); 580 } 581 FastLED.show(); 582 FastLED.delay(150); 583 for (byte i = 0; i < (sizeof(triangle1) / sizeof(byte)); i++) { 584 leds[triangle1[i]] = CRGB::Black; 585 } 586 hueTemp += 16; 587 for (byte i = 0; i < (sizeof(triangle2) / sizeof(byte)); i++) { 588 leds[triangle2[i]].setHue(hueTemp); 589 } 590 FastLED.show(); 591 FastLED.delay(150); 592 for (byte i = 0; i < (sizeof(triangle2) / sizeof(byte)); i++) { 593 leds[triangle2[i]] = CRGB::Black; 594 } 595 hueTemp += 16; 596 for (byte i = 0; i < (sizeof(triangle3) / sizeof(byte)); i++) { 597 leds[triangle3[i]].setHue(hueTemp); 598 } 599 FastLED.show(); 600 FastLED.delay(150); 601 for (byte i = 0; i < (sizeof(triangle3) / sizeof(byte)); i++) { 602 leds[triangle3[i]] = CRGB::Black; 603 } 604 hueTemp += 16; 605 for (byte i = 0; i < (sizeof(triangle4) / sizeof(byte)); i++) { 606 leds[triangle4[i]].setHue(hueTemp); 607 } 608 FastLED.show(); 609 FastLED.delay(150); 610 for (byte i = 0; i < (sizeof(triangle4) / sizeof(byte)); i++) { 611 leds[triangle4[i]] = CRGB::Black; 612 } 613 614} 615 616
Parola_Fonts_data.h
arduino
Fonts for the dot matrix to allow umlaute etc.
1// Data file for UTF-8 example user defined fonts 2#ifndef FONTS_DATA_H 3#define FONTS_DATA_H 4 5MD_MAX72XX::fontType_t ExtASCII[] PROGMEM = 6{ 7 0, // 0 - 'Unused' 8 0, // 1 - 'Unused' 9 0, // 2 - 'Unused' 10 0, // 3 - 'Unused' 11 0, // 4 - 'Unused' 12 0, // 5 - 'Unused' 13 0, // 6 - 'Unused' 14 0, // 7 - 'Unused' 15 0, // 8 - 'Unused' 16 0, // 9 - 'Unused' 17 0, // 10 - 'Unused' 18 0, // 11 - 'Unused' 19 0, // 12 - 'Unused' 20 0, // 13 - 'Unused' 21 0, // 14 - 'Unused' 22 0, // 15 - 'Unused' 23 0, // 16 - 'Unused' 24 0, // 17 - 'Unused' 25 0, // 18 - 'Unused' 26 0, // 19 - 'Unused' 27 0, // 20 - 'Unused' 28 0, // 21 - 'Unused' 29 0, // 22 - 'Unused' 30 0, // 23 - 'Unused' 31 0, // 24 - 'Unused' 32 0, // 25 - 'Unused' 33 0, // 26 - 'Unused' 34 0, // 27 - 'Unused' 35 0, // 28 - 'Unused' 36 0, // 29 - 'Unused' 37 0, // 30 - 'Unused' 38 0, // 31 - 'Unused' 39 2, 0, 0, // 32 - 'Space' 40 1, 95, // 33 - '!' 41 3, 7, 0, 7, // 34 - '"' 42 5, 20, 127, 20, 127, 20, // 35 - '#' 43 5, 36, 42, 127, 42, 18, // 36 - '$' 44 5, 35, 19, 8, 100, 98, // 37 - '%' 45 5, 54, 73, 86, 32, 80, // 38 - '&' 46 2, 4, 3, // 39 47 3, 28, 34, 65, // 40 - '(' 48 3, 65, 34, 28, // 41 - ')' 49 5, 42, 28, 127, 28, 42, // 42 - '*' 50 5, 8, 8, 62, 8, 8, // 43 - '+' 51 2, 128, 96, // 44 - ',' 52 5, 8, 8, 8, 8, 8, // 45 - '-' 53 2, 96, 96, // 46 - '.' 54 5, 32, 16, 8, 4, 2, // 47 - '/' 55 5, 62, 81, 73, 69, 62, // 48 - '0' 56 3, 66, 127, 64, // 49 - '1' 57 5, 114, 73, 73, 73, 70, // 50 - '2' 58 5, 33, 65, 73, 77, 51, // 51 - '3' 59 5, 24, 20, 18, 127, 16, // 52 - '4' 60 5, 39, 69, 69, 69, 57, // 53 - '5' 61 5, 60, 74, 73, 73, 49, // 54 - '6' 62 5, 65, 33, 17, 9, 7, // 55 - '7' 63 5, 54, 73, 73, 73, 54, // 56 - '8' 64 5, 70, 73, 73, 41, 30, // 57 - '9' 65 1, 20, // 58 - ':' 66 2, 128, 104, // 59 - ';' 67 4, 8, 20, 34, 65, // 60 - '<' 68 5, 20, 20, 20, 20, 20, // 61 - '=' 69 4, 65, 34, 20, 8, // 62 - '>' 70 5, 2, 1, 89, 9, 6, // 63 - '?' 71 5, 62, 65, 93, 89, 78, // 64 - '@' 72 5, 124, 18, 17, 18, 124, // 65 - 'A' 73 5, 127, 73, 73, 73, 54, // 66 - 'B' 74 5, 62, 65, 65, 65, 34, // 67 - 'C' 75 5, 127, 65, 65, 65, 62, // 68 - 'D' 76 5, 127, 73, 73, 73, 65, // 69 - 'E' 77 5, 127, 9, 9, 9, 1, // 70 - 'F' 78 5, 62, 65, 65, 81, 115, // 71 - 'G' 79 5, 127, 8, 8, 8, 127, // 72 - 'H' 80 3, 65, 127, 65, // 73 - 'I' 81 5, 32, 64, 65, 63, 1, // 74 - 'J' 82 5, 127, 8, 20, 34, 65, // 75 - 'K' 83 5, 127, 64, 64, 64, 64, // 76 - 'L' 84 5, 127, 2, 28, 2, 127, // 77 - 'M' 85 5, 127, 4, 8, 16, 127, // 78 - 'N' 86 5, 62, 65, 65, 65, 62, // 79 - 'O' 87 5, 127, 9, 9, 9, 6, // 80 - 'P' 88 5, 62, 65, 81, 33, 94, // 81 - 'Q' 89 5, 127, 9, 25, 41, 70, // 82 - 'R' 90 5, 38, 73, 73, 73, 50, // 83 - 'S' 91 5, 3, 1, 127, 1, 3, // 84 - 'T' 92 5, 63, 64, 64, 64, 63, // 85 - 'U' 93 5, 31, 32, 64, 32, 31, // 86 - 'V' 94 5, 63, 64, 56, 64, 63, // 87 - 'W' 95 5, 99, 20, 8, 20, 99, // 88 - 'X' 96 5, 3, 4, 120, 4, 3, // 89 - 'Y' 97 5, 97, 89, 73, 77, 67, // 90 - 'Z' 98 3, 127, 65, 65, // 91 - '[' 99 5, 2, 4, 8, 16, 32, // 92 - '\\' 100 3, 65, 65, 127, // 93 - ']' 101 5, 4, 2, 1, 2, 4, // 94 - '^' 102 5, 64, 64, 64, 64, 64, // 95 - '_' 103 2, 3, 4, // 96 - '`' 104 5, 32, 84, 84, 120, 64, // 97 - 'a' 105 5, 127, 40, 68, 68, 56, // 98 - 'b' 106 5, 56, 68, 68, 68, 40, // 99 - 'c' 107 5, 56, 68, 68, 40, 127, // 100 - 'd' 108 5, 56, 84, 84, 84, 24, // 101 - 'e' 109 4, 8, 126, 9, 2, // 102 - 'f' 110 5, 24, 164, 164, 156, 120, // 103 - 'g' 111 5, 127, 8, 4, 4, 120, // 104 - 'h' 112 3, 68, 125, 64, // 105 - 'i' 113 4, 64, 128, 128, 122, // 106 - 'j' 114 4, 127, 16, 40, 68, // 107 - 'k' 115 3, 65, 127, 64, // 108 - 'l' 116 5, 124, 4, 120, 4, 120, // 109 - 'm' 117 5, 124, 8, 4, 4, 120, // 110 - 'n' 118 5, 56, 68, 68, 68, 56, // 111 - 'o' 119 5, 252, 24, 36, 36, 24, // 112 - 'p' 120 5, 24, 36, 36, 24, 252, // 113 - 'q' 121 5, 124, 8, 4, 4, 8, // 114 - 'r' 122 5, 72, 84, 84, 84, 36, // 115 - 's' 123 4, 4, 63, 68, 36, // 116 - 't' 124 5, 60, 64, 64, 32, 124, // 117 - 'u' 125 5, 28, 32, 64, 32, 28, // 118 - 'v' 126 5, 60, 64, 48, 64, 60, // 119 - 'w' 127 5, 68, 40, 16, 40, 68, // 120 - 'x' 128 5, 76, 144, 144, 144, 124, // 121 - 'y' 129 5, 68, 100, 84, 76, 68, // 122 - 'z' 130 3, 8, 54, 65, // 123 - '{' 131 1, 119, // 124 - '|' 132 3, 65, 54, 8, // 125 - '}' 133 5, 2, 1, 2, 4, 2, // 126 - '~' 134 0, // 127 - 'Unused' 135 6, 20, 62, 85, 85, 65, 34, // 128 - 'Euro sign' 136 5, 28, 62, 124, 62, 28, // 129 - 'Heart' costum char!!! 137 2, 128, 96, // 130 - 'Single low 9 quotation mark' 138 5, 192, 136, 126, 9, 3, // 131 - 'f with hook' 139 4, 128, 96, 128, 96, // 132 - 'Single low 9 quotation mark' 140 8, 96, 96, 0, 96, 96, 0, 96, 96, // 133 - 'Horizontal ellipsis' 141 3, 4, 126, 4, // 134 - 'Dagger' 142 3, 20, 126, 20, // 135 - 'Double dagger' 143 4, 2, 1, 1, 2, // 136 - 'Modifier circumflex' 144 7, 35, 19, 104, 100, 2, 97, 96, // 137 - 'Per mille sign' 145 5, 72, 85, 86, 85, 36, // 138 - 'S with caron' 146 3, 8, 20, 34, // 139 - '< quotation' 147 6, 62, 65, 65, 127, 73, 73, // 140 - 'OE' 148 0, // 141 - 'Not used' 149 5, 68, 101, 86, 77, 68, // 142 - 'z with caron' 150 0, // 143 - 'Not used' 151 0, // 144 - 'Not used' 152 2, 3, 4, // 145 - 'Left single quote mark' 153 2, 4, 3, // 146 - 'Right single quote mark' 154 4, 3, 4, 3, 4, // 147 - 'Left double quote marks' 155 4, 4, 3, 4, 3, // 148 - 'Right double quote marks' 156 4, 0, 24, 60, 24, // 149 - 'Bullet Point' 157 3, 8, 8, 8, // 150 - 'En dash' 158 5, 8, 8, 8, 8, 8, // 151 - 'Em dash' 159 4, 2, 1, 2, 1, // 152 - 'Small ~' 160 7, 1, 15, 1, 0, 15, 2, 15, // 153 - 'TM' 161 5, 72, 85, 86, 85, 36, // 154 - 's with caron' 162 3, 34, 20, 8, // 155 - '> quotation' 163 7, 56, 68, 68, 124, 84, 84, 8, // 156 - 'oe' 164 0, // 157 - 'Not used' 165 5, 68, 101, 86, 77, 68, // 158 - 'z with caron' 166 5, 12, 17, 96, 17, 12, // 159 - 'Y diaresis' 167 2, 0, 0, // 160 - 'Non-breaking space' 168 1, 125, // 161 - 'Inverted !' 169 5, 60, 36, 126, 36, 36, // 162 - 'Cent sign' 170 5, 72, 126, 73, 65, 102, // 163 - 'Pound sign' 171 5, 34, 28, 20, 28, 34, // 164 - 'Currency sign' 172 5, 43, 47, 252, 47, 43, // 165 - 'Yen' 173 1, 119, // 166 - '|' 174 4, 102, 137, 149, 106, // 167 - 'Section sign' 175 3, 1, 0, 1, // 168 - 'Spacing diaresis' 176 7, 62, 65, 93, 85, 85, 65, 62, // 169 - 'Copyright' 177 3, 13, 13, 15, // 170 - 'Feminine Ordinal Ind.' 178 5, 8, 20, 42, 20, 34, // 171 - '<<' 179 5, 8, 8, 8, 8, 56, // 172 - 'Not sign' 180 0, // 173 - 'Soft Hyphen' 181 7, 62, 65, 127, 75, 117, 65, 62, // 174 - 'Registered Trademark' 182 5, 1, 1, 1, 1, 1, // 175 - 'Spacing Macron Overline' 183 3, 2, 5, 2, // 176 - 'Degree' 184 5, 68, 68, 95, 68, 68, // 177 - '+/-' 185 3, 25, 21, 19, // 178 - 'Superscript 2' 186 3, 17, 21, 31, // 179 - 'Superscript 3' 187 2, 2, 1, // 180 - 'Acute accent' 188 4, 252, 64, 64, 60, // 181 - 'micro (mu)' 189 5, 6, 9, 127, 1, 127, // 182 - 'Paragraph Mark' 190 2, 24, 24, // 183 - 'Middle Dot' 191 3, 128, 128, 96, // 184 - 'Spacing sedilla' 192 2, 2, 31, // 185 - 'Superscript 1' 193 4, 6, 9, 9, 6, // 186 - 'Masculine Ordinal Ind.' 194 5, 34, 20, 42, 20, 8, // 187 - '>>' 195 6, 64, 47, 16, 40, 52, 250, // 188 - '1/4' 196 6, 64, 47, 16, 200, 172, 186, // 189 - '1/2' 197 6, 85, 53, 31, 40, 52, 250, // 190 - '3/4' 198 5, 48, 72, 77, 64, 32, // 191 - 'Inverted ?' 199 5, 120, 20, 21, 22, 120, // 192 - 'A grave' 200 5, 120, 22, 21, 20, 120, // 193 - 'A acute' 201 5, 122, 21, 21, 21, 122, // 194 - 'A circumflex' 202 5, 120, 22, 21, 22, 121, // 195 - 'A tilde' 203 5, 120, 21, 20, 21, 120, // 196 - 'A diaresis' 204 5, 120, 20, 21, 20, 120, // 197 - 'A ring above' 205 6, 124, 10, 9, 127, 73, 73, // 198 - 'AE' 206 5, 30, 161, 161, 97, 18, // 199 - 'C sedilla' 207 4, 124, 85, 86, 68, // 200 - 'E grave' 208 4, 124, 86, 85, 68, // 201 - 'E acute' 209 4, 126, 85, 85, 70, // 202 - 'E circumflex' 210 4, 124, 85, 84, 69, // 203 - 'E diaresis' 211 3, 68, 125, 70, // 204 - 'I grave' 212 3, 68, 126, 69, // 205 - 'I acute' 213 3, 70, 125, 70, // 206 - 'I circumplex' 214 3, 69, 124, 69, // 207 - 'I diaresis' 215 6, 4, 127, 69, 65, 65, 62, // 208 - 'Capital Eth' 216 5, 124, 10, 17, 34, 125, // 209 - 'N tilde' 217 5, 56, 68, 69, 70, 56, // 210 - 'O grave' 218 5, 56, 70, 69, 68, 56, // 211 - 'O acute' 219 5, 58, 69, 69, 69, 58, // 212 - 'O circumflex' 220 5, 56, 70, 69, 70, 57, // 213 - 'O tilde' 221 5, 56, 69, 68, 69, 56, // 214 - 'O diaresis' 222 5, 34, 20, 8, 20, 34, // 215 - 'Multiplication sign' 223 7, 64, 62, 81, 73, 69, 62, 1, // 216 - 'O slashed' 224 5, 60, 65, 66, 64, 60, // 217 - 'U grave' 225 5, 60, 64, 66, 65, 60, // 218 - 'U acute' 226 5, 58, 65, 65, 65, 58, // 219 - 'U circumflex' 227 5, 60, 65, 64, 65, 60, // 220 - 'U diaresis' 228 5, 12, 16, 98, 17, 12, // 221 - 'Y acute' 229 4, 127, 18, 18, 12, // 222 - 'Capital thorn' 230 4, 254, 37, 37, 26, // 223 - 'Small letter sharp S' 231 5, 32, 84, 85, 122, 64, // 224 - 'a grave' 232 5, 32, 84, 86, 121, 64, // 225 - 'a acute' 233 5, 34, 85, 85, 121, 66, // 226 - 'a circumflex' 234 5, 32, 86, 85, 122, 65, // 227 - 'a tilde' 235 5, 32, 85, 84, 121, 64, // 228 - 'a diaresis' 236 5, 32, 84, 85, 120, 64, // 229 - 'a ring above' 237 7, 32, 84, 84, 124, 84, 84, 8, // 230 - 'ae' 238 5, 24, 36, 164, 228, 40, // 231 - 'c sedilla' 239 5, 56, 84, 85, 86, 88, // 232 - 'e grave' 240 5, 56, 84, 86, 85, 88, // 233 - 'e acute' 241 5, 58, 85, 85, 85, 90, // 234 - 'e circumflex' 242 5, 56, 85, 84, 85, 88, // 235 - 'e diaresis' 243 3, 68, 125, 66, // 236 - 'i grave' 244 3, 68, 126, 65, // 237 - 'i acute' 245 3, 70, 125, 66, // 238 - 'i circumflex' 246 3, 69, 124, 65, // 239 - 'i diaresis' 247 4, 48, 75, 74, 61, // 240 - 'Small eth' 248 4, 122, 9, 10, 113, // 241 - 'n tilde' 249 5, 56, 68, 69, 70, 56, // 242 - 'o grave' 250 5, 56, 70, 69, 68, 56, // 243 - 'o acute' 251 5, 58, 69, 69, 69, 58, // 244 - 'o circumflex' 252 5, 56, 70, 69, 70, 57, // 245 - 'o tilde' 253 5, 56, 69, 68, 69, 56, // 246 - 'o diaresis' 254 5, 8, 8, 42, 8, 8, // 247 - 'Division sign' 255 6, 64, 56, 84, 76, 68, 58, // 248 - 'o slashed' 256 5, 60, 65, 66, 32, 124, // 249 - 'u grave' 257 5, 60, 64, 66, 33, 124, // 250 - 'u acute' 258 5, 58, 65, 65, 33, 122, // 251 - 'u circumflex' 259 5, 60, 65, 64, 33, 124, // 252 - 'u diaresis' 260 4, 156, 162, 161, 124, // 253 - 'y acute' 261 4, 252, 72, 72, 48, // 254 - 'small thorn' 262 4, 157, 160, 160, 125, // 255 - 'y diaresis' 263}; 264 265#endif 266
TelegramBot.h
arduino
Adapt to changed *.cpp
1// Copyright Casa Jasmina 2016 2// LGPL License 3// 4// TelegramBot library 5// https://github.com/CasaJasmina/TelegramBot-Library 6 7#ifndef TelegramBot_h 8#define TelegramBot_h 9 10#include <Arduino.h> 11#include <ArduinoJson.h> 12#include <Client.h> 13#include <TelegramKeyboard.h> 14 15#define HOST "api.telegram.org" 16#define SSL_PORT 443 17#define JSON_BUFF_SIZE 10000 18 19struct locationStruct{ 20 String lon; 21 String lat; 22}; 23 24struct message{ 25 String text; 26 String chat_id; 27 String sender; 28 String first_name; 29 String date; 30 locationStruct location; 31}; 32 33 34class TelegramBot 35{ 36 public: 37 TelegramBot(const char* token, Client &client); 38 void begin(); 39 String sendMessage(String chat_id, String text); 40 String sendMessage(String chat_id, String text, TelegramKeyboard &keyboard_markup, bool one_time_keyboard = true, bool resize_keyboard = true); 41 String postMessage(String msg); 42 message getUpdates(); 43 44 45 private: 46 String readPayload(); 47 String convertText(String unicodeStr); 48 const char* token; 49 50 int last_message_recived; 51 52 Client *client; 53}; 54 55#endif 56
TelegramBot.cpp
arduino
I made some changes to the TelegramBot library to get the first name and location of the user. And also a function to convert utf16 to extended ascii for use with the dot matrix.
1#include "TelegramBot.h" 2 3TelegramBot::TelegramBot(const char* token, Client &client) { 4 this->client = &client; 5 this->token=token; 6} 7 8 9void TelegramBot::begin() { 10 if(!client->connected()){ 11 client->connect(HOST, SSL_PORT); 12 } 13} 14 15/************************************************************************************ 16 * GetUpdates - function to receive messages from telegram as a Json and parse them * 17 ************************************************************************************/ 18message TelegramBot::getUpdates() { 19 begin(); 20 21 //Send your request to api.telegram.org 22 String getRequest = "GET /bot"+String(token)+"/getUpdates?limit=1&offset="+String(last_message_recived)+" HTTP/1.1"; 23 client->println(getRequest); 24 client->println("User-Agent: curl/7.37.1"); 25 client->println("Host: api.telegram.org"); 26 client->println("Accept: */*"); 27 client->println(); 28 29 String payload = readPayload(); 30 if (payload != "") { 31 message m; 32 StaticJsonBuffer<JSON_BUFF_SIZE> jsonBuffer; 33 JsonObject & root = jsonBuffer.parseObject(payload); 34 35 36 37 if(root.success()){ 38 39 int update_id = root["result"][0]["update_id"]; 40 update_id = update_id+1; 41 42 if(last_message_recived != update_id ){ 43 String sender = root["result"][0]["message"]["from"]["username"]; 44 String text = root["result"][0]["message"]["text"]; 45 String chat_id = root["result"][0]["message"]["chat"]["id"]; 46 String date = root["result"][0]["message"]["date"]; 47 String first_name = root["result"][0]["message"]["from"]["first_name"]; 48 String lon = root["result"][0]["message"]["location"]["longitude"]; 49 String lat = root["result"][0]["message"]["location"]["latitude"]; 50 51 m.sender = sender; 52 m.text = text; 53 m.chat_id = chat_id; 54 m.date = date; 55 m.first_name = first_name; 56 m.location.lon = lon; 57 m.location.lat = lat; 58 59 last_message_recived=update_id; 60 return m; 61 }else{ 62 m.chat_id = ""; 63 return m; 64 } 65 } 66 else{ 67 Serial.println(""); 68 Serial.println("Message too long, skipped."); 69 Serial.println(""); 70 int update_id_first_digit=0; 71 int update_id_last_digit=0; 72 for(int a =0; a<3; a++){ 73 update_id_first_digit= payload.indexOf(':',update_id_first_digit+1); 74 } 75 for(int a =0; a<2; a++){ 76 update_id_last_digit= payload.indexOf(',',update_id_last_digit+1); 77 } 78 last_message_recived = payload.substring(update_id_first_digit+1,update_id_last_digit).toInt() +1; 79 } 80 } 81 } 82 83// send message function 84// send a simple text message to a telegram char 85String TelegramBot::sendMessage(String chat_id, String text) { 86 if(chat_id!="0" && chat_id!=""){ 87 StaticJsonBuffer<JSON_BUFF_SIZE> jsonBuffer; 88 JsonObject& buff = jsonBuffer.createObject(); 89 buff["chat_id"] = chat_id; 90 buff["text"] = text; 91 92 String msg; 93 buff.printTo(msg); 94 return postMessage(msg); 95 } else { 96 Serial.println("Chat_id not defined"); 97 } 98} 99 100// send a message to a telegram chat with a reply markup 101String TelegramBot::sendMessage(String chat_id, String text, TelegramKeyboard &keyboard_markup, bool one_time_keyboard, bool resize_keyboard) { 102 StaticJsonBuffer<JSON_BUFF_SIZE> jsonBuffer; 103 JsonObject& buff = jsonBuffer.createObject(); 104 buff["chat_id"] = chat_id; 105 buff["text"] = text; 106 107 JsonObject& reply_markup = buff.createNestedObject("reply_markup"); 108 JsonArray& keyboard = reply_markup.createNestedArray("keyboard"); 109 110 for (int a = 1 ; a <= keyboard_markup.length() ; a++){ 111 JsonArray& row = keyboard.createNestedArray(); 112 for( int b = 1; b <= keyboard_markup.rowSize(a) ; b++){ 113 row.add(keyboard_markup.getButton(a,b)); 114 } 115 } 116 117 reply_markup.set<bool>("one_time_keyboard", one_time_keyboard); 118 reply_markup.set<bool>("resize_keyboard", resize_keyboard); 119 reply_markup.set<bool>("selective", false); 120 121 String msg; 122 buff.printTo(msg); 123 // Serial.println(msg); 124 return postMessage(msg); 125} 126 127// gets the telegram json string 128// posts the message to telegram 129// returns the payload 130String TelegramBot::postMessage(String msg) { 131 begin(); 132 133 client->println("POST /bot"+String(token)+"/sendMessage"+" HTTP/1.1"); 134 client->println("Host: api.telegram.org"); 135 client->println("Content-Type: application/json"); 136 client->println("Connection: close"); 137 client->print("Content-Length: "); 138 client->println(msg.length()); 139 client->println(); 140 client->println(msg); 141 142 return readPayload(); 143} 144 145// reads the payload coming from telegram server 146// returns the payload string 147String TelegramBot::readPayload(){ 148 char c; 149 String payload=""; 150 //Read the answer and save it in String payload 151 while (client->connected()) { 152 payload = client->readStringUntil('\ 153'); 154 if (payload == "\ ") { 155 break; 156 } 157 } 158 payload = client->readStringUntil('\ '); 159 // Serial.println(payload); 160 return convertText(payload); 161} 162 163String TelegramBot::convertText(String unicodeStr){ //converts UTF-16 Unicode to extended Ascii. Emojis not supported 164 String out = ""; 165 int len = unicodeStr.length(); 166 char iChar; 167 char* error; 168 for (int i = 0; i < len; i++){ 169 iChar = unicodeStr[i]; 170 if(iChar == '\\\\'){ // got escape char 171 iChar = unicodeStr[++i]; 172 if(iChar == 'u'){ // got unicode hex 173 char unicode[6]; 174 unicode[0] = '0'; 175 unicode[1] = 'x'; 176 for (int j = 0; j < 4; j++){ 177 iChar = unicodeStr[++i]; 178 unicode[j + 2] = iChar; 179 } 180 long unicodeVal = strtol(unicode, &error, 16); //convert the string 181 if (unicodeVal == 0x20AC) unicodeVal = 0x80; // euro sign 182 //Serial.print("strtol: "); 183 //Serial.println(unicodeVal, HEX); 184 out += (char)unicodeVal; 185 } else if(iChar == '/'){ 186 out += iChar; 187 } else if(iChar == 'n'){ 188 out += '\ 189'; 190 } 191 } else if (iChar == '<' && unicodeStr[i + 1] == '3') { //convert "<3" to costum set 'heart' char, ascii: 0x81 192 long charTemp = 0x81; 193 out += (char)charTemp; 194 i++; 195 } else { 196 out += iChar; 197 } 198 } 199 return out; 200}
leds_lookup_table.h
arduino
Look up table for the LEDs on the tree.
1byte frame[] = {52, 51, 43, 42, 32, 31, 19, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 25, 26, 38, 39, 47, 48, 54, 53}; 2 3byte inner[] = {50, 49, 44, 45, 46, 41, 40, 33, 34, 35, 36, 37, 30, 29, 28, 27, 20, 21, 22, 23, 24, 17, 16, 15, 14, 13, 12, 11, 10}; 4 5byte spiralCCW[] = {52, 51, 43, 32, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 38, 47, 48, 54, 53, 50, 44, 42, 33, 31, 19, 17, 6 16, 15, 14, 13, 12, 11, 10, 25, 26, 37, 39, 46, 49, 45, 41, 34, 30, 20, 21, 22, 23, 24, 7 27, 36, 40, 35, 29, 28, 35}; 8byte spiralCW[] = {52, 53, 54, 48, 47, 38, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 18, 32, 43, 51, 50, 49, 46, 39, 37, 26, 25, 10, 11, 12, 13, 14, 15, 16, 17, 19, 31, 9 33, 42, 44, 45, 40, 36, 27, 24, 23, 22, 21, 20, 30, 34, 41, 35, 28, 29}; 10 11byte triangle1[] = {35, 29, 28}; 12 13byte triangle2[] = {45, 41, 34, 30, 20, 21, 22, 23, 24, 27, 36, 40}; 14 15byte triangle3[] = {53, 50, 44, 42, 33, 31, 19, 17, 16, 15, 14, 13, 12, 11, 10, 25, 26, 37, 39, 46, 49}; 16 17byte triangle4[] = {52, 51, 43, 32, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 38, 47, 48, 54}; 18 19 20
TelegramBot.cpp
arduino
I made some changes to the TelegramBot library to get the first name and location of the user. And also a function to convert utf16 to extended ascii for use with the dot matrix.
1#include "TelegramBot.h" 2 3TelegramBot::TelegramBot(const char* 4 token, Client &client) { 5 this->client = &client; 6 this->token=token; 7} 8 9 10void 11 TelegramBot::begin() { 12 if(!client->connected()){ 13 client->connect(HOST, 14 SSL_PORT); 15 } 16} 17 18/************************************************************************************ 19 20 * GetUpdates - function to receive messages from telegram as a Json and parse them 21 * 22 ************************************************************************************/ 23message 24 TelegramBot::getUpdates() { 25 begin(); 26 27 //Send your request to api.telegram.org 28 String 29 getRequest = "GET /bot"+String(token)+"/getUpdates?limit=1&offset="+String(last_message_recived)+" 30 HTTP/1.1"; 31 client->println(getRequest); 32 client->println("User-Agent: 33 curl/7.37.1"); 34 client->println("Host: api.telegram.org"); 35 client->println("Accept: 36 */*"); 37 client->println(); 38 39 String payload = readPayload(); 40 41 if (payload != "") { 42 message m; 43 StaticJsonBuffer<JSON_BUFF_SIZE> 44 jsonBuffer; 45 JsonObject & root = jsonBuffer.parseObject(payload); 46 47 48 49 if(root.success()){ 50 51 int 52 update_id = root["result"][0]["update_id"]; 53 update_id = update_id+1; 54 55 if(last_message_recived 56 != update_id ){ 57 String sender = root["result"][0]["message"]["from"]["username"]; 58 String 59 text = root["result"][0]["message"]["text"]; 60 String chat_id = 61 root["result"][0]["message"]["chat"]["id"]; 62 String date = root["result"][0]["message"]["date"]; 63 64 String first_name = root["result"][0]["message"]["from"]["first_name"]; 65 66 String lon = root["result"][0]["message"]["location"]["longitude"]; 67 68 String lat = root["result"][0]["message"]["location"]["latitude"]; 69 70 m.sender 71 = sender; 72 m.text = text; 73 m.chat_id = chat_id; 74 m.date 75 = date; 76 m.first_name = first_name; 77 m.location.lon 78 = lon; 79 m.location.lat = lat; 80 81 last_message_recived=update_id; 82 return 83 m; 84 }else{ 85 m.chat_id = ""; 86 return m; 87 } 88 } 89 else{ 90 Serial.println(""); 91 Serial.println("Message 92 too long, skipped."); 93 Serial.println(""); 94 int update_id_first_digit=0; 95 int 96 update_id_last_digit=0; 97 for(int a =0; a<3; a++){ 98 update_id_first_digit= 99 payload.indexOf(':',update_id_first_digit+1); 100 } 101 for(int a 102 =0; a<2; a++){ 103 update_id_last_digit= payload.indexOf(',',update_id_last_digit+1); 104 } 105 last_message_recived 106 = payload.substring(update_id_first_digit+1,update_id_last_digit).toInt() +1; 107 } 108 } 109 } 110 111// 112 send message function 113// send a simple text message to a telegram char 114String 115 TelegramBot::sendMessage(String chat_id, String text) { 116 if(chat_id!="0" 117 && chat_id!=""){ 118 StaticJsonBuffer<JSON_BUFF_SIZE> jsonBuffer; 119 JsonObject& 120 buff = jsonBuffer.createObject(); 121 buff["chat_id"] = chat_id; 122 buff["text"] 123 = text; 124 125 String msg; 126 buff.printTo(msg); 127 return postMessage(msg); 128 } 129 else { 130 Serial.println("Chat_id not defined"); 131 } 132} 133 134// send 135 a message to a telegram chat with a reply markup 136String TelegramBot::sendMessage(String 137 chat_id, String text, TelegramKeyboard &keyboard_markup, bool one_time_keyboard, 138 bool resize_keyboard) { 139 StaticJsonBuffer<JSON_BUFF_SIZE> jsonBuffer; 140 JsonObject& 141 buff = jsonBuffer.createObject(); 142 buff["chat_id"] = chat_id; 143 buff["text"] 144 = text; 145 146 JsonObject& reply_markup = buff.createNestedObject("reply_markup"); 147 JsonArray& 148 keyboard = reply_markup.createNestedArray("keyboard"); 149 150 for (int a = 151 1 ; a <= keyboard_markup.length() ; a++){ 152 JsonArray& row = keyboard.createNestedArray(); 153 for( 154 int b = 1; b <= keyboard_markup.rowSize(a) ; b++){ 155 row.add(keyboard_markup.getButton(a,b)); 156 } 157 } 158 159 reply_markup.set<bool>("one_time_keyboard", 160 one_time_keyboard); 161 reply_markup.set<bool>("resize_keyboard", resize_keyboard); 162 reply_markup.set<bool>("selective", 163 false); 164 165 String msg; 166 buff.printTo(msg); 167 // Serial.println(msg); 168 return 169 postMessage(msg); 170} 171 172// gets the telegram json string 173// posts the message 174 to telegram 175// returns the payload 176String TelegramBot::postMessage(String 177 msg) { 178 begin(); 179 180 client->println("POST /bot"+String(token)+"/sendMessage"+" 181 HTTP/1.1"); 182 client->println("Host: api.telegram.org"); 183 client->println("Content-Type: 184 application/json"); 185 client->println("Connection: close"); 186 client->print("Content-Length: 187 "); 188 client->println(msg.length()); 189 client->println(); 190 client->println(msg); 191 192 return 193 readPayload(); 194} 195 196// reads the payload coming from telegram server 197// 198 returns the payload string 199String TelegramBot::readPayload(){ 200 char c; 201 String 202 payload=""; 203 //Read the answer and save it in String payload 204 while 205 (client->connected()) { 206 payload = client->readStringUntil('\ 207'); 208 if 209 (payload == "\ ") { 210 break; 211 } 212 } 213 payload = client->readStringUntil('\ '); 214 // 215 Serial.println(payload); 216 return convertText(payload); 217} 218 219String TelegramBot::convertText(String 220 unicodeStr){ //converts UTF-16 Unicode to extended Ascii. Emojis not supported 221 222 String out = ""; 223 int len = unicodeStr.length(); 224 char iChar; 225 char* 226 error; 227 for (int i = 0; i < len; i++){ 228 iChar = unicodeStr[i]; 229 if(iChar 230 == '\\\\'){ // got escape char 231 iChar = unicodeStr[++i]; 232 if(iChar 233 == 'u'){ // got unicode hex 234 char unicode[6]; 235 unicode[0] 236 = '0'; 237 unicode[1] = 'x'; 238 for (int j = 0; j < 4; j++){ 239 240 iChar = unicodeStr[++i]; 241 unicode[j + 2] = iChar; 242 } 243 244 long unicodeVal = strtol(unicode, &error, 16); //convert the string 245 246 if (unicodeVal == 0x20AC) unicodeVal = 0x80; // euro sign 247 //Serial.print("strtol: 248 "); 249 //Serial.println(unicodeVal, HEX); 250 out += (char)unicodeVal; 251 252 } else if(iChar == '/'){ 253 out += iChar; 254 } else if(iChar 255 == 'n'){ 256 out += '\ 257'; 258 } 259 } else if (iChar == '<' && 260 unicodeStr[i + 1] == '3') { //convert "<3" to costum set 'heart' char, ascii: 261 0x81 262 long charTemp = 0x81; 263 out += (char)charTemp; 264 i++; 265 266 } else { 267 out += iChar; 268 } 269 } 270 return out; 271}
dot_matrix_scrolling_text_test.ino
arduino
Code for the Arduino Nano to run the dot matrix.
1#include <MD_Parola.h> 2#include <MD_MAX72xx.h> 3#include <SPI.h> 4#include 5 <Time.h> 6#include <TimeLib.h> 7#include "Parola_Fonts_data.h" 8 9#define 10 MAX_DEVICES 8 11#define CLK_PIN 13 12#define DATA_PIN 11 13#define CS_PIN 14 10 15 16#define TIME 1 17#define TEXT 2 18#define WEATHER 3 19#define STATS 20 4 21 22#define NUM_TIMEZONES 8 23 24MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES); 25 26uint8_t 27 scrollSpeed = 30; // default frame delay value 28textEffect_t scrollEffect = 29 PA_SCROLL_LEFT; 30textPosition_t scrollAlign = PA_CENTER; 31uint16_t scrollPause 32 = 0; // in milliseconds 33 34#define BUF_SIZE 100 35char curMessage[BUF_SIZE] 36 = "www.steuermeinentannenbaum.de"; //{0x01}; 37char newMessage[BUF_SIZE]; 38String 39 newMessageString = ""; 40bool newMessageAvailable = false, showClock = false; 41unsigned 42 long lastNewMessageTime; 43byte dataByte = 0, zoneIndex, timeBuffer[3]; 44 45struct 46 timeZonesStruct { 47 int GMT; 48 String name; 49}; 50 51timeZonesStruct timeZones[NUM_TIMEZONES] 52 = { 53 {1, "Berlin"}, 54 {0, "UK"}, 55 { -8, "LA"}, 56 { -6, "Texas"}, 57 58 { -5, "NYC"}, 59 {11, "Sydney"}, 60 {9, "Tokyo"}, 61 {3, "Russia"} 62}; 63 64/* 65 66 void readSerial(void) 67 { 68 static char *cp = newMessage; 69 70 while 71 (Serial1.available()) 72 { 73 cp = (char)Serial1.read(); 74 if ((*cp 75 == '\ 76') || (cp - newMessage >= BUF_SIZE-2)) // end of message character or full 77 buffer 78 { 79 cp = '\\0'; // end the string 80 // restart the 81 index for next filling spree and flag we have a message waiting 82 cp = newMessage; 83 84 newMessageAvailable = true; 85 Serial.println(cp); 86 //Serial.flush(); 87 88 } 89 else // move char pointer to next position 90 cp++; 91 } 92 93 } 94*/ 95 96void readSerial(void) { 97 if (Serial.available()) { 98 if 99 (dataByte == 0) dataByte = Serial.read(); 100 else if (dataByte == TEXT) { 101 102 newMessageString = Serial.readStringUntil('\ 103'); 104 newMessageString.toCharArray(newMessage, 105 BUF_SIZE); 106 newMessageAvailable = true; 107 showClock = false; 108 109 lastNewMessageTime = millis(); 110 dataByte = 0; 111 } 112 else 113 if (dataByte == TIME) { 114 Serial.readBytes(timeBuffer, 3); 115 setTime(timeBuffer[0], 116 timeBuffer[1], timeBuffer[2], day(), month(), year()); 117 dataByte = 0; 118 119 } 120 } 121} 122 123 124 125void setup() 126{ 127 Serial.begin(9600); 128 129 130 randomSeed(analogRead(0)); 131 132 133 P.begin(); 134 P.setFont(ExtASCII); 135 136 P.displayClear(); 137 P.displaySuspend(false); 138 139 //P.setScrollSpacing(1); 140 141 142 lastNewMessageTime = millis(); 143 144 P.displayText(curMessage, scrollAlign, 145 scrollSpeed, scrollPause, scrollEffect, scrollEffect); 146 147 //newMessage[0] 148 = '\\0'; 149} 150 151void loop() 152{ 153 readSerial(); 154 155 if (millis() - 156 lastNewMessageTime > 30000) showClock = true; 157 158 if (P.displayAnimate()) 159 160 { 161 if (showClock) { 162 P.setTextEffect(PA_SCROLL_DOWN, PA_SCROLL_DOWN); 163 164 P.setPause(5000); 165 166 newMessageString = timeZones[zoneIndex].name 167 + ": "; 168 newMessageString += returnLocalTime(zoneIndex); 169 170 zoneIndex++; 171 172 if (zoneIndex >= NUM_TIMEZONES) zoneIndex = 0; 173 174 newMessageString.toCharArray(newMessage, 175 BUF_SIZE); 176 strcpy(curMessage, newMessage); 177 newMessageString = 178 ""; 179 180 P.displayReset(); 181 } 182 else if (newMessageAvailable) 183 184 { 185 P.setTextEffect(PA_SCROLL_LEFT, PA_SCROLL_LEFT); 186 P.setPause(0); 187 188 189 strcpy(curMessage, newMessage); 190 newMessageAvailable = false; 191 192 newMessageString = ""; 193 } 194 P.displayReset(); 195 } 196} 197 198String 199 returnLocalTime(byte index) { 200 String temp; 201 int hourInt = hour() + timeZones[index].GMT; 202 203 204 if (hourInt < 0) hourInt = 24 + hourInt; 205 else if (hourInt > 23) hourInt -= 206 24; 207 208 if (hourInt < 10) temp += "0"; 209 temp += String(hourInt) + ":"; 210 211 if (minute() < 10) temp += "0"; 212 temp += String(minute()); 213 214 return 215 temp; 216} 217 218
Telegram_Bot_xmas.ino
arduino
Code for the Arduino MKR1000.
1#define TEXT_SERIAL 1 2#define WATCHDOG 1 3#define DEBUG 0 4 5#include 6 <Arduino.h> 7#include <Time.h> 8#include <TimeLib.h> 9#include <WiFi101.h> 10//#include 11 <WiFiUdp.h> 12#include <SPI.h> 13#include <TelegramBot.h> 14//#include <time.h> 15//#include 16 <RTCZero.h> 17 18#if TEXT_SERIAL 19#include <wiring_private.h> 20#endif 21 22#if 23 WATCHDOG 24#include <Adafruit_SleepyDog.h> 25#endif 26 27#if TEXT_SERIAL 28Uart 29 textSerial (&sercom3, 0, 1, SERCOM_RX_PAD_1, UART_TX_PAD_0); 30 31void SERCOM3_Handler() 32 // Interrupt handler for SERCOM3 33{ 34 textSerial.IrqHandler(); 35} 36#endif 37 38#define 39 ledPin 6 40#define RBUFFSIZE 1000 41 42#define MAX_MESSAGES 16 43 44#define 45 TIME 1 46#define TEXT 2 47#define WEATHER 3 48#define STATS 4 49 50/* 51 #define 52 BEER_NAME 0 53 #define BEER_ID 1 54*/ 55 56char responseBuffer[RBUFFSIZE]; 57int 58 rbindex = 0; 59 60boolean startCapture; 61unsigned long lastTimeSentTime, lastTextSent, 62 currentTime, lastClockSent; 63 64// Initialize Wifi connection 65 66const char 67 ssid[] = ""; // network SSID 68const char pass[] = ""; // 69 network key 70 71// Initialize Telegram BOT 72 73const char BotToken[] = ""; 74 75char 76 server[] = "api.openweathermap.org"; 77 78String eingabe; //Nachrichten[128]; 79char 80 Nachrichten[MAX_MESSAGES][100]; 81byte numMessages, messageIndex, sendMessageIndex; 82 83WiFiSSLClient 84 client; 85WiFiClient clienthttp; 86 87TelegramBot bot(BotToken, client); 88 89//RTCZero 90 rtc; 91 92//TelegramKeyboard keyboardStart; 93/* 94const char* row1Start[] = 95 {"/help", "/wlan"}; 96const char* row2Start[] = {"/ip", "/signal"}; 97//const 98 char* row3Start[] = {"/alloff"}; 99*/ 100 101time_t tClock = 0; 102 103 104void 105 setup() { 106 107 delay(3000); 108 109#if TEXT_SERIAL 110 textSerial.begin(9600); 111 // Begin Uart for sending text to LED matrix 112#endif 113 114 Serial.begin(9600); 115 116#if 117 TEXT_SERIAL 118 pinPeripheral(0, PIO_SERCOM); // Assign pins 0 & 1 SERCOM functionality 119 120 pinPeripheral(1, PIO_SERCOM); 121#endif 122 123#if WATCHDOG 124 Watchdog.enable(10000); 125#endif 126 127 128 // attempt to connect to Wifi network: 129#if DEBUG 130 Serial.print(F("Verbine 131 mit WLAN: ")); 132 Serial.println(ssid); 133#endif 134 135 while (WiFi.begin(ssid, 136 pass) != WL_CONNECTED) { 137 delay(500); 138 } 139 140#if DEBUG 141 Serial.println(F("Mit 142 WLAN verbunden.")); 143#endif 144/* 145 byte counterT = 0; 146 while (tClock 147 == 0 && counterT < 6) { 148 delay(1000); 149 counterT++; 150 151 tClock 152 = WiFi.getTime(); 153 154 } 155 Serial.println(tClock); 156 */ 157 getCurrentTime(); 158 159 160 if (tClock != 0) { 161 textSerial.write(TIME); 162 textSerial.write(hour(tClock)); 163 164 textSerial.write(minute(tClock)); 165 textSerial.write(second(tClock)); 166 167 } 168 tClock = 0; 169 170 lastClockSent = millis(); 171 172 bot.begin(); 173 174 175 pinMode(ledPin, OUTPUT); 176 digitalWrite(ledPin, LOW); 177/* 178 keyboardStart.addRow(row1Start, 179 2); 180 keyboardStart.addRow(row2Start, 2); 181 //keyboardStart.addRow(row3Start, 182 1); 183 */ 184 185 message m = bot.getUpdates(); 186} 187 188void loop() { 189#if 190 WATCHDOG 191 Watchdog.reset(); 192#endif 193 194 if ( WiFi.status() != WL_CONNECTED) 195 { 196 //WiFi.disconnect(); 197 while (WiFi.begin(ssid, pass) != WL_CONNECTED) 198 { 199#if DEBUG 200 Serial.print("."); 201#endif 202 delay(1000); 203 204 } 205 } 206 currentTime = millis(); 207 208 if (numMessages > 0 && currentTime 209 - lastTextSent > 20000) { 210 textSerial.write(TEXT); 211 textSerial.print(String(Nachrichten[sendMessageIndex])); 212 213 lastTextSent = currentTime; 214 sendMessageIndex++; 215 numMessages--; 216 217 if (sendMessageIndex >= MAX_MESSAGES) sendMessageIndex = 0; 218 } 219 220 if 221 (currentTime - lastTextSent > 120000) { 222 textSerial.write(TEXT); 223 textSerial.print("To 224 send custom text, open/download the 'Telegram' App and add: TannenbaumBot."); 225 226 lastTextSent = currentTime; 227 } 228 229 if (currentTime - lastClockSent 230 > 600000) { 231 tClock = 0; 232 233 getCurrentTime(); 234 /* 235 byte 236 counterT = 0; 237 while (tClock == 0 && counterT < 6) { 238 counterT++; 239 240 delay(500); 241 tClock = WiFi.getTime(); 242 } 243 */ 244 if 245 (tClock != 0) { 246 textSerial.write(TIME); 247 textSerial.write(hour(tClock)); 248 249 textSerial.write(minute(tClock)); 250 textSerial.write(second(tClock)); 251 252 } 253 254 255 /* 256 textSerial.write(rtc.getHours()); 257 textSerial.write(rtc.getMinutes()); 258 259 textSerial.write(rtc.getSeconds()); 260 */ 261 262 lastClockSent = currentTime; 263 264 } 265 266 message m = bot.getUpdates(); 267 /* 268 if(millis() - lastTimeSentTime 269 > 600000) { 270 textSerial.write(TIME); 271 textSerial.print(String(rtc.getEpoch()) 272 + "\ 273"); 274 lastTimeSentTime = millis(); 275 } 276 */ 277 278 if (Serial.available() 279 > 0) { 280 eingabe = Serial.readStringUntil('\ 281'); 282 if (!eingabe.equalsIgnoreCase("i")) 283 { 284 bot.sendMessage("", eingabe); 285 eingabe = ""; 286 } 287 288 } 289 290 else if (eingabe.equalsIgnoreCase("i")) { 291 if (WL_CONNECTED) 292 { 293 Serial.println(F("Mit WLAN verbunden")); 294 IPAddress ip = WiFi.localIP(); 295 296 Serial.print(F("IP Address: ")); 297 Serial.println(ip); 298 299 // 300 print the received signal strength: 301 long rssi = WiFi.RSSI(); 302 Serial.print(F("signal 303 strength (RSSI):")); 304 Serial.print(rssi); 305 Serial.println(F(" 306 dBm")); 307 eingabe = ""; 308 } 309 else Serial.println(F("KEINE 310 Verbindung zum WLAN")); 311 eingabe = ""; 312 } 313 314 if ( m.chat_id != 315 0 ) { 316 if (1) { // if a message is received from unique Chats m.sender.equals("xxxxx") 317 318 319 //Serial.println("Location: " + m.location.lon + ", " + m.location.lat); 320 321 //Serial.println("Name: " + m.first_name); 322 //Serial.println(m.chat_id); 323 324 //Serial.println(m.sender); 325 326#if DEBUG 327 time_t t = m.date.toInt(); 328 329 t = t + 1 * 60 * 60; 330 331 Serial.print(m.sender); 332 Serial.print(F(" 333 hat um ")); 334 Serial.print(hour(t)); 335 Serial.print(":"); 336 Serial.print(minute(t)); 337 338 339 Serial.print(F(" folgendes gesendet: ")); 340 Serial.println(m.text); 341#endif 342 343 344 if (m.location.lon.length() != 0) { 345 bot.sendMessage(m.chat_id, 346 "Requesting weather data..."); 347#if DEBUG 348 Serial.println(F("Verbinde 349 zu api.openweathermap.org")); 350#endif 351 352 weatherHttpRequest(m.location.lat, 353 m.location.lon, m.chat_id); 354 355 } 356 357 if (m.text.equalsIgnoreCase("/help")) 358 { 359 bot.sendMessage(m.chat_id, "To send custom text, type: /text and your 360 message. For example: '/text Santa rocks!'. To display the current weather in your 361 area, simply send your location."); 362 363 364 } 365/* 366 else 367 if (m.text.equalsIgnoreCase("/watchdog")) { 368 while (1); 369 } 370*/ 371 372 else if (m.text.equalsIgnoreCase("/start")) { 373 bot.sendMessage(m.chat_id, 374 "Welcome " + m.first_name + "! Send /help for more information."); 375 376 } 377 378 379 else if (m.text.startsWith("/text") || m.text.startsWith("/Text")) { 380 381 m.text.remove(0, 6); 382 m.text += "\ 383"; 384 385 if (m.text.length() 386 <= 2) { 387 bot.sendMessage(m.chat_id, "Sorry, your text is too short. 388 Please send at least 2 characters."); 389 } 390 else if (m.text.length() 391 >= 75) { 392 bot.sendMessage(m.chat_id, "Sorry, your text is too long. 393 The maxmimal text length is 74 characters."); 394 } 395 else if (numMessages 396 == MAX_MESSAGES) { 397 bot.sendMessage(m.chat_id, "Sorry, there are currently 398 too many people sending messages to Santa. Try again later."); 399 } 400 401 else { 402 if (m.first_name.length() >= 21) m.first_name.remove(20); 403 404 eingabe = m.first_name + ": " + m.text; 405 eingabe.toCharArray(Nachrichten[messageIndex], 406 100); 407 eingabe = ""; 408 numMessages++; 409 messageIndex++; 410 411 if (messageIndex >= MAX_MESSAGES) messageIndex = 0; 412 bot.sendMessage(m.chat_id, 413 "Your text is on position " + String(numMessages) + " in the pipeline. It will 414 be displayed in approximately " + String((numMessages) * 20) + " seconds."); 415 416 } 417 418#if DEBUG 419 Serial.println("Der reine Text lautet: " 420 + m.text); 421 422#endif 423 424 } 425 /* 426 else 427 if (m.text.startsWith("/bierID")) { 428 m.text.remove(0, 7); 429 430 m.text.trim(); 431 beerHttpRequest(BEER_ID, m.text, m.chat_id); 432 433 } 434 435 else if (m.text.startsWith("/bier") || m.text.startsWith("/Bier")) 436 { 437 m.text.remove(0, 6); 438 m.text.trim(); 439 beerHttpRequest(BEER_NAME, 440 m.text, m.chat_id); 441 } 442 */ 443 /* 444 else if (m.text.equalsIgnoreCase("/wlan")) 445 { 446 bot.sendMessage(m.chat_id, ssid); 447 448 } 449 else if (m.text.equalsIgnoreCase("/ip")) 450 { 451 IPAddress ip = WiFi.localIP(); 452 bot.sendMessage(m.chat_id, 453 String(ip[0]) + String(".") + \\ 454 String(ip[1]) + String(".") 455 + \\ 456 String(ip[2]) + String(".") + \\ 457 String(ip[3])); 458 459 } 460 else if (m.text.equalsIgnoreCase("/signal")) { 461 long 462 rssi = WiFi.RSSI(); 463 bot.sendMessage(m.chat_id, String(rssi) + " dBm"); 464 465 } 466 */ 467 } 468 469 else { 470 bot.sendMessage(m.chat_id, 471 "Sie sind nicht befugt diesen Befehl zu verwenden."); 472 473 Serial.println(m.chat_id); 474 475 Serial.println(m.sender); 476 } 477 } 478} 479 480int findText(String 481 needle, String haystack) { 482 int foundpos = -1; 483 for (int i = 0; i <= haystack.length() 484 - needle.length(); i++) { 485 if (haystack.substring(i, needle.length() + i) 486 == needle) { 487 foundpos = i; 488 } 489 } 490 return foundpos; 491} 492 493void 494 weatherHttpRequest(String lat, String lon, String chatId) { 495 if (clienthttp.connect(server, 496 80)) { 497#if DEBUG 498 Serial.println(F("Verbunden zum Server")); 499#endif 500 501 502 clienthttp.println("GET /data/2.5/weather?lat=" + lat + "&lon=" + lon + 503 "&APPID=**yourapikey** HTTP/1.1"); 504 clienthttp.println("Host: api.openweathermap.org"); 505 506 clienthttp.println("Connection: close"); 507 clienthttp.println(); 508 509 510 responseBuffer[0] = '\\0'; 511 rbindex = 0; 512 513 startCapture = false; 514 515 } 516 517 else { 518 bot.sendMessage(chatId, "Cannot connect to weather server."); 519 520 return; 521 } 522 523 char c; 524 unsigned long startTime = millis(); 525 526 while (clienthttp.connected() && millis() - startTime < 7000) { 527 if (clienthttp.available()) 528 { 529 c = clienthttp.read(); 530 if (c == '{') { 531 startCapture 532 = true; 533 } 534 if (startCapture && rbindex < RBUFFSIZE) { 535 responseBuffer[rbindex] 536 = c; 537 rbindex++; 538 } 539 } 540 } 541 542 543 if (clienthttp.connected()) 544 { 545 clienthttp.stop(); 546 clienthttp.flush(); 547#if DEBUG 548 Serial.println(F("Client 549 won't disconnect")); 550#endif 551 bot.sendMessage(chatId, "Data couldn't be 552 recieved."); 553 return; 554 } 555 556#if DEBUG 557 Serial.println(F("Received 558 bytes.")); 559 //Serial.print(strlen(responseBuffer)); 560 Serial.println(F("Disconnecting.")); 561#endif 562 563 564 clienthttp.stop(); 565 clienthttp.flush(); 566 567 StaticJsonBuffer<RBUFFSIZE> 568 jsonBuffer; 569 570 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 571 572 573 if (!root.success()) { 574#if DEBUG 575 Serial.println(F("parseObject() fehlgeschlagen")); 576#endif 577 578 579 bot.sendMessage(chatId, "Datenverarbeitung fehlgeschlagen."); 580 } 581 else 582 { 583 char bufferw[20]; 584 char bufferc[30]; 585 root["weather"][0]["description"].prettyPrintTo(bufferw, 586 sizeof(bufferw)); 587 root["name"].prettyPrintTo(bufferc, sizeof(bufferc)); 588 589#if 590 DEBUG 591 Serial.println("Schnee: " + String((float)root["snow"]["3h"])); 592#endif 593 594 //bot.sendMessage(m.chat_id, "Aktuelle Wetter fr " + String(bufferc) + ":"); 595 596 textSerial.write(TEXT); 597 eingabe = "Current weather in " + String(bufferc) 598 + ": " + String(bufferw) + " at " + String(((double)root["main"]["temp"]) 599 - 273.15, 1) + " C"; 600 textSerial.print(eingabe); 601 lastTextSent = millis(); 602 603 eingabe = ""; 604 605 bot.sendMessage(chatId, "The current weather 606 in your region will be displayed soon."); 607 608#if DEBUG 609 Serial.print(F("Aktuelle 610 Temperatur: ")); 611 Serial.print(((double)root["main"]["temp"]) - 273.15); 612 613 Serial.println(F(" C")); 614 615 Serial.print(F("Beschreibung: ")); 616 617 Serial.println(bufferw); 618#endif 619 } 620} 621void getCurrentTime() { 622 623 if (clienthttp.connect("api.timezonedb.com", 80)) { 624 clienthttp.println("GET 625 /v2/get-time-zone?key=**yourapikey**&format=json&by=zone&zone=Europe/London HTTP/1.1"); 626 627 clienthttp.println("Host: api.timezonedb.com"); 628 clienthttp.println("Connection: 629 close"); 630 clienthttp.println(); 631 632 responseBuffer[0] = '\\0'; 633 634 rbindex = 0; 635 636 startCapture = false; 637 } 638 639 else { 640 Serial.println("Verbindung 641 zum Zeitserver fehlgeschlagen"); 642 return; 643 } 644 645 char c; 646 unsigned 647 long startTime = millis(); 648 649 while (clienthttp.connected() && millis() - 650 startTime < 7000) { 651 if (clienthttp.available()) { 652 c = clienthttp.read(); 653 654 if (c == '{') { 655 startCapture = true; 656 } 657 if (startCapture 658 && rbindex < RBUFFSIZE) { 659 responseBuffer[rbindex] = c; 660 rbindex++; 661 662 } 663 } 664 } 665 666 if (clienthttp.connected()) { 667 clienthttp.stop(); 668 669 clienthttp.flush(); 670 #if DEBUG 671 Serial.println(F("Client won't disconnect")); 672 673 #endif 674 return; 675 } 676 677 678 #if DEBUG 679 Serial.println(F("Received 680 bytes.")); 681 //Serial.print(strlen(responseBuffer)); 682 Serial.println(F("Disconnecting.")); 683 684 #endif 685 686 clienthttp.stop(); 687 clienthttp.flush(); 688 689 StaticJsonBuffer<RBUFFSIZE> 690 jsonBuffer; 691 692 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 693 694 695 if (!root.success()) { 696 #if DEBUG 697 Serial.println(F("parseObject() 698 fehlgeschlagen")); 699 #endif 700 701 } 702 else { 703 tClock = root["timestamp"]; 704 705 Serial.println(tClock); 706 } 707} 708//wanted to implement the brewery db 709 but couldn't make it work so fart 710/* 711 void beerHttpRequest(boolean type, 712 String request, String chatId) { 713 if (clienthttp.connect("api.brewerydb.com", 714 80)) { 715 #if DEBUG 716 Serial.println(F("Verbunden zum Server")); 717 #endif 718 719 720 if (type == BEER_NAME) clienthttp.println("GET /v2/search?q=" + request + 721 "&type=beer&key=**yourapikey**&format=json HTTP/1.1"); 722 else clienthttp.println("GET 723 /v2/beer/" + request + "?key=**yourapikey**&format=json HTTP/1.1"); 724 clienthttp.println("Host: 725 api.brewerydb.com"); 726 clienthttp.println("Connection: close"); 727 clienthttp.println(); 728 729 730 responseBuffer[0] = '\\0'; 731 rbindex = 0; 732 733 startCapture = false; 734 735 736 } 737 738 else { 739 bot.sendMessage(chatId, "Verbindung zur Brewery Databse 740 nicht mglich."); 741 return; 742 } 743 744 char c; 745 unsigned long startTime 746 = millis(); 747 748 while (clienthttp.connected() && millis() - startTime < 7000) 749 { 750 if (clienthttp.available()) { 751 c = clienthttp.read(); 752 if 753 (c == '{') { 754 startCapture = true; 755 } 756 if (startCapture 757 && rbindex < RBUFFSIZE) { 758 responseBuffer[rbindex] = c; 759 rbindex++; 760 761 } 762 } 763 } 764 765 if (clienthttp.connected()) { 766 clienthttp.stop(); 767 768 clienthttp.flush(); 769 #if DEBUG 770 Serial.println(F("Client won't disconnect")); 771 772 #endif 773 bot.sendMessage(chatId, "Daten konnten nicht empfangen werden."); 774 775 return; 776 } 777 778 779 #if DEBUG 780 Serial.println(F("Received bytes.")); 781 782 //Serial.print(strlen(responseBuffer)); 783 Serial.println(F("Disconnecting.")); 784 785 #endif 786 787 clienthttp.stop(); 788 clienthttp.flush(); 789 790 StaticJsonBuffer<RBUFFSIZE> 791 jsonBuffer; 792 793 JsonObject& root = jsonBuffer.parseObject(responseBuffer); 794 795 796 if (!root.success()) { 797 #if DEBUG 798 Serial.println(F("parseObject() 799 fehlgeschlagen")); 800 #endif 801 802 bot.sendMessage(chatId, "Datenverarbeitung 803 fehlgeschlagen."); 804 } 805 else { 806 807 if (type == BEER_NAME) { 808 char 809 bufferName[10][50]; // char bufferName[10][50]; 810 char bufferID[10][9]; //char 811 bufferID[10][6]; 812 int results = root["totalResults"]; // int results 813 = atoi(&root["totalResults"]); 814 if (results > 10) results = 10; 815 for 816 (byte i = 0; i < results; i++) { 817 818 root["data"][i]["id"].prettyPrintTo(bufferID[i], 819 sizeof(bufferID[i])); 820 root["data"][i]["name"].prettyPrintTo(bufferName[i], 821 sizeof(bufferName[i])); 822 } 823 824 String beerMessage; 825 826 if 827 (results > 0) { 828 beerMessage = "Hier die ersten " + String(results) 829 + " Treffer. Meintest du:"; 830 for (byte i = 0; i < results; i++) { 831 832 beerMessage += '\ 833'; 834 beerMessage += String(bufferName[i]); 835 836 beerMessage += ": /bierID"; 837 String IDtemp = String(bufferID[i]); 838 839 IDtemp.remove(0, 1); 840 IDtemp.remove(6, 1); 841 beerMessage 842 += IDtemp; 843 } 844 } 845 846 else beerMessage = "Zu diesem Suchbegriff 847 gab es leider keine Treffer."; 848 849 bot.sendMessage(chatId, beerMessage); 850 851 #if DEBUG 852 Serial.println(F("test")); 853 #endif 854 } 855 else 856 { 857 char bufferDescription[1000]; 858 char bufferStyle[50]; 859 860 861 if (root["data"]["description"] != NULL) { 862 root["data"]["description"].prettyPrintTo(bufferDescription, 863 sizeof(bufferDescription)); 864 bot.sendMessage(chatId, bufferDescription); 865 866 #if DEBUG 867 Serial.println(bufferDescription); 868 #endif 869 } 870 871 if (root["data"]["style"]["description"] != NULL) { 872 root["data"]["style"]["description"].prettyPrintTo(bufferDescription, 873 sizeof(bufferDescription)); 874 root["data"]["style"]["name"].prettyPrintTo(bufferStyle, 875 sizeof(bufferStyle)); 876 877 bot.sendMessage(chatId, "Es handelt sich um 878 ein: " + String(bufferStyle) + ".'\ 879'" + String(bufferDescription)); 880 #if 881 DEBUG 882 Serial.println("Es handelt sich um ein: " + String(bufferStyle) 883 + ".'\ 884'" + String(bufferDescription)); 885 #endif 886 } 887 } 888 } 889 890 } 891*/ 892 893
leds_lookup_table.h
arduino
Look up table for the LEDs on the tree.
1byte frame[] = {52, 51, 43, 42, 32, 31, 19, 18, 0, 1, 2, 3, 4, 5, 6, 7, 2 8, 9, 25, 26, 38, 39, 47, 48, 54, 53}; 3 4byte inner[] = {50, 49, 44, 45, 46, 5 41, 40, 33, 34, 35, 36, 37, 30, 29, 28, 27, 20, 21, 22, 23, 24, 17, 16, 15, 14, 6 13, 12, 11, 10}; 7 8byte spiralCCW[] = {52, 51, 43, 32, 18, 0, 1, 2, 3, 4, 5, 9 6, 7, 8, 9, 38, 47, 48, 54, 53, 50, 44, 42, 33, 31, 19, 17, 10 16, 11 15, 14, 13, 12, 11, 10, 25, 26, 37, 39, 46, 49, 45, 41, 34, 30, 20, 21, 22, 23, 12 24, 13 27, 36, 40, 35, 29, 28, 35}; 14byte spiralCW[] = {52, 15 53, 54, 48, 47, 38, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 18, 32, 43, 51, 50, 49, 46, 39, 16 37, 26, 25, 10, 11, 12, 13, 14, 15, 16, 17, 19, 31, 17 33, 42, 18 44, 45, 40, 36, 27, 24, 23, 22, 21, 20, 30, 34, 41, 35, 28, 29}; 19 20byte triangle1[] 21 = {35, 29, 28}; 22 23byte triangle2[] = {45, 41, 34, 30, 20, 21, 22, 23, 24, 27, 24 36, 40}; 25 26byte triangle3[] = {53, 50, 44, 42, 33, 31, 19, 17, 16, 15, 14, 27 13, 12, 11, 10, 25, 26, 37, 39, 46, 49}; 28 29byte triangle4[] = {52, 51, 43, 30 32, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 38, 47, 48, 54}; 31 32 33
Serial_Data_Read.ino
arduino
Code for the "main" Arduino Mega. Reads data from pi and controls all LEDs and devices.
1#include "FastLED.h" 2#include "leds_lookup_table.h" 3#include 4 <EEPROM.h> 5 6#define DEBUG 0 7 8#define READY_PIN 28 9#define SANTA_PIN 10 5 11#define TRAIN_PIN 39 //relay 3 12#define LIGHT_CHAIN_PIN 35 //relay 1 13#define 14 SPOT_LIGHT_PIN 37 15#define FRONT_LIGHT_PIN 41 16#define LAP_COUNT_PIN 6 17 18 19#define 20 NUM_LEDS 55 //number of total P9823's 21#define DATA_PIN 2 22#define FADE_DELAY 23 50 24#define FADE_TIME 2000 25#define CHANCE_SANTA_SOLO 20 //chance of a santa 26 solo in percent 27 28#define PiSerial Serial1 29#define DebugSerial Serial 30 31//status 32 bytes knnen werte von 1 bis 191 haben (0 = undefined) 33#define LED_START 1 34#define 35 LED_END 55 36#define TEXT_EINGABE 124 37#define TWERKING_SANTA 69 38#define TRAIN 39 56 40#define LIGHT_CHAIN 57 41#define SPARKLING 58 42#define ANIMATIONS 59 43#define 44 TREE_BLACKOUT 60 45 46//info/data bytes von 192 bis 254 47#define OFF 192 48#define 49 ON 193 50#define FARBEN_START 194 51#define FARBEN_END 210 52 53#define DATA_ERROR 54 255 55 56struct ledStepStruct { 57 int rStep, gStep, bStep; 58 boolean fade; 59}; 60 61byte 62 data[2], rndLED, hueTemp; 63char text[31]; 64boolean newText, santaFlag, trainFlag, 65 lightChainFlag, sparklingFlag, sparkleOn, santaSoloFlag, pinActive = true; 66const 67 unsigned int fadeSteps = FADE_TIME / FADE_DELAY; 68unsigned long currentMillis, 69 lastFadeTime, santaTime, trainTime, lightChainTime, sparklingTime, lastSparkleTime, 70 lastLapCount, currentTime, trainActionTime, lastTrainAction; 71unsigned int lapCounter; 72 73CRGB 74 leds[NUM_LEDS], ledsAim[NUM_LEDS], ledBefore; 75 76ledStepStruct ledsStep[NUM_LEDS]; 77 78void 79 setup() { 80 PiSerial.begin(9600); 81 82 DebugSerial.begin(9600); 83 84 pinMode(READY_PIN, 85 OUTPUT); 86 pinMode(SANTA_PIN, OUTPUT); 87 pinMode(TRAIN_PIN, OUTPUT); 88 pinMode(LIGHT_CHAIN_PIN, 89 OUTPUT); 90 pinMode(SPOT_LIGHT_PIN, OUTPUT); 91 pinMode(FRONT_LIGHT_PIN, OUTPUT); 92 93 pinMode(LAP_COUNT_PIN, INPUT_PULLUP); 94 95 96 FastLED.addLeds<WS2812B, DATA_PIN, 97 RGB>(leds, NUM_LEDS); 98 FastLED.setBrightness(70); 99 FastLED.clear(); 100 101 FastLED.show(); 102 103 digitalWrite(READY_PIN, HIGH); 104 digitalWrite(SANTA_PIN, 105 LOW); 106 digitalWrite(TRAIN_PIN, LOW); 107 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 108 109 digitalWrite(SPOT_LIGHT_PIN, LOW); 110 digitalWrite(FRONT_LIGHT_PIN, HIGH); 111 112 113 lightChainFlag = true; 114 115 //lapCounter = 200; //add counts up to now, since 116 eeprom wasnt' implemented yet 117 //EEPROM.put(0, lapCounter); 118 EEPROM.get(0, 119 lapCounter); 120 121} 122 123void loop() { 124 125 handleSerialCommunication(); 126 127 handleData(); 128 handleColorFade(); 129 handleControl(); 130 handleSparkling(); 131 132 handleLapCount(); 133 134} 135 136void handleLapCount() { 137 currentTime = millis(); 138 139 if (!digitalRead(LAP_COUNT_PIN) && pinActive && currentTime - trainActionTime 140 > 100) { 141 lapCounter++; 142 pinActive = false; 143 lastLapCount = currentTime; 144 145 PiSerial.print(lapCounter); 146 PiSerial.flush(); 147 EEPROM.put(0, lapCounter); 148 149 //Serial.println(lapCounter); 150 } 151 152 if (digitalRead(LAP_COUNT_PIN) 153 && currentTime - lastLapCount > 2000) { 154 pinActive = true; 155 } 156} 157 158void 159 handleSparkling() { 160 if (sparklingFlag) { 161 if (millis() - sparklingTime 162 > 20000) { 163 sparklingFlag = false; 164 leds[rndLED] = ledBefore; 165 166 FastLED.show(); 167 sparkleOn = false; 168 } 169 else if (!sparkleOn 170 && millis() - lastSparkleTime > 100) { 171 rndLED = random8(NUM_LEDS); 172 173 ledBefore = leds[rndLED]; 174 leds[rndLED] += CRGB::White; 175 FastLED.show(); 176 177 sparkleOn = true; 178 lastSparkleTime = millis(); 179 } 180 else 181 if (sparkleOn && millis() - lastSparkleTime > 50) { 182 leds[rndLED] = ledBefore; 183 184 FastLED.show(); 185 sparkleOn = false; 186 lastSparkleTime = millis(); 187 188 } 189 } 190} 191 192void handleControl() { 193 if (santaFlag) { 194 if 195 (santaTime == 0) { 196 digitalWrite(SANTA_PIN, HIGH); 197 santaTime = 198 millis(); 199 } 200 else if (millis() - santaTime > 20000) { 201 digitalWrite(SANTA_PIN, 202 LOW); 203 santaTime = 0; 204 santaFlag = false; 205 } 206 } 207 208 209 else if (santaSoloFlag) { 210 211 if (trainFlag) { 212 trainFlag = false; 213 214 digitalWrite(TRAIN_PIN, LOW); 215 } 216 if (lightChainFlag) { 217 digitalWrite(LIGHT_CHAIN_PIN, 218 LOW); 219 } 220 FastLED.clear(); 221 FastLED.show(); 222 223 digitalWrite(FRONT_LIGHT_PIN, 224 LOW); 225 FastLED.delay(1000); 226 digitalWrite(SPOT_LIGHT_PIN, HIGH); 227 228 FastLED.delay(500); 229 digitalWrite(SANTA_PIN, HIGH); 230 FastLED.delay(50); 231 232 digitalWrite(SANTA_PIN, LOW); 233 234 /* 235 for (int i; i < 500; 236 i++) { 237 fill_rainbow(leds, NUM_LEDS, hueTemp, 1); 238 FastLED.show(); 239 240 hueTemp++; 241 FastLED.delay(25); 242 } 243 FastLED.clear(); 244 245 FastLED.show(); 246 */ 247 for ( int k = 0; k < 20; k++ ) { 248 triangle(); 249 250 } 251 252 253 digitalWrite(SPOT_LIGHT_PIN, LOW); 254 255 digitalWrite(SANTA_PIN, 256 HIGH); 257 FastLED.delay(50); 258 digitalWrite(SANTA_PIN, LOW); 259 260 FastLED.delay(1000); 261 262 263 digitalWrite(FRONT_LIGHT_PIN, HIGH); 264 digitalWrite(LIGHT_CHAIN_PIN, HIGH); 265 266 lightChainFlag = true; 267 268 for (byte i = 0; i < NUM_LEDS; i++) { 269 270 leds[i] = ledsAim[i]; 271 } 272 FastLED.show(); 273 santaSoloFlag 274 = false; 275 digitalWrite(READY_PIN, HIGH); 276 } 277 278 if (trainFlag) { 279 280 if (millis() - trainTime > 30000) { 281 trainFlag = false; 282 digitalWrite(TRAIN_PIN, 283 LOW); 284 } 285 } 286 287 if (!lightChainFlag) { 288 if (millis() - lightChainTime 289 > 60000) { 290 lightChainFlag = true; 291 digitalWrite(LIGHT_CHAIN_PIN, 292 HIGH); 293 } 294 } 295} 296 297void handleColorFade() { 298 currentMillis = 299 millis(); 300 if (currentMillis - lastFadeTime >= FADE_DELAY) { 301 302 for 303 (byte i = 0; i < NUM_LEDS; i++) { 304 if (ledsStep[i].fade) { 305 ledsStep[i].fade 306 = false; 307 if (leds[i].r != ledsAim[i].r) { 308 ledsStep[i].fade 309 = true; 310 int rTemp = (int)leds[i].r + (int)ledsStep[i].rStep; 311 if 312 ((ledsStep[i].rStep > 0 && rTemp > ledsAim[i].r) || (ledsStep[i].rStep < 0 && rTemp 313 < ledsAim[i].r) || rTemp > 255 || rTemp < 0) leds[i].r = ledsAim[i].r; 314 else 315 leds[i].r = rTemp; 316 317 if ((ledsStep[i].rStep > 0 && leds[i].r > ledsAim[i].r) 318 || (ledsStep[i].rStep < 0 && leds[i].r < ledsAim[i].r)) leds[i].r = ledsAim[i].r; 319 320 } 321 if (leds[i].g != ledsAim[i].g) { 322 ledsStep[i].fade 323 = true; 324 int gTemp = (int)leds[i].g + (int)ledsStep[i].gStep; 325 if 326 ((ledsStep[i].gStep > 0 && gTemp > ledsAim[i].g) || (ledsStep[i].gStep < 0 && gTemp 327 < ledsAim[i].g) || gTemp > 255 || gTemp < 0) leds[i].g = ledsAim[i].g; 328 else 329 leds[i].g = gTemp; 330 } 331 if (leds[i].b != ledsAim[i].b) { 332 333 ledsStep[i].fade = true; 334 int bTemp = (int)leds[i].b + (int)ledsStep[i].bStep; 335 336 if ((ledsStep[i].bStep > 0 && bTemp > ledsAim[i].b) || (ledsStep[i].bStep 337 < 0 && bTemp < ledsAim[i].b) || bTemp > 255 || bTemp < 0) leds[i].b = ledsAim[i].b; 338 339 else leds[i].b = bTemp; 340 } 341 342 } 343 } 344 FastLED.show(); 345 346 lastFadeTime = currentMillis; 347 } 348 349 350} 351 352void handleSerialCommunication() 353 { 354 if (PiSerial.available() > 0) { //if there's any serial data 355 /* 356 357 if (data[0] == TEXT_EINGABE) { //if the upcoming data is a text; indicated 358 by first data byte = 124 359 //inputString = PiSerial.readString(); 360 361 362 for (byte textIndex = 0; textIndex < (data[1] - 193); textIndex++) { //194 363 = textlnge 1, ..., 224 = textlnge 30 364 text[textIndex] = PiSerial.read(); 365 366 } 367 text[data[1] - 193] = '\\0'; 368 369 newText = true; //text 370 saved 371 data[0] = 0; 372 data[1] = 0; 373 374 } 375 */ 376 //else 377 if !!!!!!! wenn oben auskommentiert 378 379 if (PiSerial.peek() >= 1 && PiSerial.peek() 380 <= 191) { //if first data byte is valid 381 PiSerial.readBytes(data, 2); 382 383 //if (data[0] == TEXT_EINGABE) digitalWrite(READY_PIN, LOW); 384#if DEBUG 385 386 DebugSerial.println("Empfangen: " + (String)data[0] + ", " + (String)data[1]); 387#endif 388 389 } 390 else { //else; first data byte is invalid (0 or greater than 191) 391 392 byte errorMessage = PiSerial.read(); 393 //PiSerial.print(DATA_ERROR); 394 395 //PiSerial.print(errorMessage); 396#if DEBUG 397 DebugSerial.print("DATA_ERROR: 398 "); 399 DebugSerial.println(errorMessage); 400#endif 401 } 402 } 403} 404 405void 406 handleData() { 407 if (data[0] >= LED_START && data[0] <= LED_END) { //if data 408 is LED data 409 if (data[1] < OFF || data[1] > FARBEN_END) { //if second data 410 byte has invalid color 411 //invalid color/data byte 412 //PiSerial.print(DATA_ERROR); 413 414 //PiSerial.print(data[1]); 415#if DEBUG 416 DebugSerial.print("DATA_ERROR_INVALID_COLOR: 417 "); 418 DebugSerial.println(data[1]); 419#endif 420 421 } 422 else { 423 //color value is valid 424 //led mit farbe (in data[1]) ansteuern 425 byte 426 i = data[0] - 1; 427 428 if (data[1] == OFF) ledsAim[i] = CRGB::Black; 429 430 else if (data[1] == ON) ledsAim[i] = CRGB::White; //hier warmwei einfgen 431 432 else ledsAim[i].setHue((data[1] - 194) * 16); //set aim color for led to 433 chosen value 434 435 setLEDFade(i); 436 437 } 438 data[0] = 0; 439 data[1] 440 = 0; 441 } 442 443 else if (data[0] == TWERKING_SANTA) { 444 445 446 if (!santaFlag) 447 { 448 digitalWrite(READY_PIN, LOW); 449 450 if (random8(100) > CHANCE_SANTA_SOLO 451 - 1) { 452 santaFlag = true; 453 digitalWrite(READY_PIN, HIGH); 454 455 } 456 else santaSoloFlag = true; 457 } 458 459 data[0] = 0; 460 461 data[1] = 0; 462 463 } 464 465 else if ( data[0] == TRAIN) { 466 currentTime 467 = millis(); 468 if (currentTime - lastTrainAction > 1000) { 469 if (data[1] 470 == OFF && trainFlag) { 471 trainActionTime = currentTime; 472 lastTrainAction 473 = trainActionTime; 474 digitalWrite(TRAIN_PIN, LOW); 475 trainFlag 476 = false; 477 } 478 479 else if (data[1] == ON && !trainFlag) { 480 trainActionTime 481 = currentTime; 482 lastTrainAction = trainActionTime; 483 digitalWrite(TRAIN_PIN, 484 HIGH); 485 trainFlag = true; 486 trainTime = millis(); 487 } 488 489 } 490 data[0] = 0; 491 data[1] = 0; 492 493 494 } 495 496 else if 497 (data[0] == LIGHT_CHAIN) { 498 if (data[1] == OFF && lightChainFlag) { 499 digitalWrite(LIGHT_CHAIN_PIN, 500 LOW); 501 lightChainFlag = false; 502 lightChainTime = millis(); 503 } 504 505 506 else if (data[1] == ON && !lightChainFlag) { 507 digitalWrite(LIGHT_CHAIN_PIN, 508 HIGH); 509 lightChainFlag = true; 510 } 511 data[0] = 0; 512 data[1] 513 = 0; 514 } 515 516 else if (data[0] == SPARKLING) { 517 if (data[1] == ON && 518 !sparklingFlag) { 519 sparklingFlag = true; 520 sparklingTime = millis(); 521 522 } 523 524 else if (data[1] == OFF && sparklingFlag) { 525 sparklingFlag 526 = false; 527 } 528 529 data[0] = 0; 530 data[1] = 0; 531 } 532 533 else 534 if (data[0] == ANIMATIONS) { 535 digitalWrite(READY_PIN, LOW); 536 animations(); 537 538 digitalWrite(READY_PIN, HIGH); 539 data[0] = 0; 540 data[1] = 0; 541 } 542 543 544 else if (data[0] == TREE_BLACKOUT) { 545 546 for (byte i = 0; i < NUM_LEDS; 547 i++) { 548 ledsAim[i] = CRGB::Black; 549 setLEDFade(i); 550 } 551 552 553 data[0] = 0; 554 data[1] = 0; 555 } 556 557 558 /* 559 if (newText) 560 { //handle text entry 561 //inputString.toCharArray(text, 31); 562 563 #if 564 DEBUG 565 DebugSerial.println(text); //debug 566 DebugSerial.flush(); 567 568 #endif 569 digitalWrite(READY_PIN, HIGH); 570 //text anzeigen 571 newText 572 = false; 573 } 574 */ 575} 576 577void animations() { 578 fillSpiralCCW(); 579 580 fillSpiralCW(); 581 fillSpiralCCW(); 582 fillSpiralCW(); 583 584 for (byte 585 i = 0; i < NUM_LEDS; i++) { 586 leds[i] = ledsAim[i]; 587 } 588 FastLED.show(); 589} 590 591void 592 setLEDFade(byte i) { 593 if (leds[i] != ledsAim[i]) { 594 ledsStep[i].fade = 595 true; 596 597 if (ledsAim[i].r != leds[i].r) { 598 ledsStep[i].rStep = ((int)ledsAim[i].r 599 - (int)leds[i].r) / (int)fadeSteps; 600 if (ledsStep[i].rStep == 0) { 601 if 602 (ledsAim[i].r > leds[i].r) ledsStep[i].rStep = 1; 603 else ledsStep[i].rStep 604 = -1; 605 } 606#if DEBUG 607 DebugSerial.println("rStep: " + (String)ledsStep[i].rStep); 608 //debug 609#endif 610 } 611 if (ledsAim[i].g != leds[i].g) { 612 ledsStep[i].gStep 613 = ((int)ledsAim[i].g - (int)leds[i].g) / (int)fadeSteps; 614 if (ledsStep[i].gStep 615 == 0) { 616 if (ledsAim[i].g > leds[i].g) ledsStep[i].gStep = 1; 617 else 618 ledsStep[i].gStep = -1; 619 } 620#if DEBUG 621 DebugSerial.println("gStep: 622 " + (String)ledsStep[i].gStep); //debug 623#endif 624 } 625 if (ledsAim[i].b 626 != leds[i].b) { 627 ledsStep[i].bStep = ((int)ledsAim[i].b - (int)leds[i].b) 628 / (int)fadeSteps; 629 if (ledsStep[i].bStep == 0) { 630 if (ledsAim[i].b 631 > leds[i].b) ledsStep[i].bStep = 1; 632 else ledsStep[i].bStep = -1; 633 634 } 635#if DEBUG 636 DebugSerial.println("bStep: " + (String)ledsStep[i].bStep); 637 //debug 638#endif 639 } 640 641 } 642} 643 644 645void fillSpiralCCW() { 646 647 648 FastLED.clear(); 649 FastLED.show(); 650 651 for (byte i = 0; i < (sizeof(spiralCCW) 652 / sizeof(byte)); i++) { 653 leds[spiralCCW[i]].setHue(hueTemp); 654 FastLED.show(); 655 656 FastLED.delay(30); 657 hueTemp += 2; 658 } 659 660 for (byte i = (sizeof(spiralCCW) 661 / sizeof(byte)) - 1; i > 0; i--) { 662 leds[spiralCCW[i]] = CRGB::Black; 663 664 FastLED.show(); 665 FastLED.delay(30); 666 } 667} 668 669void fillSpiralCW() 670 { 671 672 FastLED.clear(); 673 FastLED.show(); 674 675 for (byte i = 0; i < (sizeof(spiralCW) 676 / sizeof(byte)); i++) { 677 leds[spiralCW[i]].setHue(hueTemp); 678 FastLED.show(); 679 680 FastLED.delay(30); 681 hueTemp += 2; 682 } 683 684 for (byte i = (sizeof(spiralCW) 685 / sizeof(byte)) - 1; i > 0; i--) { 686 leds[spiralCW[i]] = CRGB::Black; 687 FastLED.show(); 688 689 FastLED.delay(30); 690 } 691} 692 693 694void frameMarquee() { 695 FastLED.clear(); 696 697 FastLED.show(); 698 699 for (int j = 0; j < 400; j++) { 700 for (byte i = 701 0; i < (sizeof(frame) / sizeof(byte)); i++) { 702 leds[frame[i]].setHue(hueTemp); 703 704 hueTemp += 2; 705 } 706 hueTemp = 2 * j; 707 FastLED.show(); 708 709 FastLED.delay(40); 710 } 711 FastLED.clear(); 712 FastLED.show(); 713} 714 715void 716 innerFrame() { 717 for (int j = 0; j < 15; j++) { 718 719 hueTemp += 40; 720 721 722 for (byte i = 0; i < (sizeof(frame) / sizeof(byte)); i++) { 723 leds[frame[i]].setHue(hueTemp); 724 725 } 726 FastLED.show(); 727 FastLED.delay(200); 728 729 for (byte i = 730 0; i < (sizeof(frame) / sizeof(byte)); i++) { 731 leds[frame[i]] = CRGB::Black; 732 733 } 734 735 hueTemp += 40; 736 737 for (byte i = 0; i < (sizeof(inner) / 738 sizeof(byte)); i++) { 739 leds[inner[i]].setHue(hueTemp); 740 } 741 FastLED.show(); 742 743 FastLED.delay(200); 744 745 for (byte i = 0; i < (sizeof(inner) / sizeof(byte)); 746 i++) { 747 leds[inner[i]] = CRGB::Black; 748 } 749 } 750 FastLED.clear(); 751 752 FastLED.show(); 753} 754 755void triangle() { 756 hueTemp += 16; 757 for (byte 758 i = 0; i < (sizeof(triangle1) / sizeof(byte)); i++) { 759 leds[triangle1[i]].setHue(hueTemp); 760 761 } 762 FastLED.show(); 763 FastLED.delay(150); 764 for (byte i = 0; i < (sizeof(triangle1) 765 / sizeof(byte)); i++) { 766 leds[triangle1[i]] = CRGB::Black; 767 } 768 hueTemp 769 += 16; 770 for (byte i = 0; i < (sizeof(triangle2) / sizeof(byte)); i++) { 771 772 leds[triangle2[i]].setHue(hueTemp); 773 } 774 FastLED.show(); 775 FastLED.delay(150); 776 777 for (byte i = 0; i < (sizeof(triangle2) / sizeof(byte)); i++) { 778 leds[triangle2[i]] 779 = CRGB::Black; 780 } 781 hueTemp += 16; 782 for (byte i = 0; i < (sizeof(triangle3) 783 / sizeof(byte)); i++) { 784 leds[triangle3[i]].setHue(hueTemp); 785 } 786 FastLED.show(); 787 788 FastLED.delay(150); 789 for (byte i = 0; i < (sizeof(triangle3) / sizeof(byte)); 790 i++) { 791 leds[triangle3[i]] = CRGB::Black; 792 } 793 hueTemp += 16; 794 for 795 (byte i = 0; i < (sizeof(triangle4) / sizeof(byte)); i++) { 796 leds[triangle4[i]].setHue(hueTemp); 797 798 } 799 FastLED.show(); 800 FastLED.delay(150); 801 for (byte i = 0; i < (sizeof(triangle4) 802 / sizeof(byte)); i++) { 803 leds[triangle4[i]] = CRGB::Black; 804 } 805 806} 807 808
TelegramBot.h
arduino
Adapt to changed *.cpp
1// Copyright Casa Jasmina 2016 2// LGPL License 3// 4// TelegramBot 5 library 6// https://github.com/CasaJasmina/TelegramBot-Library 7 8#ifndef 9 TelegramBot_h 10#define TelegramBot_h 11 12#include <Arduino.h> 13#include <ArduinoJson.h> 14#include 15 <Client.h> 16#include <TelegramKeyboard.h> 17 18#define HOST "api.telegram.org" 19#define 20 SSL_PORT 443 21#define JSON_BUFF_SIZE 10000 22 23struct locationStruct{ 24 String 25 lon; 26 String lat; 27}; 28 29struct message{ 30 String text; 31 String 32 chat_id; 33 String sender; 34 String first_name; 35 String date; 36 locationStruct 37 location; 38}; 39 40 41class TelegramBot 42{ 43 public: 44 TelegramBot(const 45 char* token, Client &client); 46 void begin(); 47 String sendMessage(String 48 chat_id, String text); 49 String sendMessage(String chat_id, String text, TelegramKeyboard 50 &keyboard_markup, bool one_time_keyboard = true, bool resize_keyboard = true); 51 52 String postMessage(String msg); 53 message getUpdates(); 54 55 56 57 private: 58 String readPayload(); 59 String convertText(String unicodeStr); 60 61 const char* token; 62 63 int last_message_recived; 64 65 Client 66 *client; 67}; 68 69#endif 70
Parola_Fonts_data.h
arduino
Fonts for the dot matrix to allow umlaute etc.