• 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
Arduino+OLED+LORA <> Arduino+OLED+LORA wysyłanie struktury
#1
Witam

Robię taki mini projekcik... 

Mam arduino nano do tego oled + 3 czujniki  DS18b20 (puki co mam 1 czujnik) te czujniki badają temp wody w zasobniku na 3 wysokościach i wyświetlają na bieżąco odczytaną temp. oraz przesyłają dane przez LoRa

Drugie arduino nano ma odebrać dane i wyświetlić je na oled.
Dodatkowo sprawdzam czy dane wysłało urzadzenie z którego chciałbym czytać informacje.
if (receivedData.startsWith("123abc")) - chwilowo zakomentowane.

Nie mogę poradzić sobie z wysłaniem i odebraniem danych w strukturze... 

LoRa jest po komunikacji uart - wykorzystuje SoftwareSerial.

Co robię źle?

Udało mi się przesłać tylko 1 zmienna jako String... ale w tym przypadku gdy próbuje kilka danych (struktura) wtedy nic nie działa...


Nadajnik:
Kod:
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>

#define ONE_WIRE_BUS 10 // pin podłączenia DS18B20
#define INTERVAL 5000   // interwał wysyłania danych w ms
#define RST_PIN -1   // pin resetu OLED (nieużywany)
#define OLED_ADDR 0x3C // adres I2C OLED

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
SoftwareSerial loraSerial(2, 3);
SSD1306AsciiAvrI2c oled;

struct SensorData {
  float temperature1;
  float temperature2;
  float temperature3;
  String message;
  char newline = '\n';
};

SensorData data;

void setup() {
  Serial.begin(9600);
  loraSerial.begin(9600);
  sensors.begin();


   #if RST_PIN >= 0
  oled.begin(&Adafruit128x64, OLED_ADDR, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, OLED_ADDR);
#endif // RST_PIN >= 0


delay(2000);



oled.setFont(Adafruit5x7);
oled.clear();
oled.set2X();
oled.println("Bojler");
oled.println("TRANSMITT");
delay(2000);
oled.clear();








}

void loop() {
  static unsigned long lastMillis = 0;
  if (millis() - lastMillis >= INTERVAL) {
    lastMillis = millis();
    sensors.requestTemperatures();
    data.temperature1 = sensors.getTempCByIndex(0);
    data.temperature2 = sensors.getTempCByIndex(1);
    data.temperature3 = sensors.getTempCByIndex(2);
    data.message = "123abc";


    loraSerial.write((uint8_t *)&data, sizeof(data));
 


  oled.clear();
  oled.set2X();
  oled.print("P: ");
  if (data.temperature3 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature3);
  oled.println(" *C");
    }
  oled.set1X();
  oled.println(" ");




  oled.set2X();
  oled.print("G: ");
  if (data.temperature1 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature1);
  oled.println(" *C");
  }



  oled.set1X();
  oled.println(" ");
  oled.set2X();

  oled.print("D: ");
  if (data.temperature2 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature2);
  oled.println(" *C");
    }

Serial.print("Temperatura 1: ");
  Serial.println(data.temperature1);
  Serial.print("Temperatura 2: ");
  Serial.println(data.temperature2);
  Serial.print("Temperatura 3: ");
  Serial.println(data.temperature3);
  Serial.print("Message: ");
  Serial.println(data.message);
  Serial.print(data.newline);
  }
}


Odbiornik:
Kod:
#include <SoftwareSerial.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>

#define RST_PIN -1   // pin resetu OLED (nieużywany)
#define OLED_ADDR 0x3C // adres I2C OLED

SoftwareSerial loraSerial(2, 3);
SSD1306AsciiAvrI2c oled;

struct SensorData {
  float temperature1;
  float temperature2;
  float temperature3;
  String message;
  char newline = '\n';
};

SensorData data;

void setup() {
  Serial.begin(9600);
  loraSerial.begin(9600);


#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, OLED_ADDR, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, OLED_ADDR);
#endif // RST_PIN >= 0

delay(2000);



oled.setFont(Adafruit5x7);
oled.clear();
oled.set2X();
oled.println("Bojler");
oled.println("TRANSMITT");
delay(2000);
oled.clear();


}

void loop() {
  static String receivedData;
  while (loraSerial.available() > 0) {
    char c = loraSerial.read();
    if (c == '\n') {
      //if (receivedData.startsWith("123abc")) {
        memcpy(&data, receivedData.c_str() + 6, sizeof(data));



         oled.clear();
  oled.set2X();
oled.print("P: ");
  if (data.temperature3 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature3);
  oled.println(" *C");
    }
  oled.set1X();
oled.println(" ");




   oled.set2X();
  oled.print("G: ");
  if (data.temperature1 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature1);
  oled.println(" *C");
  }



oled.set1X();
   oled.println(" ");
   oled.set2X();

  oled.print("D: ");
  if (data.temperature2 == -127.00) {
    oled.println("ERROR");}
    else{
  oled.print(data.temperature2);
  oled.println(" *C");
    }

Serial.print("Temperatura 1: ");
  Serial.println(data.temperature1);
  Serial.print("Temperatura 2: ");
  Serial.println(data.temperature2);
  Serial.print("Temperatura 3: ");
  Serial.println(data.temperature3);
  Serial.print("Message: ");
  Serial.println(data.message);
  Serial.print(data.newline);


//}
    }
  }
}

Serial monitor
Dane wysłane:

Temperatura 1: 22.50

Temperatura 2: -127.00
Temperatura 3: -127.00
Message: 123abc



Dane odebrane:

Temperatura 1: ovf
Temperatura 2: 0.00
Temperatura 3: ovf
Message:
 
Odpowiedź
#2
Jeżeli udało Ci się przesłać stringa to przy pomocy sprintf składasz sobie wszystkie dane do wysłania w paczkę, dajesz odpowiednie formatowanie i po strony odbiornika bawisz się w strtok.
 
Odpowiedź
#3
Zacznij od połączenia dwóch Arduino przez Serial i zrób to co chcesz tutaj używając print i write, do struktury to powinien być write. Potem dodaj CRC do struktury, na koniec zrób to z LORA. Ze struktury wywal string i zastąp go stałą tablicą char, zajmie na stałe określoną ilość miejsca, będziesz mógł łatwiej określić w odbiorniku kiedy jest początek i koniec danych, sprawdzić ich poprawność.
Z obsługi DS w setup zrób zlecenie pomiaru, potem wyłącz czekanie na pomiar, potem w loop robisz odczyt i na koniec tego ifa z czasem interwału i millis dopiero zlecasz kolejny pomiar, jak znowu tu wrócisz, bo minął czas między pomiarami to od razu odczytujesz i nie czekasz na pomiar, jak interwał ma być większy to można zrobić zlecenie pomiaru w sekundzie poprzedzającej wysłanie, ale jak jest 5s to nie jest istotne, wyślesz pomiar sprzed 5s, ale za to program nie stoi tu 750ms.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości