503 lines
16 KiB
Arduino
503 lines
16 KiB
Arduino
|
#include "ArduinoJson.h"
|
||
|
#include <WiFi.h>
|
||
|
#include <WiFiClient.h>
|
||
|
#include <WebServer.h>
|
||
|
#include <ESPmDNS.h>
|
||
|
#include <EEPROM.h>
|
||
|
#include <HTTPUpdateServer.h>
|
||
|
#include <HTTPClient.h>
|
||
|
#include <Wire.h>
|
||
|
#include "PCA9634.h"
|
||
|
|
||
|
IPAddress staticIP(192, 168, 8, 109);
|
||
|
IPAddress gateway(192, 168, 8, 1);
|
||
|
IPAddress subnet(255, 255, 255, 0);
|
||
|
IPAddress dns(192, 168, 8, 1);
|
||
|
|
||
|
const int id_temp = 10; //ID del dispositivo si no lo tiene en memoria
|
||
|
|
||
|
int id = 0;
|
||
|
#define version 1.06
|
||
|
#define TIME 60*1
|
||
|
//#define TIME 1
|
||
|
|
||
|
#define json_decrypt true
|
||
|
#define debug true
|
||
|
#define NUM_FLORS 5
|
||
|
|
||
|
const char * host = "esp32";
|
||
|
|
||
|
//const char * ssid = "HANGAR_naus";
|
||
|
//const char * password = "nDfEXDwRr4Py4fvRdfMU";
|
||
|
|
||
|
const char * ssid = "Jardi_Mecanic";
|
||
|
const char * password = "f3RR0LU4R";
|
||
|
|
||
|
//const char * ssid = "Hello_pepe";
|
||
|
//const char * password = "labinteractius";
|
||
|
|
||
|
byte gamma_led[] = {
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||
|
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||
|
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||
|
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||
|
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||
|
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||
|
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||
|
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||
|
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||
|
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||
|
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||
|
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||
|
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||
|
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
|
||
|
};
|
||
|
|
||
|
WebServer httpServer(80);
|
||
|
HTTPUpdateServer httpUpdater;
|
||
|
|
||
|
class Color
|
||
|
{
|
||
|
public:
|
||
|
uint8_t animation=0;
|
||
|
uint8_t red=0;
|
||
|
uint8_t green=0;
|
||
|
uint8_t blue=0;
|
||
|
uint8_t warm=0;
|
||
|
uint8_t cold=0;
|
||
|
uint32_t all=0;
|
||
|
void separa(String value) // Constructor
|
||
|
{
|
||
|
all =(uint32_t) strtol( &value[7], NULL, 16);
|
||
|
warm = all>>8;
|
||
|
cold = all;
|
||
|
value[7] = 0x00;
|
||
|
all =(uint32_t) strtol( &value[1], NULL, 16);
|
||
|
red = all>>16;
|
||
|
green = all>>8;
|
||
|
blue = all;
|
||
|
}
|
||
|
} ;
|
||
|
|
||
|
|
||
|
Color color[8];
|
||
|
|
||
|
#define BLUE 3
|
||
|
#define COLD 4
|
||
|
#define WARM 5
|
||
|
#define GREEN 7
|
||
|
#define RED 6
|
||
|
|
||
|
//A6 A5 A4 A3 A2 A1 A0
|
||
|
// 1 1 0 1 0 0 0
|
||
|
// 6 8
|
||
|
|
||
|
PCA9634 foco1( 0x68 );//0x68
|
||
|
PCA9634 foco2( 0x69 );//0x6A
|
||
|
PCA9634 foco3( 0x6A );//0x6B
|
||
|
PCA9634 foco4( 0x6B );//0x69
|
||
|
PCA9634 foco5( 0x6C );
|
||
|
PCA9634 foco6( 0x6D );
|
||
|
PCA9634 foco7( 0x6E );
|
||
|
PCA9634 foco8( 0x6F );
|
||
|
|
||
|
void test_foco()
|
||
|
{
|
||
|
for(int i=3; i<8; i++)
|
||
|
{
|
||
|
foco1.set_brightness(i, 255);
|
||
|
delay(10);
|
||
|
foco2.set_brightness(i, 255);
|
||
|
delay(10);
|
||
|
foco3.set_brightness(i, 255);
|
||
|
delay(10);
|
||
|
foco4.set_brightness(i, 255);
|
||
|
delay(1000);
|
||
|
foco1.set_brightness(i, 0);
|
||
|
delay(10);
|
||
|
foco2.set_brightness(i, 0);
|
||
|
delay(10);
|
||
|
foco3.set_brightness(i, 0);
|
||
|
delay(10);
|
||
|
foco4.set_brightness(i, 0);
|
||
|
delay(10);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TaskHandle_t TaskRESET;
|
||
|
|
||
|
unsigned long time_protection = millis();
|
||
|
|
||
|
void setup() {
|
||
|
xTaskCreatePinnedToCore(Task_RESET,"TaskRESET",10000,NULL,0,&TaskRESET,1);
|
||
|
time_protection = millis();
|
||
|
EEPROM.begin(10);
|
||
|
Serial.begin(115200);
|
||
|
Wire.begin();
|
||
|
Wire.setClock(100000);
|
||
|
foco1.begin( );
|
||
|
foco2.begin( );
|
||
|
foco3.begin( );
|
||
|
foco4.begin( );
|
||
|
foco5.begin( );
|
||
|
foco6.begin( );
|
||
|
foco7.begin( );
|
||
|
foco8.begin( );
|
||
|
|
||
|
all_off();
|
||
|
delay(100);
|
||
|
// if (EEPROM.read(0)>100)
|
||
|
// {
|
||
|
// EEPROM.write(0, id_temp);
|
||
|
// EEPROM.commit();
|
||
|
// }
|
||
|
id = EEPROM.read(0);
|
||
|
Serial.print("id:");
|
||
|
Serial.println(id);
|
||
|
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 0, 255, 0, 0);
|
||
|
WiFi.config(staticIP, gateway, subnet, dns, dns);
|
||
|
WiFi.mode(WIFI_AP_STA);
|
||
|
WiFi.begin(ssid, password);
|
||
|
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||
|
WiFi.begin(ssid, password);
|
||
|
Serial.println("WiFi failed, retrying.");
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 255, 0, 0, 0, 0);
|
||
|
}
|
||
|
|
||
|
MDNS.begin(host);
|
||
|
if (MDNS.begin("esp32")) {
|
||
|
Serial.println("mDNS responder started");
|
||
|
}
|
||
|
|
||
|
httpUpdater.setup(&httpServer);
|
||
|
httpServer.begin();
|
||
|
|
||
|
MDNS.addService("http", "tcp", 80);
|
||
|
Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", host);
|
||
|
|
||
|
Serial.println("");
|
||
|
Serial.print("Connected to ");
|
||
|
Serial.println(ssid);
|
||
|
Serial.print("IP address: ");
|
||
|
Serial.println(WiFi.localIP());
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 255, 0, 0, 0);
|
||
|
vTaskDelete( TaskRESET );
|
||
|
}
|
||
|
|
||
|
void Task_RESET( void * pvParameters ){
|
||
|
for(;;)
|
||
|
{
|
||
|
if ((millis()-time_protection)>=(30*1000))
|
||
|
{
|
||
|
Serial.println("Tiempo de espera superado, dispositivo reseteado.");
|
||
|
ESP.restart();
|
||
|
}
|
||
|
}
|
||
|
vTaskDelete( TaskRESET );
|
||
|
}
|
||
|
|
||
|
unsigned long time_json = millis();
|
||
|
bool retry_json = true;
|
||
|
|
||
|
void request_json()
|
||
|
{
|
||
|
xTaskCreatePinnedToCore(Task_RESET,"TaskRESET",10000,NULL,0,&TaskRESET,1);
|
||
|
time_protection = millis();
|
||
|
retry_json = true;
|
||
|
while(retry_json){
|
||
|
if ((WiFi.waitForConnectResult() == WL_CONNECTED)) { //Check the current connection status
|
||
|
HTTPClient http;
|
||
|
http.begin("http://www.rem.jardinmecanico.com/api/modules/" +(String)id + "/?format=json");
|
||
|
int httpCode = http.GET(); //Make the request
|
||
|
if (httpCode > 0) { //Check for the returning code
|
||
|
if (httpCode==200)
|
||
|
{
|
||
|
String payload = http.getString();
|
||
|
DynamicJsonDocument root(700);
|
||
|
|
||
|
// Parse JSON object
|
||
|
DeserializationError error = deserializeJson(root, payload);
|
||
|
if (error) { //Check for errors in parsing
|
||
|
Serial.print(F("deserializeJson() failed: "));
|
||
|
Serial.println(error.c_str());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Extract values
|
||
|
int id = root["idmod"];
|
||
|
String name = root["title"];
|
||
|
String time = root["time_zone"];
|
||
|
String time_ini = root["event"][0]["pub_date"];
|
||
|
String title = root["scene"][0]["title"];
|
||
|
for(int i=0; i<8; i++)
|
||
|
{
|
||
|
color[i].animation = root["scene"][0]["animation"];
|
||
|
color[i].separa(root["scene"][0]["color" +(String)(i+1)]);
|
||
|
}
|
||
|
#if debug
|
||
|
Serial.print("id:");
|
||
|
Serial.println(id);
|
||
|
Serial.print("title:");
|
||
|
Serial.println(name);
|
||
|
Serial.print("tiempo_actual:");
|
||
|
Serial.println(time);
|
||
|
Serial.print("tiempo_inico:");
|
||
|
Serial.println(time_ini);
|
||
|
Serial.print("title:");
|
||
|
Serial.println(title);
|
||
|
for(int i=0; i<8; i++)
|
||
|
{
|
||
|
Serial.print("animation" + (String)i + ":");
|
||
|
Serial.println(color[i].animation);
|
||
|
Serial.print("color" + (String)i + ":");
|
||
|
Serial.print(color[i].red, HEX);
|
||
|
Serial.print(",");
|
||
|
Serial.print(color[i].green, HEX);
|
||
|
Serial.print(",");
|
||
|
Serial.print(color[i].blue, HEX);
|
||
|
Serial.print(",");
|
||
|
Serial.print(color[i].warm, HEX);
|
||
|
Serial.print(",");
|
||
|
Serial.println(color[i].cold, HEX);
|
||
|
}
|
||
|
#endif
|
||
|
retry_json = false;
|
||
|
time_json = millis();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
#if !json_decrypt
|
||
|
Serial.println(httpCode);
|
||
|
Serial.println(payload);
|
||
|
#endif
|
||
|
}
|
||
|
else {
|
||
|
Serial.println("Error on HTTP request");
|
||
|
retry_json = true;
|
||
|
}
|
||
|
http.end(); //Free the resources
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WiFi.begin(ssid, password);
|
||
|
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||
|
WiFi.begin(ssid, password);
|
||
|
Serial.println("WiFi failed, retrying.");
|
||
|
}
|
||
|
retry_json = true;
|
||
|
}
|
||
|
}
|
||
|
vTaskDelete( TaskRESET );
|
||
|
}
|
||
|
|
||
|
|
||
|
void loop() {
|
||
|
httpServer.handleClient(); //Servidor para programar inalambricamente
|
||
|
|
||
|
if (((millis()-time_json)>(TIME*1000))||(retry_json)) request_json();
|
||
|
|
||
|
switch (color[0].animation) {
|
||
|
case 0:
|
||
|
all_off();
|
||
|
break;
|
||
|
case 1:
|
||
|
static_mode();
|
||
|
break;
|
||
|
case 2:
|
||
|
snake_mode_in();
|
||
|
break;
|
||
|
case 3:
|
||
|
snake_mode_out();
|
||
|
break;
|
||
|
case 4:
|
||
|
random_mode();
|
||
|
break;
|
||
|
case 5:
|
||
|
snake_mode_in_out();
|
||
|
break;
|
||
|
case 6:
|
||
|
beat();
|
||
|
break;
|
||
|
default:
|
||
|
//all_off();
|
||
|
break;
|
||
|
}
|
||
|
delay(1000);
|
||
|
}
|
||
|
|
||
|
void lamp_color(int lamp, byte red, byte green, byte blue, byte cold, byte warm)
|
||
|
{
|
||
|
switch (lamp) {
|
||
|
case 0:
|
||
|
foco1.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 1:
|
||
|
foco2.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 2:
|
||
|
foco3.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 3:
|
||
|
foco4.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 4:
|
||
|
foco5.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 5:
|
||
|
foco6.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 6:
|
||
|
foco7.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
case 7:
|
||
|
foco8.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
|
||
|
break;
|
||
|
default:
|
||
|
// statements
|
||
|
break;
|
||
|
}
|
||
|
delay(1);
|
||
|
}
|
||
|
|
||
|
int animation = 0;
|
||
|
|
||
|
void all_off()
|
||
|
{
|
||
|
Serial.println("all off");
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 0, 0, 0, 0);
|
||
|
animation = 0;
|
||
|
}
|
||
|
|
||
|
unsigned long time_refresh = millis();
|
||
|
|
||
|
void static_mode()
|
||
|
{
|
||
|
Serial.println("Static mode ON");
|
||
|
if ((millis()-time_refresh)>1000)
|
||
|
{
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
|
||
|
time_refresh = millis();
|
||
|
}
|
||
|
animation = 1;
|
||
|
}
|
||
|
|
||
|
void snake_mode_in()
|
||
|
{
|
||
|
Serial.println("Snake mode in");
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
for(int i=0; i<NUM_FLORS; i++)
|
||
|
{
|
||
|
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
|
||
|
delay(5000);
|
||
|
}
|
||
|
animation = 2;
|
||
|
}
|
||
|
|
||
|
void snake_mode_out()
|
||
|
{
|
||
|
Serial.println("Snake mode Out");
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
for(int i=(NUM_FLORS-1); i>=0; i--)
|
||
|
{
|
||
|
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
|
||
|
delay(5000);
|
||
|
}
|
||
|
animation = 3;
|
||
|
}
|
||
|
|
||
|
void random_mode()
|
||
|
{
|
||
|
Serial.print("Random mode ON ");
|
||
|
if (animation!=4) for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
int i = random(0,(NUM_FLORS-1));
|
||
|
Serial.print(i);
|
||
|
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
|
||
|
delay(5000);
|
||
|
i = random(0,(NUM_FLORS-1));
|
||
|
Serial.println(" " + (String)i);
|
||
|
lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
animation = 4;
|
||
|
}
|
||
|
|
||
|
void snake_mode_in_out()
|
||
|
{
|
||
|
Serial.println("Snake mode in-out");
|
||
|
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
for(int i=0; i<NUM_FLORS; i++)
|
||
|
{
|
||
|
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
|
||
|
delay(5000);
|
||
|
}
|
||
|
for(int i=(NUM_FLORS-1); i>=0; i--)
|
||
|
{
|
||
|
lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
|
||
|
delay(5000);
|
||
|
}
|
||
|
animation = 5;
|
||
|
}
|
||
|
|
||
|
void beat()
|
||
|
{
|
||
|
uint8_t colors[5] = {color[0].red, color[0].green, color[0].blue, color[0].cold, color[0].warm};
|
||
|
float MAX = (float)getMax(colors);
|
||
|
float inc_colors[5] = {(float)color[0].red/MAX, (float)color[0].green/MAX, (float)color[0].blue/MAX, (float)color[0].cold/MAX, (float)color[0].warm/MAX};
|
||
|
float colors_act[5] = {0, 0, 0, 0, 0};
|
||
|
Serial.println("Beat mode");
|
||
|
for(int k=0; k<MAX; k++)
|
||
|
{
|
||
|
Serial.println(k);
|
||
|
for(int i=0; i<5; i++) colors_act[i]+=inc_colors[i];
|
||
|
for(int i=0; i<NUM_FLORS; i++)
|
||
|
{
|
||
|
// for(int j=0; j<5; j++) {
|
||
|
// Serial.print((uint8_t)colors_act[j], HEX);
|
||
|
// Serial.print(" ");
|
||
|
// }
|
||
|
// Serial.println();
|
||
|
lamp_color(i, (uint8_t)colors_act[0], (uint8_t)colors_act[1], (uint8_t)colors_act[2], (uint8_t)colors_act[3], (uint8_t)colors_act[4]);
|
||
|
}
|
||
|
//delay(1);
|
||
|
}
|
||
|
for(int k=MAX; k>0; k--)
|
||
|
{
|
||
|
Serial.println(k);
|
||
|
for(int i=0; i<5; i++) colors_act[i]-=inc_colors[i];
|
||
|
for(int i=0; i<NUM_FLORS; i++)
|
||
|
{
|
||
|
// for(int j=0; j<5; j++) {
|
||
|
// Serial.print((uint8_t)colors_act[j], HEX);
|
||
|
// Serial.print(" ");
|
||
|
// }
|
||
|
// Serial.println();
|
||
|
lamp_color(i, (uint8_t)colors_act[0], (uint8_t)colors_act[1], (uint8_t)colors_act[2], (uint8_t)colors_act[3], (uint8_t)colors_act[4]);
|
||
|
}
|
||
|
//delay(1);
|
||
|
}
|
||
|
animation = 6;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t getMax(uint8_t *myMeasurements)
|
||
|
{
|
||
|
byte maxIndex = 0;
|
||
|
uint8_t maxMeasurements = sizeof(myMeasurements);
|
||
|
int maxValue = myMeasurements[maxIndex];
|
||
|
for(byte i = 1; i < maxMeasurements; i++)
|
||
|
{
|
||
|
if(myMeasurements[i] > maxValue) {
|
||
|
maxValue = myMeasurements[i];
|
||
|
maxIndex = i;
|
||
|
}
|
||
|
}
|
||
|
return maxValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
void doConcat(const char *a, const char *b, char *out) {
|
||
|
strcpy(out, a);
|
||
|
strcat(out, b);
|
||
|
}
|