semaforo con 4 sensori

Buongiorno a tutti, sto cercando di fare un semaforo per un progetto scolastico.
Tale semaforo deve avere le letture di 4 sensori ad ultrasuoni che devono rilevare in sostanza lo stato delle code.
Il problema è che una volta avviato questo codice che ho scritto non funziona, ho creato un programma simile ma senza l'implementazione e l'accensione dei LED e avviando il monitor seriale e sembrerebbe che sia uno solo il sensore in funzione, da tutti viene rilevato zero tranne 1 che è in continua evoluzione in base a come si piazzano gli oggetti davanti.
Vorrei sapere da voi che ne capite molto di più di me se è un problema del codice che ho scritto, grazie mille a chiunque sarà così gentile da aiutarmi :slight_smile:

semaforoscuola.ino (8.22 KB)

Buonasera e benvenuto, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Chiedo scusa per non essermene accorto da me :slight_smile: .
Ho rimediato al mio meglio!

Ciao! Ho dato un occhiata al codice ho notato che nelle istruzioni if() dove c'è un confronto usi = al posto di

if(a=b) è un assegnazione non un confronto, si deve usare if(a==b).

Il C non da errore, ma tutte le condizioni che vorresti fare non sono verificate.
Diciamo che è un errore da principianti, dalla tua presentazione dici che usi il C da un po, e questi errori non dovresti farli :)

In realtà sono tutte verificate, perché significa a=b; if(a) {...}

Datman:
In realtà sono tutte verificate, perché significa a=b; if(a) {...}

Allora, se vogliamo fare i pignoli, sono verificate se b è diverso da zero, altrimenti ad a viene assegnato zero che, nella if, è falso :smiley:

Guglielmo

Sì, certo :slight_smile:

Dopo aver corretto qualche errore formale e averlo compattato un po', pur mantenendone la comprensibilità:

static byte triggert1b = 2;
static byte echot1b = 3;
static byte triggert1a = 4;
static byte echot1a = 5;
static byte triggert2b = 7;
static byte echot2b = 6;
static byte triggert2a = 9;
static byte echot2a = 8;
static byte greens1 = 13;
static byte reds2 = 11;
static byte greens2 = 10;
static byte reds1 = 12;
int count;
byte g1;
byte T2B;
byte T2A;
byte T1A;
byte T1B;
unsigned long duratat1b;
unsigned long distanzat1b;
unsigned long duratat2b;
unsigned long distanzat2b;
unsigned long duratat1a;
unsigned long distanzat1a;
unsigned long duratat2a;
unsigned long distanzat2a;
// abbiamo finito la dichiarazione delle variabili, ora inizia il programma
void setup() 
{
  // impostiamo la funzione dei pin prima assegnati(uscita o ingresso)
  pinMode(triggert1b, OUTPUT);
  pinMode(echot1b, INPUT);
  pinMode(triggert2b, OUTPUT);
  pinMode(echot2b, INPUT);
  pinMode(triggert2a, OUTPUT);
  pinMode(echot2a, INPUT);
  pinMode(triggert1a, OUTPUT);
  pinMode(echot1a, INPUT);
  pinMode(greens1, OUTPUT);
  pinMode(greens2, OUTPUT);
  pinMode(reds1, OUTPUT);
  pinMode(reds2, OUTPUT);

  // inizializziamo il semaforo
  digitalWrite(reds2, HIGH);
  digitalWrite(greens1, HIGH);
  // determiniamo il valore iniziale delle due variabili rimaste
  duratat1a = 0;
  distanzat1a = 0;
  duratat1b = 0;
  distanzat1b = 0;
  duratat2a = 0;
  distanzat2a = 0;
  duratat2b = 0;
  distanzat2b = 0;
  g1=0;
  delay(900);
}

