Hello everyone,
I am trying to send voltages, floats to two decimal places from arduino mega to NodeMCU via I2c (i.e. 3.45)
I need the value to be send through as a char [] because it is then going to be added to a string. I also need to add the char [] or string of "A1" in front of the voltage reading. So it would be sent as "A13.34" for example.
I was able to declare the char [] and send the whole string "A13.34" for testing purposes and I was able to read that on the other end of the I2c bus, but I am not sure how to deal with it when starting with a float value from the voltage reading.
I hope this makes sense, any help would be greatly appreciated. I have been sitting here for hours trying to just try different things to get it to go through to the NodeMCU and read correctly. As of now, it is just sending and there is weird characters in the buffer of the serial monitor of NodeMCU.
#include <Wire.h>
float v1 = 0;
char toSend[6] = "";
char myString[6] = "A13.35";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(8);
Wire.onRequest(requestEvent);
}
void loop() {
// put your main code here, to run repeatedly:
// Serial.println(test);
// delay(500);
int val = analogRead(A0);
v1 = val/204.60;
char extra[2] = "A1";
char toSend[6] = "";
dtostrf(v1, 4, 2, toSend);
Serial.println(toSend);
delay(250);
}
void requestEvent() {
sendVolts();
Serial.println("Sending data...");
}
void sendVolts(){
// Serial.print(c1);
// Serial.println("V");
// String toSend = "A1";
// toSend += v1;
char toSend[6];
dtostrf(v1, 4, 2, toSend);
Wire.write(toSend);
}
It should be pretty simple, but does anyone have any idea?
YoungestEVer:
It should be pretty simple, but does anyone have any idea?
Yes, it is simple when you send from NodeMCU to MEGA using I2C Bus. The other way appears to be difficult as NodeMCU can not be configured to work as an I2C Slave.
No the nodeMCU is configured as a master and the mega is the slave, the nodeMCU then requests the data from the slave
1. Insert the following codes/lines at the appropriate places of your I2CMasterNode sketch:
#include<Wire.h>
Wire.begin(4, 5); //SDA = GPIO-4/D2, SCL=GPIO-5
union
{
float txFloat = 3.45;
byte txArray[4];
}txData;
Wire.beginTransmission(slaveAddress);
Wire.write(txData.txArray, sizeof(txData.txArray));
Wire.endTransmission();
2. Insert the following codes/lines at the appropriate places of your I2CSlaveMEGA sketch:
#include<Wire.h>
Wire.begin(slaveAddress);
volatile bool flag1 = false;
union
{
float rxFloat = 3.45;
byte rxArray[4];
}rxData;
Wire.onReceive(receiveEvent);
void receiveEvent(int howMany) //howMany is equal to number of bytes received
{
for(int i=0; i<howMany; i++)
{
rxData.rxArray[i] = Wire.read();
}
flag1 = true;
}
if(flag1 == true)
{
Serial.println(rxData.rxFloat, 2); //Serial Monitor should show: 3.45.
flag1 = false;
}
delay(1000); //test interval
Thanks so much for the reply.
So I have my arduino MEGA as the master device, and nodeMCU as the slave.
Uploaded the code to each and the mega is sending the data to the nodemcu (I think), but the nodemcu serial monitor shows nothing. Not sure why it isn't working.
Again, just trying to send a float from mega to nodemcu in the form of string or char [] so that I can send that off with GET request eventually.
Any help would be greatly appreciated. And yes, I have my grounds connected between the two boards.
Arduino mega (master):
#include <Wire.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
}
void loop() {
union{
float txFloat = 3.45;
byte txArray[4];
}txData;
Wire.beginTransmission(8);
Wire.write(txData.txArray, sizeof(txData.txArray));
Wire.endTransmission();
Serial.println("Sending data...");
delay(1000);
}
nodeMCU (slave, but receiving the data):
#include <Wire.h>
volatile bool flag1 = false;
union
{
float rxFloat = 3.45;
byte rxArray[4];
}rxData;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void loop() {
// put your main code here, to run repeatedly:
if(flag1 == true){
Serial.println(rxData.rxFloat, 2);
flag1 = false;
}
delay(1);
}
void receiveEvent(int howMany){
for(int i=0; i<howMany; i++){
rxData.rxArray[i] = Wire.read();
}
flag1 = true;
}
Does anyone know why this isn’t working? I feel like everything is correct I’m not sure why they aren’t communicating!
@OP
1. Connect I2C Master NodeMCU and I2C Slave MEGA as per following diagram: (The pull-ups are within the MEFGA Board; there is no need to install these.)

