Skocz do zawartości

Błąd "SSD306 allocation failed" - wyświetlacz SSD1306 podłączony do arduino


Pomocna odpowiedź

Napisano

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

 

  • Lubię! 1
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.

 

  • Lubię! 1
(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 przez Blach
  • 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...