Go Down

Topic: Semaforo Complesso OK-Flip Flop Semplice ( e non ci salto fuori). (Read 6217 times) previous topic - next topic

docsavage

Hai un po' di confusione in linea

if (4,HIGH) non significanulla

semmai if (digitalread(4)==HIGH)

che comunque non serve, basta
if (digitalread(4))
dato ce la digitalread su un pulsante premuto vale vero di suo, senza proseguire con la condizione

poi millis()>2000 varra' vero dopo due secondi dall'accensione e per sempre (si, OK dopo 50 giorni altri due secondi di NO, ma non credo che adesso ci preoccupi)

la differenza tra int e long

int è un tipo di variabile che può contenre numeri interi tra (imparare a leggere il reference)
comunque tra -32000 e passa e + 32000 e passa

se ti servono numeri più grandi si usa long

che tiene un fracco di più (quanto? come ho detto fa fede il reference ed è necessario imparare a consultarlo)

se non ti basta ancora si usano unsigned int  e unsigned long, che tengono il doppio di int e lon, ma senza il segno (solo numeri positivi)

millis è di tipo unsigned long, che vuol dire che la millis ti risponde con un numero che arriva al massimo fino al massimo della unsigned long


poi

la tua if (A==LOW) con tutto quello che segue può diventare

A=!A;


che significa: qualunque sia A, metti il suo opposto
se era 0 mette 1 (ricordati sempre che 0 è uguale a LOW e uguale a condizione NON ripettata)
se era "non 0"  0 (ricordati che qualunque cosa differente da zero viene valutata come HIGH o condizione rispettata)


in pratica il tuo programma dice:

dopo i primi 2 secondi
misura il tempo e salvalo in B (inutile visto che poi B non la usi mai)
inverti il valore di A
accendi o spegni l'uscita a seconda del valore di A
che non mi sembra essere quello che volevi fare

Sbaglio?
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Claudio_FF

Quote from: Puso
sarà la maledidone del pulsante del vecchietto??
Sarà che la scaletta da percorrere è sempre la solita  ;)

Studiare:

- tipi di variabili / rappresentazione dei dati
- operazioni aritmetiche / logiche
- esecuzione condizionata (if else switch)
- cicli (for / while)
- uso delle funzioni
- uso degli array
- un minimo, ma proprio minimo, di puntatori, che su Arduino in pratica servono solo per passare i valori per riferimento alle funzioni.

Trentacinque anni fa andava via un mese per ogni punto...
Una domanda ben posta è già mezza risposta.

docsavage

io quoto intero quello che dice Claudio_FF

sono un pochino più ottimista sui tempi

in particolare if else secondo me è veloce veloce da imparare

i cicli son un po' la bestia nera della programmazione

i puntatori sono la bestia nera del C

ma per cominciare se ne puo' fare a meno

certamente tipi di variabili e operatori sono la base senza la quale nemmeno si puo' pensare a programmare


io consiglio sempre di scriversi il programma in italiano

e poi lentamente tradurlo in linguaggio

del tipo:

se premo il pulsante


accendo il led


diventa
1) devo dichiarare il pulsante
pinmode...........
2) devo dichiarare il led
pinmode.....
3) test sul pulsante
if (pulsante.........
e qui metto subito le 2 graffe (mica di dimenticare di chiuderle)

quindi
Code: [Select]
pinMode(3,INPUT);
pinMode(4, OUTPUT);

if (digitalRead(3)){
degitalwrite(4,....
}
finito


e intanto mi ricordo che i pinmode vanno nella setup

e il resto nella loop

il processo di traduzione italiano->C non è immediato
vado passo a passo

anche perchè nel frattempo mi accorgo che:
1) mi spno dimenticato cosa fare se NON premo il pulsante
2) mi sono dimenticato anche come rimettere a posto il led quando non premo più il pulsante

a questo punto diventa:
Code: [Select]

if (digitalread(3)){
digitalwrite(4,HIGH);
}
else{
digitalWrite(4,LOW);
}


solo che a questo punto mi sono accorto che la if non mi serve più

perchè la condizione è uguale all'uscita

quindi scriverò solo

Code: [Select]
digitalWrite(4,digitalRead(3));





E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

Lo ammetto ho fatto un po di casino, ma prima o poi ce la farò.

docsavage

Parti dal poco, un led che lampeggia con millis


Poi un tasto che cambia il tempo


E poi...
.
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

Per un po non scrivo più

