• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Balon meteo z GPS, czujnikiem temperatury i wilgotności oraz modułem karty SD
#1
Lightbulb 
Witam was serdecznie,
otóż od jakiegoś  czasu składam zestaw, który będzie wykorzystany do balonu meteo. Jego zadaniem będzie pomiar temperatury, wilgotności i może ciśnienia oraz zapis danych z GPSa na kartę pamięci. Oprócz tego zestaw wyposażony jest w moduł GSM, dzięki któremu będę mógł lokalizować balon w czasie lotu oraz po wylądowaniu wysyłając do mojego zestawu smsa. W wiadomości zwrotnej otrzymuję współrzędne: Cały zestaw jest gotowy i poskładany, ale problem jest z programem. Otóż mam przygotowany pełen program na podstawie 3 różnych. Każdy z nich z osobna działa, ale już po połączeniu go w jeden nic się nie dzieje. Nie wiem, w czym jest rzecz.? Może ktoś przygotowywał taki zestaw lub jest w stanie zdiagnozować problem w kodzie?
Poniżej przedstawiam wam kod programu:

Kod:
#include <SPI.h>                             // library for SPI devices (uSD board)
#include <TinyGPS.h>                         // library for GPS
#include <SoftwareSerial.h>                  // library for serial comm. with GPS
#include <SD.h>                              // library for the uSD board
#include <Wire.h>                            // library for comm. with I2C sensors
#include "DHT.h"                             // library for DHT temp and humidity sensor
#define DHTTYPE DHT22                        // DHT 22  (AM2302), AM2321
#define DHTPIN 7     

const byte chipSelect = 4;                   // the SD card CS pin is wired to pin 10
TinyGPS gps;                                 // make the tinyGPS object
SoftwareSerial ss(1, 0);                     // Assign the SoftwareSerial TX and RX pins for the GPS                 
DHT dht(DHTPIN, DHTTYPE);                   
SoftwareSerial sgps(1, 0);
SoftwareSerial sgsm(2, 3);
int state = 0;
const int pin = 4;
float gpslat, gpslon;

void setup()
    {
      ss.begin(9600);                        // only the GPS uses this
      Serial.begin(9600);                    // this is for displaying data on a serial monitor
      dht.begin();                           // Initialise the DHT sensor  
      pinMode(chipSelect, OUTPUT);           // The CS pin on the SD card                  
      if (!SD.begin(chipSelect))             // see if the card is present and can be initialized
         { while(1); }                       // Wait forever since we can't write data  
          sgsm.begin(9600);
          sgps.begin(9600);        
    }
void loop()      
                    //GPS I KARTA SD       
   {                                                             
     bool newData = false;                    
     for (unsigned long start = millis(); millis() - start < 1000;)    // gather GPS data for 1 second
     {    
       while (ss.available())                         // while the GPS data is coming via software serial
       {
          char c = ss.read();                         // read the characters into c
          if (gps.encode(c))  newData = true;         // Did a new valid sentence come in?         
       }
     }
    String dataString = "";                           // start with an empty dataString
    if (newData)                                      // if a new valid GPS sentence was read
    {          
    float flat, flon, falt;                           // these next 9 lines parse the GPS data                   
    unsigned long age;
    int year;
    byte month, day, hour, minute, second, hundredths;
    gps.f_get_position(&flat, &flon, &age);
    falt = gps.f_altitude(); 
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    char sz[32];   
    sprintf(sz, "%02d/%02d/%02d,%02d:%02d:%02d,", month, day, year, hour, minute, second);
    File dataFile = SD.open("DANE.csv", FILE_WRITE);                      // write to this file
    dataFile.print("Data i Czas: ");
    dataFile.print(sz);
    dataFile.print(" Długosc: ");// write date time data to SD card
    dataFile.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);     // write GPS data to SD card
    dataFile.print(",");
    Serial.print(" Długość: ");
    Serial.print(flon, 6);
    dataFile.print(" Szerokosc: ");
    dataFile.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);     // write GPS data to SD card
    dataFile.print(",");
    Serial.print(" Szerokość: ");
    Serial.print(flat, 6);
    dataFile.print(" Wysokosc: ");
    dataFile.print(falt == TinyGPS::GPS_INVALID_ALTITUDE ? 0.0 : falt, 1);    // write GPS data to SD card 
    dataFile.print(" m,");
    Serial.print(" Wysokość: ");
    Serial.print(falt, 1);
    delay (100);  
             //TEMPERATURA i WILGOTNOSC                             
    float temperature;                              // Temperature variable
    delay (100);
    float DHTh = dht.readHumidity();                // Read DHT sensor
    Serial.print(" Wilgotnosc: ");
    Serial.print(DHTh, 2);
    dataFile.print(" Wilgotnosc: ");
    dataFile.print(DHTh, 2);                        // write humidity data to SD card
    dataFile.print("%,");
    float DHTt = dht.readTemperature();             // Read temperature as Celsius (the default)
    Serial.print(" Temperatura: ");
    Serial.println(DHTt, 2);
    dataFile.print(" Temperatura: ");
    dataFile.print(DHTt, 2);                      // write temperature data to SD card and end line
    dataFile.println(" st. C ");
    dataFile.flush();
    dataFile.close();
    }                                       // endif (newData)
      delay (1000);                         // write data to SD card only every few seconds
      while (sgps.available())
  {
    //WYSYŁANIE DANYCH SMSEM
    int c = sgps.read();
    if (gps.encode(c))
    {
      gps.f_get_position(&gpslat, &gpslon);
    }
  }
    if (sgsm.available() > 0) {
      String    c = sgsm.readString();
      c.trim();
      if (c.indexOf("GET-GPS") > 0) {
        sgsm.print("\r");
        delay(1000);
        sgsm.print("AT+CMGF=1\r");
        delay(1000);
        /*Replace XXXXXXXXXX to 10 digit mobile number &
          ZZ to 2 digit country code*/
        sgsm.print("AT+CMGS=\"+48790208796\"\r");
        delay(1000);
        //The text of the message to be sent.
        sgsm.print("Szerokosc: ");
        sgsm.println(gpslat, 6);
        sgsm.print("Dlugosc: ");
        sgsm.println(gpslon, 6);
        delay(1000);
        sgsm.write(0x1A);
        delay(1000);
      }
    }
  }                          

