Duda Inicio de SSD1306 y Programación

Buenas a todos,

Tengo un desarrollo que funciona y realiza el cometido, sin embargo he querido sumar una SSD1306 SPI (7 pines).
Después de varias pruebas y ensayos, por lo que me pude dar cuenta, que todo se limita al espacio de memoria.

El problema es que, cuando inicializo la SSD1306 , el resto de programa no sigue su curso, pero si deshabilito la SSD1306, todo sigue normal.

El flujo es el siguiente :

  • Inicio de sensores
    1- Lectura de Sensores
    2- Se envía al puerto de Serie los datos de los sensores (recogidos por un ESP01)
    3- El ESP01, retorna vía serial una respuesta a la información recibida
    4- Se controla la temperatura con PID
    5- Punto 1

Al flujo he agregado la SSD1306 para una visualización local, este punto seria el
2.5- SSD1306 muestra los datos de los sensores y los setpoints.
( no pegare el programa del ESP01, ya que, no requiere atención y funciona perfectamente )

Agradezco desde ya cualquier comentario y/o ayuda a resolver.
Saludos.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_MOSI  11
#define OLED_CLK   13
#define OLED_DC     9
#define OLED_CS    10
#define OLED_RESET  8
#include <DHT.h>
#include <ArduinoJson.h>
#include <PID_v1.h>
#define DHTPIN1 4     // Digital pin connected to the DHT sensor
#define RELE 6
#define PIN_OUTPUT 7
#define termistorPin A0
#define termistorNominalRes 100000
#define termistorNominalTemp 25
#define termistorBValue 3950
#define VoltageDividerResistor 100000
DHT dht1(DHTPIN1, DHT11);
bool lDisplay = true; // Variable para habiltar el inicio de la SSD1306
float termistorRes = 0.0;
float steinhart;
double Setpoint, Input, Output;
double consKp=90, consKi=30, consKd=80;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
String message;
bool switchRele = 0;
bool switchData = true;
int rele = 0;
//Set Time 1
unsigned long stamp1 = 0;
unsigned long stamp2 = 0;
unsigned long diftim1 = 0;
// Set Time 3
unsigned long stamp5 = 0;
unsigned long stamp6 = 0;
unsigned long diftim3 = 0;
String inputString = ""; 
boolean stringComplete = false; 
float h1 = 1.00;
float t1 = 1.00;
float t2 = 1.00;
float SetH = 1.00;
float SetT = 1.00;
float SetN = 1.00;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void setup() { 
  Serial.begin(9600);
  stamp1 = millis();
  stamp5 = millis();
  pinMode(RELE,OUTPUT);
  digitalWrite(RELE, switchRele); 
  delay(1000);
  dht1.begin();
  Input = analogRead(termistorPin);
  Setpoint = 30; // SetPoint de seguridad inicial
  myPID.SetMode(AUTOMATIC);
  if(lDisplay){
    if(!display.begin(SSD1306_SWITCHCAPVCC)) {
      lDisplay = false;
    }else{  
      display.display();
      delay(2000);
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.cp437(true);
    }
  }
}
void loop() {
  stamp2 = millis();
  diftim1 = stamp2-stamp1;
  stamp6 = millis();
  diftim3 = stamp6-stamp5;
  if( (diftim1/1000)>=10&&switchData==false ){
    switchData=true;
    stamp1=millis();
  }
  LecturaTemp(); // Sensor NTC de impresora 3D
  Sensores();
  if(stringComplete){
    message=inputString;
    inputString="";
    stringComplete=false;
    Serial.flush();
    StaticJsonDocument<300> datos;
    datos.clear();
    DeserializationError error = deserializeJson(datos, message);
    JsonObject root = datos.as<JsonObject>();
    Serial.println(message);
    if(root["data"]=="nano"){
      //Valor de SetPoint
      SetH = root["dht11A_hum"].as<float>();
      SetT = root["dht11A_tem"].as<float>();
      SetN = root["dht11B_tem"].as<float>();
      Setpoint = root["setpoint"].as<double>(); // Setpoint variable segun la condicion presente
      rele = root["rele5v"];
      if(rele!=switchRele){
        switchRele=rele;
        digitalWrite(RELE,switchRele);
      }//IF Rele
    }// data Nano
  }
  yield();
}
void serialEvent() {
  while (Serial.available()&&!stringComplete) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }//If inChar
  } // Fin While
  if(lDisplay) Oled((int)h1,(int)t1,(int)steinhart,(int)SetH,(int)SetT,(int)SetN);
}
void Sensores(){
  if(switchData){
    switchData = false;    
    delay(2000); // Esperamos 2 segundos para medir los sensores
    h1 = dht1.readHumidity();
    t1 = dht1.readTemperature();
    if (isnan(h1) || isnan(t1)) {
      h1 = 1.00;t1 = 1.00;
      Output = 0.0;
    }else{
      // Datos a enviar
      Serial.print("{'data':'esp8266','estado':0,'humedadA':"+String(h1)+",'tempboxA':"+String(t1)+",'setpoint':"+String(Setpoint)+",'tempboxB':"+String((int)steinhart)+",'rele5v':2,'Mensaje':''}\n");
    }
  }// IF switchData  
}
void LecturaTemp(){
  if( (diftim3/1000)>=1 ){
    termistorRes = ((float)analogRead (termistorPin)* VoltageDividerResistor)/(1023 - (float)analogRead (termistorPin));
    steinhart = termistorRes / termistorNominalRes;     // (R/Ro)
    steinhart = log(steinhart);                         // ln(R/Ro)
    steinhart /= termistorBValue;                       // 1/B * ln(R/Ro)
    steinhart += 1.0 / (termistorNominalTemp + 273.15); // + (1/To)
    steinhart = 1.0 / steinhart;                        // Invert  
    steinhart -= 273.15;
    Input = steinhart;
    myPID.Compute();
    analogWrite(PIN_OUTPUT, Output);
    stamp5=millis();
  }
}
void Oled(int valor1, int valor2, int valor3, int set1, int set2, int set3){
  display.clearDisplay();
  display.display();
  //display.drawPixel(127, 63, WHITE); // This command will help you to print a pixel on display , its the last pixel, coordinate 127,63
  //display.drawPixel(0, 0, WHITE); // pixel with 0,0 coordinate
  /* ---------TITULO---------- */
  //display.drawRect(0, 0, display.width()-2, 13, SSD1306_WHITE);
  display.setCursor((display.width()/2)-23,3);
  display.setTextSize(1);
  display.println("MONITOR");
  /* ---VALOR HUMEDAD CAJA---- */
  display.setTextSize(1);
  display.setCursor(2,20);
  display.print("Hum : ");
  display.print(valor1);
  display.print((char)37);
  /* ----VALOR TEMPERATURA CAJA*/
  display.setTextSize(1);
  display.setCursor(2,28);
  display.print("Tem : ");
  display.print(valor2);
  display.print((char)248);
  /* ----VALOR TEMPERATURA NTC */
  display.setTextSize(1);
  display.setCursor(2,36);
  display.print("NTC : ");
  display.print(valor3);
  display.print((char)248);
  display.setCursor(2,55);
  display.print("H:");
  display.print(set1);
  display.setCursor(42,55);
  display.print("T:");
  display.print(set2);
  display.setCursor(82,55);
  display.print("N:");
  display.print(set3);
  display.display();
}

Porque no nos disces que Arduino usas?
La compilación que dice al final cuanta flash y RAM usa?

Arduino Nano V3

El Sketch usa 26568 bytes (86%) del espacio de almacenamiento de programa. El máximo es 30720 bytes.
Las variables Globales usan 860 bytes (41%) de la memoria dinámica, dejando 1188 bytes para las variables locales. El máximo es 2048 bytes.
C:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -V -patmega328p -carduino -PCOM11 -b115200 -D -Uflash:w:C:\Users\LENOVO~1\AppData\Local\Temp\arduino_build_992923/MonitorNano.ino.hex:i

avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
         System wide configuration file is "C:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM11
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 3
         Firmware Version: 4.4
         Vtarget         : 0.3 V
         Varef           : 0.3 V
         Oscillator      : 28.800 kHz
         SCK period      : 3.3 us
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "C:\Users\LENOVO~1\AppData\Local\Temp\arduino_build_992923/MonitorNano.ino.hex"
avrdude: writing flash (26568 bytes):

Writing | ################################################## | 100% 4.37s

avrdude: 26568 bytes of flash written

avrdude done.  Thank you.

Tambien sucede que :
al cambiar este linea

StaticJsonDocument<300> datos;

por otro valor (como por ejemplo) :

StaticJsonDocument<150> datos;

El SSD1306 no me inicia, y si uso el StaticJsonDocument antes del setup(), también me bloquea el inicio del SSD1303.

