Go Down

Topic: Continuare a leggere dati (Read 343 times) previous topic - next topic

grigorot

Ciao a tutti, è da molto che non scrivo causa esami, per fortuna che me ne manca solo uno.
cerco di essere il più sintetico possibile,

1) uso una scheda Arduino uno

2) uso una ventola pc pilotabile, un relè per una pompa per acquari, una termocoppia con chip max6675, un sensore digitale DS18b20, un led e un sensore di fiamma.

3) Ho realizzato un listato che mi legge il sensore di fiamma, la termocoppia e il sensore di temperatura digitale, e attraverso la lettura di questi ultimi riesco a gestire delle periferiche(ventola, led, relè e quindi anche la pompa siccome è collegata a quest'ultimo), il problema è che io vorrei leggere con un ritardo basso (delay(500) o più piccolo) i valori dei sensori, ma questo mi è impossibile in quanto se mettessi quel delay la ventola e la pompa mi vanno ad intermittenza e questo non mi piace.

4) se volessi usare matlab per programmare Arduino come dovrei fare per passargli le librerie? ho cercato in internet e sul sito della mathworks ma non ci ho capito nulla.
In realtà posso anche non programmare direttamente Arduino con matlab l'importante e che gli riuscissi a passare i dati che i sensori stampano, ho letto qualcosa relativo alla porta rs232 qui sul forum ma non mi è chiaro che passaggio dovrei fare, se avete dei suggerimenti... intanto continuo ad approfondire.

scusate se ho scritto molto ma è tutta roba per la tesi di laurea


Code: [Select]
#include <DallasTemperature.h>
#include <OneWire.h>
#include <max6675.h>

#define l 8 //collegato al pin 8 led
#define f 9 //collegato al pin 9 sensore di fiamma
#define v 10 // collegato al pin 10 ventola
#define r 11 // collegato al pin 11 rele
#define t 4 //collegato al pin 4 sensore ds18b20 temperatura

OneWire ourWire(t);
DallasTemperature sensors(&ourWire);

int ktcSO = 5; //collegato al pin 5, so del max6675
int ktcCS = 6; //collegato al pin 6, cs del max6675
int ktcCLK = 7;//collegato al pin 7, clk del max 6675

MAX6675 ktc(ktcCLK, ktcCS, ktcSO);
int Fiamma = 0;
double Temp = 0;
 
void setup() {
  pinMode(l,OUTPUT); //led
  pinMode(v,OUTPUT); //ventola
  pinMode(r,OUTPUT);  //rele
  pinMode(f,INPUT);  //sensore di fiamma

 
  Serial.begin(9600);
  delay(500);
  sensors.begin();
}

void loop() {
   
  digitalWrite(v,0);//Ventola spenta
  digitalWrite(r,0);//disattivo il rele, il cavo nero della pompa va al NC1, mentre il jumper nero va alla
  //COM1
  digitalWrite(l,0);//imposto il led a stato basso
 
 
  Fiamma = digitalRead(f);
 
  //faccio lampeggiare il led se c'è una fiamma attiva
  if(Fiamma==1){
     digitalWrite(l,1);
     delay(1000);
     digitalWrite(l,0);
  }

  //stampo sulla porta seriale i valori di temperatura
  Serial.print("Deg C = ");
  Serial.println(ktc.readCelsius());
 
  sensors.requestTemperatures();
  Serial.print("Temperatura = ");
  Serial.print(sensors.getTempCByIndex(0));
  Serial.println(" gradi C");
   
    Temp = sensors.getTempCByIndex(0);
  if(Temp>50){
     digitalWrite(v,1);
     digitalWrite(r,1);
  }   

  delay(1000); //vorrei che fosse 500

}

ORSO2001

ciao grigorot,

scusa ma non ho mai usato matlab...quindi per questo punto non so aiutarti.

per i restanti punti qualche cosa posso dirti...in primis: per rendere l'esecuzione del programma fluido e non a "scatti" devi sostituire il delay() con millis()...questo implica un cambio di logica nella stesura dello sketch....ma visto che attualmente è meno di 70 righe ed ha "sole" 2 if()...ti conviene assolutamente rivederlo.
come secondo punto...c'è poco da fare...i due metodi utilizzati sensors.requestTemperatures() ed sensors.getTempCByIndex(0) necessitano di circa 700 ms per essere eseguiti...da qua non si scappa...

attualmente il tuo codice per eseguire un ciclo ha bisogno di circa 2.7 secondi dati dai due delay di 1000 ciascuno più, come detto, i due metodi della DS18b20...non so al max6675 quanto tempo serve per ritornarti le informazioni richieste.

se hai bisogno di scendere sotto i 500 ms ciclo loop...devi cambiare sensore DS18b20 con altro.

grigorot

#2
May 16, 2018, 11:55 pm Last Edit: May 17, 2018, 12:02 am by grigorot
ho appena guardato la funzione millis() si effettivamente dovrebbe migliorare, domani lo provo.

per la sostituzione non c'è problema, metto un' altra termocoppia.

gpb01

