Skocz do zawartości

Arduino nano + OLED + LoRa - Zawieszanie się Arduino


Pomocna odpowiedź

Napisano

Witam

 

Mam problem z wieszającym się Arduino... Generalnie program działa przez kilka / kilkanaście minut i potrafi się zawiesić - Oled zostaje zamrożony i komunikacja LoRa <> LoRa nie działa.

Arduino zasilone z portu USB z ładowarki telefonu 5V 2A

 

Druga strona przestaje odbierać dane... 

Działanie programu na Arduino nano to: dokonywanie pomiarów z 4 czujników DS18B20 i wyświetlanie ich na OLED, oraz nasłuch na LoRa (softwareserial) jeśli LoRa odbierze ciąg znaków " a1b2c3 " to odsyła dane odczytane z czujników temp. 

 

Ktoś podpowie co robię źle?

 

/**
LoRa E32 433T200 Piny:
Góra Piny po lewej antena po prawej

7- podpiać go GND
6- podpiać go GND
5- Lora_RX (softwareserial)
4- Lora_TX (softwareserial)
3- NC
2- podpiać go VCC
1- podpiać go GND


OLED  > Arduino
SDA  > A4
SCK  > A5


**/




#include <OneWire.h>
#include <DallasTemperature.h>
//#include <SPI.h>
//#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
//#include <Adafruit_GFX.h>
//#include <Adafruit_SSD1306.h>


#include <SoftwareSerial.h>
//#include <RH_ASK.h>

const uint8_t LORA_TX = 2;
const uint8_t LORA_RX = 3;
SoftwareSerial LoRaSerial(LORA_TX, LORA_RX);  //TX, RX

SSD1306AsciiAvrI2c oled;
#define RST_PIN -1
#define I2C_ADDRESS 0x3C
//#define SCREEN_WIDTH 128 // OLED display width, in pixels
//#define SCREEN_HEIGHT 64 // OLED display height, in pixels
//Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//================================================ Struct



#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);



DeviceAddress CWUupThermometer = { 0x28, 0xD5, 0x20, 0x94, 0x97, 0x0A, 0x03, 0x71 };  //ok
DeviceAddress CWUdownThermometer = { 0x28, 0x88, 0x30, 0x97, 0x94, 0x09, 0x03, 0x50 };
DeviceAddress PiecThermometer = { 0x28, 0x84, 0x0C, 0x94, 0x97, 0x02, 0x03, 0xC7 };
DeviceAddress testtemp = { 0x28, 0xA8, 0x1C, 0x94, 0x97, 0x0A, 0x03, 0x06 };


unsigned long czas_aktualny = 0;
unsigned long czas_zapisany = 0;
unsigned long interwal = 10000;  //  interwal petli odczytu czujnikow



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

SensorData data;



//================================================ SETUP

