Go Down

Topic: due lm35 comandano un servomotore (Read 1 time) previous topic - next topic

Patrick_M

... ancora più semplice dall'IDE Arduino..

1) premere Ctrl + T (per formattare il tutto) oppure dal menu strumenti scegliere formattazione automatica

2) premere Ctrl+maiuscolo + C oppure dal menu modifica selezionare copia per il forum

nel post di risposta fasr Ctrl + V o click con tasto destro e scegliere incolla e i tag ci sono già :)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Cantatore74


Cantatore74

Di solito, al fine di non ripetere la scrittura di parti di codice già definite, si usa scrivere il codice da ripetere all'interno di una funzione richiamabile più volte a piacere nel loop, da dentro un'altra funzione oppure sia nell'uno che nell'altro caso contemporaneamente. Non ha importanza quante volte chiami la funzione e dove lo fai. Se vuoi che il comando che hai dato perduri fra una chiamata della funzione e l'altra, nella funzione puoi dichiarare di tipo "static" la variabile che memorizza il comando che fornisci alla tua uscita. In questo modo, ad ogni chiamata della funzione, la variabile "static" manterrà il valore che aveva assunto nella chiamata precedente e di conseguenza anche la tua uscita il cui stato è funzione di tale variabile.
Salve, per usare questo comando c'è un programmino? Non mi è molto chiaro. Avevo fatto delle prove ma credo di incasinarmi, non trovo degli esempi per i riferimenti.

Cantatore74

Nel frattempo vorrei chiedere quando si carica uno sketch su Arduino questo rimane in memoria, ma quando si applicano delle modifiche cambiando resistenze ecc. e collego il cavo usb per caricare un nuovo sketch, questo crea dei cortocircuiti? Perchè avendo in memoria il vecchio sketch dà segnali in modo sbagliato al nuovo progetto giusto? Come si resetta Arduino?

Patrick_M

#19
Jun 22, 2018, 09:13 pm Last Edit: Jun 22, 2018, 09:14 pm by Patrick_M
come dice il buon Guglielmo (ovviamente non solo lui :D )
gli carichi il buon vecchio blink (che trovi negli esempi) così lo rimetti com'era quando l'hai comprato ;)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)


gpb01

Sarebbe che apri gli esempi dell'IDE, prendi il Blink (che è quello che viene caricato quando Arduino ti viene venduto) e ci carichi quello.

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

Cantatore74

Ecco finalmente trovato. Grazie.
Non ho ancora potuto risolvere il problema di ricopiare le parti di comando quando cambio il menù, spero che i troppi comandi non mi occupino troppa memoria ad arduino mega.

krypton18

#23
Jun 24, 2018, 11:44 pm Last Edit: Jun 24, 2018, 11:56 pm by krypton18
Salve, per usare questo comando c'è un programmino? Non mi è molto chiaro. Avevo fatto delle prove ma credo di incasinarmi, non trovo degli esempi per i riferimenti.
Esempio di come usare una variabile static in un generico programma per PC:
(con piccole modifiche funziona anche su Arduino)

Code: [Select]

#include <stdio.h>

int funzione(int); /*dichiarazione di funzione (o prototipo)*/

  int main(void)
  {

int ingresso, uscita;
 
  while(1) { //ciclo infinito


ingresso = rand(); //assegno valore casuale alla variabile ingresso

printf("Valore attuale variabile di ingresso: %i \n", ingresso);

uscita = funzione(ingresso) - 1; //assegno ad uscita il risultato della funzione decrementato di 1


printf("Valore attuale variabile di uscita (ingresso - 1): %i \n\n", uscita);

getch(); //premi ENTER per continuare l'esecuzione del programa

}
    return 0;
}

int funzione (int var_in) /* definizione della funzione */
{
static int var_stat = 0;

int var_non_stat = 0;

printf("Valore precedente salvato nella variabile statica var_stat: %i \n", var_stat);

printf("Valore della variabile non statica var_non_stat: %i \n", var_non_stat);

var_stat = var_in;

var_non_stat = var_non_stat;

return var_in;

}


E' un programma del tutto senza senso fatto per PC, serve solo per farti capire come si comporta una variabile static dentro una funzione. La funzione replica in uscita il suo parametro di ingresso, non effettua alcuna elaborazione. Quindi se avessi scritto "uscita = ingresso - 1;" il risultato dell'output sarebbe stato il medesimo. Lo ripeto, è un programma campato per aria in 5 minuti a scopo didattico.

Questo è come si presenta l'output del programma:

Quote
Valore attuale variabile di ingresso: 41
Valore precedente salvato nella variabile statica var_stat: 0
Valore della variabile non statica var_non_stat: 0
Valore attuale variabile di uscita (ingresso - 1): 40

