Pages: 1 [2] 3 4   Go Down
Author Topic: Problemi sul software per un progetto!  (Read 4831 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao scusate il ritardo, ma sono appena tornato dall'università.
il mio intendo era quello di bloccare i 2 sottoprogrammi qualora non ci siano state le condizioni per attivarli,
cioè raggiungere una determinata temperatura.
Per quanto riguarda la lettura della temperatura sull' lcd ci sono riuscito senza problemi, per il resto, da come avete notato un po' tutti, ho fatto un grandissimo casino. Sinceramente avevo pensato che quei 2 sottoprogrammi li avrei potuti attivare semplicemente come attivare un pin (es: accendere un led normale). Quindi....
1)come posso integrare i sottoprogrammi con il programma principale in modo corretto?
2)in molti avete scritto che uso troppi delay(), come potrei sostituirli?
Grazie in anticipo!!!! smiley-red
« Last Edit: December 03, 2012, 01:05:57 pm by acca90 » Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao scusate il ritardo, ma sono appena tornato dall'università.

1)come posso integrare i sottoprogrammi con il programma principale in modo corretto?
2)in molti avete scritto che uso troppi delay(), come potrei sostituirli?
Grazie in anticipo!!!! smiley-red

...io partirei da uno schema generale un po' diverso... ti accontenti di un piccolo programmino assolutamente non testato?
Manca da muovere il servo... vedrai dopo... intanto vendiamo se funzionano i led... non ho l'arduino collegato ne il sensore ne il display quindi te lo scrivo di istinto... bene sarebbe mettere un bel serial.print di tanto in tanto per capire dove sta andando il programma...

Code:

#include <LiquidCrystal.h>
#include <Servo.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Servo mioservo;
float tempC;
int sensore = A1;
int val = 0;
int vecchio_val = 0;
int stato = 0;
int valore;
int fascia;
int angolo = 0;

// ***************occhio qua.... ho messo delle costanti a caso tu metti quelle giuste ****************
const byte tempOttimaMin = 10;
const byte tempOttimaMax = 20;
const byte tempCritica = 30;
const byte ledVerde = 7;
const byte ledGiallo = 8;
const byte ledRosso = 9;

// ***************qui ci sono tre flag che mi indicano in ogni momento lo stato ****************
bool Verde=false;
bool Giallo=false;
bool Rosso=false;




//****************** questa è farina del tuo sacco... aggiungimi anche l'output dei 3 led... *****************
void setup() {
  lcd.begin(16, 2);
  pinMode(13, INPUT);
  mioservo.attach(6);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

//****************** questa è farina del tuo sacco*****************
void lcdLM35() {
  lcd.print( "Temperatura...");
  tempC = analogRead(sensore);
  tempC = (50. * tempC * 100.0)/1024.0;
  lcd.setCursor(0, 1);
  lcd.print(tempC);
  lcd.print(" Celsius ");
  //delay(750);
  lcd.clear();
}


//****************** qui guardo lo stato e accendo e spengo i led *****************
void AggiornaColori(){
 
  if (Verde == true) {
          digitalWrite(ledVerde,HIGH); 
    } else
    {    digitalWrite(ledVerde,LOW); 
  };
   
  if (Giallo == true) {
//** qui devi testare se funziona... l'idea è che interroghi la funzione millis e fai il modulo a 1000 se il resto dell'operazione
// è maggiore di 500 accende il led altrimenti lo spegne... quindi mi aspetto un lampeggio acceso+spento al secondo.
        if ((millis() % 1000) > 500)
        {
             digitalWrite(ledGiallo,HIGH);  }
         else {
            digitalWrite(ledGiallo,LOW);  }
           
    } else
    {    digitalWrite(ledGiallo,LOW);  };
   
  if (Rosso == true) {
        if ((millis() % 1000) > 500){
             digitalWrite(ledRosso,HIGH);  }
         else {
            digitalWrite(ledRosso,LOW);  }
           
    } else
    {    digitalWrite(ledRosso,LOW);  };
 
 
 
  }




void loop() {
   lcdLM35();    //legge la temperatura

   if ((tempC >= tempOttimaMin) && (tempC <= tempOttimaMax))
       { Verde = true;
    } else {
      Verde = false;
    };
 
    if ((tempC > tempOttimaMax) && (tempC <= tempCritica))
       { Giallo = true;
    } else {
      Giallo = false;
    };
   
    if (tempC > tempCritica)
       { Rosso = true;
    } else {
      Rosso = false;
    }; 
 
   AggiornaColori();   
     
}
 
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti....nel mio programma in pratica, non funziona niente...o per meglio dire viene tutto avviato ma senza che io abbia dato l'imput con il pulsante, e per il resto lasciamo perdere.... p.s.
Ogni singolo programma funziona perfettamente.
Rimane il problema di unirli e far attivare il ciclo con il button!!!
Ho fatto alcuni tentativi...ma non riesco a risolvere!!! smiley-sad
« Last Edit: December 04, 2012, 12:37:40 pm by acca90 » Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti....nel mio programma in pratica, non funziona niente...o per meglio dire viene tutto avviato ma senza che io abbia dato l'imput con il pulsante, e per il resto lasciamo perdere....

 be... ma facci capire... ora che cosa stai usando? hai ripensato alla mia struttura di programma?
io il bottone non l'ho proprio considerato ma se hai difficoltà a far partire un programma dopo la pressione di un tasto questo programma ti risulta palesemente complesso.
Mi pare di capire che ti manca il concetto di "top-down" della risoluzione dei problemi.... tu devi sempre puntare a risolvere un problema per volta: prima fai il programma che quando premi un bottone accende il led verde, poi aggiungi che quando accende il led verde fa il display della temperatura, poi fai che disquisisce sulla temperatura il led verde e giallo... e quando fra 2 settimane avrai fatto tutto l'aggeggio con il led ci aggiungi il servo.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Probabilmente è così.
Dal bottone deve partire l' lcd e lm35;
poi a seconda delle temperature vengono attivati sottoprogrammi diversi.
Il fatto è che non ho capito come posso integrarli.
Ho controllato il tuo programma, ma non va!!!
Un mio amico mi ha consigliato di usare i comandi switch/case; oppure if/else.
Tranquillamente riesco a far partire con il button singoli led, ma non riesco per sottoprogrammi!!!
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Probabilmente è così.
Dal bottone deve partire l' lcd e lm35;
poi a seconda delle temperature vengono attivati sottoprogrammi diversi.
Il fatto è che non ho capito come posso integrarli.
Ho controllato il tuo programma, ma non va!!!
Un mio amico mi ha consigliato di usare i comandi switch/case; oppure if/else.
Tranquillamente riesco a far partire con il button singoli led, ma non riesco per sottoprogrammi!!!

si non va per forza... non l'ho testato,non è completo  e devi mettere a posto ingressi ed uscite... ma tu di quel programma dovevi capire il concetto generale del funzionamento... come funzionava in logica per poi implementarlo TE.
il costrutto switch case lo puoi usare ma viene usato per scelte multiple e comunque è sempre sostituibile con il costrutto if then else... nel tuo caso non saprei dove piazzarlo in ogni caso non è che perchè hai una bella istruzione la devi usare per forza.
...il serial... ed il display lcd... ti possono essere utilissime per fare il debug del programma e capire cosa va e cosa non va.

i sottoprogrammi si chiamano "procedure" e sono di fatto delle funzioni che ritornano "void" cioè nulla... togliti dalla testa la chiamata che hai fatto sul tuo programma... non si fa così...e non si può bloccare/sbloccare in automatico con un HIGH o un LOW l'esecuzione ... si fa come ho scritto sul mio codice ed un esempio è la chiamata alla procedura
Code:
lcdLM35();    //legge la temperatura
e basta... tutto al più ci metti un if se è una chiamata condizionata ad una condizione (temperatura entro un certo range per esempio).

La procedura setup è particolare e viene eseguita solo appena acceso l'arduino mentre la procedura loop viene ripetuta all'infinito.
che ruolo ha il tasto? ok lo premo e partono le lucette... e poi cosa succede? lo ripremo e si spegne tutto?
questo potrebbe essere codificato per esempio in un codice loop di questo genere:

sulle var globlali dichiari
bool modoStart=false;    // ---> se true è in start mode se no è stoppato...
e nel loop

tasto = digitalRead(pinTasto);
if (tasto == HIGH) {
     while (tasto ==HIGH) {tasto = digitalRead(pinTasto); };    // interrompe il ciclo loop ed attende il   
                                                                                  //fronte di discesa del tasto   
      modoStart = !modoStart;   //scambia da modo start a stop.     
     };

if (modoStart) fai_Il_Caffe()
else boo fa niente...

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao....ho visto cosa era sbagliato nel programma e l'ho corretto.
Il valore compreso tra i 2 (cioè il led giallo) risponde esattamente alla temperatura.
Anche la temperatura va bene.Quindi penso già di aver fatto un bel passo in avanti, adesso devo solo aggiustare i valori nel miglior modo possibile.
Adesso mi manca una cosa da capire bene:
Come faccio a disattivare il servo e buzzer quando si abbassa la temperatura visto che sono altri 2 processi diversi?
Riesco ad attivarli, ma quando si abbassa la temperatura non si spengono.
« Last Edit: December 05, 2012, 03:55:23 pm by acca90 » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include <Servo.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
float tempC;     
int sensore = A1;
int val = 0;                   
int vecchio_val = 0;           
int stato = 0;
int valore;
int angolo = 0;
Servo mioservo;


const byte tempOttima = 0;
const byte tempOttimaMax = 20;
const byte tempCritica = 25;
const byte ledgreen = 10;
const byte ledyellow = 9;
const byte ledred = 8;

bool green=false;
bool yellow=false;
bool red=false;
bool buzzer=false;
bool servo=false;
 
void setup() {                 
  lcd.begin(16, 2);
  pinMode(13, INPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  mioservo.attach(6);
  pinMode(7, OUTPUT);
}
void loop() {
  lcdlm35();
 
  if ((tempC >= tempOttima) && (tempC <= tempOttimaMax))
  {green = true;}
  else { green = false;};
 
  if ((tempC >tempOttimaMax) && (tempC <= tempCritica))
  {yellow = true; }
  else { yellow = false; };
 
  if (tempC > tempCritica)
  {red = true;}
  else {red = false;}
 
  if (tempC > tempCritica)
  {buzzer = true;}
  else {buzzer = false;}
 
  if (tempC > tempCritica)
  {servo = true;}
  else {servo = false;}
  aggiornacolori();
  }

void lcdlm35() {
  lcd.clear();
  lcd.print( "Temperatura...");
  tempC = analogRead(sensore);
  tempC = (5.0 * tempC * 100.0)/1024.0;
  lcd.setCursor(0, 1);
  lcd.print(tempC);
  lcd.print( (char) 223);
  lcd.print(" Celsius ");
  delay(1500);
  lcd.clear();
}

void aggiornacolori() {
  if (green == true) {
    digitalWrite(ledgreen, HIGH);
  }
  else {
    digitalWrite(ledgreen, LOW);
  };
  if (yellow == true) {
    if(( millis() % 1000) > 500)
    {
      digitalWrite(ledyellow, HIGH);
    }
    else {
      digitalWrite(ledyellow, LOW);
    }
  }
  else {
    digitalWrite(ledyellow, LOW);
  }
  if (red == true) {
    if(( millis() % 1000) > 500) {
      digitalWrite(ledred, HIGH);
    }
    else {
     digitalWrite(ledred, LOW);
    }
  }
  else {
    digitalWrite(ledred, LOW);
  }
  if ( buzzer == true) {
    if((millis()% 1000) < 500) {
      buzzer1();}
  }
   
  if (servo == true) {
    if((millis() % 1000) >500){
    servo1();}
  }
}

void buzzer1() {
  buzz(7, 1000, 500);
  delay(400);
  buzz(7, 2000, 500);
  delay(400);
}

void buzz(int targetPin, long frequency, long length) {
  long delayValue = 100000/frequency/7;
  long numCycles = frequency * length/ 1000;
 
  for (long p=0; p < numCycles; p++) {
    digitalWrite(targetPin, HIGH);
    delayMicroseconds(delayValue);
    digitalWrite(targetPin, LOW);
    delayMicroseconds(delayValue);
  }
}
   
void servo1()
{
  for(angolo = 0; angolo < 180; angolo +=1)
{
mioservo.write(angolo);
delay(20);
}
 for(angolo = 180; angolo >= 1; angolo -=1)
{
 mioservo.write(angolo);
delay(20);
}
}

 

Ecco il codice.
Come posso regolare per bene il servo e il buzzer affinchè si disattivino appena la temperatura scende sotto i 25°?
Inoltre il buzzer non funziona come vorrei:
1)Perchè "suona" ogni tot di tempo e non come se fosse un allarme?
2)Perchè produce una "nota" completa ma semplicemente un minuscolo bip, non intendo come volume, ma come durata del suono, cioè è molto breve...