Figure-1: I2C Bus connection
2. Upload the following sketch in Node.
#include <Wire.h>
byte x0, x1, x2, x3;
void setup()
{
Serial.begin(115200);
Wire.begin(4, 5); //SSDA = GPIO-4; SSCL = GPIO-5
byte *ptr;
ptr = (byte*) &txFloat;
x0 = *ptr;
ptr++;
x1 = *ptr;
ptr++;
x2 = *ptr;
ptr++;
x3 = *ptr;
}
void loop()
{
Wire.beginTransmission(0x09);
Wire.write(x0);
Wire.write(x1);
Wire.write(x2);
Wire.write(x3);
byte busStatus = Wire.endTransmission();
Serial.println(busStatus);
Serial.println("Sending float data...");
delay(1000);
}
3. Upload the following sketch in MEGA.
#include <Wire.h>
volatile bool flag1 = false;
volatile byte x;
union
{
float rxFloat;
byte rxArray[4];
} rxData;
void setup()
{
Serial.begin(9600);
Wire.begin(0x09);
Wire.onReceive(receiveEvent);
}
void loop()
{
if (flag1 == true)
{
for (int i = 0; i < 4; i++)
{
rxData.rxArray[i] = Wire.read();
}
Serial.println (rxData.rxFloat, 2);
flag1 = false;
}
}
void receiveEvent(int howMany)
{
flag1 = true;
}
4. Check that 3.45 has appeared on the SM2 of MEGA. 


Alright, thanks! But again, the nodeMCU needs to be the slave receiving the data, so what bits do I have to change such that it’ll work that way?
The way your wrote that, is it being sent as a string or char [] ?
YoungestEVer:
Alright, thanks! But again, the nodeMCU needs to be the slave receiving the data, so what bits do I have to change such that it’ll work that way?
The way your wrote that, is it being sent as a string or char [] ?
THE NODEMCU WILL NEVER EVER WORK AS I2C SLAVE; THIS HAS BEEN COMMUNICATED TO YOU ALREADY! WHEN YOU ARE PLAYING IN TH FORUM, PLEASE BE RESPECTFUL TO THE POSTS OF OTHERS!
Oh ok... geez I am so sorry I overlooked that part!
So in that case, I still have to get the data from the mega to the nodemcu. So with that being said, I should probably request form the nodemcu, setup the requestEvent, and in the requestEvent function, I would then set flag1 = true.
Does that seem about right?
YoungestEVer:
Oh ok... geez I am so sorry I overlooked that part!
So in that case, I still have to get the data from the mega to the nodemcu. So with that being said, I should probably request form the nodemcu, setup the requestEvent, and in the requestEvent function, I would then set flag1 = true.
Does that seem about right?
Perfectly alright! make the setup, write codes, upload, and observe the result. If problem, place the results/codes in the Forum and seek help.
Well this is interesting....also please note in the Mega sketch, I had to add a float declaration for txFloat because it was missing
So I rewrote it so it would request data from the mega, but still doesn't work, must be something I am doing wrong.
NodeMCU is outputting to the serial monitor:
"nan
Reading float data..."
Mega is not outputting anything to the serial monitor, which means the nodemcu isn't successfully requesting data i think.. but don't know why.
Ugh! Frustrating stuff...What happens if you try to send a string like "A13.45" via I2c? not sure how it handles the '.' if it would handle it differently. Just an idea since in the end in the node, it has to be a string anyway.
NodeMCU code (master)
#include <Wire.h>
volatile bool flag1 = false;
volatile byte x;
union{
float rxFloat;
byte rxArray[4];
}rxData;
void setup()
{
Serial.begin(115200);
Wire.begin(4, 5); //SSDA = GPIO-4; SSCL = GPIO-5
}
void loop()
{
Wire.requestFrom(8, 4);
for(int i = 0; i< 4; i++){
rxData.rxArray[i] = Wire.read();
}
Serial.println(rxData.rxFloat,2);
// Wire.beginTransmission(0x09);
// Wire.write(x0);
// Wire.write(x1);
// Wire.write(x2);
// Wire.write(x3);
// byte busStatus = Wire.endTransmission();
// Serial.println(busStatus);
Serial.println("Reading float data...");
delay(1000);
}
Mega code (slave):
#include <Wire.h>
byte x0, x1, x2, x3;
float txFloat = 3.45;
void setup()
{
Serial.begin(9600);
Wire.begin(8);
Wire.onRequest(requestEvent);
byte *ptr;
ptr = (byte*) &txFloat;
x0 = *ptr;
ptr++;
x1 = *ptr;
ptr++;
x2 = *ptr;
ptr++;
x3 = *ptr;
}
void loop()
{
delay(250);
}
void requestEvent(){
Wire.write(x0);
Wire.write(x1);
Wire.write(x2);
Wire.write(x3);
byte busStatus = Wire.endTransmission();
Serial.println(busStatus);
Serial.println("Sending float data...");
}
@OP
Begin by placing questions to yourself like these:
1. I have I2C setup where NodeMCU is Master and MEGA is Slave.
2. I want to send 3.45 from Node to MEGA. This is my sketch which works:
3. Now I want that the Node will place a request to the MEGA to send 12.45. What modification/addition should I bring in the codes of Step-2?
4. Now I want that the Node will place a request to the MEGA to send "A13.45". What modification/addition should I bring in the codes of Step-2?
BTW:
You are just randomly putting the codes with a hope they will work. You need to understand the theory of 'I2C Bus Protocol' or 'the mechanical rules to be followed' for the network to work.
Search the Forum, and you will find various posts that have explained the theory of the I2C Bus and have also listed the 'mechanical rules' for I2C Bus based data communication technology.