Riduzione software

Ciao a tutti! Premettendo di essere alle prime armi con arduino, lo scorso anno ho realizzato un progetto di una caldaia a pellet funzionante come tesina di maturità. Ora vorrei "ridurre" un po' il software poiché sicuramente è possibile, per questo mi rivolgo a voi del forum molto più esperti di me.
Di seguito trovate il codice, è una sorta di polling, non voletemi troppo male :slight_smile:
Mi piacerebbe anche aggiungere un potenziometro per variare il tempo della coclea, ma penso di potermela cavare su questo! Grazie anticipatamente
Federico.

1.// Pin A0 sensore fiamma valore sale se c'è luce
2.// Pin 5 resistenza
3.//Pin 4 ventola
4.//Pin 3 coclea
5.int res = 5; // Pin D5 resistenza
6.int ventola = 4;
7.int cocl =3;
8.int fiamm= A0;
9.int temp= A1;
11.int tempmin = 50;
12.int tempmax = 65;
13.float vref = 1.1;
14.int nread = 10;
15.int ledgreen = 6; //led verde per accensione avvenuta
16.int ledblue = 7; //led blue per raggiunto temperatura
17.int ledred = 8; // led rosso per blocco
18.// Setup del sistema dove si impostano le porte di IN/OUT
19.void setup() { 
20.  pinMode (fiamm ,INPUT);
21. pinMode (temp , INPUT);
22. pinMode (senspell , INPUT); 
23. analogReference( INTERNAL );
24. pinMode (ledred ,OUTPUT);
25.Serial.begin(9600);
26.  //seleziono uscite e ingressi su portd (pin da 0 a 7) 
27. DDRD = DDRD | B11111100}
28.// Di qui in avanti inizia il ciclo loop che viene eseguito continuamente.                                           
        E’ il contenitore principale del programma.

29.void loop() {
30.peppo: float somma = 0.0;
31.for (int i=0 ;i< nread ; i++){
32.float val = analogRead( A1 );              // legge il dato della tensione sul 33.pin 'LM35_pin'
34.  float temp = (( 100.0 *  vref * val ) / 1024.0) ;   // lo converte in °C
35.  somma += temp;}
36.  float media = somma / nread;
37.  Serial.println ("media="); //stampa sullo schermo del pc il valore della media della temperatura.
38.  Serial.println (media);
  
39.pippa:  if (media < tempmin) {
40.//se la temperatura minore di 60, esegue
41.  //
42.PORTD = B01010000;  //parte solo la ventola
43.delay(60000);   // accesa un minuto
44.PORTD = B01011000; //accendo coclea
45. delay (50000);  //accesa 50 secondi
46.  int fiamm = analogRead (A0);
47. Serial.println ("fiamma=");
48.  Serial.println (fiamm);}
49.pippo: while (fiamm < 100 ){  //esegue istruzioni nelle parentesi graffe 
50.se il sensore fiamma è off,quando è on esce, CICLO ACCENSIONE
51.   PORTD = B01110000;    
52. delay(10000); 
53.fiamm= analogRead (A0);
54.  Serial.println ("fiamma="); //stampa sul monitor del pc il valore della      	fiamma
55. Serial.println (fiamm);     } 
56.  PORTD = B01010000;
57.delay (70000);    
58.pippa1:  while (fiamm> 30){    //CICLO FIAMMA NORMALE
59.   //se arrivato a questo punto la fiamma è ON quindi spegno resistenza
60. PORTD = B01011000; //Ciclo di istruzioni se la fiamma è 
61.accesa,carico pellet e lascio acceso il resto
62.  delay (20000); //tempo della coclea 
63. PORTD = B01010000; //spengo pellet e lascio ventola bruciare
64. delay (40000);     //lascio spenta coclea 40 secondi
65. fiamm = analogRead (A0); //ricontrollo sensore fiamma
66. somma=0.0;
67.for (int k=0;k<nread;k++){
68.   float val = analogRead(A1);              // legge il dato della tensione sul 
69.pin 'LM35_pin'
70.  temp = (( 100.0 *  vref * val ) / 1024.0) + 5;   // lo converte in °C
71. somma += temp;}
72.  media = somma/nread;
73.  Serial.println ("media=");
74. Serial.println (media);
75. if (media > tempmax) {
76.  PORTD = B10010000;
77.delay (120000);
78.  PORTD = B10000000;
79. goto peppo;} 
80. goto pippa1;  } 
81. Serial.println ("BLOCCO FIAMMA OFF");
82. digitalWrite (ledred,HIGH);
83. PORTD = B00000000;
83.pippo1:  goto pippo1;            //sto fermo se sensore fiamma OFF }}

Primo consiglio fai sparire i goto.

Dovresti anche eliminare i numeri di riga. :confused:

Più che da ridurre è da riscrivere di sana pianta.
Dimentica i goto e la programmazione procedurale e passa alla programmazione strutturata o a quella ad oggetti.

Inoltre il codice non compila: manca la descrizione di una variabile, alcuni punti e virgola e non torna il conteggio della parentesi. Alcuni label no sono richiamate e sono apparentemente inutili.
Cerca di evitare i delay() e usa la funzione millis() per temporizzare gli eventi.
Descrivi cosa deve fare il programma, creati un diagramma di flusso e studi cosa sono le macchine a stati.

Chiaro ragazzi, io "arrivo" dalla programmazione assembler o C++...questo è un altro mondo, ma sono comunque soddisfatto del mio lavoro.
Il flow chart c'è ed è completo, c'è documentazione riguardo alla macchina a stati?
Di seguito posto il codice che funziona

// Pin A0 sensore fiamma valore sale se c'è luce
// Pin 5 resistenza
//Pin 4 ventola
//Pin 3 coclea
int res = 5;
int ventola = 4;
int cocl =3;
int fiamm= A0;
int temp= A1;
int senspell = A2;
int tempmin = 50;
int tempmax = 65;
float vref = 1.1;
int nread = 10;
int ledgreen = 6; //led verde per accensione avvenuta
int ledblue = 7; //led blue per raggiunto temp
int ledred = 8; // led rosso per blocco

// the setup routine runs once when you press reset:
void setup() { 
   pinMode (fiamm ,INPUT);
   pinMode (temp , INPUT);
   pinMode (senspell , INPUT); 
   analogReference( INTERNAL );
   pinMode (ledred ,OUTPUT);
   Serial.begin(9600);
  
  //seleziono uscite e ingressi su portd (pin da 0 a 7) 
 DDRD = DDRD | B11111100;
}
// the loop routine runs over and over again forever:
void loop() {
peppo: 
  float somma = 0.0;
  for (int i=0 ;i< nread ; i++){
  float val = analogRead( A1 );              // legge il dato della tensione sul pin 'LM35_pin'
   float temp = (( 100.0 *  vref * val ) / 1024.0) ;   // lo converte in °C
   somma += temp;}
  float media = somma / nread;
  Serial.println ("media=");
  Serial.println (media);
  
pippa:  if (media < tempmin) {
  //se il sensore dei pellet è basso e la temperatura minore di 60, esegue dopo ,ricorda mettere graffe.
   PORTD = B01010000;  //parte solo ventola
  delay(60000);   // accesa un minuto
  PORTD = B01011000; //accendo coclea
  delay (25000);  //25 secondi
  int fiamm = analogRead (A0);
  Serial.println ("fiamma=");
  Serial.println (fiamm);
pippo: while (fiamm < 100 ){  //esegue istruzioni nelle parentesi graffe se il sensore fiamma è off,quando è on esce, CICLO ACCENSIONE
 
   PORTD = B01110000;    
  delay(10000); 
  fiamm= analogRead (A0);
  Serial.println ("fiamma=");
  Serial.println (fiamm);     } 
  PORTD = B01010000;
delay (80000);    
pippa1:  while (fiamm> 30){    //CICLO FIAMMA NORMALE
                         //se arrivato a questo punto la fiamma è ON quindi spegno resistenza
 PORTD = B01011000; //Ciclo di istruzioni se la fiamma è accesa,carico pellet.lascio acceso il resto
  delay (3500); //tempo della coclea da calibrare
 PORTD = B01010000; //spengo pellet e lascio ventola bruciare
 delay (26000);     //lascio spenta coclea 90 secondi
  fiamm = analogRead (A0); //ricontrollo sensore fiamma
  somma=0.0;
  for (int k=0;k<nread;k++){
   float val = analogRead(A1);              // legge il dato della tensione sul pin 'LM35_pin'
    temp = (( 100.0 *  vref * val ) / 1024.0) + 5;   // lo converte in °C
   somma += temp;}
  media = somma/nread;
  Serial.println ("media=");
  Serial.println (media);
  if (media > tempmax) {
    PORTD = B10010000;
    delay (200000);
    PORTD = B10000000;
    goto peppo;} 
  goto pippa1;  
} 
 Serial.println ("BLOCCO FIAMMA OFF");
 digitalWrite (ledred,HIGH);
 PORTD = B00000000;
pippo1:  goto pippo1;            //sto fermo se sensore fiamma OFF
} PORTD = B10000000; }

Se cerchi su google "macchina a stati arduino" trovi tanti risultati interessanti.
Arduino si programma in C o C++ e mette a disposizione librerie per il controllo delle periferiche interne, quindi non è un altro mondo, anzi ti dovresti trovare bene.
Dovresti giusto dimenticare quel pò di Visual Basic che traspare dalla lettura dello sketch. :wink:

Fedeasche:
Chiaro ragazzi, io "arrivo" dalla programmazione assembler o C++...questo è un altro mondo

Puoi anche optare per la programmazione diretta in assembly degli AVR. Comunque, veramente il goto lascialo ai jumper dell'assembly. In C non è mai necessario, è stato dimostrato, e poi fa cadere di molto la valutazione di te come programmatore, nonché la qualità del tuo programma.

Ma dimenticalo anche in Visual Basic! :confused:

Dai ragazzi non trattatemi troppo male, sto cercando di imparare! :slight_smile: ho riscritto tutto usando stati finiti, ed il loop si è ridotto a poche cose...ma proprio non so come liberarmi di quei goto :disappointed_relieved: help! :slight_smile:

void loop() {
controllotemperatura:  controllotemperatura ();
                         if (media < tempmin) {
                         digitalWrite (ledblue,LOW);
                         digitalWrite (ledgreen,HIGH);
                         puliziainizio ();
                         cicloaccensione();
cicloriscaldamento:      cicloriscaldamento();
                         controllofiamma ();
                         controllotemperatura ();
                         if (media > tempmax) {
                             digitalWrite (ledgreen, LOW);
                             digitalWrite (ledblue,HIGH) ;
                             funzionespegnimento();
                             goto controllotemperatura ;}
                         goto cicloriscaldamento ;
       
}         
           PORTD = B10010000;
           delay (200000);
           PORTD = B10000000;
           goto controllotemperatura ;
}

Nessuno ti tratta male, ma sarebbe ora di abbandonare il VB6, è un linguaggio morto e sepolto. E poi qui si parla di C un paio di gradini più in alto :grinning:
Mai sentito parlare del ciclo while?

E se capire il livello di considerazione del goto => qui

Ahahaha ma scherzo naturalmente!
I while già li uso in altre parti del listato, effettivamente dovrei riuscire forse :slight_smile:

Sono proprio i cicli while che permettono di far a meno dei goto.

Cavoli ragazzi ho un problema! Ho riscritto tutto il programma e ho dei problemi con il controllo della temperatura.. Mi spiego meglio, nel "main" ho necessità di gestire la variabile "temp" della temperatura appunto..e ho creato una scheda con un sottoprogramma che si occupa appunto di acquisire i dati della temperatura.. Il problema è che la variabile nel main "temp" non viene aggiornata col valore reale e resta sempre a 0..in pratica non riesco a far passare i dati dalla subroutine al main..

Senza vedere il codice dubito che chiunque possa dirti granché...

ciao

Da quello che vedo nel tuo codice (?) direi che la variabile "temp" non è una variabile globale.

Devi dichiararla prima del void setup()

Ma potre anche aver visto male :grin:

No, aspetta.... l'hai dichiarata anche dentro l'altro sottoprogramma. Non si può...

Forse è meglio se posti il codice...

ciao
pippo72

Diventa difficile postare il codice perché è diviso tra tante schede (o c'è un medoto?)
Se non la dichiarò nel main mi da un errore di compilazione in quanto quando arriva all' if non riconosce la variabile media appunto..nella subroutine è dichiarata...se la metto prima del set-up ovvero come globale si estende anche ai sottoprogrammi?

ciao

Una variabile per essere globale deve essere dichiarata prima del void setup().
Attenzione però: se dichiari una variabile all'interno si una funzione (subroutine) questa è una variabile locale anche se ha lo stesso nome di una variabile globale.
Quindi tu hai una variabile "temp" che ha una visibilità globale ma all'interno della tua funzione hai un'altra variabile "temp" che è però locale.

All'interno della funzione non dichiarare "temp" ma usala semplicemente.

ciao
pippo72