Problem with SSD1306 and ESP8266

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
helzayat
 
Posts: 5
Joined: Sun Mar 26, 2023 8:29 am

Problem with SSD1306 and ESP8266

Post by helzayat »

This is my first posting in these forums, so please forgive me if this is the wrong place for my post.
I have built several projects using SSD1306 OLED displays with ESP-01, NodeMCU etc. I use the Arduino IDE and the Adafruit GFX and SSD1306 libraries. I have not had any display problems until now.
On this one project, which was working fine, I made some changes to the sketch, and now the display has gone haywire. Starting with the Adafruit logo, the pixels jump around the screen, text changes size and position. Reverting to the older sketch, everything is fine again, so it's not hardware.
I thought it might be a memory problem, but I have no experience with debugging memory problems. I'm using an ESP-01s. Strangely, the compiled sketch (.bin) with problems is smaller than the one that works.
I would appreciate any suggestions including where to post this :)

User avatar
barshatriplee
 
Posts: 200
Joined: Wed Mar 22, 2023 10:11 am

Re: Problem with SSD1306 and ESP8266

Post by barshatriplee »

Sounds like the issue is with the code inteself.

User avatar
helzayat
 
Posts: 5
Joined: Sun Mar 26, 2023 8:29 am

Re: Problem with SSD1306 and ESP8266

Post by helzayat »

What in the code could make the Adafruit logo appear distorted on initializing the display?

User avatar
millercommamatt
 
Posts: 831
Joined: Tue Jul 31, 2018 4:57 pm

Re: Problem with SSD1306 and ESP8266

Post by millercommamatt »

Post your code.

User avatar
helzayat
 
Posts: 5
Joined: Sun Mar 26, 2023 8:29 am

Re: Problem with SSD1306 and ESP8266

Post by helzayat »

OK, here it is. The RemoteXY code works and the app on my Android phone does what I want it to do.
The IFTTT code works and I get the notifications I expect.
The communication between the ESP-01 controlling the front lights and the one controlling the back lights works and they turn on and off together.
The lights come on and go off at the expected times as shown on the RemoteXY display and the OLED display (when it is legible).
Replacing the OLED makes no difference, and an earlier version of this sketch works on this hardware with no display problems.
:)Please be kind, I am not a programmer and am an Arduino/8266 newbie and strictly an amateur.

Code: Select all

//   -- OutdoorLights --
//   -- 30 April, 2023

//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266WIFI_LIB_CLOUD
#include <ESP8266WiFi.h>
#include <RemoteXY.h>

// RemoteXY connection settings
#define REMOTEXY_WIFI_SSID "RCG"
#define REMOTEXY_WIFI_PASSWORD "password"
#define REMOTEXY_CLOUD_SERVER "cloud.remotexy.com"
#define REMOTEXY_CLOUD_PORT 6376
#define REMOTEXY_CLOUD_TOKEN "BANNED"


// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =   // 220 bytes
{ 255, 2, 0, 81, 0, 213, 0, 16, 24, 1, 70, 33, 53, 11, 5, 5, 26, 31, 8, 0,
  67, 4, 6, 16, 20, 5, 176, 24, 10, 67, 4, 6, 33, 20, 5, 218, 24, 10, 67, 4,
  36, 52, 20, 5, 2, 24, 10, 67, 4, 6, 52, 20, 5, 2, 24, 10, 67, 4, 36, 33,
  20, 5, 218, 24, 10, 129, 0, 5, 10, 24, 4, 98, 67, 117, 114, 114, 101, 110, 116, 32,
  84, 105, 109, 101, 0, 129, 0, 5, 27, 14, 4, 98, 83, 117, 110, 114, 105, 115, 101, 0,
  129, 0, 35, 46, 15, 4, 98, 79, 110, 32, 84, 105, 109, 101, 0, 129, 0, 5, 46, 13,
  4, 98, 83, 117, 110, 115, 101, 116, 0, 129, 0, 35, 27, 15, 4, 98, 79, 102, 102, 32,
  84, 105, 109, 101, 0, 129, 0, 49, 17, 11, 4, 98, 76, 105, 103, 104, 116, 115, 0, 2,
  1, 37, 68, 22, 11, 31, 26, 12, 31, 79, 78, 0, 79, 70, 70, 0, 10, 48, 8, 67,
  15, 15, 4, 26, 31, 78, 111, 114, 109, 97, 108, 0, 31, 79, 118, 101, 114, 114, 105, 100,
  101, 0, 67, 5, 21, 88, 20, 5, 24, 31, 7, 67, 1, 5, 2, 53, 5, 178, 26, 23
};

