Hi,
I am working on sometihing with 1 ESP32 as master and 15 ATMEGA 328p as nodes, on an I2C bus. The data transmission is two way. So far I have tested with 4 nodes, everything was working fine, but suddenly Master stopped recognizing the nodes anymore, as there was something wrong with the I2C bus. Since then I have encountered multiple errors like:
can't init sda=0 scl=0 (sometimes it's different combinations sda=1, scl=0 and so on)
Whole system working fine for an hour or so and suddenly I2C communication stops, and is revived when I disconnect and then reconnect the power, basically turn it off and on again.
I have removed the whole code and gone back to the super basic scanner code but still same problem.
I have read multiple forums with same problems but none has any satisfactory / reliable answers.
Things to know:
ATMEGA 328p ICs are soldered with the crystals and capacitors just like arduino UNO and work fine otherwise
I have a bidirectional logic level converter between master and nodes for power, ground, SDA and SCL lines
There is a 4.7 k ohm resistor between ESP32's Vin (5v) and SDA line and one between Vin and SCL line
The power is being provided through a 5V 2A DC adaptor, from master to all the nodes
The code running in the master is I2C scanner code
The nodes have a simple code in which begin the I2C communication, assign address to the node
There is a 5 second delay in setup() before initializing I2C communication on both the master and nodes side so that all the devices are up before I2C bus begins and hence no device is pulling the line low
The master scans for the nodes, sometimes yields correct results, sometimes while giving correct results for a while switches to No devices found
Restarting everything helps sometimes but not everytime
Been stuck at it for a long time, Any sort of help would be extremely appreciated.
Thanks
Did you try reading the ESP32's Docs to find out how many devices the I2C bus of an ESP32 can drive? API Reference - ESP32 - — ESP-IDF Programming Guide latest documentation. I guess you did not read somewhere in that doc that the ESP32 can drive 3 or was that 4 devices per I2C bus. Anyways, think I2C expanders that can drive more connected devices. Plus those pull ups have to be done correctly.
Serial Wombat 18AB I2C / UART Smart I/O GPIO and Analog Expander for Arduino
Are you using level shifters to connect the ESP32, a 3V3 non 5V tolerant device to a 5V device?
Ouch. The ESP32 is a 3.3volt-logic device, so pull up should be between 3.3volt and SDA/SCL.
I assume VCC of the slaves is 5volt, with a 16Mhz crystal. Which means there should be a 5volt-logic slave bus with pull up to 5volt, and a 3.3volt-logic master bus with pull up to 3.3volt.
What does the I2C bus wiring look like, and what is the total length.
What is the total pull up current on the ESP side of the level shifter, and what is it on the slave side.
Couldn't you have used 3.3volt-logic slaves.
Leo..
It looks to me like both sides have 10k pullups, connected to LV and HV for the low and high side. So it's essential that LV and HV is properly connected to the right voltage.
Yes I just noticed that. Can you please suggest a solution for that? Do i need to add separate pull ups now?
if yes then, What should be the pullup resistance's value? Should i add it on both sides of HV and LV.
On slave side, I have two 5V relays on each node, and two sensors operating at 5 V
I'm sorry to say, but this is why we (especially me) say that the I2C bus is not a good bus to communicate between Arduino boards It was not designed for that. The hardware I2C bus has weak signals and the software for Slave mode causes trouble.
Can you give schematics, photos, sketches of the Master and all the Slaves ? I would like to know everything.
Because the I2C bus is so weak, 15 devices on a ESP32 might be too much. It can not drive all the wires to all the Slaves. The level shifter solves the voltage levels, but makes the signals even weaker.
What worries me the most is the relays, powered by the same 5V that is used for the Arduino boards. Are the currents to and from the relays in the 5V and GND wires next to the SDA and SCL wires ? Then the I2C bus will not work.
I see many more problems. You may assume that there are between 10 and 20 serious problems
What if you can not make it work ? Can you do your project in a different way ?
Can you tell what your project is ? Please give us a broader view. I think that you have to redesign it.
The project I am working on is to monitor and control power in a certain premesis. It has 1 master as ESP32 and 15 Slaves as ATMEGA 328p.
Each slave has 2 relays that will control the appliances (like light, fan) based on commands recieved from master on I2C. This has been tested several times and works fine.
In addition to that, each slave also has 2 PZEMs that measure voltage and current of the same electricity lines which are controlled by Relays and send the values back to the master on I2C.
Master takes these values from every slave after 1 minute (this interval can be increased) one by one from each slave, over I2C and publishes those to MQTT topics. The values include Voltage, Current, Frequency and Power factor. One slave sends these values at once (with a 10 ms delay in every Wire.write) after a single request from Master to that slave.
At the same time, if there is any msg recieved from MQTT topics (callbacks), master passes it to the particular slave over I2C and that particular relay is operated.
The slaves are close together and I2C wire length is not that long.
The whole thing is on a pcb board and SDA, SCL are not near the relays' wires. How does it effect, if I may ask? Interference of signal?
What I am thinking after your post is:
If i can use the two I2C buses on ESP32.
connect 3 or 4 slaves to each bus, that means 6 or 8 slaves per ESP32.
replicate the same with another ESP32.
Then I can use 2 ESP32 and have 12 to 16 slaves that will work for me. The two ESP 32 won't need to communicate with each other since they just have to publish values on MQTT topics.
Will it work? feasible?
I am very much looking forward to your answer now
Sort of, but that is just a rough estimate. Currently I have connected the master and nodes with simple wires that are soldered to the pins but I will improve this wire situation in the final prototype and maybe shorten the length more. And the slaves are not very far apart.
Could you please go through the project description and possible redesign in post#13. I would appreciate your thoughts on it.
Hi leo,
The reason for slaves is not because of less I/O. I need the processors that's why multiple slaves. Could you please go through the project description and possible alternate solution in post#13. I would love your feedback on that.
Thanks
Long story short.
I2C is not designed to be a cable bus.
Imho you will not get reliable results and all efforts towards I2C are wasted time for this project.
Beside using another bus technology I would like to elaborate on that:
what can 15 atmegas do what can't be done on one ESP in your usecase?
@noiasca Could you please fix the typing mistake ?
@noor_H When something works, that does not mean that it is okay. Without showing the all the code, I can only assume that there are problems as well.
Do those PZEM modules sample at a high frequency to calculate the power for the 50Hz/60Hz mains ? Then the Arduino does not have to do that. What kind of processing do they have to do ?
In my opinion, even if you do everything right, the I2C will not work reliable. The I2C bus is not a fault-tolerant bus, it must work 100% all the time.
You can use Serial or RS-485. The RS-485 is used in a industrial environment for longer distances, but it is a good solution for short distances as well when there are a number of modules.
Are all the Slaves on the same PCB as the Master ? Then normal Serial RX TX signals might be good enough.
When a relay is turned on and off, then there might be a peak in the current or voltage. Some noise peaks in the 5V is probably no problem, but noise in the GND is often a problem.
A PCB with a ground-plane solves many problems, and a star-ground can avoid that a sensitive circuit (Arduino with sensors) gets noise from a high current circuit (motors). See: Common ground and why you need one
Grounding is a craftsmanship on its own.
@noiasca
It was required in the usecase for some processing. However, I think it can be droped if I modify the project a bit.
@Koepel Thank you for the guidance. Your github wiki page on this topic is very helpful
I am modifying the project and droping the I2C and ATMEGAs, and now switching to UART, Serials on ESP32 multiplexed together to get values from PZEMs one by one.
@Idahowalker Because I would have required network interfaces for all the nodes which was not feasible in case of ATMEGA ICs.
@noobmastha Yes. Got it. I guess this should be mentioned in the blogs saying I2C can connect 127 devices (yes, development boards too)
Anyways guys, Thank you all for your guidance and help. I am switching to UART with ESP32 and multiplexing the PZEMs to take their values one by one.
Serial 1 and Serial 2 of ESP32 will be connected to 3 PZEMs each and the PZEM whose value is to be measured is decided by optocouplers connected to a transistor. I have tested the circuit and it works.