Go Down

Topic: AnalogRead e ritardi (Read 1 time) previous topic - next topic

giocastel


PS:
siccome la SoftwareSerial usa gli interrupt, potresti provare a rendere "atomica" la lettura analogica di A0. Per "atomico" si intende un blocco di codice che non è interrompibile da un interrupt. In questo modo evitiamo che interferenze esterne della libreria diano noia alla funzione di lettura del pin analogico.

Code: [Select]
cli();
batt = analogRead(A0);
sei();




vero e già provato....ma nulla...stesso problema
come è vero che ho anche provato a Stoppare la seriale prima di leggere il valore analogico per poi farlo ripartire....NULLA....sto impazzendo!

si la sonda è finita da tempo....in primavera lanciamo!

:-)
Il mio BLOG : PALLONE SONDA
http://roborover.wordpress.com

leo72

Ma hai provato questo codice che ti ho postato?
A me funziona perfettamente, e non si blocca.


Quote
void readline(void) {
  char c;
  buffidx = 0; // start at begninning
  unsigned long tempMillis = millis();
 
  Serial.print(batt);
  while (millis() - tempMillis < 5000) {
    c=gps.read();
    if (c == -1)     
      continue;
      //Serial.print(" ");
      delay(1);
    if (c == '\n')
      continue;
    if ((buffidx == BUFFSIZ-1) || (c == '\r')) {         
      buffer[buffidx] = 0;
      return;
    }     
    buffer[buffidx++]= c;
      }
}

Con questo funziona perfettamente.
E' un timeout di 5 secondi, se non riceve nulla sulla seriale software, esce.

giocastel

purtroppo non funziona ancora neanche così

..
Il mio BLOG : PALLONE SONDA
http://roborover.wordpress.com

leo72


purtroppo non funziona ancora neanche così


A me però funziona.
Domanda: perché usi "continue"? Per uscire dal while? Forse dovresti usare "break", allora.
Mi potresti spiegare anche la logica della funzione readline: che cosa dovrebbe attendersi per uscire? Vediamo cioè se la si può rendere più efficiente.

giocastel



purtroppo non funziona ancora neanche così


A me però funziona.
Domanda: perché usi "continue"? Per uscire dal while? Forse dovresti usare "break", allora.
Mi potresti spiegare anche la logica della funzione readline: che cosa dovrebbe attendersi per uscire? Vediamo cioè se la si può rendere più efficiente.



la readline deve contenere la sentenza disponibile nmea del gps, quindi tutto quello che sente dalla seriale lo butta in buffer. ovviamente fa un controllo che buffer non sia pieno e che ci sia una nuova linea , tutto semplicissimo
Il mio BLOG : PALLONE SONDA
http://roborover.wordpress.com

leo72


leo72

Ecco i risultati del test fatto sullo sketch tuo, commentando analogRead: BLOCCO.

Quindi a me non è l'analogRead che blocca il codice, ma proprio la funzione readline che, senza timeout, si blocca in un loop infinito.
Usando il seguente codice al posto del tuo:
Code: [Select]
//#include <SdFatUtil.h>
#include <SoftwareSerial.h>
//#include "sms.h"



#define BUFFSIZ 70// se troppo grosso 70
#define LED 6
#define DC 5   
SoftwareSerial gps(4,5); //Seriale Software Vs GPS(RX,TX)


//SMSGSM sms;
boolean lettura=false;
boolean GPRMC=true;
boolean GPGGA=true;
// PArsing GPS variabili Globali
char buffer[BUFFSIZ];        // Buffer dei dati G
char *parseptr;              // un puntatore Char per il Parsing
char buffidx;                // Indice del Parsing
boolean startup=true;
boolean stato=false;              //0 atterrato 1 Volo
char TEXT_SMS[30];




//  time, date, location data, etc.
//uint8_t  day;
uint32_t day,time,latitude, longitude;
uint8_t groundspeed, trackangle,altitude;
uint8_t latdir, longdir,quality;
int status;
String STR_SMS;         //Variabile String per concatenare la stringa SMS
int batt;


