Arduino IoT Cloud fa a cazzotti con le sue stesse variabili

Buongiorno a tutti,
periodo natalizio, ma è già più di un mese che faccio a cazzotti con questa storia: ho arduinizzato il villaggio di Natale con 5 relé (vacca boia che gran cosa!) che accendono e spengono i 5 edifici in modo che siano comandati da Alexa.
Creato la thing sul cloud, creato 6 variabili (una per ogni edificio + una per sequenza random), impostato lo sketch tenendo tutto ben compartimentato, caricato prima su ESP32, poi su MKR1010 WifFi per comodità, ma ho 3 problemi che non riesco proprio a risolvere. Comincio a caricarvi lo sketch così vi fate un'idea.

/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/1b5fdbe0-6f15-4181-b771-04cf65ed409a

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  CloudSwitch chiesa;
  CloudSwitch nutcracker;
  CloudSwitch osservatorio;
  CloudSwitch skySwing;
  CloudSwitch tazze;
  CloudSwitch villaggioDiNatale;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"

#define SERIAL_BAUDRATE 115200

#define Suoni_Osservatorio 1
#define Suoni_Chiesa 0

#define Suoni_Nutcracker 3
#define Suoni_SkySwing 4
#define Suoni_Tazze 5
byte randomArray;

unsigned long lastChiesa;
unsigned long lastOsservatorio;
unsigned long lastTazze;
unsigned long lastSkySwing;
unsigned long lastNutcracker;
unsigned long lastCycle;

/*int iter = 0;
  int cycles;
  int residuo;*/



void setup() {
  pinMode(Suoni_SkySwing, OUTPUT);
  SkySwingOff();
  pinMode(Suoni_Chiesa, OUTPUT);
  ChiesaOff();
  pinMode(Suoni_Nutcracker, OUTPUT);
  NutcrackerOff();
  pinMode(Suoni_Tazze, OUTPUT);
  TazzeOff();
  pinMode(Suoni_Osservatorio, OUTPUT);
  OsservatorioOff();

  initProperties();  // Defined in thingProperties.h
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);  // Connect to Arduino IoT Cloud
}

void loop() {
  ArduinoCloud.update();
}

void onOsservatorioChange() {
  digitalWrite(Suoni_Osservatorio, !osservatorio);
}

void onSkySwingChange() {
  digitalWrite(Suoni_SkySwing, !skySwing);
}

void onChiesaChange() {
  digitalWrite(Suoni_Chiesa, chiesa);
}

void onTazzeChange() {
  digitalWrite(Suoni_Tazze, !tazze);
}

void onNutcrackerChange() {
  digitalWrite(Suoni_Nutcracker, !nutcracker);
}

void ChiesaOn() {
  digitalWrite(Suoni_Chiesa, HIGH);
  chiesa = true;
}
void OsservatorioOn() {
  digitalWrite(Suoni_Osservatorio, LOW);
  osservatorio = false;
}
void SkySwingOn() {
  digitalWrite(Suoni_SkySwing, LOW);
  skySwing = false;
}
void NutcrackerOn() {
  digitalWrite(Suoni_Nutcracker, LOW);
  nutcracker = false;
}
void TazzeOn() {
  digitalWrite(Suoni_Tazze, LOW);
  tazze = false;
}

void ChiesaOff() {
  digitalWrite(Suoni_Chiesa, LOW);
  chiesa = false;
}
void OsservatorioOff() {
  digitalWrite(Suoni_Osservatorio, HIGH);
  osservatorio = true;
}
void SkySwingOff() {
  digitalWrite(Suoni_SkySwing, HIGH);
  skySwing = true;
}
void NutcrackerOff() {
  digitalWrite(Suoni_Nutcracker, HIGH);
  nutcracker = true;
}
void TazzeOff() {
  digitalWrite(Suoni_Tazze, HIGH);
  tazze = true;
}

void ChiesaCycle() {
  lastChiesa = millis();
  ChiesaOn();
  if (millis() - lastChiesa >= 62000) {
    //delay(62000);
    ChiesaOff();
  }
}

void OsservatorioCycle() {
  lastOsservatorio = millis();
  OsservatorioOn();
  if (millis() - lastOsservatorio >= 30000) {
    //delay(30000);
    OsservatorioOff();
  }
}

void TazzeCycle() {
  lastTazze = millis();
  TazzeOn();
  if (millis() - lastTazze >= 30000) {
    //delay(29000);
    TazzeOff();
  }
}

void NutcrackerCycle() {
  lastNutcracker = millis();
  NutcrackerOn();
  if (millis() - lastNutcracker >= 45000) {
    //delay(45000);
    NutcrackerOff();
  }
}

void SkySwingCycle() {
  lastSkySwing = millis();
  SkySwingOn();
  if (millis() - lastSkySwing >= 65000) {
    //delay(65000);
    SkySwingOff();
    lastSkySwing = millis();
    //delay(10000);
  }
  if (millis() - lastSkySwing >= 10000) {}
}