leggo solo
prima voglio capire sto millis() e ste variabili , è facile fare copia incolla, ma appena cambi qualkosa ti rendi conto che ........o lo sai fare oppure no.

ed io voglio imparare non copiare.

Vi ringrazio a tutti per la pazienza
 appena riesco a fare qualkosa di concreto... nella mia ignoranza,
lo metto nel forum
per il momento GRAZIE SIETE GRANDI

docsavage

E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

Ciao
dunque sto studiando e mi sono creato uno skecth per capire meglio il MILLIS

ho notato che ci sono diversi modi per utilizzarlo quindi sto tentando capire le differenze...pero mi sono perso qualkosa.

Questo è lo sketch che dovrebbe utilizzando il pulsante INT P1=0;

accendere led in sequenza e finquì tutto ok.

Poi col pulsante INT PAUT=0;
era mia intenzione mettere in automatico la sequenza di P1 utilizzando una modalità MILLIS

però i led si accendono come gli pare a loro.
Code: [Select]

unsigned long A;
unsigned long B;
unsigned long C;
unsigned long D;
unsigned long on1=1000;
unsigned long off1=1000;
unsigned long on2=2000;
unsigned long off2=5000;
int P1=0;
int PAUT=0;

void setup()
{
 pinMode(2,OUTPUT);
 pinMode(3,OUTPUT);
 pinMode(4,OUTPUT);
 pinMode(12,INPUT);
 pinMode(8,OUTPUT);
 pinMode(9,OUTPUT);
 pinMode(10,OUTPUT);
 pinMode(11,INPUT);
}

void loop()
{
  if(digitalRead(11)==HIGH)
{
   delay(250);
   ++PAUT;
     if(PAUT>=2){PAUT=0;}
 }
 if(PAUT==0)
 {
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
 }
 if(PAUT==1)
 {
  digitalWrite(8,HIGH);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(12,LOW);                                  // questo l'ho aggiunto durante i vari tentativi
 
   if(millis()> A +500){P1=1+P1;}                    // qui è dove non funziona anche mettendo ++P1
   if(millis()> A +1000){P1=1+P1;A=millis();}      // qui è dove non funziona anche mettendo ++P1
   if(P1>=5){P1=0;}                                     // questo l'ho aggiunto durante i vari tentativi
 }
 if(digitalRead(12)==HIGH)
{
   delay(250);
   ++P1;
     if(P1>=5){P1=0;}
}
 switch(P1)
 {
 case 0:
  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
 break;
 case 1:
  digitalWrite(2,HIGH);
  digitalWrite(3,LOW);
  digitalWrite(4,LOW);
 break;  
 case 2:
  digitalWrite(2,LOW);
  digitalWrite(3,HIGH);
  digitalWrite(4,LOW);
 break;  
 case 3:  
  digitalWrite(2,LOW);
  digitalWrite(3,LOW);
  digitalWrite(4,HIGH);
 break;
 case 4:
  digitalWrite(2,HIGH);
  digitalWrite(3,HIGH);
  digitalWrite(4,HIGH);
 break;
 }
 
 if(digitalRead(11)==HIGH)
{
   delay(250);
   ++PAUT;
     if(PAUT>=2){PAUT=0;}
}
 
 
 
}
           
in pratica i led si accendono in sequenze diverse dai casi che ho messo nello SWITCH.


docsavage

Guarda che noi ti abbiamo aiutato....


te la ricordi la barzelletta del pio uomo che durante una alluvione aspetta di essere salvato da Dio?

Il fiume stava straripando e le acque stavano raggiungendo la casa di Jim. Erano arrivate al portico, dove lui si trovava. Un uomo in barca a remi si avvicinò e lo chiamò: "Salta dentro che ti porto in salvo".
Jim rispose: "No, il mio Dio mi salverà!"
Salì poi di corsa fino al primo piano. Il fiume continuava a salire e raggiunse le finestre del primo piano. Un uomo in un motoscafo si avvicinò e lo chiamò: "Salta dentro che ti porto in salvo".
E Jim di rimando: "No, il mio Dio mi salverà!"
Poi Jim corse sul tetto. Ben presto il fiume lambì il tetto della casa. Jim era seduto sul bordo, con le acque che gli mulinavano attorno ai piedi. Vide un elicottero sorvolarlo e sentì la gente urlare attraverso il megafono: "Afferra la corda e issati, ti porteremo in salvo".
E Jim, di rimando: "No, il mio Dio mi salverà!"
Il fiume continuò a salire e, infine, travolse tutta la casa. Jim annegò.
Un istante dopo, si rese conto di essere al cospetto di Dio. In collera, Jim gli chiese: "Ho riposto la mia fiducia in te. Perché mi hai abbandonato?"
Dio sorrise e rispose: "Non ti ho mai abbandonato. Ho inviato una barca a remi, un motoscafo e un elicottero. Perché non ci sei salito sopra?"


