问题
Here is my testing code:
from periphery import PWM
import time
# Open PWM channel 0, pin 0
pwm = PWM(0,0)
# Set frequency to 1 kHz
pwm.frequency = 50
# Set duty cycle to 75%
pwm.duty_cycle = 0.02
pwm.enable()
print(pwm.period)
print(pwm.frequency)
print(pwm.enabled)
# Change duty cycle to 50%
pwm.duty_cycle = 0.05
pwm.close()
Problem is this part:
# Open PWM channel 0, pin 0
pwm = PWM(0,0)
I can see output when running PWM(0,0)
PWM(0,1)
PWM(0,2)
but I get the error messsage when trying to run the following:
PWM(1,1)
PWM(2,2)
mendel@elusive-jet:/sys/class/pwm$ sudo python3 /usr/lib/python3/dist-packages/edgetpuvision/testPWM.py
OSError: [Errno 19] No such device
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/periphery/pwm.py", line 69, in _open
f_export.write("%d\n" % pin)
OSError: [Errno 19] No such device
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/edgetpuvision/testPWM.py", line 5, in <module>
pwm = PWM(1,1)
File "/usr/local/lib/python3.5/dist-packages/periphery/pwm.py", line 44, in __init__
self._open(channel, pin)
File "/usr/local/lib/python3.5/dist-packages/periphery/pwm.py", line 71, in _open
raise PWMError(e.errno, "Exporting PWM pin: " + e.strerror)
periphery.pwm.PWMError: [Errno 19] Exporting PWM pin: No such device
Based off the document from both Coral and the library site: https://coral.withgoogle.com/tutorials/devboard-gpio/
https://github.com/vsergeev/python-periphery
The
PWM(1,1)
PWM(2,2)
should have worked without issue, I can see the following directories existed:
"\sys\class\pwm\pwmchip0"
"\sys\class\pwm\pwmchip1"
"\sys\class\pwm\pwmchip2"
In the python-periphery source code https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py
it should getting the path as following:
PWM(1,1) ===> /sys/class/pwm/pwmchip1/pwm1
if pwm1
not exists, then it should call the export
to generate it.
So, My main question are:
- What is
channel
andpin
and how it is been used ? - Why I'm not able to get PWM(1,1) PWM(2,2) to work ?
Thank you in advance.
---------------2019.4.2 Update--------------------
I figured out the previous answer by myself (and thank you for anyone who provided help).
But as you can see from my own answer, I'm still not able to get the PWM to work as it is not output stable Voltage. (You can check out more detail below).
I'm currently running into another issue in which the output voltage are not stable at all. So, here is what I did to test:
I set up both Raspberry Pi 3+ Model B
and the EdgeTPU Coral Board
with 50hz
PWM with 5%
duty cycle. Since both device have GPIO output 3.3V, My theory is, their output should be identical, but they are NOT.
Here are the voltage measured by using a Arduino UNO board: Pi vs. EdgeTPU. (Note: all the voltage should be divide by 10). You can see there is a clear pattern(PWM) in the Pi output, alternating around 1.8v. but if you look at the EdgeTPU output, you can see the voltage is all over the places and it is much lower voltage (1.1v vs 1.8v).
it clearly to me something wrong with the EdgeTPU PWM output, So I did further research. found out from the (limited) document, it says
All GPIO pins have a 90k pull-down resistor inside the iMX8M SOC that is used by default during bootup, except for the I2C pins, which instead have a pull-up to 3.3V on the SOM. However, these can all be changed with a device tree overlay that loads after bootup.
Which lead me suspect the 90k pull-down resistor
might have lower the output voltage due to the fact of this formula V=IR
. So, I'm thinking change the device tree overlay
at bootup as it instructed. but, guess what, there is no documents on how to change it besides the following line from the overlays.txt
file:
# List of device tree overlays to load. Format: overlay=<dtbo name, no extenstion> <dtbo2> ...
overlay=
I have searched all over the place, there is no document regarding to how does Mendel Linux device tree overlay should be configured. so, I'm currently stuck, If you know the answer, please share it, I would much appreciated.
I will share this question to the Coral Support team as well to see if they will get me any response.(FYI, I did send something to them back when I posted the original question, haven't hear anything from them yet, even tho their website says We try to respond to inquiries within one business day — but often you'll get a response even quicker, usually a few hours.
) so, wish me luck. Will keep this answer updated if hear anything back.
Here is the passage/question I would like to convey to Google/Google Cloud/Google EdgeTPU/Google Coral Board teams also:
- Why choose python-periphery as the default library to implement GPIO and PWM ?
- Why choose the Mendel Linux as the default OS, when there is no site/document or any sort to be found ?
回答1:
What is channel and pin and how it is been used ?
The channel maps to the driver chip in Linux sysfs (e.g. pwmchip0
), and the pin maps to the individual outputs on each channel. Each channel will have npwm
pins.
You can run the pinout
command on your device to get some more details about the Peripheral ports on the 40-pin connector and the PWM channels they are connected to:
$ pinout
3.3.V -> 1 2 <- 5V
I2C2_SDA (i2c-1) -> 3 4 <- 5V
I2C2_SCL (i2c-1) -> 5 6 <- GND
UART3_TXD -> 7 8 <- UART1_TX
GND -> 9 10 <- UART1_RX
UART3_RXD -> 11 12 <- SAI1_TXC
GPIO_P13 (gpio6) -> 13 14 <- GND
PWM3 (pwmchip2) -> 15 16 <- GPIO_P16 (gpio73)
3.3V -> 17 18 <- GPIO_P18 (gpio138)
SPI1_MOSI -> 19 20 <- GND
SPI1_MISO -> 21 22 <- GPIO_P22 (gpio140)
SPI1_SCLK -> 23 24 <- SPI1_SS0
GND -> 25 26 <- SPI1_SS1
I2C3_SDA (i2c-2) -> 27 28 <- I2C3_SCL (i2c-2)
GPIO_P29 (gpio7) -> 29 30 <- GND
GPIO_P31 (gpio8) -> 31 32 <- PWM1 (pwmchip0)
PWM2 (pwmchip1) -> 33 34 <- GND
SAI1_TXFS -> 35 36 <- GPIO_P36 (gpio141)
GPIO_P37 (gpio77) -> 37 38 <- SAI1_RXD0
GND -> 39 40 <- SAI1_TXD0
On this board, there is only one pin per channel (cat npwm
returns 1) so the pin number in periphery would always be zero.
Why I'm not able to get PWM(1,1) PWM(2,2) to work ?
Per the explanation above, here are the valid periphery commands to initialize each PWM on the dev board:
- PWM1 (Pin 32) -->
pwm = PWM(0,0)
- PWM2 (Pin 33) -->
pwm = PWM(1,0)
- PWM3 (Pin 15) -->
pwm = PWM(2,0)
回答2:
There appears to still be an outstanding question of 3.3V PWM operation (as opposed to 2.5, which is correctly noted as the voltage divider between the pin having a pull up enabled and every pin having a weak pull down).
The pin configuration for the device tree overlay can be found here: https://coral.googlesource.com/linux-imx/+/refs/heads/master/arch/arm64/boot/dts/freescale/fsl-imx8mq-phanbell.dts#171
The number there (0x7f), can be decoded with this bitmask: https://coral.googlesource.com/linux-imx/+/refs/heads/master/Documentation/devicetree/bindings/pinctrl/fsl%2Cimx8mq-pinctrl.txt.
2.5V comes from PUE (pull up enable) being set while all GPIOs have a weak pull down. If this is removed (and you should remove LVTTL and ODE for maximum drive strength), the IO will drive 3.3V. Here's an overlay that does it. To enable, copy pwm.dtbo to /boot and then edit overlays.txt to add pwm into the list (i.e. overlays=pwm)
PWM Overlay
回答3:
Well, End up answering my own question again after couple days of research. Here is what I have found:
What is channel and pin and how it is been used ?
Answer: Channel
is like lane
as if PIN
is a high-way, some chip/pin support multiple channel
some doesn't, you can figure this one out by using the following command(Using EdgeTPU for example, other Linux SOC should be similar):
cd /sys/class/pwm
then do a ls
should show multiple chip/pin like
pwmchip0 pwmchip1 pwmchip2
, let say you want to know how many channel/lane
is pwmchip0
support, then you cd pwmchip0
and then cat npwm
it should give you a number, for EdgeTPU it showing 1
which means 1 channel/lane supported for pin PWM1
. You can do the same for pwmchip1 pwmchip2 ... pwmchip#
(FYI, all the pin from EdgeTPU are support 1 channel only)
Why I'm not able to get PWM(1,1) PWM(2,2) to work ?
This is the fun part, I have too much to say about this.
Short Anwser: THEIR DOCUMENT IS WRONG.
it should be PWM(Pin,Channel)
Long Anser: In here it says you should initial the PWM as PWM(Channel, Pin)
but by look at its implementation, it should be PWM(Pin, Channel)
according to the code. and another great example of PWM standalone module here(Highly suggest any EdgeTPU user go with this one instead of the python-periphery
).
I have PR to update their document, but I want to say, their PWM definitely have not been tested by any means. Otherwise,the misleading info should have noticed by now. (TBH, the project seems dead, no update over a year, not even sure if my PR will get merged or not. Future Work: if my document correction PR get approved, I will work on get the stand alone PWM module PR to the python-periphery library)
So,did everything working as it suppose to be after get PWM to work in the code ?
Answer: Unfortunately not Please checkout my updated question.
来源:https://stackoverflow.com/questions/55385943/google-edgetpu-cant-get-pwm-to-work-with-python