// this structure defines all the variables and events of your control interface
struct {

  // input variables
  uint8_t switch_1; // =1 if switch ON and =0 if OFF
  uint8_t pushSwitch_1; // =1 if state is ON, else =0

  // output variables
  uint8_t led_1; // led state 0 .. 2
  char curr_time[10];  // string UTF8 end zero
  char sunr_time[10];  // string UTF8 end zero
  char on_time[10];  // string UTF8 end zero
  char suns_time[10];  // string UTF8 end zero
  char off_time[10];  // string UTF8 end zero
  char day_night[7];  // string UTF8 end zero
  char show_date[23];  // string UTF8 end zero

  // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

//***************************************
//         Added for OTA
//***************************************
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
//***************************************

#include <TimeLib.h>
//#include <JsonListener.h>
//#include <time.h>
#include <SimpleTimer.h>
#include <Sun.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <fonts/freeSans9pt7b.h>

#define OLED_address  0x3c
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

SimpleTimer timer;

IPAddress server(192, 168, 5, 81);    // the fixed IP address of the server

WiFiClient client;

int relay_control = 2;
int old_relay_control = HIGH;
const char* ssid = "RCG";
const char* pass = "password";
const int EPOCH_1_1_2019 = 1546300800;
char timeString[32];
char this_day[22];
long t_offset;
time_t its_now;
time_t tset;
time_t trise;
time_t t_on;
time_t t_off;
int old_day;
String O_status;

/******************************
  IFTTT stuff
*******************************/
// Set IFTTT Webhooks event name and key
#define IFTTT_Key "BANNED"
#define IFTTT_Event "Outdoor_Lights"
#define IFTTT_Value1 "Outdoor Lights are now "
//#define IFTTT_Value2 "OFF"
String IFTTT_Value2 = "OFF";
#define IFTTT_Value3 "value 3"

void setup()
{
  RemoteXY_Init();
  RemoteXY.switch_1 = 0;
  RemoteXY.pushSwitch_1 = 1;

  Wire.begin(0, 3);
  Serial.begin(115200);
  delay(3000);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
    for (;;);
  }
  Serial.println("SSD1306 allocation succeeded");
  pinMode(relay_control, OUTPUT);
  digitalWrite(relay_control, HIGH);
  delay(random(500));
  randomSeed(millis());

  display.display();
  delay(1000);
  display.clearDisplay();
  display.setFont(&FreeSans9pt7b);
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, 0x10);
  display.println("Getting ready...");
  Serial.println("Getting ready...");
  display.display();  
  Serial.println("\n\r======================================================================================");
  Serial.println("- connecting to Home Router SSID: " + String(ssid));
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("*");
    delay(2500);
  }
  Serial.println();
  Serial.print("- succesfully connected - IP address: ");
  Serial.println(WiFi.localIP());
  display.println(WiFi.localIP());
  display.display();
  delay(2000);
  
  //*****************************************
  //         Added for OTA
  //*****************************************
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  //  ArduinoOTA.setHostname("OutdoorLightsOTA-2");
  ArduinoOTA.setHostname("OutdoorLightsOTA");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("\r\\n\n\nStart updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
  //*****************************************
  //         End Added for OTA
  //*****************************************

  GetOWM;
  timer.setInterval(2000L, TimeCheck);  // Update Time Check every 2 seconds
}

void loop()
{
  timer.run();

  //***************************************
  //         Added for OTA
  //***************************************
  ArduinoOTA.handle();
  //***************************************

  //  yield();
}


