PiSupply / PiJuice

Resources for PiJuice HAT for Raspberry Pi - use your Pi Anywhere
https://uk.pi-supply.com/collections/pijuice/products/pijuice-portable-power-raspberry-pi
GNU General Public License v3.0
435 stars 103 forks source link

Intermittent COMMUNICATION_ERROR with Pijuice and Fan_Hat #700

Open sanderplug opened 3 years ago

sanderplug commented 3 years ago

I have a RPi4B 4GB with Ubuntu 20.04 TLS installed. I have installed the Pijuice according to this instruction. I use SW1.7 and upgraded to FW1.5. This all works fine and no communication errors are seen.

To cool the RPi4B I have bought a Fan_Hat from Waveshare. The Fan_Hat is directly connected to the RPi4B and the Pijuice is connected on top of that. I verified there are no conflicts. The Pijuice is using 0x14 and 0x68. Whereas the the Fan_Hat is using 40 (PWM) and 3c (oled display). Occasionally 03 is seen as well, not sure where that comes from or even has impact:

output of i2cdetect -y 1 command:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- 14 -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Just rebooted again (same hardware setup) and now this is seen:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- 14 -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

The Pijuice works in that configuration and pijuice_cli shows the right parameters in Hat Status screen.

In order to make the Fan_Hat work either a python script or binary (need to be compiled) need to run permanently. However as soon as I run that binary (or python script) I get almost permanent COMMUNICATION_ERROR in the Pijuice Hat Status screen. Searching through git I found that adding the following in /boot/firmware/usercfg.txt (and reboot) could help:

dtoverlay=disable-wifi
dtoverlay=disable-bt
dtoverlay=i2c-bcm2708

The COMMUNICATION_ERROR still regularly pops up and then the information of the Pijuice HAT status is lost. I also noticed that by stopping the Fan_Hat binary to run, the COMMUNICATION_ERROR disappears. When I changed the Fan_Hat binary checking from 1 to 10 seconds the COMMUNICATION_ERRORS were less frequent, but still happen. Similar cycle f 10 seconds.

It must be some conflict on between invoking the binary towards the Fan_Hat and with the pijuice software to the Pijuice Hat.

The following is the source code of the Fan_Hat binary (for reference). fan_hat_main.c.txt

Any help would be appreciated as I would like to keep my RPi4B cool and powered up! ;-)

tvoverbeek commented 3 years ago

I suspect the OLED_Display takes a considerable amount of time updating 128x32=4096 pixels. During this time the I2C bus is blocked for the PiJuice. For testing comment out the the calls to OLED_Display and see if this improves the situation. dtoverlay=i2c-bcm2708 is not needed for recent versions of the software (>= 1.6) for Pi4.

sanderplug commented 3 years ago

Thanks for that suggestion. I have removed the dtoverlay=i2c-bcm2708 directive. The Hat is in a case anyway so will not be able to see the OLED. Therefore I have updated the example code to remove all OLED_Display calls, set the refresh rate to 4500ms (hoping it would not line up with the pijuice calls) and recompiled it. The COMMUNICATION_ERROR is still seen however and takes about 4 seconds to resolve. Here is the updated code: fan_hat_main_nooled.c.txt

Any further idea?

sanderplug commented 3 years ago

Have been looking at the Python code and libraries. The Example code did not have all the right settings. When I made the changes, including some new info (fanspeed) on the OLED display it seems to work much better with the Pijuice and I can not see any COMMUNICATION_ERROR or DATA_CORRUPT errors so far. Interesting that with python code it seems to work but with complied c code there are some issues. For reference I am adding here the python code I used: fan_hat_main_oled.py.txt

tvoverbeek commented 3 years ago

Python code looks similar to the C code. I do not know what the units are for DEV_delay_ms: milli seconds or micro seconds. Maybe it is micro seconds. Of course C code executes much faster as interpreted python code. Anyway, glad you have it working now.

sanderplug commented 3 years ago

It looks like 'DEV_delay_ms' is using milliseconds. It takes microseconds (= 1e-6 seconds) as parameter, so to sleep 1 millisecond you would enter: usleep (1000).

/**
 * delay x ms
**/
void DEV_Delay_ms(UDOUBLE xms)
{
#ifdef USE_BCM2835_LIB
        bcm2835_delay(xms);
#elif USE_WIRINGPI_LIB
        delay(xms);
#elif USE_DEV_LIB
        UDOUBLE i;
        for(i=0; i < xms; i++) {
                usleep(1000);
        }
#endif
}

This came from the Fan_HAT/c/lib/Config/DEV_Config.c included code from Fan_Hat.

tvoverbeek commented 3 years ago

So it smells it actually used microseconds. So in the loop it then only waits 9.5 milliseconds compared to the 1000 milli seconds in the python code, which would explain your COMMUNICATION_ERROR problem.

sanderplug commented 3 years ago

No no, the 9500 was originally 1000 (every second), I changed it to 10x as much to request to much updates. Basically it does 9500 x 1000 usleep microseconds, which is 9.5 seconds. It must have been something else within the c library that caused the issues.

sanderplug commented 3 years ago

I also reached out to Waveshare (the manufacturer of the Fan_Hat) with the same question as in the first post. They came back to me today with the following:

They will conflict of you set up the i2c at the same time with two C codes. You need to combine tow script to one or use python.

So it looks like that either I need to:

  1. select C code for all i2c interactions and add all into one single binary OR
  2. use python code for all i2c interactions. Then it looks however I am able to use different scripts (pijuice as well as fanhat).

Pijuice seem to solely use python code right? That is probably why initially above it was observed to work better with the fanhat python script.

This information might also be interesting for others trying to use i2c with multiple devices and ran into the same problems.

Already created a service out of the fanhat python script and together with the pijuice service it seems to work well now.

tvoverbeek commented 3 years ago

I do not agree with your interpretation of Waveshares answer. What I believe they want to say is if you have 2 different applications accessing the I2C bus there is always the possibility for conflicts since they might access the bus simultaneously. If you want to avoid that then it is best to use a single application which accesses the bus.

Alternatively you have to work with a limited number of retries after failure in both applications.

sanderplug commented 3 years ago

Well it is their last sentence

... or you use python ...

which let me to believe that if you use python that the conflicts seem not to occur or at least better managed. Since I use python I do not see any issues anymore.