two arduinos communicating via i2c with an OLED

note: I posted this in the programming questions forum but figured this forum may be better suited for my question!

I am trying to connect two arduinos and an OLED display via i2c but am running into some problems. The goal is to send a value from one arduino to the other, then to print that value on an OLED screen. I've attached the code for both devices:

Here is the code for the arduino that is sending data. A button is pushed and sends the value (either 1 or 0) to the other arduino.

#include <Wire.h>

int x = 0;
int led = 13;
int slaveAddress = 9;

const int buttonPin = 2; // the number of the pushbutton pin
int buttonState = 0; // variable for reading the pushbutton status

void setup(){
  pinMode(led, OUTPUT);
  pinMode( buttonPin, INPUT ); // initialize the pushbutton pin as an input
  Wire.begin(); // join i2c bus (address optional for master)
}

void loop(){

  buttonState = digitalRead( buttonPin );
  if ( buttonState == HIGH ){
    x = 1;
    digitalWrite(led, HIGH);
  }
  else{
    x = 0;
    digitalWrite(led, LOW);
  }

  Wire.beginTransmission( 9 ); // transmit to device #9
  Wire.write(x); // sends x
  Wire.endTransmission(); // stop transmitting
  delay(10);
}

Here is the code for the recieving arduino and the OLED. I want it to read the value from the first arduino and print the value on the OLED screen. On both arduinos there is an LED indicator to show the value of x.

#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <splash.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

Adafruit_SSD1306 display;  // Create display
#include <Fonts/FreeMonoBold12pt7b.h>  // Add a custom font
#include <Fonts/FreeMono9pt7b.h>  // Add a custom font

int LED = d[19];
int x = 0;

void setup() {
  pinMode (LED, OUTPUT);
  Wire.begin(9);
  Wire.onReceive(receiveEvent);

  delay(100);  // This delay is needed to let the display to initialize
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
  display.clearDisplay();  // Clear the buffer
  display.setTextColor(WHITE);  // Set color of the text
  display.setRotation(0);  // Set orientation. Goes from 0, 1, 2 or 3
  display.setTextWrap(false);
  display.dim(0);  //Set brightness (0 is maximun and 1 is a little dim)
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
}



void loop() {
 // delay(100);
      display.clearDisplay();  // Clear the display so we can refresh
      display.setFont(&FreeMono9pt7b);  // Set a custom font
      display.setTextSize(0);  // Set text size. We are using a custom font so you should always use the text size of 0
      display.setCursor(10, 10);  // (x,y)
      display.println(x);  // Text or value to print
      display.display();  // Print everything we set previously


  if (x == 1) {
    digitalWrite(LED, HIGH);
    // delay(200);
  }

  if (x == 0) {
    digitalWrite(LED, LOW);
    // delay(200);
  }

}  // End of loop

any help would be appreciated!

does your second Arduino with the OLED even write correctly to the OLED?

does the second Arduino even receive what the first Arduino is sending?
how did you verify this?

timyoyoyo:
I posted this in the programming questions forum...

Do not cross-post. Other thread removed.

@OP

The receiver code is slightly changed. Give a try and report the result.

#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <splash.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

Adafruit_SSD1306 display;  // Create display
#include <Fonts/FreeMonoBold12pt7b.h>  // Add a custom font
#include <Fonts/FreeMono9pt7b.h>  // Add a custom font

int LED = d[19];
volatile int x = 0;
volatile bool flag1 = false;

void setup() {
  pinMode (LED, OUTPUT);
  Wire.begin(9);
  Wire.onReceive(receiveEvent);

  delay(100);  // This delay is needed to let the display to initialize
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
  display.clearDisplay();  // Clear the buffer
  display.setTextColor(WHITE);  // Set color of the text
  display.setRotation(0);  // Set orientation. Goes from 0, 1, 2 or 3
  display.setTextWrap(false);
  display.dim(0);  //Set brightness (0 is maximun and 1 is a little dim)
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
  flag1 = true;
}



void loop() 
{
   if(flag1==true)
   { 

// delay(100);
      display.clearDisplay();  // Clear the display so we can refresh
      display.setFont(&FreeMono9pt7b);  // Set a custom font
      display.setTextSize(0);  // Set text size. We are using a custom font so you should always use the text size of 0
      display.setCursor(10, 10);  // (x,y)
      display.println(x);  // Text or value to print
      display.display();  // Print everything we set previously


 // if (x == 1) 
  //{
    digitalWrite(LED, HIGH);
    // delay(200);
  //}

 // if (x == 0) 
  //{
   // digitalWrite(LED, LOW);
    // delay(200);
 // }
  flag1 = false;
 }

}  // End of loop

ieee488:
does your second Arduino with the OLED even write correctly to the OLED?

does the second Arduino even receive what the first Arduino is sending?
how did you verify this?