Moderador:
Por favor, lee las Normas del foro. En el futuro edita tu código/error usando etiquetas de código, aunque solo sea una línea.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en </>


Observa estos datos al programara

El Sketch usa 26568 bytes (86%) del espacio de almacenamiento de programa. El máximo es 30720 bytes.
Las variables Globales usan 860 bytes (41%) de la memoria dinámica, dejando 1188 bytes para las variables locales.

Debes vigilar el consumo de RAM.
Creo que usas un UNO de modo que es posible que se quede sin memoria dinámica.
Por lo que muestras no sería el caso.

Ok, entiendo. Mis disculpa por eso. Creo que ya he reparado la publicación.
Saludos

Estoy Usando Arduino Nano Genérico. Estoy Tratando de optimizar el código. Pero aun no tengo alguna idea de como Saber cuanto y como.

Saludos

He realizado algunos cambios, pero el problema principal que tengo es el siguiente :
Si se inicializa el SSD1306, los datos por SERIAL no se envían, tampoco reciben.
Si no inicializa el SSD1306, los datos si envían y también se reciben.

He optimizado bastante la RAM, pero aun no me queda claro, cuanto mas de optimizar para que el SSD1306 funcione e inicialice junto con la lógica del SERIAL.

Cuando se inicia el OLED, es como si bloquera el puerto serial y no permite el envío ni la recepción, sera que, de alguna forma al iniciarse en modo SPI, el puerto RX/TX de Arduino nano se bloquea?.

Si modifico este dato :

 StaticJsonDocument<235> datos; // CON ESTA LINEA NO SE INICIALIZA LA SSD1306

Por este otro

 StaticJsonDocument<236> datos; // CON ESTA LINEA SI SE INICIALIZA LA SSD1306

Resultado Monitor

Código Actualizado

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <ArduinoJson.h>
#include <PID_v1.h>
#define DHTPIN1 4     // Digital pin connected to the DHT sensor
#define RELE 6
#define PIN_OUTPUT 7
#define termistorPin A0
#define termistorNominalRes 100000
#define termistorNominalTemp 25
#define termistorBValue 3950
#define VoltageDividerResistor 100000
DHT dht1(DHTPIN1, DHT11);
bool lDisplay = true;
double termistorRes = 0.0;
double steinhart;
double Setpoint, Input, Output;
double consKp=90, consKi=30, consKd=80;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
String message;
bool switchRele = 0;
bool switchData = true;
byte rele = 0;
//Set Time 1
unsigned long stamp1 = 0;
unsigned long stamp2 = 0;
unsigned long diftim1 = 0;
// Set Time 3
unsigned long stamp5 = 0;
unsigned long stamp6 = 0;
unsigned long diftim3 = 0;
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
byte h1 = 1.00;
byte t1 = 1.00;
byte t2 = 1.00;
byte SetH = 1.00;
byte SetT = 1.00;
byte SetN = 1.00;
Adafruit_SSD1306 display(128, 64,11, 13, 9, 8, 10);
void setup() { 
  Serial.begin(9600);
  stamp1 = millis();
  stamp5 = millis();
  pinMode(RELE,OUTPUT);
  digitalWrite(RELE, switchRele); 
  delay(1000);
  dht1.begin();
  Input = analogRead(termistorPin);
  Setpoint = 30; // SetPoint de seguridad inicial
  myPID.SetMode(AUTOMATIC);
  if(lDisplay){
    if(!display.begin(SSD1306_SWITCHCAPVCC)) {
      lDisplay = false;
    }else{  
      display.display();
      delay(2000);
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.cp437(true);
    }
  }
}
void loop() {
  stamp2 = millis();
  diftim1 = stamp2-stamp1;
  stamp6 = millis();
  diftim3 = stamp6-stamp5;
  if( (diftim1/1000)>=10&&switchData==false ){
    switchData=true;
    stamp1=millis();
  }
  LecturaTemp(); // Sensor NTC de impresora 3D
  Sensores();
  if(stringComplete){
    message=inputString;
    inputString="";
    stringComplete=false;
    Serial.flush();
    StaticJsonDocument<235> datos;
    datos.clear();
    DeserializationError error = deserializeJson(datos, message);
    JsonObject root = datos.as<JsonObject>();
    Serial.println(message);
    if(root["data"]=="nano"){
      //Valor de SetPoint
      SetH = root["dht11A_hum"].as<byte>();
      SetT = root["dht11A_tem"].as<byte>();
      SetN = root["dht11B_tem"].as<byte>();
      Setpoint = root["setpoint"].as<byte>(); // Setpoint variable segun la condicion presente
      rele = root["rele5v"];
      if(rele!=switchRele){
        switchRele=rele;
        digitalWrite(RELE,switchRele);
      }//IF Rele
    }// data Nano
  }
  yield();
}
void serialEvent() {
  while (Serial.available()&&!stringComplete) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }//If inChar
  } // Fin While
  if(lDisplay) Oled((byte)h1,(byte)t1,(byte)steinhart,(byte)SetH,(byte)SetT,(byte)SetN);
}
void Sensores(){
  if(switchData){
    switchData = false;    
    delay(2000); // Esperamos 2 segundos para medir los sensores
    h1 = dht1.readHumidity();
    t1 = dht1.readTemperature();
    if (isnan(h1) || isnan(t1)) {
      h1 = 1.00;t1 = 1.00;
      Output = 0.0;
    }else{
      // Datos a enviar
      Serial.print("{'data':'esp8266','estado':0,'humedadA':"+String(h1)+",'tempboxA':"+String(t1)+",'setpoint':"+String(Setpoint)+",'tempboxB':"+String(steinhart)+",'rele5v':2,'Mensaje':''}\n");
    }
  }// IF switchData  
}
void LecturaTemp(){
  if( (diftim3/1000)>=1 ){
    termistorRes = ((byte)analogRead (termistorPin)* VoltageDividerResistor)/(1023 - (byte)analogRead (termistorPin));
    steinhart = termistorRes / termistorNominalRes;     // (R/Ro)
    steinhart = log(steinhart);                         // ln(R/Ro)
    steinhart /= termistorBValue;                       // 1/B * ln(R/Ro)
    steinhart += 1.0 / (termistorNominalTemp + 273.15); // + (1/To)
    steinhart = 1.0 / steinhart;                        // Invert  
    steinhart -= 273.15;
    Input = steinhart;
    myPID.Compute();
    analogWrite(PIN_OUTPUT, Output);
    stamp5=millis();
  }
}
void Oled(byte valor1, byte valor2, byte valor3, byte set1, byte set2, byte set3){
  display.clearDisplay();
  /* ---------TITULO---------- */
  //display.drawRect(0, 0, display.width()-2, 13, SSD1306_WHITE);
  display.setCursor((display.width()/2)-23,3);
  display.setTextSize(1);
  display.print(F("MONITOR"));
  OledLine2(2,20,F("HUM : "),valor1,37);
  OledLine2(2,28,F("TEM : "),valor2,248);
  OledLine2(2,36,F("NTC : "),valor3,248);
  OledLine1(2,55,F("H:"),set1);
  OledLine1(42,55,F("T:"),set2);
  OledLine1(82,55,F("N:"),set3);
  display.display();
}
void OledLine1(byte y, byte x, String titulo, byte nvl){
  display.setCursor(y,x);
  display.print(titulo);
  display.print(nvl);
}
void OledLine2(byte y, byte x, String titulo, byte nvl, byte caracter){
  display.setCursor(y,x);
  display.print(titulo);
  display.print(nvl);
  display.print((char)caracter);
}

Compilación

El Sketch usa 26124 bytes (85%) del espacio de almacenamiento de programa. El máximo es 30720 bytes.
Las variables Globales usan 808 bytes (39%) de la memoria dinámica, dejando 1240 bytes para las variables locales. El máximo es 2048 bytes.
C:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -V -patmega328p -carduino -PCOM11 -b115200 -D -Uflash:w:C:\Users\LENOVO~1\AppData\Local\Temp\arduino_build_843949/MonitorNano.ino.hex:i 

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\LenovoG450\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM11
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 3
         Firmware Version: 4.4
         Vtarget         : 0.3 V
         Varef           : 0.3 V
         Oscillator      : 28.800 kHz
         SCK period      : 3.3 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "C:\Users\LENOVO~1\AppData\Local\Temp\arduino_build_843949/MonitorNano.ino.hex"
avrdude: writing flash (26124 bytes):

Writing | ################################################## | 100% 4.31s

avrdude: 26124 bytes of flash written

avrdude done.  Thank you.

Hola a todos, he resuelto el problema usando la librería U8GLib, me permitió optimizar de mejor manera la programación y ya no se bloquea el puerto de serie.

Saludos y gracias a todos.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.