I am trying to make I2C Communication between NodeMCU and arduino Uno boards. However it is not working properly. It makes communication for once time when i uploaded code.
Master Device Code(NodeMCU 1.0)
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Wire.h>
HTTPClient client;
StaticJsonDocument <200> doc;
const char* ssid = "MY_SSID";
const char* pass = "MY_PASSWORD";
void setup() {
Serial.begin(9600);
Wire.begin(D1,D2);
WiFi.begin(ssid,pass);
while(WiFi.status() != WL_CONNECTED) {;}
}
void loop() {
const char* cd = getCode();
if(cd==nullptr) {
Serial.println("Problem Occurred.");
delay(10000);
return;
}
//Bad code is starting...
//Basically, sending 24 bytes of data for a Wire Transmission
int n = strlen(cd);
int rem = n%24; //remainder
int quo = (n-rem)/24; //quotient
while(quo!=0) {
char sel[24];
for(int i =0;i<24;i++) {
sel[i] = cd[((((n-rem)/24)-quo)*24)+i];
}
Wire.beginTransmission(8);
Wire.write(sel);
Wire.endTransmission();
quo-=1;
}
char sel[rem];
for(int i =0;i<rem;i++) {
sel[i] = cd[n-rem+i];
}
if(rem>0) {
Wire.beginTransmission(8);
Wire.write(sel);
Wire.endTransmission();
}
//Bad code finished!
//this is also not working.
Wire.requestFrom(8,3);
while(Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
delay(15000);
}
//get code from server.
const char* getCode() {
client.begin("http://...");
int res = client.GET();
if(res<0) {
return 0;
}
String root = client.getString();
deserializeJson(doc,root);
const char* code = doc["Liste"][0]["code"];
return code;
}
Slave Device Code(Arduino Uno)
#include <Wire.h>
void setup() {
Serial.begin(9600);
Wire.begin(8);
Wire.onReceive(received);
Wire.onRequest(requested);
}
void loop() {delay(200);}
void received(int bytes) {
while (Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
}
void requested() {
Wire.write("abc");
}
Circuit:
D1-SDA
D2-SCL
GND-GND
-
2To which voltage 3.3V or 5V do you pull up the SCL and SDA line? Is the MCU a 3.3V controller? Just connecting D1-SDA D2-SCL is not enough. If the electrical setup is OK, you could remove all the Wifi and JSON code from the MCU prog and try I2S alone. Another strange thing: you call client.begin("http://..."); each time you call the getCode() method without client.end(). Perhaps this crashes the connection to the server. I don't know if the client.begin is safely callable twice without calling close before..Peter Paul Kiefer– Peter Paul Kiefer2020年12月01日 16:31:48 +00:00Commented Dec 1, 2020 at 16:31
2 Answers 2
You may need to do some additional research. I'm debugging some I2C problems myself at the moment. Happy to share what my research has turned up:
Guiding Ideas - What could break?
Physical Layer
- Unintentionally switched connections (SDA<>SCL)
- Incorrect Pins selected on Microcontroller
- Pull-up Resistors
- Too many
- Devices often have pull-ups installed by default. Only one set is needed per bus. Rule of parallel resistors applies to calculate effective resistance.
- Too big (too high resistance)
- Too small (too low resistance)
- Too many
- Voltage Conversion / Mismatched devices
- Spikes or noise on SDA, SCL or Vcc
- Parasitic Capacitance
- wire / trace design
- bus too long
Protocol Layer
- Bus Addresses incorrect / collisions
- No ACK received from slave (ref. TI article "Troubleshooting I2C Bus Protocol" below)
- Timing
- Missing / Unexpected SCL pulses
- Incomplete 8 bit block
- Missing Bytes
- False slave address
- Unsuccessful address change
- NACK signal meaning ambiguity
- Clock speed mismatch (should be running at the speed of the slowest slave on the bus)
- Blocked bus (i.e., a device has reset or dropped during transmission putting the bus into an invalid state. There is no timeout.)
- Multimastering (too many masters on bus?) - if more than one all must support multi-master mode
- Clock stretching (a slave is holding the clock low)
- What part of the message is missing? Is the initial ACK from the slave received?
Code Layer
- For boards with multiple I2C ports, correctly passing the desired port to the relevant library.
- Use of interrupts causing timing problems
- Use of blocking code structures causing timing problems
Testing Methods
- Bus Pinging / Bus Scan (like Arduino Multi-speed scanner https://forum.arduino.cc/index.php?topic=197360)
- Connect additional devices to the bus and see which combinations work to identify the failing item
- Multimeter checks
- Stable Vcc?
- Common Ground?
- (Open Drain) pull-up resistance from SDA & SCL to Vcc
- Test devices like Bus Pirate
- Oscilloscope Analysis / Decode (references below)
- Sifting out which device is causing the problem. (See Hackaday article) Put different-value resistors on the output of all chips on the bus. The low voltage values will be slightly different for each chip, allowing you to see on a scope which chip is talking at any given time, and diagnose when they’re talking over each other.
- install I2C multiplexor to seperate bus into a single connector for each device (i.e., from bus to star topology) (e.g., PCA9544A)
References
I2C General
- For Arduino Programming Arduino Next Steps - Going Further with Sketches Chapter 7
- For ESP32 https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
I2C Debug Advice
- I2C Primer (I2C-bus.org) - a good reference for everything discussed here https://www.i2c-bus.org/i2c-primer/
- Common Problems https://www.i2c-bus.org/i2c-primer/common-problems/
- Obscure Problems https://www.i2c-bus.org/i2c-primer/obscure-problems/ Analysing Obscure Problems https://www.i2c-bus.org/i2c-primer/analysing-obscure-problems/
- WHAT COULD GO WRONG? I2C EDITION (Hackaday) https://hackaday.com/2016/07/19/what-could-go-wrong-i2c-edition/
- How to design and debug a custom I2C master-slave system? (Stack Exchange) How to design and debug a custom I2C master-slave system?
- Troubleshooting I2C Bus Protocol https://www.ti.com/lit/an/scaa106/scaa106.pdf
Oscilloscope Analysis of I2C
- How to debug I2C through waveform analysis (Texas Instruments) https://www.ti.com/lit/an/slyt770/slyt770.pdf
- Using an oscilloscope to debug the I2C protocol https://www.electronicproducts.com/using-an-oscilloscope-to-debug-the-i2c-protocol/
-
I will get reference this answer for my future projects. I found solution but unfortunately can't remember, however i guess it was related with code layer.Snefru Clone– Snefru Clone2021年01月27日 15:50:55 +00:00Commented Jan 27, 2021 at 15:50
A few of my tips:
- if Arduino is powered using VIN port, the battery must STRICTLY between 7 to 12 volts, otherwise the Arduino board is unstable. Serial communication typically require good board stability
- A capacitor (100 to 500uF) across the 5V (or 3.3V) and GND port helps to give I2C device a consistent voltage level, which is essential
Explore related questions
See similar questions with these tags.