Grazie e scusatemi ancora!!!!
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22813
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Come posso regolare per bene il servo e il buzzer affinchè si disattivino appena la temperatura scende sotto i 25°?
Sui servo ti aiuterà qualcun altro...

Quote
Inoltre il buzzer non funziona come vorrei:
1)Perchè "suona" ogni tot di tempo e non come se fosse un allarme?
Perché la funzione per emettere il suono la chiami ogni tot, quindi viene suonata la nota ogni tot.

Quote
2)Perchè produce una "nota" completa ma semplicemente un minuscolo bip, non intendo come volume, ma come durata del suono, cioè è molto breve...
Per il motivo di cui sopra. Per far sì che la nota sia emessa sempre, bisogna che ci sia un generatore di onda quadra collegato al buzzer, altrimenti sentirai solo "sputacchi".
Perché non usi la funzione Tone, scusa?
http://arduino.cc/en/Reference/Tone

Logged


Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if (red == true) {
    if(( millis() % 1000) > 500) {
      digitalWrite(ledred, HIGH);
    }
    else {
     digitalWrite(ledred, LOW);
    }
  }
  else {
    digitalWrite(ledred, LOW);
  }
  if ( buzzer == true) {
    if((millis()% 1000) < 500) {
      buzzer1();}
  }
 