Ecco, qui siamo

la millis te la abbiamo spiegata
di leggere il reference te lo abbiamo detto
di scrivere il codice dentro i tag code, pure
un esempio di millis te lo ho messo anch'io
come organizzare le paline te lo ho detto
come scrivo un programma, ti ho fatto un esempio
di partire col poco, te lo abbiamo detto in varii
di più................ non so

una spazzola scrive e un campo legge
io non sono ne la spazzola ne il campo
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

gpb01

Ricordo a tutti che in conformità al regolamento, punto 7, dovete editare i vostri post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

Resto in attesa delle correzioni nell'intero thread !

Guglielmo
Search is Your friend ... or I am Your enemy !

PaoloP

Guarda i commenti interni al codice.
La millis è implementata male.
Code: [Select]
unsigned long A;
unsigned long B;
unsigned long C;
unsigned long D;
unsigned long on1 = 1000;
unsigned long off1 = 1000;
unsigned long on2 = 2000;
unsigned long off2 = 5000;
int P1 = 0;
int PAUT = 0;

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(12, INPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, INPUT);

  // manca lo stato iniziale dei pin 2,3,4,8,9 e 10.
  // sono HIGH o LOW?

  // perche non aggiungi la seriale per capire cosaa fa il programma?
}

void loop()
{
  if (digitalRead(11) == HIGH) // controlla i collegamenti ed eventualmente metti un pull-donw
  {
    delay(250);       // come debounce bastano 50 millisecondi.
    ++PAUT;           // su singola riga PAUTT++ o ++PAUT è indifferente.
    if (PAUT >= 2) {
      PAUT = 0;
    }
  }

  if (PAUT == 0)
  {
    // dovresti stampare via seriale che sei all'interno di questo if.
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
  }

  if (PAUT == 1)
  {
    // dovresti stampare via seriale che sei all'interno di questo if.
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(12, LOW);    // questo l'ho aggiunto durante i vari tentativi
    // mettere LOW in pin di input non serve

    if (millis() > A + 500) {
      P1 = 1 + P1; // qui è dove non funziona anche mettendo ++P1
    }
    if (millis() > A + 1000) {
      P1 = 1 + P1;  // qui è dove non funziona anche mettendo ++P1
      A = millis();
    }
    if (P1 >= 5) {
      P1 = 0; // questo l'ho aggiunto durante i vari tentativi
    }
  }

  if (digitalRead(12) == HIGH) // controlla i collegamenti ed eventualmente metti un pull-down
  {
    delay(250);
    ++P1;
    if (P1 >= 5) {
      P1 = 0;
    }
  }

  switch (P1)
  {
    // dovresti stampare via seriale il valore di P1
    case 0:
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      break;
    case 1:
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      break;
    case 2:
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      break;
    case 3:
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      break;
    case 4:
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      break;
  }

  // perchè fai il controllo 2 volte?
  if (digitalRead(11) == HIGH)  // controlla i collegamenti ed eventualmente metti un pull-down
  {
    delay(250);
    ++PAUT;
    if (PAUT >= 2) {
      PAUT = 0;
    }
  }
}

Claudio_FF

Quote from: Puso
ho notato che ci sono diversi modi per utilizzarlo quindi sto tentando capire le differenze
Il modo in cui l'hai usato (confrontare direttamente il valore restituito da millis() con qualcosa) soffre del problema dell'overflow.

Tornando al cerchio delle ore è come voler confrontare direttamente l'ora di un orologio (0..11) con un valore ottenuto da un'ora di partenza (facciamo le 8 ) sommato a una durata (facciamo 6 ore). Se l'"ora di arrivo" supera la mezzanotte allora anche tutte le ore comprese tra quella iniziale e la mezzanotte risulteranno matematicamente maggiori (quindi il test millis()>A+n contiene un errore di logica):