#3
May 17, 2018, 07:00 am Last Edit: May 17, 2018, 07:01 am by gpb01
ho appena guardato la funzione millis() si effettivamente dovrebbe migliorare, domani lo provo.

... relativamente all'uso corretto della millis(), leggi prima QUESTO post, dopo di che leggi QUI, poi QUI e QUI e QUI e gli articoli che sono in QUESTA pagina. Dovrebbe esserti tutto più chiaro ;)

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

Standardoil

ho dato una scorsa veloce al tuo codice
alcune cose si otrebbero ottimizzare, ma diviene questione di stile
per il lampeggio usa una millis, te la cavi con poche righe, se non hai idea di come fare cerca quin nel forum, da
ultimo cerca il mio topic "il tempo delle librerie", ma solo come isprazione, non usare quella libreria
Per stampa e lettura anche potresti usare millis
invece per velocizzare la loop
tu leggi il sensore 6675, lo stampi ma non lo usi, ok, se va bene per te
invece leggi due volte il DS18B20, la prima stampi, la seconda usi il valore
leggi una volta sola e usa il valore salvato
Code: [Select]

  Serial.print(Temp=sensors.getTempCByIndex(0));

ricorda che in C le assegnaznazioni hanno un valore, lo stesso assegnato, l'istruzione che ti ho messo legge il sensore lo stampa e lo assegna a Temp (in realtà prima lo assegna e poi lo stampa)
per il test invece non spegnere all'inizio del ciclo per riaccendere solo al testo
Non spegnere prorpio ventola e pompa, all'inizio del ciclo
invece del test "assegna" a ventola e pompa l'esito del test
Code: [Select]

digitalWrite(v,Temp>50);

vedrai che magia
Prima legge di Nelson (che sono io):
A parità di risultato maggiore
è il pensiero, minore il lavoro.
Quindi prima di fare pensa!

grigorot

#5
May 17, 2018, 08:43 am Last Edit: May 17, 2018, 08:49 am by grigorot
Grazie mille delle info

Code: [Select]
digitalWrite(v,Temp>50);
//questa cosa non la sapevo, è come se fosse un if?


per quanto riguarda il led penso che non lo farò lampeggiare ma mi limiterò ad accenderlo quando c'è la presenza di una fiamma.

userò comunque la funzione millis() che non ferma il ciclo da quello che ho capito come invece fa il delay

Per quanto riguarda matlab, sapete come posso fare per inviargli i dati?
riesco a fare la connessione tra il dispositivo e il programma attraverso il listato che importo su arduino (adio.pde) per poi scrivere lo script di comando su matlab


torn24

Quote
digitalWrite(v,Temp>50);
//questa cosa non la sapevo, è come se fosse un if?


Temp>50 , viene valutata e restituisce 1 se vero, 0 se falso, in questo caso si comporta come un if else

if(Temp>50)
   digitalWrite(v,1)
else
   digitalWirte(v,0)


Però  non è che sia proprio un if, è solo che l'espressione viene valutata e restituisce 1 o 0


Per quanto riguarda matlab, non conosco il linguaggio, ma di solito per comunicare si usa la comunicazione seriale, ho un arduino e un programma su PC, comunico tramite seriale.



grigorot

si, comunicare tramite seriale è proprio quello che vorrei fare, hai idea di come si faccia, leggevo della porta rs232 ma di più non so

torn24

#8
May 17, 2018, 10:20 am Last Edit: May 17, 2018, 10:23 am by torn24
So per quanto riguarda la comunicazione seriale di arduino, ci sono vari esempi su questo.
Se comunichi con un PC, allora userai la porta usb, esistono esempi sul forum di come comunicare
in seriale tra arduino e matlab.

In arduino esiste  il metodo serial.available(), che ci indica se ci sono caratteri sulla seriale.

Volendo mandare un "comando" ad arduino , nella funzione loop() metto una condizione
"se ci sono caratteri sulla seriale ALLORA leggi il comando", poi in base al comando ricevuto faccio
qualcosa.

La cosa più semplice per inviare un comando, è inviare un semplice carattere, ad ogni carattere corrisponde un azione o un richiamo di una funzione.

Esempio ricezione comandi su arduino

Code: [Select]


char comando;
void loop(){

    if(Serial.available()){// Solo se ho trasmesso un comando da seriale, se ci sono caratteri sulla seriale

          comando=Serial.read();
          switch(comando){
              case 'a':
                   funzione1();
                   break;
               case 'b':
                   funzione2();
                   break;
               case 'c':
                   funzione3();
                   break;
          }
   }

}



Se i comandi sono superiori ai caratteri disponibili o si è interessati ad inviare una parola come comando, allora si dovrà trasmettere una stringa, e in arduino leggere una stringa "ci sono esempi sul forum" e poi confrontare la stringa con un if e la funzione strcmp(), Ma per quanto mi riguarda non è quasi mai necessario   e inviare un semplice carattere è sufficiente.

grigorot

okok, allora adesso sistemo il listato e poi mi informo meglio su come comunicare da seriale, Grazie mille a tutti

Go Up