Problema con la lettura seriale dei sensori

Salve; possiedo un modulo GPS per Arduino Uno e un sensore di umidità/temperatura DHT11. Separatamente, funzionano entrambi alla grande. Se cerco di combinare i codici, invece, mi viene restituito un solo valore nel monitor seriale e poi basta (mentre dovrebbe continuare all’infinito a printare le rilevazioni, posizione nel caso del GPS e umidità/temperatura nel caso del DHT11). Il codice del programma è il seguente:

#include <SoftwareSerial.h>

#define PIN_GPS_ENABLE 7

#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 7

SoftwareSerial gpsSerial(5,6);
String NMEA;
int posizione_delimitatore = 0;
int index = 0;
int campo = 0;
int ora, secondi, secondi2;
String tempo, longitudine, latitudine, quota;

void setup() {
  //init seriale hardware
  Serial.begin(9600);
  //init seriale software
  gpsSerial.begin(4800);
  pinMode(PIN_GPS_ENABLE,OUTPUT);
  digitalWrite(PIN_GPS_ENABLE,HIGH);
}
 
void loop() {
  start_gps();
  gpsSerial.overflow();
  if (gpsSerial.available()) {
    char c = gpsSerial.read();
    if (c != '\n') {
      NMEA += c;
    }
    else {
      posizione_delimitatore = 0;
      index = 0;
      campo = 0;
      if (NMEA.substring(0, 6) == "$GPGGA")
      {
        while (posizione_delimitatore != -1)
        {
          posizione_delimitatore = NMEA.indexOf(",", index);
          int chk = DHT11.read(DHT11PIN);
          switch(campo)
          {
            case 1:
              Serial.print("Time:   ");
              tempo = NMEA.substring(index, posizione_delimitatore);
              ora = ((tempo.substring(0,1)+tempo.substring(1,2))).toInt();
              Serial.print(ora+2);
              Serial.println(":"+tempo.substring(2,3)+tempo.substring(3,4));
              break;
            case 2:
              Serial.print("Lat:    ");
              latitudine = NMEA.substring(index, posizione_delimitatore);
              Serial.print(latitudine.substring(0,1)+latitudine.substring(1,2)+"");
              Serial.print(" "+latitudine.substring(2,3)+latitudine.substring(3,4)+"'");
              secondi = (latitudine.substring(5,6)+latitudine.substring(6,7)+latitudine.substring(7,8)+latitudine.substring(8,9)).toInt();
              secondi = secondi/100;
              secondi = (60*secondi)/100;
              Serial.print(" "+String(secondi)+"''");
              Serial.print("    ");
              break;
            case 4:
              Serial.print("Long:   ");
              longitudine = NMEA.substring(index, posizione_delimitatore);
              Serial.print(longitudine.substring(1,2)+longitudine.substring(2,3)+"");
              Serial.print(" "+longitudine.substring(3,4)+longitudine.substring(4,5)+"'");
              secondi2 = (longitudine.substring(6,7)+longitudine.substring(7,8)+longitudine.substring(8,9)).toInt();
              secondi2 = secondi2/100;
              secondi2 = (60*secondi2)/100;
              Serial.println(" "+String(secondi2)+"''");
              Serial.print("    ");
              break;
            case 9:
              Serial.print("Quota:  ");
              quota = NMEA.substring(index, posizione_delimitatore);
              Serial.println(quota+"M");
              Serial.print("    ");
              
              Serial.print("Umidita'(%): ");
              Serial.println((float)DHT11.humidity, 2);
              
              break;
          }
          index = posizione_delimitatore;
          index++;
          campo++;
        }
      }
      NMEA = "";
    }
  }
}
void start_gps() {
    gpsSerial.listen();
    digitalWrite(PIN_GPS_ENABLE,LOW);
}

Mi sono accorto che la stringa di codice che “interrompe” il loop è quella che esegue la lettura dal sensore DHT11:

int chk = DHT11.read(DHT11PIN);

Se la metto a commento, nel monitore seriale continuo a ricevere valori solo dal GPS, se la inserisco, invece, vedo posizione e umidità/temperatura ma solo una volta (come se poi il programma terminasse). Un esempio in allegato. Non ne vengo fuori, come posso risolvere?
Grazie

Forse hai semplicemente esaurito la RAM.

Usa per il print delle [u]costanti[/u] la funzione F(), ad esempio:

Serial.print("Umidita'(%): "); diventa Serial.print(F("Umidita'(%): "));

Poi ti conviene allocare spazio per le variabili String, ad esempio per NMEA:

NMEA.reserve(size);

ove size è la massima lunghezza possibile (in caratteri) che può assumere la variabile NMEA,

Ma perché mai hai messo la lettura di quel sensore nel ciclo di decodifica della sentenza NMEA? :o In quel modo viene eseguita molte più volte del necessario. E se la sua esecuzione richiede un certo tempo, rallenta a manetta il parsing.

Capisci un po' il codice o l'hai messa a caso?

Takenfal: Salve;

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni e a leggere il regolamento se non lo hai già fatto: Regolamento Qui una serie di link utili, non inerenti al tuo problema: - qui una serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - qui le pinout delle varie schede by xxxPighi: Pinout - qui una serie di link [u]generali[/u] utili: Link Utili

P.S. bello l'avatar. E' un personaggio fumetti o è un tuo disegno ?

nid69ita:
Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento se non lo hai già fatto: Regolamento
Qui una serie di link utili, non inerenti al tuo problema:

P.S. bello l’avatar. E’ un personaggio fumetti o è un tuo disegno ?

Mi scuso per la presentazione, l’ho fatto immediatamente. Per quanto riguarda il regolamento l’ho letto tutto prima di postare (spero di non aver scordato nulla). Me la cavo con l’elettronica e con i segnali, il problema sta proprio nella programmazione;

P.S. L’avatar è un personaggio di un gioco =)

SukkoPera:
Ma perché mai hai messo la lettura di quel sensore nel ciclo di decodifica della sentenza NMEA? :o In quel modo viene eseguita molte più volte del necessario. E se la sua esecuzione richiede un certo tempo, rallenta a manetta il parsing.

Capisci un po’ il codice o l’hai messa a caso?

In effetti hai ragione; il codice lo capisco in parte e sto cercando di imparare (ho avuto a che fare con il c++ solo con arduino, io ho studiato Java, python e linguaggi di programmazione web). Dovrei metterlo nel void setup()?

cyberhs:
Forse hai semplicemente esaurito la RAM.

Usa per il print delle costanti la funzione F(), ad esempio:

Serial.print("Umidita’(%): "); diventa Serial.print(F("Umidita’(%): "));

Poi ti conviene allocare spazio per le variabili String, ad esempio per NMEA:

NMEA.reserve(size);

ove size è la massima lunghezza possibile (in caratteri) che può assumere la variabile NMEA,

Provo anche questo metodo, grazie :wink:

Grazie a tutti per ora =)

Mah oddio, se conosci Python, Java o [u]qualunque[/u] linguaggio, direi che dovrebbe esserti chiaro che ti conviene leggere la temperatura solo quando la devi stampare, o all'inizio/fine del loop() se vuoi tenerla sempre aggiornata (cosa inutile in questo caso, direi).

PS: Si chiamano FUNZIONI, non VOID!!! >:(

#define PIN_GPS_ENABLE 7
...
#define DHT11PIN 7

Sono d'accordo di risparmiare pin ma essere cosí tirchio...

Ciao Uwe

SukkoPera: Mah oddio, se conosci Python, Java o [u]qualunque[/u] linguaggio, direi che dovrebbe esserti chiaro che ti conviene leggere la temperatura solo quando la devi stampare, o all'inizio/fine del loop() se vuoi tenerla sempre aggiornata (cosa inutile in questo caso, direi).

PS: Si chiamano FUNZIONI, non VOID!!! >:(

E invece ho proprio bisogno che ad ogni loop mi venga stampata umidità e temperatura; e come ripeto, sono qui per imparare.

uwefed: ```

define PIN_GPS_ENABLE 7

...

define DHT11PIN 7




Sono d'accordo di risparmiare pin ma essere cosí tirchio...

Ciao Uwe

Il problema era proprio questo e mi sento davvero un ritardato; ho letto e riletto il codice una marea di volte, ma proprio non mi sono accordo di quel maledetto pin. Grazie mille!

A me sembra che la stampi solo quando leggi il 9° campo. A quel punto l'avrai letta 9 volte inutilmente.

Takenfal: Il problema era proprio questo e mi sento davvero un ritardato; ho letto e riletto il codice una marea di volte, ma proprio non mi sono accordo di quel maledetto pin. Grazie mille!

Non preoccuparTi. Sono cose che capitano ed é normale che un estraneo nota cose dopo 3 secodi che Tu non vedi perché non ci pensi. È uno delle leggi derivate di Murphy.

http://web.freepass.it/cazzionario/murphy.htm: Terza legge di Finagle In un qualsiasi insieme di dati, la cifra cosi' evidentemente corretta da non richiedere un controllo e' l'errore. Corollari: 1. Nessuno a cui chiedete aiuto la vedra'. 2. Chiunque passi di li' per darvi un consiglio gratuito la vedra' immediatamente.

Ciao Uwe