adafruit / adafruit-beaglebone-io-python

Adafruit's BeagleBone IO Python Library
http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black
476 stars 220 forks source link

BeagleBone Blue PWM #313

Open ansarid opened 4 years ago

ansarid commented 4 years ago

Code:fade.py

import Adafruit_BBIO.PWM as PWM

pwm = "P9_23"

#PWM.start(channel, duty, freq=2000, polarity=0)
PWM.start(pwm, 0)

#optionally, you can set the frequency as well as the polarity from their defaults:
#PWM.start(pwm, 50, 1000, 1)

PWM.set_frequency(pwm, 10)

PWM.set_duty_cycle(pwm, 0)

for x in range(10000):

    for duty in range(0,100,1):

        PWM.set_duty_cycle(pwm, duty)
        time.sleep(0.05)

    for duty in range(0,100,-1):

        PWM.set_duty_cycle(pwm, duty)
        time.sleep(0.05)

Run:

sudo python3 fade.py
ansarid commented 4 years ago

I created this table of what GPIO pins do and do not work on the BeagleBone Blue as Inputs/Outputs. I was unable to make any pins work as a PWM.

Screenshot from 2019-07-22 12-36-33

pdp7 commented 4 years ago

Hello, I see that you are using pin P9_23 in fade.py. Where did you derive the "name to use in code" column from?

ansarid commented 4 years ago

@pdp7 Yes, using the pin name for the BeagleBone Blue does not work. As you can see in the table above I found all the pin names that work in code to address pins in code. Because I am using GPIO1_17 on the Beaglebone Blue, addressing that pin with the name P9_23 in code does work if I want to address that pin so set it as an input or as an output.

ansarid commented 4 years ago

@pdp7 I dont remember now where I got that pin name from since I made that table a long time ago, I think I found a pin map of the Blue in the BBIO source, and then wrote a program that cycled through pin names and sent a blink code to each pin name. If the pin name threw an error it moved on, if it worked I checked if an LED I had connected was blinking. If it was not blinking I told it to move on, if it was blinking I had found the pin name.

I did this because I could not find proper documentation for what names to address pins by in code for the BeagleBone Blue.

RobertCNelson commented 4 years ago

@ansarid , yeah we screwed up on the Blue pin naming, it's a cross between the Black's pin naming and a few addon's. By the time this became evident, boards where already shipping with the librobotcontrol library with original naming.

This is why on the PocketBeagle, pin naming is so different, we just started it from scratch..

I'd like to clean up the Blue's naming, but there's too much to break now..

Regards,

pdp7 commented 4 years ago

@jadonk do you know if PWM is working on the BeagleBone Blue in BoneScript?

pdp7 commented 4 years ago

@RobertCNelson any idea what PWM channels map to the pins on the Blue?

RobertCNelson commented 4 years ago

Here's the data when i looked at all the pins:

https://github.com/beagleboard/bb.org-overlays/blob/master/tools/pinmux-generator/BeagleBone_Blue.dts

Looks like pwm is on:

GPS_3 (ZCZ ball A17) uart2_rxd

GPS_3_pwm_pin: pinmux_GPS_3_pwm_pin { pinctrl-single,pins = <
    AM33XX_IOPAD(0x0950, PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3) >; };  /* spi0_sclk.ehrpwm0a */

GPS_4 (ZCZ ball B17) uart2_txd

GPS_4_pwm_pin: pinmux_GPS_4_pwm_pin { pinctrl-single,pins = <
    AM33XX_IOPAD(0x0954, PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE3) >; };  /* spi0_d0.ehrpwm0b */

SPI1_4 (ZCZ ball B13) spi1_d0

SPI1_4_pwm_pin: pinmux_SPI1_4_pwm_pin { pinctrl-single,pins = <
    AM33XX_IOPAD(0x0994, PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1) >; };  /* mcasp0_fsx.ehrpwm0b */

SPI1_5 (ZCZ ball A13) spi1_sclk

SPI1_5_pwm_pin: pinmux_SPI1_5_pwm_pin { pinctrl-single,pins = <
    AM33XX_IOPAD(0x0990, PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE1) >; };  /* mcasp0_aclkx.ehrpwm0a */

S1.2_6 (ZCZ ball C18) spi1_cs1

S1.2_6_pwm_pin: pinmux_S1.2_6_pwm_pin { pinctrl-single,pins = <
    AM33XX_IOPAD(0x0964, PIN_OUTPUT_PULLDOWN | INPUT_EN | MUX_MODE0) >; };  /* eCAP0_in_PWM0_out.ecap0_in_pwm0_out */