Proszę o pomoc.
 
Odpowiedź
#2
1 rada: zrób sobie w programie kontrolne Serial.println ("1") ; potem 2 3 i tak dalej będziesz wiedział, gdzie program się ewentualnie zacina.
2 rada: używasz 2 SoftwareSerial a w danej chwili może działać tylko jeden, ten ostatnio uruchomiony czyli w Twoim przypadku sgps.begin(9600); a ten sgsm.begin(9600); nie działa. Trzeba je "beginować " bezpośrednio przed użyciem czyli w pętli LOOP a w SETUP niekoniecznie. Sprawdzone doświadczalnie i to z trzema SoftwareSerial.
Nie analizowałem Twojego programu, ale delay można stosować w zasadzie tylko w programach demo. Jak masz połączonych kilka "programów" musisz nauczyć się używać millis() .
Powodzenia w dalszych pracach.
 
Odpowiedź
#3
Używasz jednego pinu do kilku funkcji a tak się nie da...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#4
Kurcze teraz zauważyłem, że masz 3 SoftwareSerial a dwa są na tych samych pinach ss i sgps. No i jeszcze pin 4.
 
Odpowiedź
#5
(16-10-2020, 17:13)Agregacik napisał(a): Kurcze teraz zauważyłem, że masz 3 SoftwareSerial a dwa są na tych samych pinach ss i sgps. No i jeszcze pin 4.
A tak nie powinno być ?
 
Odpowiedź
#6
(16-10-2020, 17:04)Agregacik napisał(a): 1 rada: zrób sobie w programie kontrolne Serial.println ("1") ; potem 2 3 i tak dalej będziesz wiedział, gdzie program się ewentualnie zacina.
2 rada: używasz 2 SoftwareSerial a w danej chwili może działać tylko jeden, ten ostatnio uruchomiony czyli w Twoim przypadku sgps.begin(9600); a ten sgsm.begin(9600); nie działa. Trzeba je "beginować " bezpośrednio przed użyciem czyli w pętli LOOP a w SETUP niekoniecznie. Sprawdzone doświadczalnie i to z trzema SoftwareSerial.
Nie analizowałem Twojego programu, ale delay można stosować w zasadzie tylko w  programach demo. Jak masz połączonych kilka "programów" musisz nauczyć się używać millis() .
Powodzenia w dalszych pracach.

Dzięki za cenne informacje.
Właśnie poprawiiłem kod.Zmieniłem delay na millis() no i resztę beginów dałem do pętli przed początkiem danej części programu natomiast nie jestem aż tak dobry w programowaniu.
Co mam zmienić w związku z trzema SoftwareSerial, jak to obejść?
 
Odpowiedź
#7
A potrafisz jednocześnie jechać rowerem i samochodem??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#8
(16-10-2020, 19:16)Jarewa0606 napisał(a): A potrafisz jednocześnie jechać rowerem i samochodem??

Nie, nie wiedziałem, że to tak działa w tym przypadku Smile

Dzięki za info.

Zmieniłem co nieco, jak kolega napisał w komentarzu wcześniej, zmieniłem delay na millis i beginy dałem do pętli przed kodem programu. Nie wiem jak roziwązać problem z tymi SOftwareSerial?
 
Odpowiedź
#9
SoftwareSerial bazuje na przerwaniach, wiec twój projekt to wielka lipa i jedyna możliwość to zmiana na ardunio mega
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#10
(16-10-2020, 20:32)Jarewa0606 napisał(a): SoftwareSerial bazuje na przerwaniach, wiec twój projekt to wielka lipa i jedyna możliwość to zmiana na ardunio mega
Powiem tak, wcale nie musi być wielką lipą. Mam taki projekt z 3 SoftwareSerial i płytce nano i działa bardzo dobrze. Wszystko zależy co się chce osiągnąć. W moim przypadku poszczególne SoftwareSerial działają po kolei, czyli w danej chwili tylko jeden pyta i oczekuje odpowiedzi, inne śpią i nie oczekuję od nich działania w tle. Jeżeli ktoś oczekuje, że w tym samym czasie jak działa jeden SoftwareSerial drugi będzie zbierał w buforze dane to się może przeliczyć. Po zainicjowaniu każdego SoftwareSerial czyszczę bufor odbiorczy i dopiero wysyłam zapytania do podpiętego pod niego urządzenie. 
Do autora wątku, pokaż poprawiony kod. 
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości