Blach Napisano Czerwiec 14, 2023 Udostępnij Napisano Czerwiec 14, 2023 Mam problem. Mianowicie budując moją stację meteo na układzie Arduino Uno natknąłem się na błąd "SSD1306 allocation failed". Wywnioskowałem, że błąd ten powoduje zbyt mała ilość pamięci RAM dla wyświetlacza oraz że tą pamięć zabierają zmienne "char" wykorzystywane w moim kodzie. Program działał, gdy występowały dwie zmienne "char", teraz zaimplementowane są trzy, a mam w planach dodać jeszcze kilka. Poniżej dodaje kod całego programu modułu odbiornika stacji, do którego podłączony jest wyświetlacz. Jeżeli ktoś miałby jakieś rady co do sposobu pisanie kodu, lub zauważył w moim jakieś błędy, proszę śmiało pisać, gdyż nie jestem specem od pisania kodu. Wolę kabelki i lutownicę. Z góry dziękuję za odpowiedź. #include <SPI.h> #include <Wire.h> #include <VirtualWire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_BMP280.h> #include "DHT.h" #include <virtuabotixRTC.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define DHTPIN 2 // Pin, do którego podłączony jest DHT 11 #define DHTTYPE DHT11 // Typ czujnika DHT #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_BMP280 bmp280; DHT dht(DHTPIN, DHTTYPE); virtuabotixRTC myRTC(6, 7, 8); const int receive_pin = 3; char temperatureChar[10]; char humidityChar[10]; char pressureChar[10]; struct package { float temperature = 0.0; float humidity = 0.0; float pressure = 0.0; }; typedef struct package Package; Package data; void setup() { Serial.begin(9600); dht.begin(); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } myRTC.setDS1302Time(00, 9, 15, 6, 01, 06, 2023); // Ustawienie zegara display.display(); delay(2000); display.clearDisplay(); //Wyczyszczenie ekranu vw_set_rx_pin(receive_pin); vw_setup(500); // Bits per sec vw_rx_start(); // Start the receiver PLL running } void loop() { float h = dht.readHumidity(); // Odczyt wilgotności wewnętrznej float t = dht.readTemperature(); //Odczyt temperatury wewnętrznej if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } float hic = dht.computeHeatIndex(t, h); uint8_t buf[sizeof(data)]; uint8_t buflen = sizeof(data); if (vw_have_message()) { for (int i = 0; i < 5; i++) { myRTC.updateTime(); delay(1050); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,0); display.print(" Data: "); display.setTextSize(2); display.println(); display.println(); display.setTextColor(WHITE); display.print(myRTC.dayofmonth); display.print("/"); display.print(myRTC.month); display.print("/"); display.print(myRTC.year); display.print(" "); display.print(myRTC.hours); display.print(":"); display.print(myRTC.minutes); display.print(":"); display.print(myRTC.seconds); display.display(); display.clearDisplay(); } delay(2000); //Odczyt temperatury wewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Temperatura WEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(t); display.print(" C"); display.display(); display.clearDisplay(); delay(2000); //Odczyt wilgotności wewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Wilgotnosc WEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(h); display.print(" %"); display.display(); display.clearDisplay(); delay(2000); Serial.print(F("Temperatura wew.: ")); Serial.print(t); Serial.print(F("°C Wilgotność wew.: ")); Serial.print(h); Serial.print(F("% ")); Serial.println(); vw_get_message(buf, &buflen); //Odczyty z odbiornika zewnętrznego memcpy(&data,&buf,buflen); Serial.print(data.temperature); //Wypissanie odczytów na terminalu String temperatureString = String(data.temperature,1); temperatureString.toCharArray(temperatureChar,10); Serial.println(); Serial.println(data.humidity); String humidityString = String(data.humidity,1); humidityString.toCharArray(humidityChar,10); Serial.println(); Serial.print(data.pressure); String pressureString = String(data.pressure,1); pressureString.toCharArray(pressureChar,10); Serial.println(); display.setTextSize(1); //Odczyt temperatury zewnętrznej display.setTextColor(WHITE); display.setCursor(0,0); display.println("Teperatura ZEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.temperature); display.print(" C"); temperatureString.toCharArray(temperatureChar,10); display.display(); display.clearDisplay(); delay(2000); //Odczyt wilgotności zewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Wilgotnosc ZEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.humidity); display.print(" %"); humidityString.toCharArray(humidityChar,10); display.display(); display.clearDisplay(); delay(2000); //Odczyt ciśnienia display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Cisnienie.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.pressure); display.print(" hPa"); pressureString.toCharArray(pressureChar,10); display.display(); display.clearDisplay(); delay(2000); } } 1
ethanak Czerwiec 15, 2023 Udostępnij Czerwiec 15, 2023 12 godzin temu, Blach napisał: Jeżeli ktoś miałby jakieś rady Niestety, driver 1306 przydziela sobie połowę pamięci na swoje bufory i niewiele zostaje. Może pomóc coś takiego: zamiast display.println("Wilgotnosc ZEW.:"); coś w stylu: display.println(F("Wilgotnosc ZEW.:")); i tak wszędzie gdzie masz print/println ze stałym napisem. Nie gwarantuję że pomoże. Poza tym taki kwiatek: display.print(data.pressure); display.print(" hPa"); pressureString.toCharArray(pressureChar,10); Czyli najpierw wyświetlasz tablicę a potem wstawiasz do niej napis... a nie powinno być przypadkiem odwrotnie: pressureString.toCharArray(pressureChar,10); display.print(data.pressure); display.print(F(" hPa")); Dodatkowo: możesz mieć tylko jedną tablicę zamiast trzech (tzn. wpisujesz wartość do tablicy, wyświetlasz, wpisujesz następną wartość do tej samej tablicy, wyświetlasz i tak dalej). Ale do tego musiałbyś poprawić ten wcześniejszy błąd. 1
ethanak Czerwiec 15, 2023 Udostępnij Czerwiec 15, 2023 A poza tym po co zamieniasz w ogóle String na jakieś tablice?
Blach Czerwiec 15, 2023 Autor tematu Udostępnij Czerwiec 15, 2023 (edytowany) Szczerze mówiąc znalazłem w internecie przykładowy program wysyłania danych z czujnika przez moduły RF 433 i zastosowałem taki sam sposób przechowywania danych. @ethanak zobaczę czy twoje rady pomogły i wtedy napiszę, czy się udało. Edit: wywaliłem tablice i powstał w ten sposób taki kod: #include <SPI.h> #include <Wire.h> #include <VirtualWire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_BMP280.h> #include "DHT.h" #include <virtuabotixRTC.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define DHTPIN 2 // Pin, do którego podłążcony jest DHT 11 #define DHTTYPE DHT11 // Typ czujnika DHT #define OLED_RESET -1 #define receive_pin 3 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_BMP280 bmp280; DHT dht(DHTPIN, DHTTYPE); virtuabotixRTC myRTC(6, 7, 8); struct package { float temperature = 0.0; float humidity = 0.0; float pressure = 0.0; }; typedef struct package Package; Package data; void setup() { Serial.begin(9600); dht.begin(); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } myRTC.setDS1302Time(00, 9, 15, 6, 01, 06, 2023); // Ustawienie zegara display.display(); delay(2000); display.clearDisplay(); //Wyczyszczenie ekranu vw_set_rx_pin(receive_pin); vw_setup(500); // Bits per sec vw_rx_start(); // Start the receiver PLL running } void loop() { float h = dht.readHumidity(); // Odczyt wilgotności wewnętrznej float t = dht.readTemperature(); //Odczyt temperatury wewnętrznej if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } float hic = dht.computeHeatIndex(t, h); uint8_t buf[sizeof(data)]; uint8_t buflen = sizeof(data); if (vw_have_message()) { for (int i = 0; i < 5; i++) { myRTC.updateTime(); delay(1050); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,0); display.print(" Data: "); display.setTextSize(2); display.println(); display.println(); display.setTextColor(WHITE); display.print(myRTC.dayofmonth); display.print("/"); display.print(myRTC.month); display.print("/"); display.print(myRTC.year); display.print(" "); display.print(myRTC.hours); display.print(":"); display.print(myRTC.minutes); display.print(":"); display.print(myRTC.seconds); display.display(); display.clearDisplay(); } delay(2000); //Odczyt temperatury wewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Temperatura WEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(t); display.print(" C"); display.display(); display.clearDisplay(); delay(2000); //Odczyt wilgotności wewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Wilgotnosc WEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(h); display.print(" %"); display.display(); display.clearDisplay(); delay(2000); Serial.print(F("Temperatura wew.: ")); Serial.print(t); Serial.print(F("°C Wilgotność wew.: ")); Serial.print(h); Serial.print(F("% ")); Serial.println(); vw_get_message(buf, &buflen); //Odczyty z odbiornika zewnętrznego memcpy(&data,&buf,buflen); String temperatureString = String(data.temperature,1); Serial.print(data.temperature); //Wypissanie odczytów na terminalu Serial.println(); String humidityString = String(data.humidity,1); Serial.println(data.humidity); Serial.println(); String pressureString = String(data.pressure,1); Serial.print(data.pressure); Serial.println(); display.setTextSize(1); //Odczyt temperatury zewnętrznej display.setTextColor(WHITE); display.setCursor(0,0); display.println("Teperatura ZEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.temperature); display.print(" C"); display.display(); display.clearDisplay(); delay(2000); //Odczyt wilgotności zewnętrznej display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Wilgotnosc ZEW.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.humidity); display.print(" %"); display.display(); display.clearDisplay(); delay(2000); //Odczyt ciśnienia display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Cisnienie.:"); display.println(); display.setTextSize(3); display.setTextColor(WHITE); display.print(data.pressure); display.print(" hPa"); display.display(); display.clearDisplay(); delay(2000); } } Dalej występuje dalej ten sam błąd: "SSD1306 allocation failed". Nie wiem, czy ja zrobiłem coś źle, czy to coś innego to powoduje. Niestety nie mogę dodać do mojego kodu, tego co napisał kolega @ethanak. Być może będę musiał zmienić rodzaj wyświetlacza. Proszę o szybką odpowiedź. Z góry dziękuję. Pozdrawiam Edytowano Czerwiec 15, 2023 przez Blach 1
Pomocna odpowiedź
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ę »