[Howto] Software PWM simulation for all GPIO output pins

Post Reply
ivandavidov
Posts: 13
Joined: Fri Dec 02, 2016 8:36 am
languages_spoken: english
ODROIDs: C2
Has thanked: 0
Been thanked: 2 times
Contact:

[Howto] Software PWM simulation for all GPIO output pins

Unread post by ivandavidov » Wed Dec 14, 2016 3:50 am

I own C2 device and this device has official hardware PWM support for only two of the GPIO pins. Perhaps there is similar limitation on other HardKernel devices.

But what if you need to use PWM on 3 or more pins? Typical use case would be a RGB LED where you want to control the R, G and B channels independently. Therefore you need 3 pins with PWM capabilities.

Since the C2 device has support for only 2 PWM pins, I came up with software solution which simulates PWM via Bash script which utilizes the gpio (wiringPi) command.

Here is the whole script:

Code: Select all

#!/bin/bash

if [ "$1" = "" ] ; then
  cat << CEOF

  Usage: $0 pin duty

  pin   - Physical pin
  duty  - Duty cycle in 10% steps. Valid values are 1 through 9.
          Values 0 and 10 correspond to digital write 0 and 1,
          eg 'gpio -1 write 7 0' and 'gpio -1 write 7 1'.

  Examples:

  $0 7 2
  This will send PWM signal from physical pin #7 with 20% duty.

  $0 7 8
  This will send PWM signal from physical pin #7 with 80% duty.

CEOF
  exit 1
fi

pin=$1
up=$2
down=$((10 - $2))

trap ctrl_c INT

function ctrl_c() {
  gpio -1 write $pin 0
  echo
  exit 0
}

gpio -1 mode $pin out

while true;
do
  gpio -1 write $pin 1
  sleep 0.00$up

  gpio -1 write $pin 0
  sleep 0.00$down
done
The script uses physical pin notation, i.e. pin numbers are from 1 to 40. You can exit the script with Ctrl + C. You can put the script in background by placing & in the end of the command like this:

Code: Select all

./pwm.sh 7 4 &
And then you can exit the script either by invoking pkill pwm or by using the fg command, followed by Ctrl + C.

Pros:

* You can simulate PWM on every output pin.

Cons:

* The duty step is 10% and it is not guaranteed. You can try to modify the sleep intervals to improve the duty step.
* The theoretical pulse frequency is 0.1Khz (100 times per second) and it is not guaranteed. You can try to modify the sleep intervals to improve the duty step.
* The PWM simulation has negative impact on the CPU. I get high CPU load and flickering LED (instead of stable) when I use the script on 2 or more different pins.

You should be able to get better performance if you use the same approach to simulate PWM with another wiringPi wrapper different than gpio, perhaps via Python or directly via C.

Let me know if you find this useful and/or if you run into any trouble.
These users thanked the author ivandavidov for the post (total 2):
mad_ady (Thu Oct 31, 2019 2:52 am) • rooted (Sat Nov 02, 2019 3:57 pm)

User avatar
mad_ady
Posts: 6796
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 166 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by mad_ady » Fri Nov 01, 2019 9:44 pm

Thanks for posting. I'm trying to use a custom PWM with your script in order to control the brightness of my VU7. With your script I get terrible flickering, so it's switching too slowly.
I will try to access it through wiringpi and see if I can improve the switching speed and get less flickering.

User avatar
rooted
Posts: 6779
Joined: Fri Dec 19, 2014 9:12 am
languages_spoken: english
Location: Gulf of Mexico, US
Has thanked: 224 times
Been thanked: 42 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by rooted » Sat Nov 02, 2019 3:57 pm

mad_ady wrote:Thanks for posting. I'm trying to use a custom PWM with your script in order to control the brightness of my VU7. With your script I get terrible flickering, so it's switching too slowly.
I will try to access it through wiringpi and see if I can improve the switching speed and get less flickering.
If you figure it out I would like to learn how.

User avatar
mad_ady
Posts: 6796
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 166 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by mad_ady » Mon Nov 04, 2019 6:16 pm

Ok, here is the wiringpi python implementation:

Code: Select all

#!/usr/bin/python3
import odroid_wiringpi as wpi               
                                                                     
                                                                      
# Prerequisites:                                                           
# * wiringPi: http://odroid.com/dokuwiki/doku.php?id=en:c1_tinkering#python_example
                                                                    
#initialize wiringPi                        
wpi.wiringPiSetup()                                                                 
                                                                                           
pwmPin = 7 #GPIO 249 on Odroid C2, Pin 7
brightness = 70 #percent

#set as output pin 
wpi.pinMode(pwmPin, 1)

wpi.softPwmCreate(pwmPin,0,100) # Setup PWM using Pin, Initial Value and Range parameters
while True:
    wpi.softPwmWrite(pwmPin,brightness) # Change PWM duty cycle
It works better than the GPIO implementation, but I still get the occasional flicker every couple of seconds (CPU is clocked at 1.8GHz). When the system is idle I get 100% CPU usage on one core (which is too much for me). When I run a stress test on the CPU the flickering worsens considerably.

Here is a video with the VU7 with 70% brightness using the sh script (sysfs implementation) in the first post:
https://www.youtube.com/watch?v=ZmV6pd2Q6UY

Here is a video with the VU7 with 70% brightness using wiringpi. Using C wouldn't likely improve things since wiringpi-python calls a C method in the background.
https://www.youtube.com/watch?v=f3kpna50RGU

Time for plan C - which is more complicated. As far as I know the odroid_lirc module uses the kernel to generate (and modulate) a 38KHz pulse on any GPIO. So it's software-based, but in kernel space. Now, an IR code is short and I want continuous pulses, but maybe there is a way to modify the module to generate a PWM signal from the kernel (where odds are the signal is more stable). Though it would still consume CPU, it wouldn't show up in htop because it's a kernel process...
This looks promising too: https://github.com/sarfata/pi-blaster/ and it seems it's hooked into a different PWM or PCM source, but not sure if it's PI specific...
These users thanked the author mad_ady for the post:
rooted (Mon Nov 04, 2019 7:01 pm)

User avatar
rooted
Posts: 6779
Joined: Fri Dec 19, 2014 9:12 am
languages_spoken: english
Location: Gulf of Mexico, US
Has thanked: 224 times
Been thanked: 42 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by rooted » Mon Nov 04, 2019 7:04 pm

The wiringpi implementation is much better, I'm guessing with a bit more speed the flicker would be so small it would be invisible.

Good work.

User avatar
mad_ady
Posts: 6796
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 166 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by mad_ady » Mon Nov 04, 2019 7:09 pm

It's not the speed that's missing, it's the unreliability caused by the software scheduler that may pause the program and keep the screen off for too long. I ran it with nice with higher priority, but didn't see much improvement. Anyway, I'm against having programs use up 100% CPU, so I need to find something else.

User avatar
rooted
Posts: 6779
Joined: Fri Dec 19, 2014 9:12 am
languages_spoken: english
Location: Gulf of Mexico, US
Has thanked: 224 times
Been thanked: 42 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by rooted » Mon Nov 04, 2019 7:10 pm

mad_ady wrote:It's not the speed that's missing, it's the unreliability caused by the software scheduler that may pause the program and keep the screen off for too long. I ran it with nice with higher priority, but didn't see much improvement. Anyway, I'm against having programs use up 100% CPU, so I need to find something else.
Is using a microcontroller out of the question?

User avatar
mad_ady
Posts: 6796
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 166 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by mad_ady » Mon Nov 04, 2019 8:22 pm

No, that's plan F for FUUU... :D

joerg
Posts: 908
Joined: Tue Apr 01, 2014 2:14 am
languages_spoken: german, english, español
ODROIDs: C1, C1+, C2
Location: Germany
Has thanked: 6 times
Been thanked: 21 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by joerg » Mon Nov 04, 2019 10:10 pm

@mad_ady: I'am using this adafruit PCA9685 breakout board to control my living room led lights from home assistant via i2c. Maybe this is a way you can go? Some clones you can get for less than 10€.
IMG_20191104_140144.jpg
IMG_20191104_140144.jpg (452.83 KiB) Viewed 220 times

User avatar
mad_ady
Posts: 6796
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 166 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by mad_ady » Mon Nov 04, 2019 10:27 pm

Well, ideally I'd like to do it without external hardware. I mean, I still have pins left unused :D
Plan D is to see if any of the RTC pins could be used as hardware pwm - maybe pins 3 or 5? https://wiki.odroid.com/accessory/displ ... c_pin_info
Plan E is to solder a wire to the pwm0 pin. That way I control both screens with one pin.

User avatar
odroid
Site Admin
Posts: 32552
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID
Has thanked: 189 times
Been thanked: 352 times
Contact:

Re: [Howto] Software PWM simulation for all GPIO output pins

Unread post by odroid » Tue Nov 05, 2019 9:17 am

"Plan E" is much more feasible.
These users thanked the author odroid for the post:
mad_ady (Tue Nov 05, 2019 2:02 pm)

Post Reply

Return to “Ubuntu (All Linux'es)”

Who is online

Users browsing this forum: No registered users and 7 guests