I2C Two Arduinos reacting to each other

Hi!

I would like to establish a two-way communication between Arduino 1 and Arduino 2 using I2C.

Arduino 1 has a weight-sensor with an HX711 connected to it & a ZS040 bluetooth module.
Arduino 2 has a button and a LED connected to it.

If the weight sensor exceeds a certain weight-limit, the LED at Arduino 2 should light up.
If the LED is lit AND the button connected to Arduino 2 is pressed, Arduino 1 should send a bluetooth-signal to the computer to initiate Mouse.press.

At the moment Arduino 2 is the Master with this code:

#include <Wire.h>

int LED = 13;
int button = 2;
int mouse_send = 0;

void setup(){
  Wire.begin();
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(button, INPUT);
}

void loop(){
  buttonState = digitalRead(button);
  Wire.requestFrom(8,2);
  while (Wire.available()) {
    int weight_received = Wire.read(); 
    Serial.println(weight_received);
    if (weight_received == 2){
      digitalWrite(LED, HIGH);
      }
    if (weight_received == 3){
      digitalWrite(LED, LOW);
      }
    if (weight_received == 2 && button == HIGH)){
      mouse_send = 4;
      Wire.beginTransmission(8);
      Wire.write(mouse);
      Wire.endTransmission();
      }
    if (button == LOW)){
      mouse_send = 5;
      Wire.beginTransmission(8);
      Wire.write(mouse);
      Wire.endTransmission();
      }
  }
}

And Arduino 1 is the Slave with this code:

#include "HX711.h"
#include <Wire.h>
#include <Mouse.h>
#define DOUT  5
#define CLK  4
HX711 scale(DOUT, CLK);

float calibration_factor = -7050;
int weight = 0;

void setup(){
 Wire.begin(8);
 Serial.begin(9600);
 Wire.onReceive(receiveEvent);
 scale.tare();
 long zero_factor = scale.read_average(); 
 Serial.print("Zero factor: ");
}


void receiveEvent(int bytes){
 int mouse_received = Wire.read();
 if (mouse_received == 4){
   Mouse.press();
 }
 if (mouse_received == 5){
   Mouse.release();
 }
}


void loop(){
 scale.set_scale(calibration_factor);
 delay(200);
 Serial.println(scale.get_units());
 if (scale.get_units() < -40.00) {
   int weight = 2;
   Wire.write(weight);
 }
 if (scale.get_units() > -40.00) {
   int weight = 3;
   Wire.write(weight);
 }

}

The bluetooth is not connected because it didn't work like this connected to the laptop yet...
I think the problem is probably that I didn't understand the I2C communication completely.

Hope you can help and thanks in advance!

    int weight_received = Wire.read();

The read() method does NOT return an int.

    if (weight_received == 2 && button == HIGH)){

button is a poorly named variable containing a pin NUMBER not a pin STATE. 2 is NOT HIGH.

      Wire.beginTransmission(8);
      Wire.write(mouse);
      Wire.endTransmission();

You have NOT defined mouse or given it a value.

    if (button == LOW)){

2 is NOT LOW, either.

   int weight = 2;
   Wire.write(weight);

The write() method does NOT take an int.

Thanks a lot for the quick reply!
I think that helps already :slight_smile:
The main problem were the data types.

jasper_z:
I think the problem is probably that I didn't understand the I2C communication completely.

Implement the following points one-by-one and see if you can meet your objectives. Please add codes as needed including the missing codes.
1. Check that your hardware setup is very close to the following diagram.
i2cBusloadcell.png

Figure-1: Connection diagram between NANO (Arduino-1) and UNO (Arduino-2) using I2C Bus

2. Include the following codes at the appropriate place (s) of your NANO sketch o create I2C Bus.

#include<Wire.h>
Wire.begin(0x08); //Slves's I2C Bus address

3. It is not clear form your code if the data type of your weight is integer or float. I assume that it is a floating point number with 2-digit precision (xx.xx). Acquire floating point type (xx.xx) weight from the Load Cell and save into variable float weight;. I am assuming that the acquired weight is being compared with 40.35 (Limit of the Weight, kg). If the acquired weight exceeds 40.35 (kg), the NANO will send code 0x03 to the UNO over the I2C Bus. To implement these events, you may include the following lines in your NANO sketch.

void loop()
{
   acquireWeigh();    //this SUR will put weight into global variable float weight;
   if(weight > 40.35)
   {
      Wire.beginTransmission(0x19);   //UNO (the Master) is being accessed by NANO as Slave at address 0x19
      Wire.write(0x03);                      //I2C Bus always sends byte data (8-bit)
      Wire.endTransmission();
   }
   delay(1000);      //acquire weight at 1-sec interval
}

4. When UNO receives 0x03 from NANO, it will ignite L (the built-in LED of UNO). The user will observe that L is ON; so, he will press the button K1. In response, the UNO will send a code (say, 0x17) to NANO. To implement these events, you may include the following lines in your UNO sketch.

#include<Wire.h>
bool flag1 = false;

void setup()
{
    Serial.begin(9600);
    pinMode(13, OUTPUT);
    digitalWriet(13, LOW);
    pinMode(2, INPUT);      //button pin

    Wire.begin(0x19);   //UNO will be accessed by NANO at address 0x19
    Wire.onReceive(receiveEvent);
}

void loop()
{
    if(flag1 == true)
    {
       if(digitalRead(2) == HIGH)
       {
          Wire.beginTransmission(0x08);   //UNO is addressing NANO at address 0x08
          Wire.write(0x17);                      //UNO is sending code 0x17
          Wire.endTransmission();
          flag1 = false;
       }
    }
}

void receiveEvent(int howMany)
{
    byte x1 = Wire.read();
    if(x1 = 0x03)
    {
        digitalWrite(13, HIGH);   //L is ON
        flag1 = true;    //flag1 indicates that NANO has detected over weight
    }
}

5. The 0x17 will arrive to NANO from UNO (Arduino-2) via I2C Bus. When the code arrives to NANO, the NANO will be go out from its loop() function; it will enter to void receiveEvent(int howMany) sub-program (an interrupt context) and will read the code from the FIFO into a global variable (say x1). The following codes could be included in the NANO sketch:

Wire.onReceive(receiveEvent);  //this declaration should be made under setup()
void receiveEvent(int howMany)
{
   x1 = Wire.read();   //x1 = 0x17
   flag1 = true;          //indicates that UNO has received the over weight message
}

6. After the reception of code 0x17 from the UNO, the NANO will send a message ("over weight etected") to the PC via BT Module which is connected with NANO via Software UART Port (SUART). The following codes could be included in the NANO sketch to implement these tasks:

#include<SoftwareSerial.h>
SoftwareSerial SUART(6, 7);  //SRX = DPin-6, STX = DPin-7
SUART.begin(9600);

void loop()
{
   if(flag1 == true)
   {
       SUART.print(""over weight etected...!");
       flag1 = false;
   }

7. Please, post the progress!

i2cBusloadcell.png