void loop() 
{
 //alimentiamo il trigger per attivare il sensore 
  digitalWrite (triggert1b, HIGH);
  digitalWrite (triggert2b, HIGH);
  digitalWrite (triggert1a, HIGH);
  digitalWrite (triggert2a, HIGH);
  //delay in microsecondi (il delay normale è misurato in millisecondi)
  delayMicroseconds(10);
  digitalWrite (triggert1b, LOW);
  digitalWrite (triggert2b, LOW);
  digitalWrite (triggert1a, LOW);
  digitalWrite (triggert2a, LOW);
  //pulseIn è un comando che serve a misurare il tempo in cui un determinato pin sta a valore alto o basso(da indicare tra parentesi)
  duratat1b = pulseIn(echot1b, HIGH);
  duratat2b = pulseIn(echot2b, HIGH);
  duratat1a = pulseIn(echot1a, HIGH);
  duratat2a = pulseIn(echot2a, HIGH);
  // Adesso bisogna traformare il tempo in distanza
  // Si divide per 2 perchè la distanza è la metà del percorso di andata e ritorno.
  // Si divide per 29 perchè la velocità del suono (emesso dal sensore) è 340m/s, cioè 29cm/microsecondo.
  distanzat1b = duratat1b/58;
  distanzat1a = duratat1a/58;
  distanzat2a = duratat2a/58;
  distanzat2b = duratat2b/58;
  if (distanzat1b>=20 && distanzat1b<=50) {T1B=1;}
  else {T1B=0;}
  if (distanzat2b>=20 && distanzat2b<=50) {T2B=1;}
  else {T2B=0;}
  if (distanzat1a>=20 && distanzat1a<=50) {T1A=1;}
  else {T1A=0;}
  if (distanzat2a>=20 && distanzat2a<=50) {T2A=1;}
  else {T2A=0;}
  
  if ((T1A=T2A)&&(T1B=T2B))
  {
    if (g1=0)
    {
      //digitalWrite(reds1, HIGH);
      //delay(4000);
      digitalWrite(greens1, LOW);
      delay(2500);
      digitalWrite(reds2, LOW);
      digitalWrite(greens2, HIGH);
      delay(9000);
      //alimentiamo il trigger per attivare il sensore 
      digitalWrite (triggert1b, HIGH);
      digitalWrite (triggert2b, HIGH);
      digitalWrite (triggert1a, HIGH);
      digitalWrite (triggert2a, HIGH);
      //delay in microsecondi (il delay normale è misurato in millisecondi)
      delayMicroseconds(10);
      digitalWrite (triggert1b, LOW);
      digitalWrite (triggert2b, LOW);
      digitalWrite (triggert1a, LOW);
      digitalWrite (triggert2a, LOW);
      
      duratat1b = pulseIn(echot1b, HIGH);
      duratat2b = pulseIn(echot2b, HIGH);
      duratat1a = pulseIn(echot1a, HIGH);
      duratat2a = pulseIn(echot2a, HIGH);
      // Adesso bisogna traformare il tempo in distanza
      distanzat1b = duratat1b / 29 / 2;
      distanzat1a = duratat1a / 29 / 2;
      distanzat2a = duratat2a / 29 / 2;
      distanzat2b = duratat2b / 29 / 2;
      if (distanzat1b>=20 && distanzat1b<=50) {T1B=1;}
      else {T1B=0;}
      if (distanzat2b>=20 && distanzat2b<=50) {T2B=1;}
      else {T2B=0;}
      if (distanzat1a>=20 && distanzat1a<=50) {T1A=1;}
      else {T1A=0;}
      if (distanzat2a>=20 && distanzat2a<=50) {T2A=1;}
      else {T2A=0;}
      if (T1A==1 || T1B==1)
      {
        //digitalWrite(reds2, HIGH);
        //delay(4000);
        digitalWrite(greens2, LOW); 
        delay(2500);
        digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH); 
        delay(9000);
      }
      else {delay(900);}
    }
    if (g1==1)
    {
      //digitalWrite(reds2, HIGH);
      //delay(4000);
      digitalWrite(greens2, LOW); 
      delay(2500);
      digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH); 
      delay(9000);
      g1=0;
    }      
  }
  else
  {
    if (T2A==1 || T2B==1)
    {
      //digitalWrite(reds1, HIGH);
      //delay(4000);
      digitalWrite(greens1, LOW); 
      delay(2500);
      digitalWrite(reds2, LOW); digitalWrite(greens2, HIGH);
      count=0;
      delay(9000);
      // alimentiamo il trigger per attivare il sensore 
      digitalWrite (triggert1b, HIGH);
      digitalWrite (triggert2b, HIGH);
      digitalWrite (triggert1a, HIGH);
      digitalWrite (triggert2a, HIGH);
      // delay in microsecondi (il delay normale è misurato in millisecondi)
      delayMicroseconds(10);
      digitalWrite (triggert1b, LOW);
      digitalWrite (triggert2b, LOW);
      digitalWrite (triggert1a, LOW);
      digitalWrite (triggert2a, LOW);
      // pulseIn è una funzione che misura il tempo in cui un pin sta a valore alto o basso (da indicare tra parentesi)
      duratat1b = pulseIn(echot1b, HIGH);
      duratat2b = pulseIn(echot2b, HIGH);
      duratat1a = pulseIn(echot1a, HIGH);
      duratat2a = pulseIn(echot2a, HIGH);
      // Adesso bisogna trasformare il tempo in distanza
      distanzat1b = duratat1b/58;
      distanzat1a = duratat1a/58;
      distanzat2a = duratat2a/58;
      distanzat2b = duratat2b/58;
      if (distanzat1b>=20 && distanzat1b<=50) {T1B=1;}
      else {T1B=0;}
      if (distanzat2b>=20 && distanzat2b<=50) {T2B=1;}
      else {T2B=0;}
      if (distanzat1a>=20 && distanzat1a<=50) {T1A=1;}
      else {T1A=0;}
      if (distanzat2a>=20 && distanzat2a<=50) {T2A=1;}
      else {T2A=0;}
      if (T1A==1 || T1B==1)
      {
        //digitalWrite(reds2, HIGH);
        //delay(4000);
        digitalWrite(greens2, LOW);
        delay(2500);
        digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH);
        delay(9000);
      }
      else {delay(9000); g1=1;}
    }
    else {delay(9000);}
  }
}