void GetOWM()  {
  configTime(10800, 0, "eg.pool.ntp.org"); // get UTC time via NTP
  while (its_now < EPOCH_1_1_2019) {
    its_now = time(nullptr);
    delay(500);
  }
  time(&its_now);
  formatTimestamp("%H:%M:%S", its_now).toCharArray(timeString, 9);
  Serial.print("\r\nNew day at: " + String(timeString));
  old_day = day(its_now);
  Sun sun(29.97, 31.28);
  formatTimestamp(" %B %e, %Y", its_now).toCharArray(this_day, 22);
  Serial.println(this_day);
  strcpy (RemoteXY.show_date, this_day);
  //Sunrise
  trise = (sun.getRise(its_now));
  formatTimestamp("%H:%M:%S on %B %e, %Y", trise).toCharArray(timeString, 32);
  Serial.println("Sunrise is at: " + String(timeString) + "  ");
  formatTimestamp("%H:%M:%S", trise).toCharArray(timeString, 9);
  strcpy  (RemoteXY.sunr_time, timeString);
  //Off time
  t_off = trise + random(-600, 600);
  formatTimestamp("%H:%M:%S on %B %e, %Y", t_off).toCharArray(timeString, 32);
  display.clearDisplay();
  Serial.println("Off Time: " + String(timeString) + "  ");
  formatTimestamp("%H:%M:%S", t_off).toCharArray(timeString, 9);
  strcpy  (RemoteXY.off_time, timeString);
  display.setCursor(0x00, 0x26);
  display.print("Off   ");
  display.print(timeString);
  //Sunset
  tset = (sun.getSet(its_now));
  formatTimestamp("%H:%M:%S on %B %e, %Y", tset).toCharArray(timeString, 32);
  Serial.println("Sunset is at: " + String(timeString) + "  ");
  formatTimestamp("%H:%M:%S", tset).toCharArray(timeString, 9);
  strcpy  (RemoteXY.suns_time, timeString);
  //On time
  t_on = tset + random(-600, 600);
  formatTimestamp("%H:%M:%S on %B %e, %Y", t_on).toCharArray(timeString, 32);
  display.setCursor(0x00, 0x39);
  display.print("On   ");
  display.print(timeString);
  Serial.println("On Time: " + String(timeString));
  formatTimestamp("%H:%M:%S", t_on).toCharArray(timeString, 9);
  strcpy  (RemoteXY.on_time, timeString);
  Serial.println();
  display.display();
yield();
}  //End GetOWM()


void TimeCheck() {
  RemoteXY_Handler();
  time(&its_now);
  int today = day(its_now);
  //Current time
  formatTimestamp("%H:%M:%S", its_now).toCharArray(timeString, 9);
  Serial.print("\rCurrent time: " + String(timeString) + "     ");
  display.fillRect(0, 0, 127, 20, BLACK);
  display.setCursor(0x00, 0x12);
  display.print("Now ");
  display.print(timeString);
//  display.display();
  strcpy  (RemoteXY.curr_time, timeString);

  //check for a new day
  if (today != old_day) {
    GetOWM();
  }

  //Check RemoteXY app settings
  if (RemoteXY.pushSwitch_1 == 0)
  {
//    Serial.print("    OVERRIDE\r");
    O_status = "    OVERRIDE";
    digitalWrite(relay_control, (RemoteXY.switch_1 == 1) ? LOW : HIGH);
  }
  else
  {
    //**********
    
    if (secs_since(its_now) > secs_since(t_off) && secs_since(its_now) < secs_since(t_on))
      //	if ((localtime(&its_now)->tm_hour == localtime(&t_off)->tm_hour) && (localtime(&its_now)->tm_min == localtime(&t_off)->tm_min))
    { // We are in daylight
      strcpy  (RemoteXY.day_night, "DAY");
//      Serial.print("     DAY    ");
      O_status = "     DAY    ";
      digitalWrite(relay_control, HIGH);
    }
    else
      //	if ((localtime(&its_now)->tm_hour == localtime(&t_on)->tm_hour) && (localtime(&its_now)->tm_min == localtime(&t_on)->tm_min))
    { // We are at night
      strcpy  (RemoteXY.day_night, "NIGHT");
//      Serial.print("    NIGHT   ");
      O_status = "    NIGHT   ";
      digitalWrite(relay_control, LOW);
    }
//    Serial.print("\r");
  }

  //Indicators
  if (!digitalRead(relay_control)) {
    RemoteXY.led_1 = 1;
    display.fillRect(114, 0, 13, 63, WHITE);
  }
  else {
    RemoteXY.led_1 = 0;
    display.fillRect(114, 0, 13, 63, BLACK);
  }
  //*****************************************
  //          For IFTTT
  if (digitalRead(relay_control) != old_relay_control) {
    // Send Webhook to IFTTT
    IFTTT_Value2 = (digitalRead(relay_control) == LOW ? "ON" : "OFF");
    send_webhook();
//    Serial.println("Sent webhook ");
    old_relay_control = digitalRead(relay_control);
  }
  //*****************************************
  display.display();

    SetBackLights();
}  //End TimeCheck()


