Progetto Domotica, come "snellire" il codice?

Salve a tutti, oggi condivido con voi la mia esperienza con arduino in questo ultimo periodo.

Premessa: Voglio capire se è possibile rendere il mio sketch più "fluido", utilizzo arduino mega per la gestione di tutta l'abitazione, un wemos d1 r2 per il collegamento wifi (esp8266).
Caricando il codice attuale però ho già raggiunto il 56% di memoria, so che già ora potrebbe fare brutti scherzi il mega, devo ancora aggiungere delle parti di codice abbastanza "pesanti" (tutta la parte dell'anti furto, la parte della temperatura e dell'irrigazione) e non so se possibile.
Ringrazio SukkoPera per la sua pazienza e per il suo aiuto, lo sketch è basato sulla libreria Webbino.

Ho tirato su un plastico in scala 1:20 di un'abitazione domotizzata, cioè gestione di..

-Illuminazione di ogni singolo ambiente sia tramite pulsante fisico posto all'interno dell'abitazione che tramite smartphone/pc in remoto. [testato e funzionante]

-Cancello automatico gestito sia da un pulsante che in remoto da un qualsiasi smartphone/pc. (il cancello comprende fotocellule interne/esterne e lampeggiante per segnalare qualsiasi movimento) [testato e funzionante]

-Antifurto con sensore PIR e chiave RFID per l'attivazione/disattivazione dell'allarme, un lcd per il controllo dello stato di funzionamento. [devo ancora includere questa parte di codice]

-Temperatura attraverso un lm35, una ventola posizionata in modo da abbassare la temperatura se richiesto, quindi un set della temperatura gestito tramite web e visualizzazione della temperatura su un lcd. [devo ancora includere questa parte di codice]

-Irrigazione del prato gestita da smartphone/pc con set del timer della durata dell'irrigazione. [devo ancora includere questa parte di codice]

La pianta dell'abitazione

Il progetto realizzato

Come si può notare c'è il sensore pir alla fine del corridoio, il sensore di temperatura in cucina con la presa d'aria (e sotto lo scatolato la ventola)
Il cancello per comodità è stato realizzato a doppia anta scorrevole.

Lo sketch (pastebin)
Domotica last edit: 14/06/2017 21:40

Altre schede (pastebin)
Cancello
Crepuscolare
Illuminazione last edit: 14/06/2017 21:40
html.h last edit: 14/06/2017 21:40

In Webbino_config.h:

#define ON F("<td bgcolor=\"#00FF00\"><font color=\"#000000\">accesa</font></td><td><form method=\"get\">")
#define OFF F("<td bgcolor=\"#FF0000\"><font color=\"#FFFFFF\">spenta</font></td><td><form method=\"get\">")
#define LUCE_CUCINA_ON F("<input type=\"submit\" name=\"s1\" value=\"SPEGNI\" /></form></td>")
#define LUCE_CUCINA_OFF F("<input type=\"submit\" name=\"s1\" value=\"ACCENDI\" /></form></td>")
#define LUCE_STANZA_ON F("<input type=\"submit\" name=\"s2\" value=\"SPEGNI\" /></form></td>")
#define LUCE_STANZA_OFF F("<input type=\"submit\" name=\"s2\" value=\"ACCENDI\" /></form></td>")
#define LUCE_STANZETTA_ON F("<input type=\"submit\" name=\"s3\" value=\"SPEGNI\" /></form></td>")
#define LUCE_STANZETTA_OFF F("<input type=\"submit\" name=\"s3\" value=\"ACCENDI\" /></form></td>")
#define LUCE_BAGNO_ON F("<input type=\"submit\" name=\"s4\" value=\"SPEGNI\" /></form></td>")
#define LUCE_BAGNO_OFF F("<input type=\"submit\" name=\"s4\" value=\"ACCENDI\" /></form></td>")
#define LUCE_SALOTTO_ON F("<input type=\"submit\" name=\"s5\" value=\"SPEGNI\" /></form></td>")
#define LUCE_SALOTTO_OFF F("<input type=\"submit\" name=\"s5\" value=\"ACCENDI\" /></form></td>")
#define LUCE_CORRIDOIO_ON F("<input type=\"submit\" name=\"s6\" value=\"SPEGNI\" /></form></td>")
#define LUCE_CORRIDOIO_OFF F("<input type=\"submit\" name=\"s6\" value=\"ACCENDI\" /></form></td>")
#define LUCE_INGRESSO_ON F("<input type=\"submit\" name=\"s7\" value=\"SPEGNI\" /></form></td>")
#define LUCE_INGRESSO_OFF F("<input type=\"submit\" name=\"s7\" value=\"ACCENDI\" /></form></td>")
#define LUCE_GARAGE_ON F("<input type=\"submit\" name=\"s8\" value=\"SPEGNI\" /></form></td>")
#define LUCE_GARAGE_OFF F("<input type=\"submit\" name=\"s8\" value=\"ACCENDI\" /></form></td>")