PS, i should regenerate that with exporting the pin_name.timer* pins too, as that is now a generic pwm output in 4.14.x+ kernels too..

Regards,

ansarid commented 4 years ago

@pdp7 @RobertCNelson I was able to write a program to PWM four of the PWM pins and found that when I PWM UART2_TX(P9_21), It also sends the same PWM signal to SPI1_MISO(P9_29) even if I do not call it in code. Also if I send a PWM to SPI1_MISO(P9_29), a PWM signal will also go to UART2_TX(P9_21).

This relationship is also seen between UART2_RX(P9_22) and SPI1_SCK(P9_31).

UART2_TX == SPI1_MISO UART2_RX == SPI1_SCK

This means that 4 PWM pins instead behave as only 2. For my particular application, I need 4 individually addressable PWM pins.

The program below should demonstrate the issue with some LED's connected.

import time
import Adafruit_BBIO.PWM as PWM

l_pwm1 = 'P9_21'     # UART2_TX
l_pwm2 = 'P9_22'     # UART2_RX
r_pwm1 = 'P9_29'     # SPI1_MISO
r_pwm2 = 'P9_31'     # SPI1_SCK

def setpwm(duty):

    # PWM.set_duty_cycle(l_pwm1, duty)
    PWM.set_duty_cycle(l_pwm2, duty)
    # PWM.set_duty_cycle(r_pwm1, duty)
    # PWM.set_duty_cycle(r_pwm2, duty)

# PWM.start(l_pwm1, 0, 1000)
PWM.start(l_pwm2, 0, 1000)
# PWM.start(r_pwm1, 0, 1000)
# PWM.start(r_pwm2, 0, 1000)

while 1:

    for i in range(0,100,1):

        setpwm(i)
        print(i)
        time.sleep(0.01)

    for i in range(100,0,-1):

        setpwm(i)
        print(i)
        time.sleep(0.01)

# PWM.stop(l_pwm1)
PWM.stop(l_pwm2)
# PWM.stop(r_pwm1)
# PWM.stop(r_pwm2)

PWM.cleanup()
pdp7 commented 4 years ago

@jadonk Does bonescript support PWM on the Blue? I am wondering if I could use bonescript as a reference.

mvduin commented 4 years ago

@pdp7 @RobertCNelson I was able to write a program to PWM four of the PWM pins and found that when I PWM UART2_TX(P9_21), It also sends the same PWM signal to SPI1_MISO(P9_29) even if I do not call it in code. Also if I send a PWM to SPI1_MISO(P9_29), a PWM signal will also go to UART2_TX(P9_21).

GPS.4 / P9.21 and SPI1.4 / P9.29 are two mux options for the same signal (ehrpwm0b), hence if you mux both of them to pwm, they will both output the same signal.

Same goes for GPS.3 / P9.22 and SPI1.5 / P9.31, which are two mux options for ehrpwm0a.

Here's an overview of all PWM resources on the AM335x and to which connector pin or on-board resource of the beaglebone blue they can be muxed:

mvduin commented 4 years ago

(and of course in times of desperation, a PRU core could be used to generate additional PWM outputs.)

pdp7 commented 4 years ago

@MarkAYoder fyi - if you have any students that might want to help with this issue

MaheshChaudhari2000 commented 2 years ago
  • Platform/operating system: BeagleBone Blue, bone-debian-9.5-iot-armhf-2018-10-07
  • Python version: Python 3.5.3 and Python 2.7.13
  • Error message you are receiving, including any Python exception traces:
debian@beaglebone:~$ sudo python3 fade.py
Traceback (most recent call last):
  File "fade.py", line 6, in <module>
    PWM.start(pwm, 0)
ValueError: Invalid PWM key or name.
  • List the steps to reproduce the problem below:

Code:fade.py

import Adafruit_BBIO.PWM as PWM

pwm = "P9_23"

#PWM.start(channel, duty, freq=2000, polarity=0)
PWM.start(pwm, 0)

#optionally, you can set the frequency as well as the polarity from their defaults:
#PWM.start(pwm, 50, 1000, 1)

PWM.set_frequency(pwm, 10)

PWM.set_duty_cycle(pwm, 0)

for x in range(10000):

    for duty in range(0,100,1):

        PWM.set_duty_cycle(pwm, duty)
        time.sleep(0.05)

    for duty in range(0,100,-1):

        PWM.set_duty_cycle(pwm, duty)
        time.sleep(0.05)

Run:

sudo python3 fade.py

Hey, I am trying to do the same thing. I have connected an LED to UART2_TXD and I am varying duty cycle. But I can't see the intensity of LED changing, it is always high. Any idea what can be done?