Ma comunque, tornando al semaforo iniziale e al pulsante da ascoltare durante le attese, se la funzione millis intanto è "complicata", e fermo restando che il suo uso assieme alla logica del ciclo continuo senza delay è la via più generale per scrivere qualsiasi programma multitasking... un minimultitasking lo si fa anche con dei piccoli delay... ad esempio se il problema è leggere un pulsante durante un'attesa (e oltre ad attendere e leggere il pulsante non c'è bisogno di fare altro... altrimenti saremmo da capo), una soluzione come questa è sicuramente più "semplice":

Code: [Select]
// Attesa circa 40 secondi e campionamento pulsante ogni 0.1s
for(unsigned int t = 0;  t < 400;  t++)
    if(digitalRead(input_pin) == HIGH) break; else delay(100);
Una domanda ben posta è già mezza risposta.

Puso

Intanto GRAZIE  a TUTTIper la pazienza:

 DOCSAVAGE innazitutto sto studiando e sto facendo tesoro di quello che mi avete insegnato, part dal principio che quando mi sino iscritto su questo url,avevo a malapena capito la differenza chedentro le parentesi tonde e quelle e graffe e grazie al vostro aiuto il mio ultimo schetch postato,me lo sono fatto quasi tutto da solo a memoria,ricontrollando tutto ed andando a copiare solo quando non ci saltavo fuori........ed io non sono jim e non credo nelle parabole.

gpb01 non ho capito ne cosa hai detto e neppure se era riferito a me......ti chiedo scusa.

Claudio_FF l'esempio sull'orologio è stato chiarissimo e mi ha fatto comprendere il millis ora  ( se non ho studiato male, posso mettere vari orologi),ma non ora prima voglio capire in quanti modi posso utilizzarlo......non mi preoccupo neppure di azzerarlo per il momento....però grazie è stata un ottima spiegazione


PaoloP ti ringrazio nuovamente.....ho rifatto un nuovo schetch molto più corto riprovando piu volte con tentativi diversi,ma il problema persiste è sempre lo stesso con millis incremeta gli INT fino a 2 e poi torna  0 (incrementarlo a 3....NON CI PENSA PROPRIO).

Premesso che sto utillizzando tinkercad per fare gli schect commento solo i codici che mi danno problemi...i codici inutili sono solo per fare esperienza e per scrivere senza copiare:
Code: [Select]

int P1=0;
unsigned long T1= millis();
unsigned long T2= millis();
unsigned long startime;
int A=0;

void setup() {
 Serial.begin(9600);
 pinMode(2, OUTPUT);
 pinMode(3, INPUT);
 startime = millis();
}

void loop() {
 if(digitalRead(3))
 {
   while(digitalRead(3)){;}
 
  ++P1;++A;Serial.println(A);Serial.println(P1);}
 
 if(P1>=3){P1=0;}
 if(A>=2){A=0;}
 if(A==0){digitalWrite(2,LOW);Serial.println(A);Serial.println(P1);}
 if(A==1){digitalWrite(2,HIGH);Serial.println(A);Serial.println(P1);}
 if(P1==3)
 {
 Serial.println(A);
 if(startime>=T1+500){++A;}
   if(startime>=T2+1000){++A;}}                                           // qui incrementa solo fino a 2 a 3 NO
}


Lo schetc è corretto unico problema l'incremento,,,,poi se magari potessi vedere in serial monitor i dati incolonnati siù colonne diverse sarebbe meglio,ma non ci sono ancora arrivato.


Per il momento Grazie a tutti.

docsavage

PaoloP ti ringrazio nuovamente.....ho rifatto un nuovo schetch molto più corto riprovando piu volte con tentativi diversi,ma il problema persiste è sempre lo stesso con millis incremeta gli INT fino a 2 e poi torna  0 (incrementarlo a 3....NON CI PENSA PROPRIO).

omissis, ma mettendo il tag code
Code: [Select]

  if(A>=2){A=0;}


Lo schetc è corretto unico problema l'incremento,,,,poi se magari potessi vedere in serial monitor i dati incolonnati siù colonne diverse sarebbe meglio,ma non ci sono ancora arrivato.


Lo Scjetch é corretto cosa?
 che non ti incrementa fino a tre perché tu stesso lo castri a due?

la vedi l'unica linea che ti ho citato?
tra l'altre cose scritta tra i tag code, che non è mica difficile, basta volerlo, si vede che qualcuno non vuole...


significa:
se A è maggiore o uguale a due lo riporto a zero

quindi TRE non lo sarà mai, ma non è colpa della millis

è colpa del tuo programma


ripeto, partire dal poco? per fare un solo errore per volta? per fare in fretta a capire e correggere?

si vede che ti da fastidio...........
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Go Up