Have a problem with mapping a data on OLED I2C 128×64 (SSD1306)

I have two arduino nano boards.
The first arduino receives a altutude and temperature from bmp280 via I2C. Then this arduino sends these values on the second board via SPI. I used (d7 pin for it).

Master code

Спойлер

#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <Wire.h>

Adafruit_BMP280 bmp;

void setup (void) {
Serial.begin(115200); //set baud rate to 115200 for usart

if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "
"try a different address!"));
while (1) delay(10);
}

bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. /
Adafruit_BMP280::SAMPLING_X2, /
Temp. oversampling /
Adafruit_BMP280::SAMPLING_X16, /
Pressure oversampling /
Adafruit_BMP280::FILTER_X16, /
Filtering. /
Adafruit_BMP280::STANDBY_MS_500); /
Standby time. */

digitalWrite(7, HIGH); // disable Slave Select
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}

void loop (void) {
char c;
String data = String(bmp.readTemperature()) + ";" + String(bmp.readAltitude(1013.25)) + "\r";
digitalWrite(7, LOW); // enable Slave Select
// send test string
char* dataStr = data.c_str();
for (const char * p = dataStr ; c = *p; p++) {
SPI.transfer (c);
Serial.print(c);
}
digitalWrite(7, HIGH); // disable Slave Select
delay(200);
}

The second arduino receives these data via SPI and map it on the OLED display (via I2C).

Спойлер

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif9pt7b.h>
#include <OneTouch.h>

char buff [50];
volatile byte indx;
volatile boolean process;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

OneTouch first_button(2);
OneTouch second_button(3);

int y_coordinate = 5;
int i = 0;
//String par_names[8] = {"1.Date:", "2.Time:", "3.Alt.:", "4.Speed:", "5.Accel.:", "6.Gyro.:", "7.GPS:", "8.Pres.:"};

void setup (void) {

Serial.begin (115200);

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
Serial.println("SSD1306 allocation failed");
for(;;);

}

delay(200);

display.clearDisplay();
display.setTextSize(1.7);
display.setTextColor(WHITE);

delay(200);

pinMode(MISO, OUTPUT); // have to send on master in so it set as output
SPCR |= _BV(SPE); // turn on SPI in slave mode
indx = 0; // buffer empty
process = false;
SPI.attachInterrupt(); // turn on interrupt
}

ISR (SPI_STC_vect){
byte c = SPDR; // read byte from SPI Data Register
if (indx < sizeof buff) {
buff [indx++] = c; // save data in the next index in the array buff
if (c == '\r') //check for the end of the word
process = true;
}
}

char k[50];
void loop (void) {

display.display();

if (process) {
process = false; //reset the process
//Serial.println (buff); //print the array on serial monitor
indx= 0; //reset button to zero

  for (int i = 0; i < 50; i++){
    k[i] = buff[i];
    //Serial.print(k[i]);
  }
  //Serial.println();

}

String temporary = String(k);


String temper = "";
temper.concat(temporary.charAt(0));  temper.concat(temporary.charAt(1)); 
temper.concat(temporary.charAt(2)); temper.concat(temporary.charAt(3));
temper.concat(temporary.charAt(4)); temper.concat(" C");

Serial.println(temper);

String par_names[8] = {"1.Temp: " + temper, "2.Alt: ", "3.Day.:",
"4.Speed:", "5.Accel.:", "6.Gyro.:",
"7.GPS:", "8.Pres.:"};

display.clearDisplay();
display.setCursor(0,y_coordinate);
display.println(par_names[i]);

display.setCursor(0,y_coordinate + 20);
display.println(par_names[i + 1]);

display.setCursor(0,y_coordinate + 40);
display.println(par_names[i + 2]);

display.display();

  if (first_button.get_state()){
    
    if (i > 0 ){
    i -= 1;
    }
  }



  if (second_button.get_state()){
      
     if (i < 5){
     i += 1;
     }
  }

delay(50);

}

It does not display first row. Also I the buttons don't work. It looks like it hangs.

I am newbie in Arduino, I know the code is not optimized :sweat_smile:

I can not find OneTouch.h anywhere.

It is not supported by the IDE Library Manager.
Google did not find it.

I strongly advise using libraries that are supported by the Library Manager.
Otherwise we can not compile your code.

David.

1 Like

this is my own library for button
VipNooob/OneTouch_Arduino_Button (github.com)

I copied "OneTouch.h" and "OneTouch.cpp" to local tabs in the sketch.

Then built for a Uno.

Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.13\hardware\arduino\avr\libraries\SPI 
Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.13\hardware\arduino\avr\libraries\Wire 
Using library Adafruit_GFX_Library at version 1.10.10 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library 
Using library Adafruit_SSD1306 at version 2.4.6 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_SSD1306 
Using library Adafruit_BusIO at version 1.7.3 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_BusIO 
"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_147669/vipnoob_ssd1306.ino.elf"
Sketch uses 16186 bytes (50%) of program storage space. Maximum is 32256 bytes.
Global variables use 733 bytes (35%) of dynamic memory, leaving 1315 bytes for local variables. Maximum is 2048 bytes.

Since your sketch will allocate 1024 bytes at run-time, you will only have 1315-1024=291 bytes for stack and local variables.

I would feel happy with 291 bytes if there was no String use.

David.

1 Like

I am sorry, but could you tell me where did you take 1024 bytes ?

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
...
void setup (void) {

    Serial.begin (115200);

    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { //allocates 128x64 buffer
        Serial.println("SSD1306 allocation failed"); //allocation fails
        for (;;);
    }
    // allocation succeeds but does not reserve any room for stack
    ...

Now do you see ?

David.

1 Like

Thank you a lot! I got the problem, what can you advice to solve it ?

Read this similar thread Random garbage ASCII chars on display?

Personally, I would avoid dynamic String
Life is much easier with regular C char arrays

You don't seem to have much anonymous data. (which is what most Arduino programs have)

If SRAM is your problem you could see if the program works on a Leo or Mega2560.

David.

1 Like