Pi IoT in Python using Linux drivers

0


[ad_1]

Page 1 of 4

PWM is a basic output mode suitable for controlling servos, motors and more. Linux has a driver which means you can use PWM without worrying about the hardware – if you know how.

This content comes from our recently published book:

Raspberry Pi IoT in Python Using linux drivers

By Harry Fairhead and Mike James

Buy on Amazon.

Contents

  1. Choosing a Pi for the IoT

  2. Getting started with Python

  3. Pilots: a first program

  4. The GPIO character driver

  5. GPIO using I / O control

  6. GPIO events

  7. The device tree
    Extract: The DHT22

  8. Some electronic devices

  9. Pulse width modulation
    Extract: PWM***NEW!!

  10. SPI devices

  11. I2C bases

  12. The Linux I2C driver

  13. Advanced I2C

  14. Sensor drivers

  15. 1-wire bus
    Extract 1-Wire And The DS18B20

  16. Go further with the drivers

  17. Annex I

One way to get around the problem of getting a fast response from a microcontroller is to move the problem away from the processor. In the case of the Pi’s processor, some onboard peripherals can use GPIO lines to implement protocols without the processor being involved. In this chapter, we take a close look at Pulse Width Modulation (PWM), including sound generation and LED driving.

When performing their most basic function, i.e. output, the GPIO lines can be set high or low by the processor. How quickly they can be set high or low depends on the speed of the processor.

By using the GPIO line in its pulse width modulation (PWM) mode, you can generate pulse trains up to 4.8 MHz, that is, pulses of just over 0.08 µs. The reason for the increase in speed, a factor of at least 100, is that the GPIO is connected to a pulse generator and, once set to generate pulses of a specific type, the pulse generator takes care of it without any intervention from the GPIO line or the processor. In fact, the pulse output can continue after your program ends if you forget to reset it.

Of course, even though the PWM line can generate pulses as short as 0.1 µs, it cannot change the pulses it produces whenever the processor can change them. For example, you cannot use PWM to produce a single 0.1 µs pulse because you cannot turn off the PWM generator in just 0.1 µs. That said, hardware-generated PWM is available on the Pi and there is a good PWM driver that makes it super easy to use.

Some basic facts about the Pi PWM

There are some facts worth clarifying from the start, although their full significance only becomes clear as we move forward.

First of all, what is PWM? The simple answer is that a pulse width modulated signal has pulses that repeat at a fixed rate, say, one pulse every milliseconds, but the pulse width can be changed.

There are two basic things to specify about the pulse train that is generated, its repetition rate and the width.
of each impulse. Usually, the repetition rate is defined as a single repetition period and the width of each pulse is specified as a percentage of the repetition period, called the duty cycle. So, for example, a repetition of 1 ms and a duty cycle of 50% specifies a period of 1 ms, which is high for 50% of the time, that is, a pulse width of 0.5 ms .

pwm1

The two extremes are 100% duty cycle, i.e. the line is always high, and 0% duty cycle, i.e. the line is always low. The duty cycle is simply the proportion of time the line is high. Note that it is the duty cycle that carries the information in PWM and not the frequency. This means that usually you select a repetition rate and stick to it and what you change as the program runs is the duty cycle.

There are many ways to specify a PWM signal – frequency and duty cycle, high time and low time, etc. It is easy to convert between these different representations.

As you can guess, there is no PWM input, just an output. If for some reason you need to decode or respond to a PWM input, you should program it using the GPIO input lines and pulse measurement techniques discussed in previous chapters.

PWM software

The alternative to dedicated PWM hardware is to implement it in software. You can easily find out how to do this. All you need is to set a sync loop to set the line high at repetition rate and then set it low again based on duty cycle. You can easily implement PWM software using GPIO character driver:

import gpiod
from time import sleep
chip = gpiod.Chip("0")
line = chip.get_line(4)
line.request(consumer="myprog.py",
       type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
period = 20
duty = 25
ontime = period/1000 * duty/ 100
offtime = period/1000 - ontime
while(True):
    line.set_value(1)
    sleep(ontime)
    line.set_value(0)
    sleep(offtime)  

The basic idea is to take the period in ms and the duty cycle as a percentage and calculate the on and off time.

A more advanced version of the same program uses a thread to implement PWM line failover. To understand how it works, you need to be happy with the threads:

import gpiod
from time import sleep
import threading
def softPWM(line,period,duty):
    ontime = period/1000 * duty/ 100
    offtime = period/1000 - ontime
    while(True):
        line.set_value(1)
        sleep(ontime)
        line.set_value(0)
        sleep(offtime)  
chip = gpiod.Chip("0")
line = chip.get_line(4)
line.request(consumer="myprog.py",
         type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
period = 20
duty = 75
IntThread=threading.Thread(target=softPWM,
                              args=(line,period,duty))
IntThread.start()
while(True):
    print("working",flush=True)
    sleep(2)

This will generate the PWM signal on the specified gpio line regardless of the main program. If you want to use it in production, you will need to add error handling and some functions to pause and stop the thread.

The accuracy of the PWM signal decreases as the frequency increases. At a period of 20ms and a duty cycle of 25% the frequency and the duty cycle are typically 48.5Hz and 25.5% or about 2% accuracy but at 2ms the figures are 425Hz and 29% or about 10% precision. It becomes more and more inaccurate and becomes unusable around 1kHz. The reason is that sleep is used for timing. This suspends the thread and relies on the operating system to restart it. The problem is that as the requested sleep time decreases, the operating system fails to restart the thread early enough because it is executing other threads while the PWM thread is suspended. You can replace the standby call with a busy wait loop to make synchronization more accurate, but this would not allow the operating system to run another thread while waiting. It would work fine on a multi-core Pi 4 but wouldn’t be so good on a single-core Pi Zero.

The implemented PWM software cannot be used for higher frequencies. It is however sufficient to operate at 50 Hz, which is suitable for driving servos – see below.

[ad_2]

Share.

Leave A Reply