vedi il codice sopra? il red è il mio if... il buzzer è il tuo...se il boolean "buzzer"  è falso tu devi spegnerlo...ti manca il ramo else... addirittura potresti buttar via il tuo lavoro ed integrare il buzzer nel mio if red... fare tipo una cosa così:

Code:
if (red == true) {
    tone(pin, 1000);
    if(( millis() % 1000) > 500) {
      digitalWrite(ledred, HIGH);
    }
    else {
     digitalWrite(ledred, LOW);
    }
  }
  else {
    noTone(pin);
    digitalWrite(ledred, LOW);
  }

...forse poi spostando il tone dopo il digitalWrite High e mettendone un tone ad altra frequenza dopo il digitalwrite low potresti ottenere un bitonale simpatico.

...passiamo al servo?
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi dà lo stesso problema di prima...anche cambiando le impostazioni!!!
Dà sempre quella specie di "sputo"  smiley-cry
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22813
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi dà lo stesso problema di prima...anche cambiando le impostazioni!!!
Dà sempre quella specie di "sputo"  smiley-cry
Ma hai provato ad usare la funzione Tone? Con la Tone NON puoi avere lo sputacchìo perché la funzione genera una nota con una determinata frequenza usando un timer del microcontrollore, quindi senza i problemi che ti avevo descritto del tuo programma.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti!!!
Per il buzzer vorrei usare questo processo!!!
Code:
void setup() {
  pinMode(7, OUTPUT);
}

void loop() {
  buzz(7, 1000, 500); // emissione suono a 1 KHz
  delay(500);
  buzz(7, 2000, 500); // emissione suono a 2 KHz
  delay(500);
  }


void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/7;
  long numCycles = frequency * length/ 1000;
 
  for (long p=0; p < numCycles; p++){
    digitalWrite(targetPin ,HIGH);
    delayMicroseconds(delayValue);
    digitalWrite(targetPin ,LOW);
    delayMicroseconds(delayValue);
  }
}

//cercare comando per alzare volume!!!

Come faccio ad unirlo nel modo corretto?
Ricordo che ancora mi manca il servo!!! smiley-sad
Sinceramente non ho la più pallida idea di come impostarli per far si che una volta che si abbassa la temperatura si disattivino(servo e buzzer)!!!


p.s.
Questo processo funziona esattamente come voglio!!!
« Last Edit: December 07, 2012, 01:13:29 pm by acca90 » Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma la funzione tone cosa ti ha fatto di male? fa esattamente quello che vuoi... anche il doppio suono se lo applichi esattamente come ti ho detto di fare sopra... non blocca il processo con questi %Péç°ç di delay che ti stanno tanto simpatici e che ti bloccano aggiornamento temperatura e blink dei led e ti manderanno sicuramente scemo con il servo... che cosa vuoi di più?

nel mio ciclo originale mi sembra che quando tornava giù la temperatura il ciclo percorreva l'else e metteva il red ed il jellow a false... spegnendo tutto...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 332
Posts: 22813
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Difatti non capisco neanch'io.
Affinché quella funzione... funzioni, devi chiamarla continuamente. Cosa che non puoi fare visto appunto tutti i blocchi causati dalle varie delay.
Logged


Pages: 1 [2] 3 4   Go Up
Jump to: