joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.43k stars 403 forks source link

Possible issue with wave function on PI 4 8GB bullseye 64bit #585

Closed Zachary57-fr closed 9 months ago

Zachary57-fr commented 9 months ago

Hello,

I suspect an issue with pigpio V79 on PI 4 8GB running raspbian bullseye 64bit From same python code using function "wave_send_once", I have correct output ( taken from piscope on PI B+ ) on a PI B+: PI2B

From PI 4, signal is slighly different ( taken from piscope on same PI B+ with a wire linking PI 4 GPIO 5 to PI B+ GPIO 6 ) : PI4

Are you aware of any issue or some specific parameters to set to have wave function working on a PI 4 ?

Thank you

guymcswain commented 9 months ago

There are unresolved issues with late silicon stepping on pi4 models - specifically with hardware pwm peripheral (#517). I'm not aware of any issues with waves. However, the pwm is used to pace the timing on the waves. Hmmm.

Can you run the pigpio tests? ./x_pigpio.c for instance

Zachary57-fr commented 9 months ago

There are unresolved issues with late silicon stepping on pi4 models - specifically with hardware pwm peripheral (#517). I'm not aware of any issues with waves. However, the pwm is used to pace the timing on the waves. Hmmm.

Can you run the pigpio tests? ./x_pigpio.c for instance

Hello,

I ran test and it seems ok :

`# ./x_pigpio

Testing pigpio C I/F pigpio version 79. Hardware revision 13644053. Mode/PUD/read/write tests. TEST 1.1 PASS (set mode, get mode: 0) TEST 1.2 PASS (set pull up down, read: 1) TEST 1.3 PASS (set pull up down, read: 0) TEST 1.4 PASS (write, get mode: 1) TEST 1.5 PASS (read: 0) TEST 1.6 PASS (write, read: 1) PWM dutycycle/range/frequency tests. TEST 2.1 PASS (set PWM range, set/get PWM frequency: 10) TEST 2.2 PASS (get PWM dutycycle: 0) TEST 2.3 PASS (set PWM dutycycle, callback: 0) TEST 2.4 PASS (get PWM dutycycle: 128) TEST 2.5 PASS (set PWM dutycycle, callback: 40) TEST 2.6 PASS (set/get PWM frequency: 100) TEST 2.7 PASS (callback: 400) TEST 2.8 PASS (set/get PWM frequency: 1000) TEST 2.9 PASS (callback: 4000) TEST 2.10 PASS (get PWM range: 255) TEST 2.11 PASS (get PWM real range: 200) TEST 2.12 PASS (set/get PWM range: 2000) TEST 2.13 PASS (get PWM real range: 200) PWM/Servo pulse accuracy tests. TEST 3.1 PASS (get servo pulsewidth: 500) TEST 3.2 PASS (set servo pulsewidth: 40000) TEST 3.3 PASS (get servo pulsewidth: 1500) TEST 3.4 PASS (set servo pulsewidth: 13333) TEST 3.5 PASS (get servo pulsewidth: 2500) TEST 3.6 PASS (set servo pulsewidth: 8000) TEST 3.7 PASS (set/get PWM frequency: 1000) TEST 3.8 PASS (set PWM range: 200) TEST 3.9 PASS (get PWM dutycycle: 20) TEST 3.10 PASS (set PWM dutycycle: 200) TEST 3.11 PASS (get PWM dutycycle: 40) TEST 3.12 PASS (set PWM dutycycle: 400) TEST 3.13 PASS (get PWM dutycycle: 60) TEST 3.14 PASS (set PWM dutycycle: 600) TEST 3.15 PASS (get PWM dutycycle: 80) TEST 3.16 PASS (set PWM dutycycle: 800) Pipe notification tests. TEST 4.1 PASS (notify open/begin: 0) TEST 4.2 PASS (notify pause: 0) TEST 4.3 PASS (notify close: 0) TEST 4.4 PASS (sequence numbers ok: 1) TEST 4.5 PASS (gpio toggled ok: 1) TEST 4.6 PASS (number of notifications: 80) Waveforms & serial read/write tests. TEST 5.1 PASS (callback, set mode, wave clear: 0) TEST 5.2 PASS (pulse, wave add generic: 4) TEST 5.3 PASS (wave tx repeat: 9) TEST 5.4 PASS (callback: 50) TEST 5.5 PASS (wave tx stop: 0) TEST 5.6 PASS (serial read open: 0) TEST 5.7 PASS (wave clear, wave add serial: 3405) TEST 5.8 PASS (wave tx start: 6811) TEST 5.9 PASS (NOT APPLICABLE: 0) TEST 5.10 PASS (NOT APPLICABLE: 0) TEST 5.11 PASS (wave tx busy, serial read: 0) TEST 5.12 PASS (serial read close: 0) TEST 5.13 PASS (wave get micros: 6158148) TEST 5.14 PASS (wave get high micros: 6158148) TEST 5.15 PASS (wave get max micros: 1800000000) TEST 5.16 PASS (wave get pulses: 3405) TEST 5.17 PASS (wave get high pulses: 3405) TEST 5.18 PASS (wave get max pulses: 12000) TEST 5.19 PASS (wave get cbs: 6810) TEST 5.20 PASS (wave get high cbs: 6810) TEST 5.21 PASS (wave get max cbs: 25016) TEST 5.22 PASS (wave create pad, count==1, wid==: 0) TEST 5.23 PASS (wave create pad, count==2, wid==: 1) TEST 5.24 PASS (delete wid==0 success: 0) TEST 5.25 PASS (No more CBs using wave create: -67) TEST 5.26 PASS (wave create pad, count==3, wid==: 0) TEST 5.27 PASS (wave chain [1,0]: 0) TEST 5.28 PASS (callback count==: 5) Trigger tests TEST 6.1 PASS (gpio trigger count: 5) TEST 6.2 PASS (gpio trigger pulse length: 150) Watchdog tests. TEST 7.1 PASS (set watchdog on count: 39) TEST 7.2 PASS (set watchdog off count: 0) Bank read/write tests. TEST 8.1 PASS (read bank 1: 0) TEST 8.2 PASS (read bank 1: 33554432) TEST 8.3 PASS (clear bank 1: 0) TEST 8.4 PASS (set bank 1: 1) TEST 8.5 PASS (read bank 2: 0) TEST 8.6 PASS (clear bank 2: 0) TEST 8.7 PASS (NOT APPLICABLE: 0) TEST 8.8 PASS (set bank 2: 0) TEST 8.9 PASS (NOT APPLICABLE: 0) Script store/run/status/stop/delete tests. TEST 9.1 PASS (store/run script: 100) TEST 9.2 PASS (run script/script status: 201) TEST 9.3 PASS (run/stop script/script status: 110) TEST 9.4 PASS (delete script: 0)`

guymcswain commented 9 months ago

For sanity, can you toggle the gpio on Pi4 using another method to verify a reasonable output on piscope? From Pi4 terminal for example:

pigs pwm 5 128

should produce a square wave on gpio 5.

Zachary57-fr commented 9 months ago

I tested with following command issued on pi4 ( gpio 6 of pi4 connected to gpio 6 of pi 2 running piscope ) : pigs pwm 6 128 Here is screenshot of piscope. The other strange behaviour is that after issuing command, gpio 6 send signal forever until pi reboot.

pwm-gpio6

Zachary57-fr commented 9 months ago

Here is also the vcd file containing the entire trace : pigs-pwm-sample.zip

guymcswain commented 9 months ago

Thanks for the vcd file.

The low pulses are generally 3 to 5 us wide but sometimes are groups of small pulses lasting for 45 us. Obviously, this is wrong. Not only is the duty cycle wrong but there should never be multiple transitions within a pwm cycle. (Sometimes they are missing entirely). Is it possible there is an output drive issue with the gpio?

The frequency of the pulses (or pulse groups) is around 800 Hz which seems plausible for a pwm cycle.

On my Pi 4 4GB bullseye 64-bit I'm able to observe a square wave of 800 Hz. Initially, the frequency was 4000 but I was able to set it to 800 with pigs pfs 27 800. I'm using gpio 27.

guymcswain commented 9 months ago

pigpio.zip My captured vcd file for reference.

Zachary57-fr commented 9 months ago

Thanks for the vcd file.

The low pulses are generally 3 to 5 us wide but sometimes are groups of small pulses lasting for 45 us. Obviously, this is wrong. Not only is the duty cycle wrong but there should never be multiple transitions within a pwm cycle. (Sometimes they are missing entirely). Is it possible there is an output drive issue with the gpio?

The frequency of the pulses (or pulse groups) is around 800 Hz which seems plausible for a pwm cycle.

On my Pi 4 4GB bullseye 64-bit I'm able to observe a square wave of 800 Hz. Initially, the frequency was 4000 but I was able to set it to 800 with pigs pfs 27 800. I'm using gpio 27.

All is possible but since pi is new and argon one fan seems correctly controlled, I don't think that GPIO are broken. I did several other tests without being able to get a correct output. I also tried following commands : # pigs write 6 0 # pigs write 6 1 # pigs write 6 0

The output is attached and seems inverted sample-1-0-only.zip

Regarding GPIO 27 : i can mesure some signal on it ( from pi 2 GPIO 27 ) without issuing any command : gpio27-after-reboot.zip

guymcswain commented 9 months ago

Regarding GPIO 27 : i can mesure some signal on it ( from pi 2 GPIO 27 ) without issuing any command

What mode is gpio27? pigs mg 27 issued from Pi 2

Zachary57-fr commented 9 months ago

pigs mg 27

Without anything plug on it, command is returning 0 ( it is a fresh raspbian install used only for piscope )

guymcswain commented 9 months ago

Regarding the 'sample-1-0-only' vcd, it appears that a transition is missing.

$enddefinitions $end
#0
...
0G
...
#5
1G

I'm unsure, but could be an artifact of piscope. In any case, the gpio seems to be driving the pin correctly.

guymcswain commented 9 months ago

Mode 0 indicates the gpioi is in 'input' mode. By default the gpio should have a weak pull down so it should remain low (0). That said, if you touch it with your finger it could pick up noise.

guymcswain commented 9 months ago

Please tell me more about what is running on the Pi4 8GB:

guymcswain commented 9 months ago

... and show the script you are running to generate the waveform.

Zachary57-fr commented 9 months ago

Here are requested details regarding the Pi4 :

`#cat /proc/cpuinfo processor : 0 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3

processor : 1 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3

processor : 2 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3

processor : 3 BogoMIPS : 108.00 Features : fp asimd evtstrm crc32 cpuid CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 CPU part : 0xd08 CPU revision : 3

Hardware : BCM2835 Revision : d03115 Serial : 1000000004b26661 Model : Raspberry Pi 4 Model B Rev 1.5

cat /sys/firmware/devicetree/base/model

Raspberry Pi 4 Model B Rev 1.5`

And the script used to generate wave is from following repo : https://github.com/Nickduino/Pi-Somfy Code involved is inside operateShutters.py file : since same code works on pi 2 and script logs produce same output on pi4 and pi2 when using same input parameters, I suspected issue to be more on gpio part Part of code that produce wave should be this ( I removed some lines to put only parts that are used to generate signal but complete script is available on the git ) : `

       pi.wave_add_new()
       pi.set_mode(self.TXGPIO, pigpio.OUTPUT)

       self.frame[0] = 0xA7;       # Encryption key. Doesn't matter much
       self.frame[1] = button << 4 # Which button did  you press? The 4 LSB will be the checksum
       self.frame[2] = code >> 8               # Rolling code (big endian)
       self.frame[3] = (code & 0xFF)           # Rolling code
       self.frame[4] = teleco >> 16            # Remote address
       self.frame[5] = ((teleco >>  8) & 0xFF) # Remote address
       self.frame[6] = (teleco & 0xFF)         # Remote address

       #This is where all the awesomeness is happening. You're telling the daemon what you wanna send
       wf=[]
       wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 9415)) # wake up pulse
       wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 89565)) # silence
       for i in range(2): # hardware synchronization
          wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 2560))
          wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 2560))
       wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 4550)) # software synchronization
       wf.append(pigpio.pulse(0, 1<<self.TXGPIO,  640))

       for i in range (0, 56): # manchester enconding of payload data
          if ((self.frame[int(i/8)] >> (7 - (i%8))) & 1):
             wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 640))
             wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 640))
          else:
             wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 640))
             wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 640))

       wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 30415)) # interframe gap

       for j in range(1,repetition): # repeating frames
                for i in range(7): # hardware synchronization
                      wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 2560))
                      wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 2560))
                wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 4550)) # software synchronization
                wf.append(pigpio.pulse(0, 1<<self.TXGPIO,  640))

                for i in range (0, 56): # manchester enconding of payload data
                      if ((self.frame[int(i/8)] >> (7 - (i%8))) & 1):
                         wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 640))
                         wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 640))
                      else:
                         wf.append(pigpio.pulse(1<<self.TXGPIO, 0, 640))
                         wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 640))

                wf.append(pigpio.pulse(0, 1<<self.TXGPIO, 30415)) # interframe gap

       pi.wave_add_generic(wf)
       wid = pi.wave_create()
       pi.wave_send_once(wid)
       while pi.wave_tx_busy():
          pass
       pi.wave_delete(wid)

       pi.stop()`
guymcswain commented 9 months ago

pigpiod is started via crontab with following command : pigpiod -l -m -n 127.0.0.1

I have not invoked the daemon using crontab before. Can you explain how that is done?

Agree with you on -m argument shouldn't matter but just for sanity can you run the ./x_pigpiod_if2 test suite. EDIT: Or better, run ./x_pigpio.py since you are using that particular client.

Zachary57-fr commented 9 months ago

Here are test results :

./x_pigpio.py

Connected to pigpio daemon.

Testing pigpio Python module 1.78 Python 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] pigpio version 79. Hardware revision 13644053. Mode/PUD/read/write tests. TEST 1.1 PASS (set mode, get mode: 0) TEST 1.2 PASS (set pull up down, read: 1) TEST 1.3 PASS (set pull up down, read: 0) TEST 1.4 PASS (write, get mode: 1) TEST 1.5 PASS (read: 0) TEST 1.6 PASS (write, read: 1) PWM dutycycle/range/frequency tests. TEST 2.1 PASS (set PWM range, set/get PWM frequency: 10) TEST 2.2 PASS (get PWM dutycycle: 0) TEST 2.3 PASS (set PWM dutycycle, callback: 0) TEST 2.4 PASS (get PWM dutycycle: 128) TEST 2.5 FAILED got 0 (set PWM dutycycle, callback: 40) TEST 2.6 PASS (set/get PWM frequency: 100) TEST 2.7 FAILED got 0 (callback: 400) TEST 2.8 PASS (set/get PWM frequency: 1000) TEST 2.9 FAILED got 0 (callback: 4000) TEST 2.10 PASS (get PWM range: 255) TEST 2.11 PASS (get PWM real range: 200) TEST 2.12 PASS (set/get PWM range: 2000) TEST 2.13 PASS (get PWM real range: 200) PWM/Servo pulse accuracy tests. TEST 3.1 PASS (get servo pulsewidth: 500) Traceback (most recent call last): File "./x_pigpio.py", line 1028, in if '3' in tests: t3() File "./x_pigpio.py", line 209, in t3 CHECK(3, t, int((1E3*(on+off))/on), int(2E7/x), 1, "set servo pulsewidth") ZeroDivisionError: float division by zero

Regarding launching deamon from crontab, I simply add this line to crontab ( I was starting deamon same way on PI 2 on did some test after launching it manually ) : @reboot pigpiod -l -m -n 127.0.0.1

After killing deamon and starting it again without -m option, I got those results :
killall pigpiod pigpiod -l -n 127.0.0.1

./x_pigpio.py

Connected to pigpio daemon.

Testing pigpio Python module 1.78 Python 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] pigpio version 79. Hardware revision 13644053. Mode/PUD/read/write tests. TEST 1.1 PASS (set mode, get mode: 0) TEST 1.2 PASS (set pull up down, read: 1) TEST 1.3 PASS (set pull up down, read: 0) TEST 1.4 PASS (write, get mode: 1) TEST 1.5 PASS (read: 0) TEST 1.6 PASS (write, read: 1) PWM dutycycle/range/frequency tests. TEST 2.1 PASS (set PWM range, set/get PWM frequency: 10) TEST 2.2 PASS (get PWM dutycycle: 0) TEST 2.3 PASS (set PWM dutycycle, callback: 0) TEST 2.4 PASS (get PWM dutycycle: 128) TEST 2.5 PASS (set PWM dutycycle, callback: 40) TEST 2.6 PASS (set/get PWM frequency: 100) TEST 2.7 PASS (callback: 400) TEST 2.8 PASS (set/get PWM frequency: 1000) TEST 2.9 PASS (callback: 4000) TEST 2.10 PASS (get PWM range: 255) TEST 2.11 PASS (get PWM real range: 200) TEST 2.12 PASS (set/get PWM range: 2000) TEST 2.13 PASS (get PWM real range: 200) PWM/Servo pulse accuracy tests. TEST 3.1 PASS (get servo pulsewidth: 500) TEST 3.2 PASS (set servo pulsewidth: 40000) TEST 3.3 PASS (get servo pulsewidth: 1500) TEST 3.4 PASS (set servo pulsewidth: 13333) TEST 3.5 PASS (get servo pulsewidth: 2500) TEST 3.6 PASS (set servo pulsewidth: 8000) TEST 3.7 PASS (set/get PWM frequency: 1000) TEST 3.8 PASS (set PWM range: 200) TEST 3.9 PASS (get PWM dutycycle: 20) TEST 3.10 PASS (set PWM dutycycle: 200) TEST 3.11 PASS (get PWM dutycycle: 40) TEST 3.12 PASS (set PWM dutycycle: 400) TEST 3.13 PASS (get PWM dutycycle: 60) TEST 3.14 PASS (set PWM dutycycle: 600) TEST 3.15 PASS (get PWM dutycycle: 80) TEST 3.16 PASS (set PWM dutycycle: 800) Pipe notification tests. TEST 4.1 PASS (notify open/begin: 0) TEST 4.2 PASS (notify pause: 0) TEST 4.3 PASS (notify close: 0) TEST 4.4 PASS (sequence numbers ok: 1) TEST 4.5 PASS (gpio toggled ok: 1) TEST 4.6 PASS (number of notifications: 80) Waveforms & bit bang serial read/write tests. TEST 5.1 PASS (callback, set mode, wave clear: 0) TEST 5.2 PASS (pulse, wave add generic: 4) TEST 5.3 PASS (wave send repeat: 9) TEST 5.4 PASS (callback: 50) TEST 5.5 PASS (wave tx stop: 0) TEST 5.6 PASS (serial read open: 0) TEST 5.7 PASS (wave clear, wave add serial: 3405) TEST 5.8 PASS (wave send once: 6811) TEST 5.9 PASS (callback: 0) TEST 5.10 PASS (wave tx busy, callback: 1702) TEST 5.11 PASS (wave tx busy, serial read: 1) TEST 5.12 PASS (serial read close: 0) TEST 5.13 PASS (wave get micros: 6158148) TEST 5.14 PASS (NOT APPLICABLE: 0) TEST 5.15 PASS (wave get max micros: 1800000000) TEST 5.16 PASS (wave get pulses: 3405) TEST 5.17 PASS (NOT APPLICABLE: 0) TEST 5.18 PASS (wave get max pulses: 12000) TEST 5.19 PASS (wave get cbs: 6810) TEST 5.20 PASS (NOT APPLICABLE: 0) TEST 5.21 PASS (wave get max cbs: 25016) TEST 5.22 PASS (wave clear: 0) TEST 5.23 PASS (pulse, wave add generic: 4) TEST 5.24 PASS (wave create: 0) TEST 5.25 PASS (wave send repeat: 9) TEST 5.26 PASS (callback: 50) TEST 5.27 PASS (wave tx stop: 0) TEST 5.28 PASS (wave add serial: 3405) TEST 5.29 PASS (wave create: 1) TEST 5.30 PASS (wave send once: 6811) TEST 5.31 PASS (callback: 0) TEST 5.32 PASS (wave tx busy, callback: 1702) TEST 5.33 PASS (wave delete: 0) TEST 5.34 PASS (wave create and pad, wid==: 0) TEST 5.35 PASS (wave create and pad, wid==: 1) TEST 5.36 PASS (delete wid==0 success: 0) TEST 5.37 PASS (No more CBs using wave create: -67) TEST 5.38 PASS (wave create pad, count==3, wid==: 0) TEST 5.39 PASS (wave chain [1,0]: 0) TEST 5.40 PASS (callback count==: 10) Trigger tests. TEST 6.1 PASS (gpio trigger count: 5) TEST 6.2 PASS (gpio trigger pulse length: 150) Watchdog tests. TEST 7.1 PASS (set watchdog on count: 39) TEST 7.2 PASS (set watchdog off count: 0) Bank read/write tests. TEST 8.1 PASS (read bank 1: 0) TEST 8.2 PASS (read bank 1: 33554432) TEST 8.3 PASS (clear bank 1: 0) TEST 8.4 PASS (set bank 1: 1) TEST 8.5 PASS (read bank 2: 0) TEST 8.6 PASS (clear bank 2: 0) TEST 8.7 PASS (clear bank 2: -42) TEST 8.8 PASS (set bank 2: 0) TEST 8.9 PASS (set bank 2: -42) Script store/run/status/stop/delete tests. TEST 9.1 PASS (store/run script: 100) TEST 9.2 PASS (run script/script status: 201) TEST 9.3 PASS (run/stop script/script status: 110) TEST 9.4 PASS (delete script: 0) Wavechains & filter tests. TEST 13.1 PASS (callback, set mode, wave clear: 0) TEST 13.2 PASS (pulse, wave add generic: 6) TEST 13.3 PASS (clear glitch filter: 0) TEST 13.4 PASS (clear noise filter: 0) TEST 13.5 PASS (wave chain: 0) TEST 13.6 PASS (wave chain, tally: 2688) TEST 13.7 PASS (glitch filter, wave chain, tally: 1792) TEST 13.8 PASS (glitch filter, wave chain, tally: 896) TEST 13.9 PASS (glitch filter, wave chain, tally: 0) TEST 13.10 PASS (noise filter, wave chain, tally: 1500) TEST 13.11 PASS (noise filter, wave chain, tally: 750) TEST 13.12 PASS (noise filter, wave chain, tally: 0) TEST 13.13 PASS (wave delete: 0)

Regarding those tests, are waves timers compared to what is generated using same clock ? I am not good enough to understand all your code but maybe if clock is not correct for generating and have same drift for reading, it may pass tests even if waves are incorrectly generated.

Please ignore if it is not relevant but is there any way to measure from PI2 with a wire between GPIO 25 of both devices so measure are taken from a device which have correct clock ?

guymcswain commented 9 months ago

Can you now observe your waveform via piscope on your Pi2?

Essentially, I want to understand if the problem is related to pigpiod coming up in a bad state from boot. That means either to turn off your crontab and launch pigpiod manually after reboot or kill it then restart it manually. Then see if you can observe your waveforms as your original post.

Zachary57-fr commented 9 months ago

I killed pigpiod and launched it manually with following commands : #killall pigpiod #pigpiod -l

Same result than previous tests ( see VCD file on GPIO 5 ). I am pretty sure I already tested multiple pigpiod arguments and also without crontab launch. wave-signal.zip

guymcswain commented 9 months ago

Do you have a pigpiod service installed? systemctl status pigpiod

If so, please show systemctl cat pigpiod

guymcswain commented 9 months ago

Same result than previous tests ... without crontab launch.

Does this mean you have tested starting from a clean boot without pigpiod invoked, then manually running your waveform? This is the result I'm interested in. I'm suspicious of some corruption occurring if pigpiod tries to initialize before the system is ready. Please bear with my persistent questions.

Zachary57-fr commented 9 months ago

I have service installed but not active : systemctl status pigpiod ● pigpiod.service - Daemon required to control GPIO pins via pigpio Loaded: loaded (/lib/systemd/system/pigpiod.service; disabled; vendor preset: enabled) Active: inactive (dead)

systemctl cat pigpiod

/lib/systemd/system/pigpiod.service

[Unit] Description=Daemon required to control GPIO pins via pigpio [Service] ExecStart=/usr/bin/pigpiod -l ExecStop=/bin/systemctl kill pigpiod Type=forking [Install] WantedBy=multi-user.target

I did several tests but yes, I also tried to run manually after reboot ( crontab entry is disabled ) I also tried without argonone script and then without argon one case ( only pi with official power attached ) and results looks similar ( see attached ) sample-without-case-and-script.zip

I also tried to disable 3D acceleration from /boot/config.txt by commenting following lines ( like below ) :

Enable DRM VC4 V3D driver

dtoverlay=vc4-kms-v3d

max_framebuffers=2

Still same kind of result each time

guymcswain commented 9 months ago

Thanks. I'm at a loss to understand what is going on. It seems like the pwm peripheral, which controls timing of waveforms as well as pwm output, is getting fouled up on your Pi4. I'm not sure where to go next. I'll think about it.

guymcswain commented 9 months ago

Can you paste a copy of your /boot/config.txt?

Zachary57-fr commented 9 months ago

Here is my last /boot/config.txt I also tried to force CPU frequency to maximum value by changing governor with those commands : echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

Still same results config.txt

guymcswain commented 9 months ago

Please comment this section:

# Enable audio (loads snd_bcm2835)
#dtparam=audio=off
guymcswain commented 9 months ago

For sanity, we should insure we are on the same code base. Do you mind installing the latest pigpio from the 'develop' branch? This is the one I'm running. It's possible some bug fixes were made that may have relevance, but it's been too long for me to remember.

wget https://github.com/joan2937/pigpio/archive/refs/heads/develop.zip
unzip develop.zip
cd pigpio-develop
make
sudo make install
Zachary57-fr commented 9 months ago

I tried with dev version and line commented after a reboot ( default line was dtparam=audio=on ) Still same, here is the VCD output ( GPIO 5 ) sample-dev-version.zip

Zachary57-fr commented 9 months ago

Also found some discussion related to the other issue on which you referenced this one here : https://forums.raspberrypi.com/viewtopic.php?t=331110

I don't know if following results can help : vcgencmd measure_clock plld && vcgencmd measure_clock pwm frequency(100)=3000000000 frequency(25)=9993164

guymcswain commented 9 months ago

I get:

vcgencmd measure_clock plld && vcgencmd measure_clock pwm
frequency(100)=3000000000
frequency(25)=107143064
Zachary57-fr commented 9 months ago

This is the max value I saw for now :

vcgencmd measure_clock plld && vcgencmd measure_clock pwm
frequency(100)=3000000000
frequency(25)=10006348
Zachary57-fr commented 9 months ago

I made following code to test :

#!/usr/bin/python3

import time
import pigpio

TXGPIO = 5 #Define which GPIO to use
iteration = 2
pi = pigpio.pi() # connect to Pi

#pi.wave_add_new()
pi.set_mode(TXGPIO, pigpio.OUTPUT)

#Init to 0
pi.write(TXGPIO, 0)

i = 0
print('Starting ' + str(iteration) + ' loop')
while i < iteration:
  print('Loop ' + str(i))
  print('Current time : ' + str(int(round(time.time() * 1000))))
  pi.write(TXGPIO, 1)
  time.sleep(1)
  print('Current time : ' + str(int(round(time.time() * 1000))))
  pi.write(TXGPIO, 0)
  time.sleep(1)
  print('-------------------------')
  i += 1

print('Done')
pi.write(TXGPIO, 0)

pi.stop()

Output is :

./gpio_test2.py
Starting 2 loop
Loop 0
Current time : 1696089877876
Current time : 1696089878877
-------------------------
Loop 1
Current time : 1696089879878
Current time : 1696089880880
-------------------------
Done

But measure from PI shows following :
Test2

Here is the VCD test2.zip

Is PWM clock involved for this test ?

guymcswain commented 9 months ago

I'm not sure which clock source is used for pwm. I think joan mentioned PLLD in the link you referenced above. But, pigpio wave apis use the pwm to time the dma transfers that generate the output waveform. In your test above, you are writing directly to the gpio so, no, pwm should not be involved. Strange behavior.

guymcswain commented 9 months ago

Try adding a callback function that prints level and tick.

def cbf(gpio, level, tick):
   print(gpio, level, tick)

pi.callback(TXGPIO, pigpio.EITHER_EDGE, cbf)
guymcswain commented 9 months ago

Reading about the Argon One, it appears that raspi-gpio is installed which is likely to conflict with pigpio. Also, the Argon forum reveals complaints about the lack of documentation on gpio usage. My recommendation is to do a fresh install of RPi OS and pigpio and then re-run waveforms.

Zachary57-fr commented 9 months ago

I tested after removing packages installed by argon script except i2c-tools ( raspi-gpio python3-rpi.gpio python3-smbus i2c-tools ) and rebooting.

It seems better ( I can now measure a 1s signal while running test script ) but I still have strange behaviours :

./gpio_test2.py
Starting 2 loop
Loop 0
Current time : 1696104377993
5 0 801707006
5 1 801707476
Current time : 1696104378993
5 0 802707906
-------------------------
Loop 1
Current time : 1696104379995
5 1 803709241
Current time : 1696104380996
5 0 804710296
-------------------------
Done

test-without-argontool.zip

Regarding GPIO usage on argon case, there were a paper document with the case indicating that GPIO 3,4 and 7 are used. From the internet I found following usage ( https://forum.argon40.com/t/argon-one-v2-used-pins/1576 ) :

BMC pin  Function
=================
2        SDA.1 (I2C data)
3        SCL.1 (I2C clock)
4        GPIO.7 Shutdown button
14       TXD transmit UART <== Function?
22       GPIO.3 IR LED pin
23       GPIO.4 IR receiver pin

Not sure if it can interfer as well but since I removed argon script and installed tools, I put following script in place to control FAN :

#!/bin/bash
# Script require package i2c-tools
# Fan control info : https://github.com/Argon40Tech/Argon-ONE-i2c-Codes
while true; do
    cpu_temp=$(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000)) #Retrieve CPU temp in °C

    if [ $cpu_temp -gt 60 ]; then
        i2cset -y 1 0x1A 0x64
    elif [ $cpu_temp -gt 55 ]; then
        i2cset -y 1 0x1A 0x4B
    elif [ $cpu_temp -gt 50 ]; then
        i2cset -y 1 0x1A 0x3C
    elif [ $cpu_temp -gt 47 ]; then
        i2cset -y 1 0x1A 0x14
    else
        i2cset -y 1 0x1A 0x00
    fi

    sleep 60  # Wait for 60 seconds
done
Zachary57-fr commented 9 months ago

I tried with a fresh install on another drive without argon case script using pigpio from apt and here are the results :

Looking at the first one it seems that timing are correct but GPIO value stay high despite having callback showing correct values : Test-script-with-callback

guymcswain commented 9 months ago

I would tend to believe the callback and suspect the waveforms. Do you have an independent tool such as an oscilloscope? If not, can you run piscope from the Rpi4?

Zachary57-fr commented 9 months ago

I made new test and all is now working perfectly : issue was most probably due to conflict with raspi-gpio or other tools. The reason it was not working after test on fresh install was due to dead RF transceiver : since it was working from pi2 with transceiver inside pi4 case, it probably died after reassembling inside case following test with pi4 only.

I can now confirm that GPIO wave is working perfectly on the pi4 8GB ( version 1.5 ) inside argon case ( but without installing script ).

For those who are interested, it is mandatory to not install argon one script. I did not test other features ( button and ir as I don't use them ) but FAN control is still possible using pigpio : Only add following line to /boot/config.txt :

dtparam=i2c_arm=on

And control FAN using python script like this :

#!/usr/bin/env python3

import sys
import pigpio

import time

def i2c_set_device(bus, address, register, value):
    pi = pigpio.pi()
    if not pi.connected:
        print("Unable to connect to Pigpio daemon.")
        return

    handle = pi.i2c_open(bus, address)
    if handle < 0:
        print("Unable to open I2C device.")
        pi.stop()
        return

    pi.i2c_write_byte_data(handle, register, value)
    pi.i2c_close(handle)
    pi.stop()

def get_cpu_temp():
    # Retrieve CPU temp in °C
    with open("/sys/class/thermal/thermal_zone0/temp", "r") as file:
        temp = int(file.read()) / 1000
    return temp

def set_fan_speed(temp):
    if temp > 60:
        i2c_set_device(1, 0x1A, 0x64, 0x00)
    elif temp > 55:
        i2c_set_device(1, 0x1A, 0x4B, 0x00)
    elif temp > 50:
        i2c_set_device(1, 0x1A, 0x3C, 0x00)
    elif temp > 47:
        i2c_set_device(1, 0x1A, 0x14, 0x00)
    else:
        i2c_set_device(1, 0x1A, 0x00, 0x00)

if __name__ == "__main__":
    while True:
        cpu_temp = get_cpu_temp()
        set_fan_speed(cpu_temp)
        time.sleep(60)  # Wait for 60 seconds

It is possible to run as a service starting after pigpio ( service has also to be enable ) :

[Unit]
Description=Control argonone fan depending on CPU temperature
After=pigpiod.service
Wants=pigpiod.service

[Service]
ExecStart=/$PATH_TO_SCRIPT$/$SCRIPT_NAME$.py
ExecStop=/bin/pkill -f "python3 /$PATH_TO_SCRIPT$/$SCRIPT_NAME$.py"

[Install]
WantedBy=multi-user.target

Thank you for your help