Pages: [1] 2 3 4   Go Down
Author Topic: Problemi sul software per un progetto!  (Read 4997 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 a tutti, essendo un principiante ed avendo tempi ristretti, mi trovo nella situazione di chiedere un vostro aiuto...
Devo fare un progetto utile ad un esame per l'università, ma mi sono bloccato poichè non riesco a capire l'errore nel programma  smiley-confuse.
I componenti che devo usare sono:
Arduino uno;
sensore termico LM35;
un microservo;
un LCD 16x2;
un pulsantino (per l'accensione e spegnimento);
un buzzer;
3 led(rosso, giallo e verde).
Il mio scopo è quello di avere un termostato in cui la temperatura viene visualizzata sull' LCD;
a determinate temperature vengono attivati differenti sottoprogrammi:
temperatura ottimale: led verde;
temperatura critica: led giallo ad intermittenza;
superata la temperatura critica: led rosso ad intermittenza, servo e buzzer.
Ecco il programma.

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

#define BUTTON 1                   
#define LM35 2
#define D4 3
#define D5 4
#define D6 5
#define D7 6
#define RS 7
#define EN 8
#define SERVO 9
#define BUZZER 10
#define LEDRED 11
#define LEDYELLOW 12
#define LEDGREEN 13


float vref = 1.1;
LiquidCrystal lcd( D4, D5, D6, D7, RS, EN );
Servo myservo;

int val = 0;                       
int vecchio_val = 0;               
int stato = 0;                     
int pos = 0;
int fascia;
int valore;

void setup() {
  pinMode( BUTTON, INPUT);
  pinMode( LM35, INPUT );
  pinMode( LEDGREEN, OUTPUT);
  analogReference( INTERNAL );
  analogRead( LM35 );
  lcd.begin( 2, 16 );
  pinMode( LEDYELLOW, OUTPUT );
  pinMode( LEDRED, OUTPUT );
  pinMode( BUZZER, OUTPUT );
  myservo.attach ( 9 );
  }
 
void loop(void) {
  val = digitalRead(BUTTON);
 
  if ((val = HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(35);
  }
  vecchio_val = val;
 
  if (stato == 1) {
    lcdLM35(), HIGH;
    segnalatoriLM35(), HIGH;
  }
  else {
    lcdLM35(), LOW;
    segnalatoriLM35(), LOW;
  }
 
 
  void lcdLM35()
  {
    float temp = readTemp()); 
    sendTempToLCD( temp );   
  }


float readTemp()
{
  float temp = 0.0;       
  int val = 0;           
  int nread = 5;         
  float somma = 0.0;     
  for (int i=0; i<nread; i++)
  {
    val = analogRead( LM35 );               
    temp = ( 100.0 *  vref * val ) / 1024.0;   
    somma += temp;                               
  }   
  return ( somma / nread );                     
}


void sendTempToLCD( float temp )
{
  lcd.clear();               
  lcd.setCursor( 0, 0 );     
  lcd.print( "Temperatura di: ");
  lcd.setCursor( 0, 1 );     
  lcd.print( temp );         
  lcd.print( ' ' );         
  lcd.print( (char) 223 );   
  lcd.print( 'C' );
  delay( 250 );
}


void segnalatoriLM35()
{
valore=analogRead(LM35);     
fascia=map(valore, 0, 1023, 0, 3);
if (fascia==0) fascia=1;       
spegni();
digitalWrite(14-fascia, HIGH); 
delay(500);                     
}

void spegni() {
digitalWrite(LEDGREEN,LOW);
digitalWrite(ledyellow(),LOW);
digitalWrite(allarme(),LOW);
}

void ledyellow() {
  digitalWrite( LEDYELLOW, HIGH);
  delay(1000);
  digitalWrite( LEDYELLOW, LOW);
  delay(1000);
}

void allarme() {
  digitalWrite({ledred()}, HIGH);
  digitalWrite({servo()}, HIGH);
  digitalWrite({buzzer()}, HIGH);
}

void ledred() {
  digitalWrite(LEDRED, HIGH);
  delay(500);
  digitalWrite(LEDRED, LOW);
  delay(500);
}

void servo() {
  for(pos = 0; pos < 180; pos +=1)
  {
    myservo.write(pos);
    delay(15);
  }
  for(pos = 180 ;pos >= 1; pos -=1)
  {
  myservo.write(pos);
  delay(15);
  } 
}

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

P.S.
nelle temperature deve essere presente un range,
il led verde deve essere acceso tra 0 e 20°C;
il led giallo invece tra 21°C e 30°C;
il led rosso, buzzer e microservo, infine, dai 31°C in poi.

Grazie in anticipo per l'aiuto  smiley-surprise
Logged

Torino
Offline Offline
God Member
*****
Karma: 3
Posts: 766
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma qual'è il problema di fondo?
Dov'è che ti sei bloccato,cosa non capisci?
Se tu esponessi più informazioni sarebbe più semplice poterti aiutare  smiley
Logged

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

Quando vado a fare la verifica mi da degli errori nei sottoprogrammi...e non riesco a capire il motivo.
Visto che non riesco a finire il programma, non posso nemmeno provare se funziona come io voglio.
precisamente questo:

progetto.ino: In function 'void loop()':
progetto:63: error: a function-definition is not allowed here before '{' token
progetto:70: error: a function-definition is not allowed here before '{' token
progetto:165: error: expected `}' at end of input
Logged

Torino
Offline Offline
God Member
*****
Karma: 3
Posts: 766
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ti manca semplicemente una parentesi graffa di chiusura del loop
Code:
void loop(void) {
  val = digitalRead(BUTTON);
 
  if ((val = HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(35);
  }
  vecchio_val = val;
 
  if (stato == 1) {
    lcdLM35(), HIGH;
    segnalatoriLM35(), HIGH;
  }
  else {
    lcdLM35(), LOW;
    segnalatoriLM35(), LOW;
  }
} LA DEVI INSERIRE QUI
 
Logged

Tuscany
Offline Offline
Edison Member
*
Karma: 77
Posts: 2133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

e comunque ci sono un sacco di errori

l'assegnazione dei pin LCd e' errata
LiquidCrystal lcd( D4, D5, D6, D7, RS, EN );
quella corretta e'  LiquidCrystal lcd( RS, EN, D4, D5, D6, D7 );

l'LM35 lo hai collegato a un input digitale ( Pin 2 )
dato che devi leggere un valore analogico, va' usato su una porta da A0 a A5

in lcd.begin( 2, 16 );
prima si mette il numero dei caratteri e poi le righe.  lcd.begin( 16 , 2 );

e poi chissa' cosa hai combinato

Logged

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

Grazie...infatti ho notato che qualcosa non quadrava...
Altri errori di che genere?
Logged

Tuscany
Offline Offline
Edison Member
*
Karma: 77
Posts: 2133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

io mi sono fermato alle prime righe
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 139
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ricontrolla tutto, ci sono molti altri errori.... parentesi che mancano, parentesi in piu, assegnazioni errate....
Logged

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

Ciao a tutti...dopo una mattinata a studiare e dopo le partite del campionato, ho trovato un paio di orette per dedicarmi al programma.
Lo posto nettamente modificato rispetto a quello di ieri. Spero che ci siano meno errori!!! smiley-lol
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;




void setup() {
  lcd.begin(16, 2);
  pinMode(13, INPUT);
  mioservo.attach(6);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop() {
  val = digitalRead(13);
 
  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);
  }
  vecchio_val = val;
 
  if (stato == 1) {
    lcdLM35(), HIGH;
    segnalatoriLM35(), HIGH;
  }
  else {
    lcdLM35(), LOW;
    segnalatoriLM35; LOW;
  }
}

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();
}

void segnalatoriLM35() {
  valore = analogRead(sensore);
  fascia=map(valore, 0, 1024.0, 0, 3);
  if(fascia == 0) fascia = 1;
  spegni();
  digitalWrite(11-fascia, HIGH);
}

void spegni() {
  digitalWrite(10, LOW);
  ledyellow(), LOW;
  allarme(), LOW;
}

void ledyellow() {
  digitalWrite(9, HIGH);
  delay(1000);
  digitalWrite(9, LOW);
  delay(1000);
}

void allarme() {
  ledred(), HIGH;
  servo(), HIGH;
  buzzer(), HIGH;
}

void ledred() {
  digitalWrite(8, HIGH);
  delay(500);
  digitalWrite(8, LOW);
  delay(500);
}

void servo()
{
  for(angolo = 0; angolo < 180; angolo +=1)
{
mioservo.write(angolo);
delay(20);
}
 for(angolo = 180; angolo >= 1; angolo -=1)
{
 mioservo.write(angolo);
delay(20);
}
}

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

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);
  }
}
 
 
Aspetto consigli, suggerimenti o correzioni!!!
Grazie in anticipo!!!

Logged

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

scusami io non l'ho letto il programma... è molto più difficile correggere un programma staticamente senza ausilio di debug o di punti di controllo... normalmente quando si fa un programma si divide in sottoproblemi e nel caso di arduino dove al software devi unire la componente hardware che hai fatto tu diventa ancora più fondamentale.
Quello che io faccio di solito è (...esempio) attacco l'lcd e faccio un lcd.print per vedere se va... poi attacco il sensore di temperatura e lo provo con un analog write ed un serial print.. e poi avanti così e poi quando attacco tutto su un'unico programma ci metto di tanto in tanto dei serial.print ("sono qua") per "debug".... ripeto così staticamente diventa un po' difficile... magari se ci dici cosa "non fa" diventa più facile.
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 22907
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Scusa, mi spieghi queste righe di codice?
Code:
  ledyellow(), LOW;
  allarme(), LOW;
Logged


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

Scusa, mi spieghi queste righe di codice?
Code:
  ledyellow(), LOW;
  allarme(), LOW;

...io pensavo che non si compilassero nemmeno... smiley-red ... invece il programma si compila  smiley-eek
Comunque consiglio acca di cominciare a scrivere sul display la sola temperatura, quando ci siamo riusciti poi andiamo avanti... una cosa semplice tipo

temperatura = analogRead(PinLM);
lcd.print (temperatura);
... e un bel delay(1000);

... e sul delay poi avremo da lavorare perchè tu intendi far  lampeggiare tutto con il delay ma il delay ti blocca tutto il programma quindi... casino... bisogna cambiare approccio.
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 22907
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Scusa, mi spieghi queste righe di codice?
Code:
  ledyellow(), LOW;
  allarme(), LOW;

...io pensavo che non si compilassero nemmeno... smiley-red ... invece il programma si compila  smiley-eek
Perché la virgola fra 2 operandi indica al compilatore l'uso dell'operatore "," che istruisce appunto il compilatore a verificare le condizioni ma a restituire quella più a destra. Qui LOW non viene assegnato a nulla. Se avessi fatto:
byte temp = ledyellow(), LOW;
dopo l'esecuzione della riga di codice temp avrebbe assunto il valore LOW (cioè "0").
Nell'esempio che ho mostrato, non ha senso. Cos'è che si voleva fare?
Logged


Torino
Offline Offline
God Member
*****
Karma: 3
Posts: 766
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Guardando il codice mi pare di capire che scrivendo
Code:
ledyellow(), LOW;
  allarme(), LOW;
lui volesse/credesse in qualche modo di pilotare le void esterne al loop con il LOW e HIGH......dico questo perchè lo ripete più volte nel loop e lo utilizza sempre con le void esterne pensando magari che con LOW non entra nella void e che con HIGH invece si. Se così fosse non si scrive "ledyellow(),HIGH;" se si vuole entrare nella void ma semplicemente "ledyellow();".
In buona sostanza tutte le void esterne non vengono mai eseguite fino a quando non vengono chiamate dal loop principale e,una volta letta ed eseguito il codice scritto,si ritorna in automatico al loop principale continuando da dove aveva lasciato.
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 22907
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

lui volesse/credesse in qualche modo di pilotare le void esterne al loop con il LOW e HIGH......dico questo perchè lo ripete più volte nel loop e lo utilizza sempre con le void esterne pensando magari che con LOW non entra nella void e che con HIGH invece si.
Probabile. Difatti chiedevo appunto cosa volesse fare, perché qualunque cosa fosse, in quel modo era sbagliato  smiley-sweat
Logged


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