Valore attuale variabile di ingresso: 18467
Valore precedente salvato nella variabile statica var_stat: 41
Valore della variabile non statica var_non_stat: 0
Valore attuale variabile di uscita (ingresso - 1): 18466

Valore attuale variabile di ingresso: 6334
Valore precedente salvato nella variabile statica var_stat: 18467
Valore della variabile non statica var_non_stat: 0
Valore attuale variabile di uscita (ingresso - 1): 6333

Valore attuale variabile di ingresso: 26500
Valore precedente salvato nella variabile statica var_stat: 6334
Valore della variabile non statica var_non_stat: 0
Valore attuale variabile di uscita (ingresso - 1): 26499
Come puoi notare la variabile statica, prima di essere sovrascritta, mantiene il valore che le era stato assegnato ad ogni precedente chiamata.

Cantatore74

Salve, scusatemi ho dovuto sospendere il tutto e adesso riprendo il progetto.

Il programma l'ho visto e rivisto, purtroppo non è ancora per il mio livello di conoscenza, inoltre è un programma per pc da fare qualche piccola modifica, mi complico ancora di più.

Ti ringrazio krypton18 comunque stò provando a ricopiare i frammenti di comandi che mi occorrono e poi vediamo in seguito cosa esce.

Nel frattempo non riesco a capire perchè una posizione del menù che era completa adesso  noto che non funziona più niente.
La funzione era di rilevare il valore dei due lm35 e quando entrambi scendono ad una soglia di 22°C deve aprire la botola e scrivere aperta/chiusa.
Nei primi tentativi stranamente ho bruciato il servomotore, adesso con il nuovo non funziona. Ho provato con un programma specifico solo per il servomotore, ed è tutto ok, ho rivisto il programma ed è tutto ok (apparentemente), nel senso che non vorrei aver messo troppe cose che danno queste anomalie o per colpa di qualche parentesi. Inoltre quando i valori di entrambi i sensori scendevano al di sotto di 22°C solo in quel caso deve visualizzare chiusa, invece vede solo il valore di un sensore.
In più ad uso sperimentale mi è venuto l'idea di aggiungere un beep generato da un buzzer nella fase di chiusura per accorgermi quando stà funzionando il sistema e se è funzionante, ma questo beep nel loop lo ripete in continuo. Qualche esempio che ho trovato in giro non mi ha portato al risultato che desideravo.

Nonostante numerosi problemi che ho trovato una buona parte sono riuscito a risolvere un'altro che non riesco a capire è perchè il menù composto da diversi (case) che arrivano fino a 15, tra il 9 e il 10 non compare nulla e devo premere il pulsante 4 o 5 volte per visualizzare il 10?   

Cantatore74

#25
Oct 16, 2018, 09:53 pm Last Edit: Oct 16, 2018, 09:55 pm by Cantatore74
Code: [Select]