void SetBackLights() {

//  Serial.print("----------");
//  Serial.print(client.connect(server, 80));   // Connection to the server
  client.connect(server, 80);   // Connection to the server
//  Serial.print(".");
  String mesg = "HIGH";
  if (!digitalRead(relay_control)) {
    mesg = "LOW";
  }
  client.println(mesg);  // sends the message to the server
  client.println("\r");
  String answer = client.readStringUntil('\r');   // receives the answer from the sever
//  Serial.print(" - from server: " + answer);
  client.flush();
}  //End SetBackLights


String formatTimestamp(const char* fmt, time_t ctm ) {
  char buf[80];
  struct tm* t = localtime(&ctm);
  strftime(buf, sizeof(buf), fmt, t);
  return String(buf);
}  //End formatTimestamp

void send_webhook() {
  // construct the JSON payload
  String jsonString = "";
  jsonString += "{\"value1\":\"";
  jsonString += IFTTT_Value1;
  jsonString += "\",\"value2\":\"";
  jsonString += IFTTT_Value2;
  jsonString += "\",\"value3\":\"";
  jsonString += IFTTT_Value3;
  jsonString += "\"}";
  int jsonLength = jsonString.length();
  String lenString = String(jsonLength);
  // construct the POST request
  String postString = "";
  postString += "POST /trigger/";
  postString += IFTTT_Event;
  postString += "/with/key/";
  postString += IFTTT_Key;
  postString += " HTTP/1.1\r\n";
  postString += "Host: maker.ifttt.com\r\n";
  postString += "Content-Type: application/json\r\n";
  postString += "Content-Length: ";
  postString += lenString + "\r\n";
  postString += "\r\n";
  postString += jsonString; // combine post request and JSON
  // connect to the Maker event server
  client.connect("maker.ifttt.com", 80);
  client.print(postString);
  //  Serial.println("\r\n" + postString);
  delay(500);
  client.stop();
}  //End send_webhook

long secs_since(time_t given_time){
    struct tm *gtime;
    gtime = localtime(&given_time);
    return(gtime->tm_sec + 60L*(60L*gtime->tm_hour + gtime->tm_min));
}

User avatar
adafruit_support_carter
 
Posts: 29151
Joined: Tue Nov 29, 2016 2:45 pm

Re: Problem with SSD1306 and ESP8266

Post by adafruit_support_carter »

Try using setPins() to set the I2C pins instead of passing them in the call to begin()
https://github.com/espressif/arduino-esp32/issues/3779

User avatar
helzayat
 
Posts: 5
Joined: Sun Mar 26, 2023 8:29 am

Re: Problem with SSD1306 and ESP8266

Post by helzayat »

Seems setPins is not supported in the library I have.

Code: Select all

'class TwoWire' has no member named 'setPins'

User avatar
helzayat
 
Posts: 5
Joined: Sun Mar 26, 2023 8:29 am

Re: Problem with SSD1306 and ESP8266

Post by helzayat »

helzayat wrote: Tue May 02, 2023 6:05 pm ...the pixels jump around the screen, text changes size and position.
I thought I would illustrate this. The top part of the image shows how sometimes the Adafruit logo is distorted right from the begining. The middle part is what the display should look like, and does sometimes. The bottom is an example of the distortion I am talking about.
Attachments
Adafruit.jpg
Adafruit.jpg (97.72 KiB) Viewed 922 times

User avatar
adafruit_support_carter
 
Posts: 29151
Joined: Tue Nov 29, 2016 2:45 pm

Re: Problem with SSD1306 and ESP8266

Post by adafruit_support_carter »

Oh, that's right, setPins() is in the ESP32 BSP, but not the ESP8266.

What's the change made to the working code that makes it no longer work?

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”