I have both parts of the code independently verified, with out the i2c communication from arduino 1, the screen works properly. Without the screen attached, the second arduino receives the value x from the first arduino.

[quote author=Coding Badly link=msg=4122393 date=1554269850]
Do not cross-post. Other thread removed.[/quote]

Sorry about that!

GolamMostafa:
@OP

The receiver code is slightly changed. Give a try and report the result.

#include <Wire.h>

#include <Adafruit_SSD1306.h>
#include <splash.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>

Adafruit_SSD1306 display;  // Create display
#include <Fonts/FreeMonoBold12pt7b.h>  // Add a custom font
#include <Fonts/FreeMono9pt7b.h>  // Add a custom font

int LED = d[19];
volatile int x = 0;
volatile bool flag1 = false;

void setup() {
  pinMode (LED, OUTPUT);
  Wire.begin(9);
  Wire.onReceive(receiveEvent);

delay(100);  // This delay is needed to let the display to initialize
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
  display.clearDisplay();  // Clear the buffer
  display.setTextColor(WHITE);  // Set color of the text
  display.setRotation(0);  // Set orientation. Goes from 0, 1, 2 or 3
  display.setTextWrap(false);
  display.dim(0);  //Set brightness (0 is maximun and 1 is a little dim)
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
  flag1 = true;
}

void loop()
{
  if(flag1==true)
  {

// delay(100);
      display.clearDisplay();  // Clear the display so we can refresh
      display.setFont(&FreeMono9pt7b);  // Set a custom font
      display.setTextSize(0);  // Set text size. We are using a custom font so you should always use the text size of 0
      display.setCursor(10, 10);  // (x,y)
      display.println(x);  // Text or value to print
      display.display();  // Print everything we set previously

// if (x == 1)
  //{
    digitalWrite(LED, HIGH);
    // delay(200);
  //}

// if (x == 0)
  //{
  // digitalWrite(LED, LOW);
    // delay(200);
// }
  flag1 = false;
}

}  // End of loop

I'm afraid this didnt change much, the value being printed on the screen stays at the initialized value of 0

I am trying to connect two arduinos and an OLED display via i2c but am running into some problems. The goal is to send a value from one arduino to the other, then to print that value on an OLED screen. I've attached the code for both devices:

That won't ever work reliably. Why did you choose that setup? Why is the display not written by the first Arduino?

You don't do any precautions to avoid that the first Arduino is sending data to the second while that one is sending data to the display.

It's generally a bad idea to have multiple masters on the same I2C bus.

I resolved the problem, kind of. The code works properly when I use an arduino nano as the reciever and OLED controller. I was previously using a homemade arduino zero board but that doesnt seem to be working properly with I2C stuff. I suppose my problem lies therein.

pylon:
That won't ever work reliably. Why did you choose that setup? Why is the display not written by the first Arduino?

You don't do any precautions to avoid that the first Arduino is sending data to the second while that one is sending data to the display.

It's generally a bad idea to have multiple masters on the same I2C bus.

I'm pretty new to the I2C stuff and dont really understand it completely but I was using this sketch to try and accomplish the goal of having text stored on one arduino, and when it is connected to the other arduino via I2C, the text on that first arduino would appear on the screen.

What would be a better way to accomplish this?

What would be a better way to accomplish this?

Why not connecting the display directly to the first Arduino? How far are the two Arduinos apart? If they are next to each other, connecting them by SPI would be an alternative that doesn't collide with the display connection.

At most they will be 5 inches or so away from each other. So it seems that i2c is out of the question? SPI is an option, I was just hoping to save a few pins.

At most they will be 5 inches or so away from each other. So it seems that i2c is out of the question? SPI is an option, I was just hoping to save a few pins.

You can also connect them by UART if you don't need that hardware for other tasks (debugging, etc.). You didn't specify any limitations so we are usually free to use any functionality the Arduino offers.

You still didn't answer the question why it's not possible from your perspective to connect the display directly to the first Arduino and omitting the second completely.

The reason I need the two arduino set up is because arduino 1 (containting the text information) needs to be removable and changeable by the user. This way different arduinos can store different text information. I'm trying to create a similar experience to classic cartridge based video games.

timyoyoyo:
The reason I need the two arduino set up is because arduino 1 (containting the text information) needs to be removable and changeable by the user. This way different arduinos can store different text information. I'm trying to create a similar experience to classic cartridge based video games.

Do you need Arduino 1 just to store texts? A much cheaper way to achieve this is to use an I2C EEPROM chip (p.e. 24LC64). You can simply attach this to the I2C bus of the Arduino with the display and read out the text messages as you like. You even get more capacity.

along with storing and sending text data, I will also be using that arduino to store 4kb of data that will write info to a 24lc32a eeprom. a few devices interacting here.