Non ho studiato tutta la logica del programma, però non mi sembra una buona idea generare contemporaneamente l'impulso ultrasonico sui 4 trasmettitori, perché ognuno potrebbe anche captare in ritardo il suono proveniente dagli altri. Compattato ulteriormente con l'uso di una funzione diventa:

#define triggert1b 2
#define echot1b 3
#define triggert1a 4
#define echot1a 5
#define triggert2b 7
#define echot2b 6
#define triggert2a 9
#define echot2a 8
#define greens1 13
#define reds2 11
#define greens2 10
#define reds1 12
int count;
byte g1=0;
byte T2B;
byte T2A;
byte T1A;
byte T1B;
unsigned long distanzat1b=0;
unsigned long distanzat2b=0;
unsigned long distanzat1a=0;
unsigned long distanzat2a=0;

void setup()
{
  pinMode(triggert1b, OUTPUT);
  pinMode(echot1b, INPUT);
  pinMode(triggert2b, OUTPUT);
  pinMode(echot2b, INPUT);
  pinMode(triggert2a, OUTPUT);
  pinMode(echot2a, INPUT);
  pinMode(triggert1a, OUTPUT);
  pinMode(echot1a, INPUT);
  pinMode(greens1, OUTPUT);
  pinMode(greens2, OUTPUT);
  pinMode(reds1, OUTPUT);
  pinMode(reds2, OUTPUT);

  // inizializziamo il semaforo
  digitalWrite(reds2, HIGH);
  digitalWrite(greens1, HIGH);
  delay(900);
}

void loop()
{
  misuraDistanze();
  if (T1A==1 || T1B==1)
  {
    //digitalWrite(reds2, HIGH);
    //delay(4000);
    digitalWrite(greens2, LOW);
    delay(2500);
    digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH);
    delay(9000);
  }
  if ((T1A=T2A)&&(T1B=T2B))
  {
    if (g1==0)
    {
      //digitalWrite(reds1, HIGH);
      //delay(4000);
      digitalWrite(greens1, LOW);
      delay(2500);
      digitalWrite(reds2, LOW);
      digitalWrite(greens2, HIGH);
      delay(9000);
      misuraDistanze();
      if (T1A==1 || T1B==1)
        {
          //digitalWrite(reds2, HIGH);
          //delay(4000);
          digitalWrite(greens2, LOW);
          delay(2500);
          digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH);
          delay(9000);
        }
      else {delay(900);}
    }
    if (g1==1)
    {
      //digitalWrite(reds2, HIGH);
      //delay(4000);
      digitalWrite(greens2, LOW);
      delay(2500);
      digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH);
      delay(9000);
      g1=0;
    }     
  }
  else
  {
    if (T2A==1 || T2B==1)
    {
      //digitalWrite(reds1, HIGH);
      //delay(4000);
      digitalWrite(greens1, LOW);
      delay(2500);
      digitalWrite(reds2, LOW); digitalWrite(greens2, HIGH);
      count=0;
      delay(9000);
      misuraDistanze();
      if (T1A==1 || T1B==1)
        {
          //digitalWrite(reds2, HIGH);
          //delay(4000);
          digitalWrite(greens2, LOW);
          delay(2500);
          digitalWrite(reds1, LOW); digitalWrite(greens1, HIGH);
          delay(9000);
        }
      else {delay(9000); g1=1;}
    }
    else {delay(9000);}
  }
}

void misuraDistanze()
{
  // alimentiamo il trigger per attivare il sensore
  digitalWrite (triggert1b, HIGH); delayMicroseconds(10); digitalWrite (triggert1b, LOW);
  distanzat1b = pulseIn(echot1b, HIGH)/58;
  digitalWrite (triggert2b, HIGH); delayMicroseconds(10); digitalWrite (triggert2b, LOW);
  distanzat2b = pulseIn(echot2b, HIGH)/58;
  digitalWrite (triggert1a, HIGH); delayMicroseconds(10); digitalWrite (triggert1a, LOW);
  distanzat1a = pulseIn(echot1a, HIGH)/58;
  digitalWrite (triggert2a, HIGH); delayMicroseconds(10); digitalWrite (triggert2a, LOW);
  distanzat2a = pulseIn(echot2a, HIGH)/58;

  if (distanzat1b>=20 && distanzat1b<=50) {T1B=1;}
  else {T1B=0;}
  if (distanzat2b>=20 && distanzat2b<=50) {T2B=1;}
  else {T2B=0;}
  if (distanzat1a>=20 && distanzat1a<=50) {T1A=1;}
  else {T1A=0;}
  if (distanzat2a>=20 && distanzat2a<=50) {T2A=1;}
  else {T2A=0;}
}

Adesso devi reimpostare la struttura del programma eliminando i delay().
Per le durate potresti usare dei #define:
#define DUR_1 2500
#define DUR_2 4000
#define DUR_3 9000

Grazie mille a tutti! Ho capito dove sbagliavo :cold_sweat: , in ogni adesso funziona tutto! Grazie ancora