AnalogRead e ritardi

un aiuto
Ho un problema dal quale non riesco ad uscire
Ho un programmino che legge da SoftwareSerial dei dati da un GPS , il problema che se nel frattempo vado a monitorare un livello di tensione su analogico (A0) con un AnalogRead (a0) mi si blocca lo schetch e non sembra andare oltre.

Se al posto di una AnalogRead inserisco (per testare) una DigitalRead (su ovviamente una porta differente) tutto funziona normalmente.

Vi è già mai capitato? se si come avete risolto?

Lo schetch deve solo leggere Velocità dal GPS e verificare di tanto in tanto lo stato di carica della batteria tramite un partitore di Tenisione.

grazie mille

ah dimenticavo Arduino UNO

Pubblica lo sketch, per favore, che altrimenti non si capisce il problema.

ECCOLO

//#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

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.print(batt);
while (1) {
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;
}
}

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

}


GRAZIE SPERIAMO

Parlavi di "blocco".... ma non è che hai esaurito la memoria?
Vorrei provare a compilare lo sketch, da dove hai prelevato le librerie SdFatUtil.h e sms.h (così da usare quelle che hai tu)?

veramente puoi anche eliminare i riferimenti alle librerie, non vengono usate...vai tranquillo

no, la memoria non è esaurita....considera che poi fa molto altro ancora che ho dovuto togliere dallo schetch altrimenti non si capiva nulla...

Ma fa sempre lo stesso problema, questa è la zona problematica. Se metti una Serial.print dopo la AnalogRad ti rendi conto che si inchioda...

....molto gentile....

Ma sei sicuro che si inchiodi all'analogRead e non alla comunicazione col GPS che c'è subito prima?
Potresti provare così:

Serial.println("Sono alla readline...");
readline();   //legge dati da GPS 
Serial.println("Adesso leggo il pin A0...");
  // se disponibile $GPRMC
  batt = analogRead (A0); 
Serial.println("Lettura fatta. Proseguo...");

e la risposta è questa


Sono alla readline...
0Adesso leggo il pin A0...
Lettura fatta. Proseguo...
DISPOSITIVO ACCESO
Sono alla readline...


quindi si ferma dopo la Read...è come se il GPS non passando l'endline ogni tanto prende e si inchioda...che dici?

praticamente si blocca alla readline ma solo se attivi l'analogread....prova a commentare analog read e tutto cammina....(tranne le letture sull'analogico).....

Il problema sembra risiedere in readline().
A me non esce da lì:
ecco l'ouput:

Sono alla readline...
0

Nel senso che se non c'è nulla in arrivo dal gps, il codice ti resta bloccato lì dentro.

si è vero,....ma che c'entra con la AnalogRead....prova a commentare l'analog e vedrai che tutto torna...
metto delle Serial.println nella funzione

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:
si è vero,....ma che c'entra con la AnalogRead....prova a commentare l'analog e vedrai che tutto torna...
metto delle Serial.println nella funzione

Sarà stato un caso. Anche a te non è uscito dalla funzione readline.

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.

cli();
batt = analogRead(A0);
sei();

PS2:
una domanda...

hai per caso intenzione di lanciare un pallone sonda con l'Arduino? ]:smiley:

leo72:
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.

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!

:slight_smile:

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

leo72:

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.

purtroppo non funziona ancora neanche così

..

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.

leo72:

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