Pubblico pure tutto l'archivio dei codici sopra elencati (download mega)
MEGA last edit: 14/06/2017 21:40

Bug conosciuti:
-Quando il cancello è in apertura/chiusura e si va ad accendere/spegnere qualsiasi luce tramite la pagina web, il cancello si ferma per qualche istante per poi continuare la sua corsa.

Condivido pure un piccolo video, vi mostro i brutti scherzi che fa! (il puntatore durante la registrazione non capisco perchè non è calibrato bene, però si capiscono le operazioni)
Magari con passi più lenti fa meno volte il brutto scherzo, però devo cercare di eliminare questo problema.
YouTube Video

Lo sketch usa 33282 byte (13%) dello spazio disponibile per i programmi. Il massimo è 253952 byte.
Le variabili globali usano 4987 byte (60%) di memoria dinamica, lasciando altri 3205 byte liberi per le variabili locali. Il massimo è 8192 byte.

Per qualsiasi domanda sono a disposizione per dare eventuali altre informazioni.
Spero di attirare l'attenzione e d'essere aiutato per rendere il codice più "fluido". Grazie a tutti voi utenti del forum!

Ho provato il tuo sketch, con un ESP8266 come scheda di rete, e non mi sembra di riscontrare il problema.

Comunque, certo è che questo è un po' strano:

if (strcmp_P (param2, PSTR ("ACCENDI")) == 0 || PLuceStanza == HIGH) {

Qua il check sul pulsante non c'entra granché, secondo me...

SukkoPera:
Ho provato il tuo sketch, con un ESP8266 come scheda di rete, e non mi sembra di riscontrare il problema.

Comunque, certo è che questo è un po' strano:

if (strcmp_P (param2, PSTR ("ACCENDI")) == 0 || PLuceStanza == HIGH) {

Qua il check sul pulsante non c'entra granché, secondo me...

Ho rimosso quell'or, come su tutti gli altri, non ho aggiornato l'archivio, lo faccio subito!
Quindi..
youtube

questi mancati segnali o non so come definire la situazione, a cosa sono dovuti?

Non saprei proprio, prova a mettere qualche print nella funzione ledToggle() e cerca di capire cosa succede.

SukkoPera:
Non saprei proprio, prova a mettere qualche print nella funzione ledToggle() e cerca di capire cosa succede.

Gia nel video si vede qualche log, in ogni caso in che modo devo aggiungere questi print, a quale scopo?

Non saprei, fai tu. Devi capire cosa succede nella funzione, quindi stampa qualcosa per vedere se viene effettivamente chiamata, stampa il valore prima del cambio, e poi di nuovo dopo.

SukkoPera:
Non saprei, fai tu. Devi capire cosa succede nella funzione, quindi stampa qualcosa per vedere se viene effettivamente chiamata, stampa il valore prima del cambio, e poi di nuovo dopo.

Ho fatto una velocissima prova con solo il primo pulsante, interessante i log, tutti sballati..

youtube

Quando premo "accendi" e non succede nulla, nel monitor seriale mi compare il print che invece avevo messo nel tasto spegni, in seguito c'è qualche timeout.
Quando invece funziona l'accendi tutto va regolare.
Presenza di molteplici "New client 0" e "Disconnecting 0" durante il caricamento della pagina, che a volte porta al crash

ps. ho provato con un'altra wemos, il risultato è uguale, credo sia problema di sketch, ma non capisco dove, eppure a te va (?) @SukkoPera

progetto con qualche luce accesa..

quelle poche volte che le luci si accendono quando premo via web v.v (invece da pulsante fisico direttamente posto nel plastico reagisce subito ovviamente)

Questa parte è il problema suppongo, consigli su come riscriverla meglio?

PString& eveluate_stato_luce_cucina (void *data __attribute__ ((unused))) {
  if (SLuceCucina) {
    pBuffer.print (ON);
    pBuffer.print (LUCE_CUCINA_ON);
  }
  else {
    pBuffer.print (OFF);
    pBuffer.print (LUCE_CUCINA_OFF);
  }
  
  return pBuffer;
}

Quando premo e non succede nulla è perchè salta l'if e va direttamente all'else

Se va all'else è perché la condizione è falsa, mica ci va per caso. Analizza tutti i punti dove manipoli quella variabile.

Ho capito dov'è il problema!

Mi è bastato cancellare la cache del browser :drooling_face:

Cosi sembra andare tutto per il verso giusto..

Ah ottimo!

Riguardo ai millis che sostituiscono i delay.. ho pensato di metterli, ma quando applico il "tradizionale" metodo viene fuori uno sketch un pò troppo lungo, so che c'è una soluzione ma non riesco a capire come si ci può arrivare

void Antifurto() {

  slave = EEPROM.read(0);

  if (rfid.isCard()) {
      if (rfid.readCardSerial()) {
        sernum0 = rfid.serNum[0];
        sernum1 = rfid.serNum[1];
        sernum2 = rfid.serNum[2];
        sernum3 = rfid.serNum[3];
        sernum4 = rfid.serNum[4];

                if (sernum0 == masnum0
                && sernum1 == masnum1
                && sernum2 == masnum2
                && sernum3 == masnum3
                && sernum4 == masnum4) {
                if (cardmas==0) {
                  lcd.clear();
                  lcd.print("CARD MASTER");
                  delay(1500);
                  lcd.clear();
                  lcd.print("GESTIONE CHIAVI");
                cardmas = 1;
                lcd.setCursor(0, 1);
                lcd.print("Chiavi slave: ");
                lcd.setCursor(15, 1);
                lcd.print(slave);
                delay(2000);
                }  else { cardmas = 0;
                  lcd.setCursor(0, 1);
                  lcd.print("Annullata       ");
                delay(3000);
                standby();
                }
                } 

                else if ((sernum0 == EEPROM.read(1) && sernum1 == EEPROM.read(2) && sernum2 == EEPROM.read(3) && sernum3 == EEPROM.read(4) && sernum4 == EEPROM.read(5))
                        || (sernum0 == EEPROM.read(6) && sernum1 == EEPROM.read(7) && sernum2 == EEPROM.read(8) && sernum3 == EEPROM.read(9) && sernum4 == EEPROM.read(10))
                        || (sernum0 == EEPROM.read(11) && sernum1 == EEPROM.read(12) && sernum2 == EEPROM.read(13) && sernum3 == EEPROM.read(14) && sernum4 == EEPROM.read(15))) {
                              
                             if (antiON == 0) {  
                             antiON = 1;
                             lcd.clear();
                             lcd.print("CHIAVE VALIDA");
                             delay(1500);
                             lcd.clear();
                             lcd.print("ANTIFURTO");
                             lcd.setCursor(0, 1);
                             lcd.print("INSERITO...");
                             delay(pausa);
                             digitalWrite(ledRed, HIGH);
                             lcd.clear();
                             lcd.print("ANTIFURTO");
                             lcd.setCursor(0, 1);
                             lcd.print("ATTIVO");
                             } 
                              else {
                                   antiON = 0;
                                   allarm = 0;
                                   digitalWrite(ledRed, LOW);
                                   digitalWrite(ledGreen, LOW);
                                   lcd.clear();
                                   lcd.print("CHIAVE VALIDA");
                                   delay(1500);
                                   lcd.clear();
                                   lcd.print("ANTIFURTO");
                                   lcd.setCursor(0, 1);
                                   lcd.print("DISATTIVO");
                                   delay(3000);
                                   standby();
                    } 
                } 

                else if (cardmas == 1 && slave == 0) {
                    lcd.clear();
                    lcd.print("Chiave rilevata!");
                    EEPROM.write(0, 1);
                    EEPROM.write(1, sernum0);
                    EEPROM.write(2, sernum1);
                    EEPROM.write(3, sernum2);
                    EEPROM.write(4, sernum3);
                    EEPROM.write(5, sernum4);
                    cardmas = 0;
                    delay(1000);
                    lcd.setCursor(0, 1);
                    lcd.print("Slave 1 salvata!");
                    delay(3000);
                    standby();
                                        
                }
                    else if (cardmas == 1 && slave == 1) {
                              lcd.clear();
                              lcd.print("Chiave rilevata!");
                              EEPROM.write(0, 2);
                              EEPROM.write(6, sernum0);
                              EEPROM.write(7, sernum1);
                              EEPROM.write(8, sernum2);
                              EEPROM.write(9, sernum3);
                              EEPROM.write(10, sernum4);
                              cardmas = 0;
                              delay(1000);
                              lcd.setCursor(0, 1);
                              lcd.print("Slave 2 salvata!");
                              delay(3000);
                              standby();
                    }
                              else if (cardmas == 1 && slave == 2) {
                                       lcd.clear();
                                       lcd.print("Chiave rilevata!");
                                       EEPROM.write(0, 3);
                                       EEPROM.write(11, sernum0);
                                       EEPROM.write(12, sernum1);
                                       EEPROM.write(13, sernum2);
                                       EEPROM.write(14, sernum3);
                                       EEPROM.write(15, sernum4);
                                       cardmas = 0;
                                       lcd.setCursor(0, 1);
                                       lcd.print("Slave 3 salvata!");
                                       delay(3000);
                                       standby();
                              }
                }
                }
         
  if (digitalRead(pir) == HIGH) {
          digitalWrite(ledgial, HIGH);
     }
     else {
           digitalWrite(ledgial, LOW);
          }
            
  if (digitalRead(pir) == HIGH && antiON == 1 && allarm == 0){
          delay(pausa);
          allarm = 1;
          lcd.clear();
          lcd.print("ALLARME!!");
     }
  if (antiON == 1 && allarm == 1) {
          lamp();
          buzz(7, 4186, 100);
          delay(10); // Attesa
     }

 if (digitalRead(resetkey) == HIGH && cardmas == 1) {
         cardmas = 0;
         for (int i=0; i<16; i++){
           EEPROM.write(i, 0);
             } 
         lcd.clear();
         lcd.print("Reset chiavi...");
         delay(3000);
         standby();
     }        
                
 rfid.halt();
}
void lamp() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    ledState ^= 1;
    digitalWrite(ledGreen, ledState);
  }
}
  
void buzz(int targetPin, long frequency, long length) {
 long delayValue = 1000000/frequency/2;
 long numCycles = frequency * length/ 1000;
 for (long i=0; i < numCycles; i++)
 {
 digitalWrite(targetPin,HIGH);
 delayMicroseconds(delayValue);
 digitalWrite(targetPin,LOW);
 delayMicroseconds(delayValue);
 }
  }
  
void standby() {
 lcd.clear();
 lcd.print("Anti-Furto 1.0"); 
}

Un piccolo esempio? ::slight_smile:

Questo non va: PasteBin
Questo nemmeno: PasteBin2

Avevo pure perso il topic, non ne apro un'altro e continuo qui sotto..

const char tab1[] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};
const char tab2[] = {0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03};

void AvvioMotore() {
  switch (cmd_motor)
  {
    case 0:
      digitalWrite(IN1, 0);
      digitalWrite(IN2, 0);
      digitalWrite(IN3, 0);
      digitalWrite(IN4, 0);
    break;

    case 1:
      for (int i = 0; i < 8; i++) { //Apertura
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(1);
      }
    break;

    case 2:
      for (int i = 0; i < 8; i++) { //Chiusura
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(1);
      }
    break;
  }
}

Ho bisogno di eliminare quel delay, ho provato con millis ma non va con il ciclo for, help!