void setup() {
  Serial.begin(9600);
  Serial.println("Serial begin");
  LoRaSerial.begin(9600);
  Serial.println("LoRa begin");
  sensors.begin();
  Serial.println("Sensors begin");
  //pinMode(LORA_TX, OUTPUT);
  //digitalWrite(LORA_TX, HIGH);

  // set the resolution to 10 bit (good enough?)
 // sensors.setResolution(CWUupThermometer, 10);
 // sensors.setResolution(CWUdownThermometer, 10);
 // sensors.setResolution(PiecThermometer, 10);
 // sensors.setResolution(testtemp, 10);
  

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


  delay(2000);

  //============================================================================================= OLED START ================================

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


//=========================================================================================== LOOP

void loop() {
  //SensorData data;





  czas_aktualny = millis();
  if (czas_aktualny - czas_zapisany >= interwal) {
  czas_zapisany = czas_aktualny;

    Serial.println("Getting temperatures...\n\r");

    data.id = "a1b2c3";

    sensors.requestTemperatures();
    data.temperature1 = sensors.getTempC(CWUupThermometer);
    data.temperature2 = sensors.getTempC(CWUdownThermometer);
    data.temperature3 = sensors.getTempC(PiecThermometer);
    data.temperature4 = sensors.getTempC(testtemp);


    oled.clear();
    

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

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

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

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


    


    Serial.print("id: ");
    Serial.print(data.id);
    Serial.print(" ");
    Serial.print("T1: ");
    Serial.print(data.temperature1);
    Serial.print(" ");
    Serial.print("T2: ");
    Serial.print(data.temperature2);
    Serial.print(" ");
    Serial.print("T3: ");
    Serial.print(data.temperature3);
    Serial.print(" ");
    Serial.print("T4: ");
    Serial.print(data.temperature4);
    
    Serial.print(" ");
    Serial.print(data.newline);


  }


if(LoRaSerial.available() > 1){//Read from  OSOYOO UART LoRa wireless module and send to serial monitor
    String input = LoRaSerial.readString();
    Serial.println(input);    
}


if (LoRaSerial.available()){
String input = LoRaSerial.readStringUntil('\n');
Serial.println("Odczytane z master ");
Serial.println(input);


if (input == "a1b2c3"){
Serial.println(" ");
Serial.print("Wysyłam LoRA");
Serial.println(" ");

//LoRaSerial.print(":");
    LoRaSerial.print(data.id);
    LoRaSerial.print(":");
    //LoRaSerial.print("T1: ");
    LoRaSerial.print(data.temperature1);
    LoRaSerial.print(":");
    //LoRaSerial.print("T2: ");
    LoRaSerial.print(data.temperature2);
    LoRaSerial.print(":");
    //LoRaSerial.print("T3: ");
    LoRaSerial.print(data.temperature3);
    LoRaSerial.print(":");
    LoRaSerial.print(data.temperature4);
    LoRaSerial.print(":");
    LoRaSerial.print(data.newline);

  }
}


}

 

 

Komunikacja widoczna w AIRSPY:

1 - wysłanie ciągu znaków dla stacji 1

2-  wysłanie ciągu znaków dla stacji 2 (przygotowana /w planach)

3 - wysłanie ciągu znaków dla stacji 3 (przygotowana /w planach)

4,5 - Odpowiedź / odesłanie danych z stacji 1

LORA AIRSPY.png

LORA odbiornik.png

  • Lubię! 1

- u mnie przy jednym projekcie zastosowanie biblioteki Adafruit dla SSD1306 powodowało zawieszenia.

- od tej pory unikam tej firmy ale wiem że zaraz znajdą się obrońcy firmy i biblioteki.

- dlatego jest to tylko moja uwaga, powodzenia

35 minut temu, 99teki napisał:

- u mnie przy jednym projekcie zastosowanie biblioteki Adafruit dla SSD1306 powodowało zawieszenia.

 

Bo żre połowę pamięci w Arduino. Akurat ta biblioteka im totalnie nie wyszła. Większość pozostałych jest OK (chociaż też mógłbym się przyczepić).

Kolejny raz widzę warunek że temperatura z dallasa = - 127 to błąd. Serio, niema w tej bibliotece żadnej flagi błędu czujnika, crc czy cokolwiek? 

  • Lubię! 1

-127 jest flagą, że to jest błąd, niestety warunek jest nieprawidłowy, używanie == z float nie jest dobrym pomysłem,wystarczy if (temperatura < -55).

Czujnik zwraca wartości prawdopodobnie prawidłowe tylko z zakresu -55 do 125.

(edytowany)

@kaczakat

void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  float tempC = sensors.getTempCByIndex(0);

  // Check if reading was successful
  if (tempC != DEVICE_DISCONNECTED_C)
  {
    Serial.print("Temperature for the device 1 (index 0) is: ");
    Serial.println(tempC);
  }
  else
  {
    Serial.println("Error: Could not read temperature data");
  }
}

Z przykładów biblioteki, tylko nie wiem jak się zachowa przy zwarciu magistrali. 

Edytowano przez _LM_

No ale to to samo, DEVICE_DISCONNECTED_C  jest zdefiniowane jako -127, dalej jest to równe/ nie równe, na to samo wychodzi, a wszyscy mi powtarzali w tutorialach internetowych, by nie robić warunków == z floatami.

#define DEVICE_DISCONNECTED_C -127
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
 static float temperatura= -127.00;
if(temperatura  != DEVICE_DISCONNECTED_C) 
{
  Serial.print("Odczyt prawidlowy  ");
  Serial.println(temperatura);
}
else Serial.println("Blad czujnika");
delay(1000);
if (temperatura<-128) temperatura =-126;
temperatura-=0.1;
}

 