void controlBotola() {

 reading = analogRead(sensorPin);
 int celsius = reading / 2;
 lcd.setCursor(0, 0);
 lcd.print("Botola(22C)In");
 lcd.setCursor(10, 1);
 lcd.print("Out");
 lcd.setCursor(14, 0);
 lcd.print(celsius, DEC);
 delay (2000);
 reading = analogRead(sensorPin2);
 int celsius2 = reading / 2;
 lcd.setCursor(14, 1);
 lcd.print(celsius2, DEC);
 delay (2000);

 if (celsius && celsius2 >= baseline_Temp) {

   lcd.setCursor(0, 1);
   lcd.print("aperta");
   digitalWrite (LampGreen3, HIGH);
   digitalWrite (LampRed, LOW);
   //alarm();

   for (pos = 0; pos <= 180; pos += 1) // goes from 0 degrees to 180 degrees
   {                                   // in steps of 1 degree
     myservo.write(pos);               // tell servo to go to position in variable 'pos'
     delay(15);                        // waits 15ms for the servo to reach the position
   }

   //myservo.write(180);
   //delay(15);
 }
 else {


   lcd.setCursor(0, 1);
   lcd.print("chiusa");
   digitalWrite (LampGreen3, LOW);
   digitalWrite (LampRed, HIGH);

   for (pos = 180; pos >= 0; pos -= 1)    // goes from 180 degrees to 0 degrees
   {
     myservo.write(pos);                  // tell servo to go to position in variable 'pos'
     delay(15);                           // waits 15ms for the servo to reach the position
   }

   //myservo.write(0);
   //delay(15);

   for (i = 0; i < 350; i++) // definisce la durata del primo suono (350 cicli da 2 millisecondi).
   {
     digitalWrite(22, HIGH); // attiva il suono
     digitalWrite(LampRed, HIGH); // accende il led
     delay(1); // attende 1 millisecondo. Di fatto ripete il suono ogni 2 millisecondi e
     // quindi con una frequenza di 500 ripetizioni al secondo
     digitalWrite(22, LOW); // disattiva il suono
     delay(1); // attende 1 millisecondo e riparte dall'istruzione for (350 ripetizioni)
   }
   delay (50); // attende 50 millisecondi prima di lanciare il secondo ciclo di suoni
   for (i = 0; i < 150; i++) // definisce la durata del secondo suono (150 cicli da 4 millisecondi)
   {
     digitalWrite(22, HIGH); // attiva il suono
     digitalWrite(LampRed, HIGH);
     delay(2); // attende 2 millisecondi (ripete il suono ogni 4 millisecondi e quindi
     // 250 volte al secondo)
     digitalWrite(22, LOW); // spegne il suono
     delay(2); // attende 2 millisecondi e ripete il ciclo per 150 volte
   }
 }

Patrick_M

per cominciare osserva questi
Code: [Select]

reading = analogRead(sensorPin);
 int celsius = reading / 2;


il risultato di analogRead è un numero che va da 0 (zero) a 255
dopodichè assegni la metà del valore letto alla variabile celsius.... sei sicuro che quelli siano gradi?

secondo
quando leggi in analogico 2 differenti pin devi fare una lettura fasulla in mezzo quindi devi modificare lle letture così
Code: [Select]

reading = analogRead(sensorPin); // prima lettura da buttare
delay(5);                 // gli diamo 5 millisecondi di tempo
reading = analogRead(sensorPin); // seconda lettura buona
 int celsius = reading / 2;
...
...

reading = analogRead(sensorPin2);  // prima lettura da scartare
delay (5);                 // gli diamo i soliti 5 millis
reading = analogRead(sensorPin2);  // seconda lettura buona
 int celsius2 = reading / 2;


terzo
Code: [Select]

 if (celsius && celsius2 >= baseline_Temp) {


come lo tradurresti questo if?
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Cantatore74

Per analogRead ho fatto copia e incolla da alcuni esempi.

Per quanto riguarda l'if... sono andato un pò a tentativi, ho visto dei comandi ed ho pensato che questo era quello che si avvicina al mio caso. Già al fatto che non mi dà un errore, si accendono e spengono i 2 led e funziona il buzzer sembrerebbe che sono sulla buona via.
 

In pratica quello che voglio realizzare è questo: quando i valori 1 e 2 sono maggiori e uguali al valore baseline (confort 22°C) apri botola altrimenti chiudi.

La cosa strana è che il servomotore in un arco di tempo ha funzionato. Non vorrei che a seguito delle modifiche e gli spostamenti in tutto lo scheck per renderlo più ordinato mi sono incasinato da qualche parte.

Il servomotore all'avvio va in posizione 0 poi tace.


Patrick_M

per l'if la versione corretta è:
Code: [Select]

if (celsius >= baseline_Temp && celsius2 >= baseline_Temp) {



per il resto.... serve il programma completo per capire cosa non va ;)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Cantatore74

In quell'if solo il celsius e il baseline potevo mettere e nient'altro quindi il concetto era giusto, era il modo della compilazione sbagliato, comunque sono contento di esserci andato vicino.

Per il programma come faccio a postarvelo? Si tratta di 1200 righe di comando, e non l'ho ancora finito.
Il menù ha 15 posizioni che però in ogni singola posizione deve fare altre cose non necessariamente visibili.
Ad esempio se stò visualizzando l'ora nel frattempo deve controllare la temperatura e muovere i servomotori per le botole e avvisarmi in caso di fiamma. Ma prima stà da risolvere i problemi principali prima di andare ad aggiungere altri comandi nel void, altrimenti non si finisce più con la macedonia.

Stà da vedere il servomotore che non ho ancora capito il perchè non funziona, poi devo rivedere lo scheck dell'orologio ds3231 che fa come il servomotore, in pratica quando ho copiato lo scheck originale (funzionante e più adatto alle mie esigenze) andava bene, mentre nel menù non riesco nè ad impostare l'ora e nemmeno a tenere in memoria quando tolgo la tensione. Dovrei trovare altri programmi e provarli per il ds3231.

Gli altri programmi non mi hanno dato grossi problemi, tipo rivel.Gas, fiamma, tester resistenze e tensioni, mentre infine rimane il problema dello spazio che si è creato nel menù tra la posizione 9 e 10 dove non compare nessuna scritta.

Tutti i sensori hanno una posizione del menù dedicata.
Adesso mi sta venendo anche l'idea di aggiungere la 16a posizione dedicata al servomotore per il comando manuale della botola.


Go Up