3

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

1
  • 2
    To 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.. Dec 1 '20 at 16:31
3

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?

  1. Physical Layer

    1. Unintentionally switched connections (SDA<>SCL)
    2. Incorrect Pins selected on Microcontroller
    3. Pull-up Resistors
      1. 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.
      2. Too big (too high resistance)
      3. Too small (too low resistance)
    4. Voltage Conversion / Mismatched  devices
    5. Spikes or noise on SDA, SCL or Vcc
    6. Parasitic Capacitance
      1. wire / trace design
      2. bus too long
  2. Protocol Layer

    1. Bus Addresses incorrect / collisions
    2. No ACK received from slave  (ref. TI article "Troubleshooting I2C Bus Protocol" below)
      1. Timing
      2. Missing / Unexpected SCL pulses
      3. Incomplete 8 bit block
      4. Missing Bytes
      5. False slave address
      6. Unsuccessful address change
    3. NACK signal meaning ambiguity
    4. Clock speed mismatch (should be running at the speed of the slowest slave on the bus)
    5. Blocked bus (i.e., a device has reset or dropped during transmission putting the bus into an invalid state. There is no timeout.)
    6. Multimastering (too many masters on bus?) - if more than one all must support multi-master mode
    7. Clock stretching (a slave is holding the clock low)
    8. What part of the message is missing? Is the initial ACK from the slave received?
  3. Code Layer

    1. For boards with multiple I2C ports, correctly passing the desired port to the relevant library.
    2. Use of interrupts causing timing problems
    3. 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

I2C Debug Advice

Oscilloscope Analysis of I2C

1
  • 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. Jan 27 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.