Hi, I have a MKR1400 running with a DS1307 ( RTC pcb). The whole system is a doorlock system.
When this systems get some noise on I2C bus, the system cannot recover from this issue. The Arduino MKR is freezed. I have to perform a power cycle in order to reset the MKR.
As fair as I see, The I2C library work as a blocking function. Then when the I2C is noisy the system could be freezed.
In order to improve this error, I start the WDT as soon as possible.
I guess this acction improves the system fiability, pero sometimes the Arduino fall into the same problem. It frezzes.
I was diging into Arduino structure and I arrive to this main.cpp (not main of Arduino). This is the main of Atmel - Arduino struture.
/*
* \brief Main entry point of Arduino application
*/
int main( void )
{
init();
__libc_init_array();
initVariant();
delay(1);
#if defined(USBCON)
USBDevice.init();
USBDevice.attach();
#endif
setup();
for (;;)
{
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Due the WDT is turned on in setup() , I guess that any problem before setup could freeze the program and the system will not recover of this situation.
Even I commented the initVariant() function, where the BQ24195 is asked. I can see on the I2C bus a request from address = 6B, BQ24195 address.
I guess __libc_init_array or a bootloader is asking to BQ24195.
What do you recommend in order to ensure the reset system if the I2C bus fails?
What gives you that confidence that the I2C bus is the problem? Given you description I would search for power problems (I guess you use a solenoid for the door). Even if the I2C bus is involved, fix the hardware. I2C is an on-board bus so any wires should be eliminated or kept extremely short (< 5cm) and the pull-ups should be tailored to your board design (= bus capacitance).
have you an oscilloscope to look at the I2C signals?
what pullup resistors are you using on the I2C bus?
post a schematic of the system?
use shielded cables for any connections which may cause problems
I am using about 5 cm of cables. I will improve these cables. Thank you.
And you are right, the solenoid is a very noisy device. But the solenoid is placed more than 2 meters away.
I have a Wifi router near the system(10 cm) . I guess that is a source of noise.
Let me share the test that I performed:
I tied to gnd the SDA signal. And the system tries to read the RTC and the WDT expires, and the system Reboot. Good for me.
I tied to gnd the SCL signal. And the system tries to read the RTC and the WDT expires, and the system Reboot. Good for me.
But if I tie SDA and SCL, the WDT reboot the system but the programm never starts. It cannot arrives to Setup();
I guess the bus is stuck, the MKR performs several tasks before launching the "Setup()" function of your program.
I am sure "these" tasks are trying to communicate with BQ24195 and due the WDT is not turned on yet, the system freezes. Never quit this state.
Where is the piece of code that is asking for BQ24195. I cannot find this. ( I was digging into Arduino structure, and I found the "first" main , as I showed before)
Logic 1 Input VIH 2.2 <-----> VCC + 0.3 V
Logic 0 Input VIL -0.3 <-----> +0.8 V
I guess these voltage values are enough for "1" and "0". What do you mean with "old ds1307" ?
However, I can freeze the MKR1400 using a clean sketch and no RTC.
If I connect SDA and SCL and start the system, It never reaches the setup () function.
Please give a link to where your bought the RTC module and tell how you have connected it and powered it.
I sometimes say that the GND wire is the most important wire of the I2C bus. It should be treated with the same care as SDA and SCL.
A noisy solenoid a few meters away is a serious problem if there would be a wire between the Arduino and the solenoid, even if that is only a single wire.
Please show the sketch that freezes and tell which RTC library you use.
You mention the DS1307's logic level thresholds, but the datasheet also states the the minimum supply voltage is +4.5V. This means that to be within the device's specification you'll most probably need to power it with a 5V supply.
As you state that you're using a PCB for your DS1307, it's likely that the I2C SCL and SDA lines' pull-up resistors are pulled to the breakout board's supply at +5V. However, the SAMD21 microcontroller on the MKR1400 is only +3.3V tolerant. If that's the case (?) then you'll require an I2C logic level shifter to protect your microcontroller.
The reason I say "old DS1307" is because it's an old design. Nowadays there are much more modern RTC chips that are both 5V and 3.3V compatible, such as the PCF8523. Another popular, but more expensive model, is the high precision DS3231 RTC. These dispense with the requirment for a level shifter, since they can be powered from a +3.3V supply directly.
The mkr has both pull up resistors at 3v3. 4k7 is the value. The waveforms are well shaped on oscilloscope.
The DS1307 is powered by a 5V regulated power supply.
I am using a modified library of DS1307 in order to get a bool value if the read or write process has been successful, I mean if the request is failed, I get a bool output in order to start a retry mechanism. The initial library is RTClib.
But, after a lot of tests I have arrived at a new single question. That is not related to RTC because this situation happens without a RTC connected!
Let's suppose that I have the MKR1400 with no other PCB added.
I use a clean sketch with the WDT turned on and a resetWDT() function, in the main block.
If I introduce some noise to the I2C bus when the MKR is starting, the sketch freezes and the WDT does not act. I can only quit this state using the reset button.
You bought a RTC module without a schematic. Are both sides separated ? or are all the 4k7 and 3k3 pullup resistors enabled ?
The DS1307 runs only at 5V, that means it has a 5V I2C bus, that means you can not connect it to a 3.3V I2C (well, you can, but there will be no noise margin).
There has been trouble with ATSAMD21G boards with halting on the I2C bus lately on this forum. Sometimes it was a Adafruit board (with other libraries), but you have a genuine Arduino board. Some can solve it with extra external pullup resistors to 3.3V.
You have to make decisions.
Are you going to continue with the Arduino board ? I don't know how you have added noise to SDA or SCL, so I don't know if that was a normal test.
Yes, continue with Arduino board: Grab a big hammer and smash that RTC module. Buy good things from good sellers, such as Adafruit, Sparkfun, Pololu.
No, not continue: Can you do your project with a ESP32 ? It seems to have better maintenance than the ATSAMD21G at the moment.
You can not afford that non-matching outdated crappy RTC module in your project.
Did you know that you can measure the total pullup in the circuit ?
Make an empty sketch and put "Wire.begin()" in setup(). Upload the sketch and measure the shortcut current from SDA to GND and from SCL to GND.
I have an original MKR1400 Arduino. I need this pcb because I need the 2/3G modem to perform a server connection.
Using the pull-up resistor of the RTC board the voltage goes between 0V-4V. That is logic because the clamp diodes of IC that are powered by 3,3V. I mean 3.3V + 0.7 diode clamp voltage.
If I remove the pull-up resistor of the RTC board the voltage goes between 0V and 3.3V. That makes sense as well.
Boths waveforms are well shaped and have no rise time for transitions. I know this is not the best situation, but for I2C I guess the VIH min and VIL max for "1" and "0" are enough.
I am adding noise on both I2C lines pulling down to GND for SDA and SCL randomly. If I keep one or booths I2C lines the WDT acts always.
But, this is the big problem here. When I connect SDA and SCL (short circuit between them) the WDT expires, and the system never starts. The program never arrives to setup();I guess the bootloader or whatever piece of code that exists before the setup () is freezing when trying to communicate with BQ24195. I guess it is a kind of stucking I2C bus. Do you agree?.
I guess, if the program arrives to setup(), without trying to communicate with BQ24195 and I turn on the WDT on setup () functions, the system will work, because It will be protected by WDT.
I tried to undef USE_BQ24195L_PMIC (into Arduino structure) in order to avoid an I2C usage before setup(), but the MKR always tries to communicate to BQ24195 when it starts.
Let me know what you think about all these.
Regards.
A shortcut between SDA and SCL is just as bad as shortcutting one of them to GND. For your board it seems even worse. That will halt the Arduino board, because there is bug or a missing timeout in the Wire library for the ATSAMD21G boards. In a embedded system, this should never happen. An event from the outside should never stop the sketch or reset the board.
I looked into the datasheet of the DS1307, anything above 2.2V is seen as a "high", so that is okay. You don't need the big hammer for now. Sorry, I spoke too soon Even a pullup to 5V will probably not harm the Arduino board, that extra current flows into the 3.3V.
Let me try to keep up with you:
The board is in the "core samd" section. Anything special is in its "variants" folder.
Many boards have only specific pin definitions there, but this board does more.
In the initVariant() function, the battery charging is enabled, and that uses the I2C bus. It does not use the high level "Wire" library, but a level below that, which uses the "Sercom" flexible hardware.
The "USE_BQ24195L_PMIC" is not defined in the code, but in the build environment.
Do you know where the hidden "arduino15" folder is ? That is where downloadable build environments are stored.
In the Arduino IDE, menu: File / Preferences, click at the bottom on the "preferences.txt" file, that brings you to the hidden "arduino15" folder.
The file "boards.txt" is in: arduino15 / packages / arduino / hardware / samd / 1.8.13
And there it is at line 402:
The option "-D" for the compiler is the same as adding a #define.
I think it does no harm to the board to remove the -DUSE_BQ24195L_PMIC, but I'm not sure what the battery fet is doing. Is there no battery at all ? Then it should be okay to remove that define.
Could you make a Issue at Github ? Add a link to this topic.
Hi Koepel. How are you?
Well I did what you recommend and the BQ24196 was still being requested by FW.
I saw a few less data exchanges over I2C bus. Then I guess that something changed.
So I got the oscilloscope, and I could see that the BQ24195 is asked in 2 blocks of data. I mean : Idle bus -- I2C data -- Idle Bus --- I2C data.
I arrived at the conclusion that que bootloader is requesting the BQ24195 as well.
Well I modified the bootloader code, that is placed on this folder ArduinoCore-samd/bootloaders/zero at master · arduino/ArduinoCore-samd · GitHub
I had to remove a defined CONFIGURE_PMIC that is used on all Arduino structures.
I guess this is working. If I add the noise on the I2C bus the MKR always reboots. ( Always)