void setup() {
    pinMode(LED,OUTPUT);
    pinMode(DC,INPUT);
    Serial.begin(9600);   //Seriale del PC   
    delay(2000);

    gps.begin(38400); //Velocità seriale GPS
    digitalWrite(LED,LOW);
}


uint32_t parsedecimal(char *str) {
    uint32_t d = 0; 
    while (str[0] != 0) {
        if ((str[0] > '9') || (str[0] < '0'))
            return d;
        d *= 10;
        d += str[0] - '0';
        str++;
    }
    return d;
}


void readline(void) {
    char c; 
    buffidx = 0; // start at begninning

    Serial.println("Stampo la lettura...");
    Serial.println(batt);
    Serial.println("Entro nel while...");
    while (1) {
        Serial.println("Leggo il GPS...");
        c=gps.read();
        Serial.println("OK. Proseguo");
        if (c == -1)     
            Serial.println("C=-1");
            continue;
        //Serial.print(" ");
        delay(1);
        Serial.println("Delay(1)");
        if (c == '\n')
            Serial.println("c=\n");
            continue;
        if ((buffidx == BUFFSIZ-1) || (c == '\r')) {         
            Serial.println("Buffer pieno o ritorno a capo...");
            buffer[buffidx] = 0;
            Serial.println("Fatto. Esco.");
            return;
        }     
        Serial.println("Inserisco il dato nel buffer...");
        buffer[buffidx++]= c;
    }
}

void loop() {
    uint32_t tmp;

    readline();   //legge dati da GPS 
    // se disponibile $GPRMC
    //batt = analogRead (A0);  //QUESTO FA INCHIODARE LO SCHETCH DOPO 2/3 letture

    if (startup) {                                                   // si attiva solo alla prima accensione  del dispositivo
        if (groundspeed == 0)Serial.println("DISPOSITIVO ACCESO ");
        if (groundspeed == 0) tone (9,700,1000);
        if (groundspeed > 0) Serial.println("WARNING WARNING");

        //Serial.println(FreeRam()); 
        startup=false;
    }
    delay(1000);
}


ottengo questo (ovviamente all'infinito):
Code: [Select]
Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo


Mentre mettendo il timeout, ottengo questo:
Code: [Select]

Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
OK. Proseguo
C=-1
Leggo il GPS...
......... (per 5 secondi circa).......
OK. Proseguo
C=-1
DISPOSITIVO ACCESO


Come vedi, esce e ritorna al loop principale. Ciò mi ha fatto pensare sull'uso di "continue". Con "continue" tu esegui l'istruzione successiva, mentre con "break" esci dal ciclo.

Modificando la readline così:
Code: [Select]
void readline(void) {
    char c; 
    buffidx = 0; // start at begninning
    unsigned long tempMillis = millis();
 
 

    Serial.println("Stampo la lettura...");
    Serial.println(batt);
    Serial.println("Entro nel while...");
    while (millis() - tempMillis < 5000) {
        Serial.println("Leggo il GPS...");
        c=gps.read();
        Serial.println("OK. Proseguo");
        if (c == -1)     
            Serial.println("C=-1");
            break;
        //Serial.print(" ");
        delay(1);
        Serial.println("Delay(1)");
        if (c == '\n')
            Serial.println("c=\n");
            continue;
        if ((buffidx == BUFFSIZ-1) || (c == '\r')) {         
            Serial.println("Buffer pieno o ritorno a capo...");
            buffer[buffidx] = 0;
            Serial.println("Fatto. Esco.");
            return;
        }     
        Serial.println("Inserisco il dato nel buffer...");
        buffer[buffidx++]= c;
    }
}


Ottengo questo:
Code: [Select]

Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
DISPOSITIVO ACCESO
Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1
Stampo la lettura...
0
Entro nel while...
Leggo il GPS...
OK. Proseguo
C=-1

Come vedi, il ciclo termina ben prima del timeout.

Go Up