Wire.read returning constant stream of data

Hello everyone. I'm having a tough time figuring out the error in my code. I have a bluetooth module on a Nano, which will send data to a Mega using Wire. Here is the code for the Nano+BT module:

char data = 0;

#define led 3
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(led, OUTPUT);
    
}
void loop()
{
   if(Serial.available() > 0)      // Send data only when you receive data:
    {
      data = Serial.read();
      Serial.print(data);
      Serial.print("\n");        
      digitalWrite(led, HIGH); // flash LED when BT command received
      delay(150);
      digitalWrite(led, LOW);
      Wire.beginTransmission(A4); // SDA on Mega
      Wire.write(data);
      Wire.endTransmission();
      int x = Wire.endTransmission();
      Serial.println(x, DEC);
    }
}

This module receives BT commands just fine, but Serial.println returns 2 for Wire.endTransmission.

Here is the code for the mega:

#include <Wire.h>
#define lights 4

int data;

void setup() {
  Wire.begin(20); // SDA
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes)
{
  data = Wire.read();
  Serial.print(data);
}

void loop() 
{
  if (data = 1) {
    analogWrite(lights,255);
    Serial.println(data);
  }
}

With that code, the serial monitor for the Mega returns a constant stream of 1's. I could change it to "if (data = 2)", but then it just returns a constant stream of 2's (even though the BT module is not sending a 2). I can also remove the receiveEvent code, but it still returns 1's. However if I change it to "if (data == 1)", then nothing is returned at all.

What am I doing wrong? Thank you in advance.

Not:

  if (data = 1) {

But:

  if (data == 1) {

wildbill:
Not:

  if (data = 1) {

But:

  if (data == 1) {

As I mentioned, having it be == instead of just = causes it to return nothing at all on the serial monitor.

      Serial.print(data);
      Serial.print("\n");

The traditional way to do that is "Serial.println(data);"

      Wire.beginTransmission(A4); // SDA on Mega

Why are you using the name of an analog input pins as a Wire address?!? This should be the address of the remote device. Since the code got the Mega says "Wire.begin(20);" this should say "Wire.beginTransmission(20);". Since A4 is not defined as 20 that would explain why none of the transmissions get to the destination address.

      Wire.endTransmission();
      int x = Wire.endTransmission();

Why are you calling "Wire.endTransmission()" twice?!?

Your codes should be like:

char data = 0;

#define led 3
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(led, OUTPUT);
   
}
void loop()
{
   if(Serial.available() > 0)      // Send data only when you receive data:
    {
      data = Serial.read();
      Serial.print(data);
      Serial.print("\n");       
      digitalWrite(led, HIGH); // flash LED when BT command received
      delay(150);
      digitalWrite(led, LOW);
      Wire.beginTransmission(20);//SlaveAddress(A4); // SDA on Mega
      Wire.write(data);
     // Wire.endTransmission();
      byte x = Wire.endTransmission();
      if (x != 0x00)
      {
         Serial.print("Transmission Problem...!");
         while(1); //wait for ever
      }
      Serial.println("Good Transmission.");//x, DEC);
    }

}

And:

#include <Wire.h>
#define lights 4
volatile bool flag1 = false;
int data;

void setup() 
{
  Wire.begin(20); // SDA
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes)
{
  //data = Wire.read();
  flag1 = true;//Serial.print(data);  //never ever issue print() command in this interrupt handler
}

void loop()
{
    if(flag1 == true)
    {
        data = Wire.read();
        if (data == 1) 
       {
          analogWrite(lights,255);
          Serial.println(data);
          flag1 = false;
       }
       else
       {
          flag1 = false;
       }
    }
 }

GolamMostafa:
Your codes should be like:

char data = 0;

#define led 3
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(led, OUTPUT);
 
}
void loop()
{
  if(Serial.available() > 0)      // Send data only when you receive data:
    {
      data = Serial.read();
      Serial.print(data);
      Serial.print("\n");     
      digitalWrite(led, HIGH); // flash LED when BT command received
      delay(150);
      digitalWrite(led, LOW);
      Wire.beginTransmission(20);//SlaveAddress(A4); // SDA on Mega
      Wire.write(data);
    // Wire.endTransmission();
      byte x = Wire.endTransmission();
      if (x != 0x00)
      {
        Serial.print("Transmission Problem...!");
        while(1); //wait for ever
      }
      Serial.println("Good Transmission.");//x, DEC);
    }

}




**And:**


#include <Wire.h>
#define lights 4
volatile bool flag1 = false;
int data;

void setup()
{
  Wire.begin(20); // SDA
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes)
{
  //data = Wire.read();
  flag1 = true;//Serial.print(data);  //never ever issue print() command in this interrupt handler
}

void loop()
{
    if(flag1 == true)
    {
        data = Wire.read();
        if (data == 1)
      {
          analogWrite(lights,255);
          Serial.println(data);
          flag1 = false;
      }
      else
      {
          flag1 = false;
      }
    }
}

Just tried it and it still doesn't work. In fact, upon booting the Nano, it will only read the first command and nothing more. I send it the digit 1, it Serial.println's a 1, then prints "Transmission Problem..." as your code states. Then it never prints another digit or flashes the LED until I reboot it, but the LED on the actual BT module itself flashes as if it received a digit. As for the Mega, it still doesn't recognize anything.

The return value from Wire.endTransmission() is:

byte, which indicates the status of the transmission:

It might be helpful to display the actual value:

      byte x = Wire.endTransmission();
      if (x != 0x00)
      {
         Serial.print("Transmission Problem! Wire.endTransmission() returned ");
         Serial.println(x);
         while(1); //wait forever
      }

I have performed a setup using NANO(Master) and MEGA(Slave) where I have uploaded your sketches (with slight modifications); the results are OK. Please, check your I2C bus wiring as follows (MEGA has built-in 2x10k pull-up with I2C bus):
NANO (A4/SDA) --------> MEGA (SDA/20)
NANO (A5/SCL) --------> MEGA (SCL/21)
NANO (GND) <---------> MEGA (GND)

NANO (Master) Sketch:

char data = 0;
#define led 3
#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(led, OUTPUT);

}
void loop()
{
  if (Serial.available() > 0)     // Send data only when you receive data:
  {
    data = Serial.read();
    Serial.println(data);
   // Serial.print("\n");
    digitalWrite(led, HIGH); // flash LED when BT command received
    delay(150);
    digitalWrite(led, LOW);
    Wire.beginTransmission(20);//SlaveAddress(A4); // SDA on Mega
    Wire.write(data);
    // Wire.endTransmission();
    byte x = Wire.endTransmission();
    if (x != 0x00)
    {
      Serial.print("Transmission Problem...!");
      while (1); //wait for ever
    }
    Serial.println("Good Transmission.");//x, DEC);
  }

}

MEGA(Slave) Sketch:

#include <Wire.h>
#define lights 4
volatile bool flag1 = false;
int data;

void setup()
{
  Wire.begin(20); // SDA
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes)
{
  //data = Wire.read();
  flag1 = true;//Serial.print(data);  //never ever issue print() command in this interrupt handler
}

void loop()
{
  if (flag1 == true)
  {
    data = Wire.read();
    if (data == '1')
    {
      analogWrite(lights, 255);
      Serial.println((char)data);
      flag1 = false;
    }
    else
    {
      flag1 = false;
    }
  }
}

Screen shot: NANO
nanoMas.png

Screen shot: MEGA
megaS.png

nanoMas.png

megaS.png

GolamMostafa:
I have performed a setup using NANO(Master) and MEGA(Slave) where I have uploaded your sketches (with slight modifications); the results are OK. Please, check your I2C bus wiring as follows (MEGA has built-in 2x10k pull-up with I2C bus):
NANO (A4/SDA) --------> MEGA (SDA/20)
NANO (A5/SCL) --------> MEGA (SCL/21)
NANO (GND) <---------> MEGA (GND)

NANO (Master) Sketch:

char data = 0;

#define led 3
#include <Wire.h>

void setup()
{
 Wire.begin();
 Serial.begin(9600);
 pinMode(led, OUTPUT);

}
void loop()
{
 if (Serial.available() > 0)     // Send data only when you receive data:
 {
   data = Serial.read();
   Serial.println(data);
  // Serial.print("\n");
   digitalWrite(led, HIGH); // flash LED when BT command received
   delay(150);
   digitalWrite(led, LOW);
   Wire.beginTransmission(20);//SlaveAddress(A4); // SDA on Mega
   Wire.write(data);
   // Wire.endTransmission();
   byte x = Wire.endTransmission();
   if (x != 0x00)
   {
     Serial.print("Transmission Problem...!");
     while (1); //wait for ever
   }
   Serial.println("Good Transmission.");//x, DEC);
 }

}




**MEGA(Slave) Sketch:**


#include <Wire.h>
#define lights 4
volatile bool flag1 = false;
int data;

void setup()
{
 Wire.begin(20); // SDA
 Wire.onReceive(receiveEvent);
 Serial.begin(9600);
}

void receiveEvent(int bytes)
{
 //data = Wire.read();
 flag1 = true;//Serial.print(data);  //never ever issue print() command in this interrupt handler
}

void loop()
{
 if (flag1 == true)
 {
   data = Wire.read();
   if (data == '1')
   {
     analogWrite(lights, 255);
     Serial.println((char)data);
     flag1 = false;
   }
   else
   {
     flag1 = false;
   }
 }
}

Thanks, I got it to work. But I think I found out what the issue is. For some reason, the Nano isn't sending a 1. It's receiving a 1 via BT, but it's sending a 49 to the Mega. This is my updated code because the "if (data == 1)" does nothing:

void loop()
{
  if(flag1 == true)
  {
    data = Wire.read();
    if (data == 49)
    {
      analogWrite(lights,255);
      Serial.println((char)data);
      flag1 = false;
    }
    else
    {
      flag1 = false;
    }
  }
}

But for some reason, the serial monitor is printing a 1 anyway... Color me confused.

Oh okay, I did some research and it turns out that's the char/int conversion. Instead of "char data = 0;" for the Nano, I put "int data = 0;" to see what would happen. Now the BT module receives a 1, but prints 49 in the serial monitor, just like it sends to the Mega.

majhi:
Now the BT module receives a 1, but prints 49 in the serial monitor.

Somewhere in your setup the character "1" is printed instead of the integral value "1". The character "1" has the ASCII value 49.

char one = '1';
Serial.print(one);
Serial.print(" - ");
Serial.println((int)one);

This should print "1 - 49".

Arduino Reference - Arduino Reference for more info on character codes.

1. You have entered digit 1 in the InputBox (Fig-1) of Serial Monitor and then has clicked on the Send Button. As a result, the data byte 0x31 (ASCII Code of 1, Fig-2) is moving towards UNO.
SerialMonitor.png
Figure-1:


Figure-2:

2. UNO has received the data byte and has saved it in a char type variable named data, which now also holds 0x31 (it holds 31; 0x is not saved; it is shown to mean that 31 is in hex). The decimal equivalent of 0x31, which a human likes is: 49 (0x31 = 3x16 + 1x1).

3. You executed this I2C code: Wire.write(data); to send 0x31 to I2C Slave; as a result, 0x31 is transmitted to Slave.

4. The Slave has received the data and now it makes comparison using one of the following codes which are equivalent:

if(data == 0x31)

or

if(data == 49)

or

if(data == '1')

and NOT

if(data == 1)

SerialMonitor.png

Arduino Reference - Arduino Reference for more info on character codes.

Y'all are awesome, thanks a ton! I was beating my head against the wall here.