18:36:55.628 -> Odczyt prawidlowy  -126.10
18:36:56.614 -> Odczyt prawidlowy  -126.20
18:36:57.601 -> Odczyt prawidlowy  -126.30
18:36:58.619 -> Odczyt prawidlowy  -126.40
18:36:59.605 -> Odczyt prawidlowy  -126.50
18:37:00.624 -> Odczyt prawidlowy  -126.60
18:37:01.608 -> Odczyt prawidlowy  -126.70
18:37:02.627 -> Odczyt prawidlowy  -126.80
18:37:03.613 -> Odczyt prawidlowy  -126.90
18:37:04.599 -> Odczyt prawidlowy  -127.00
18:37:05.617 -> Odczyt prawidlowy  -127.10
18:37:06.600 -> Odczyt prawidlowy  -127.20
18:37:07.620 -> Odczyt prawidlowy  -127.30
18:37:08.604 -> Odczyt prawidlowy  -127.40
18:37:09.623 -> Odczyt prawidlowy  -127.50
18:37:10.606 -> Odczyt prawidlowy  -127.60
18:37:11.622 -> Odczyt prawidlowy  -127.70
18:37:12.606 -> Odczyt prawidlowy  -127.80
18:37:13.624 -> Odczyt prawidlowy  -127.90
18:37:14.607 -> Odczyt prawidlowy  -128.00
18:37:15.628 -> Odczyt prawidlowy  -128.10

Z DS18B20 są trzy kłopotliwe odczyty: -127, 0 i 85oC, ten pierwszy jest najprostszy do wyeliminowania, dwa kolejne można zauważyć wykorzystując 2 bajty użytkownika, zapisać 0 i przepisać do EEPROM DS, przy starcie czujnika wartości rejestrów TL i TH są w DS przepisywane z EEPROM,  potem zapisać w rejestrach jakieś wartości !=0, jak się DS zresetuje i podaje 85oC, bo nie mierzył jeszcze temperatury, to i rejestry TH TL mają 0, jak jest to faktycznie zmierzone 85oC to rejestry mają wartości !=0 wpisane przy starcie uC. No a jak wszystko ma 0 to pewnie jest to zwarcie. Nie testowałem tego, gdzieś przeczytałem.

12 minut temu, kaczakat napisał:

No ale to to samo, DEVICE_DISCONNECTED_C  jest zdefiniowane jako -127

Oo faktycznie, nie zwróciłem uwagi że jest taka definicja. W prawdzie nadal uważam że to nie jest prawidłowe oprogramowanie błędu ale niech będzie, nie będę się z tym kłócił. 

1 godzinę temu, kaczakat napisał:

Z DS18B20 są trzy kłopotliwe odczyty: -127, 0 i 85oC, ten pierwszy jest najprostszy do wyeliminowania, dwa kolejne można zauważyć wykorzystując 2 bajty użytkownika

To wszystko bez zbędnych kombinacji może i powinna zrobić biblioteka, jeśli masz ochotę poszukaj materiałów o CRC i magistrali 1wire. Tym czasem zostawiam link do biblioteki (akurat tej nie sprawdzałem) która sprawdza sumy CRC i na ich podstawie można ocenić czy transmisja przebiegła poprawnie

https://github.com/Hotaman/OneWireSpark

Ehh... Podczas wymiany filtrów wody w kotłowni musiałem przesunąć mój "ulep" Od tego czasu działa cały czas... Muszę sprawdzić wszystkie luty... Aa i miałem problem w trakcie uruchomienia.. 3 czujniki ds18b20 działały bez problemu.. Po podpięciu  kolejnego działały tylko dwa... Ale z tym sobie poradziłem... Winny był jeden z czujników... Który czasem powodował błędy... 

  • Lubię! 1
Dnia 8.07.2023 o 09:30, Misiek_86 napisał:

Klon DS18B20?

Bardzo możliwe bo zamawiane na Ali... 

Co do warunku błędu czujnika zmienię w takim razie na opcje <= -55 (muszę doczytać dlaczego nie zaleca sie == w float.

Co do biblioteki Adafruit proszę zobaczyć iż używam innej: SSD1306AsciiAvrI2c.h (inne są za komentowane)


Generalnie luty poprawione całość działa poprawnie...  Jeszcze trochę potestuje... dorobie obudowę i będzie Git.

 

Dziękuje za wszystkie podpowiedzi.

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...