/*
  Since VillaggioDiNatale is READ_WRITE variable, onVillaggioDiNataleChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onVillaggioDiNataleChange()  {
  if (villaggioDiNatale == true) {
    randomArray = random(5);
    switch (randomArray) {
      case 0:
        ChiesaCycle();
        break;
      case 1:
        TazzeCycle();
        break;
      case 2:
        OsservatorioCycle();
        break;
      case 3:
        NutcrackerCycle();
        break;
      case 4:
        SkySwingCycle();
        break;
    }
  } else {
    ChiesaOff();
    NutcrackerOff();
    OsservatorioOff();
    SkySwingOff();
    TazzeOff();
  }
}

carico anche il foglio thingProperties.h per completezza

// Code generated by Arduino IoT Cloud, DO NOT EDIT.

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

const char SSID[]     = SECRET_SSID;    // Network SSID (name)
const char PASS[]     = SECRET_OPTIONAL_PASS;    // Network password (use for WPA, or use as key for WEP)

void onChiesaChange();
void onNutcrackerChange();
void onOsservatorioChange();
void onSkySwingChange();
void onTazzeChange();
void onVillaggioDiNataleChange();

CloudSwitch chiesa;
CloudSwitch nutcracker;
CloudSwitch osservatorio;
CloudSwitch skySwing;
CloudSwitch tazze;
CloudSwitch villaggioDiNatale;

void initProperties(){

  ArduinoCloud.addProperty(chiesa, READWRITE, ON_CHANGE, onChiesaChange);
  ArduinoCloud.addProperty(nutcracker, READWRITE, ON_CHANGE, onNutcrackerChange);
  ArduinoCloud.addProperty(osservatorio, READWRITE, ON_CHANGE, onOsservatorioChange);
  ArduinoCloud.addProperty(skySwing, READWRITE, ON_CHANGE, onSkySwingChange);
  ArduinoCloud.addProperty(tazze, READWRITE, ON_CHANGE, onTazzeChange);
  ArduinoCloud.addProperty(villaggioDiNatale, READWRITE, ON_CHANGE, onVillaggioDiNataleChange);

}

WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);

le varie funzioni On e Off sono semplicissime ma mi vengono utili per evitare di fare casino con i relé a logica inversa (LOW = ON). I relé sono collegati sul Normally Open (tranne quello della Chiesa per un estremo disperato tentativo, vedi problema n.2)
Problema n.1: il setup ha un ritardo di X secondi rispetto all'accensione e diversi edifici si accendono per quegli X secondi appena viene data corrente. È un problema piccolo, ma ho impostato l'accensione del villaggio alle 6.45 con la sveglia e mi partono le musichette a manetta senza motivo (con l'ESP32 non succedeva, si sentiva solo il clic-clic dei relé che attaccano e staccano immediatamente).

Problema n.2: l'edificio Chiesa non ne vuole sapere di stare acceso. All'accensione funziona correttamente per una trentina di secondi (in base ai tentativi è cambiato il tempo, ma a parte un paio di volte per cui è rimasto acceso fino a spegnimento intenzionale, anche senza apportare modifiche il risultato è sempre stato quello di avere spegnimenti non voluti).
L'unica cosa che ho notato è che quando stacca la Chiesa, sulla Dashboard trovo Nutcracker e Osservatorio accesi.
Ho già provato a cambiare scheda, a cambiare il pin (prima era sul 2, appena messo sullo 0 ha funzionato correttamente, ma dal secondo switch on tutto come prima), ho collegato il relé sul Normally Closed invertendo poi tutti i booleani nello sketch... nessun risultato.

Problema n.3: La variabile villaggioDiNatale controlla uno switch case basato su una funzione random(). Ogni valore ottenuto fa attivare una funzione Cycle che, molto semplicemente, deve fare

  • accendi edificio,
  • prendi il millis(),
  • se millis() - tempo di accensione supera il tempo di ciclo
  • spegni edificio
  • (la SkySwing ha una sequenza di spegnimento di 10s, quindi ho aggiunto un secondo timer)

Lo switch...case funziona correttamente: ogni volta che accendo lo switch villaggio di natale si accende un edificio diverso che, però, va in eterno (tranne la Chiesa). Sembra che la condizione del timer all'interno del Cycle non arrivi mai a essere vero. Cosa sto sbagliando? Come dovrei fare per tornare poi alla OnVillaggioDiNataleChange()?

Grazie a tutti per l'aiuto

Nessuno? Il Natale ormai è passato e mi sono arrangiato, ma caspita…

Leggo adesso questa discussione per la prima volta, ma il problema on/off si risolve facilmente con:

#define ACCESO LOW
#define SPENTO HIGH

Vero! Questo mi snellisce decisamente lo sketch, anche se ne ho uno che funziona con logica invertita… posso collegare al NC invece che al NO l’uscita dal relé e sistemo.

Per il resto hai qualche idea?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.