BeagleY-AI and Stepper/DC Motor Hat and Trouble...

Hello There,

I am currently testing to promote findings via some posts I will make.

There is the schematic of the “Hat” in question here. Is everything about that Hat only for the PWM peripherals on the BeagleY-AI?

I figured I would be using the motor drivers but it seems the PCA9685 is used for adopting a way to push PWM to the Motor Drivers and the Motor Drivers only acknowledge the PWM peripherals. I am guessing when I type that idea…

The write up on Adafruit’s website is fine but it lacks definition (I think).

I am not even sure I understand this contraption so far, i.e. the Stepper and DC Motor Hat.

The board boots with the Hat on it. I apply a simple 9v battery and the Hat powers on for stepper usage. I am just not sure yet. Do I just use PWM peripherals from the BeagleY-AI or is there a catch somewhere I am missing?

Seth

P.S. Using PCA9685 Motor Drivers — BeagleBoard Documentation is another resource I am following to understand what it is I am doing.

So, from what I thought, GPIO peripheral access controls the direction while PWM peripheral access controls speed via Hz and duty_cycle.

Anyway, if you find this answer is easy to comprehend and you have time, please do reply. I will be testing some more GPIO and PWM peripheral access on the BeagleY-AI in time.

I think my source was not working and hence why I bring it up…

The issue I currently have is that the PWM peripherals are not brought out in userland.

So, I am writing a more recent image now. I will reply here for future self and others questioning me on why I am wondering about the Hat in question.

Seth

P.S. Here is an update…

Update

I put in the overlays and the PWM in userland does not get listed at /dev/bone/pwm/* via ls -l or if I traverse to the file(s) in question. The files are not located at that directory.

Is there a way to bring the PWM peripherals to the userland seeing eye here?

Okay and So On,

So, I am at a loss on what and why for now. What is going on with the PWM peripherals on the BeagleY-AI? Why are the PWM peripherals so difficult to get registered in userland?

I see people using DTSO files for arranging the DTS before compilation.

I found a nice way to compile the DTS0 via a script on the board (BeagleY-AI).

Outside of that, I see many entries in that file. The file, this DTSO, needs to be compiled to be able to utilize it. This is as far as I have been. I did read some of the files.

Is there some happy medium or am I at it alone here with PWM and the BeagleY-AI.

I know, PWM, whoopty. Oh. I found some pwmchip0 - pwmchip7 registered components within the FS.

Can I use 'em. Nope, not yet. I cannot even get gpioinfo to welcome the PWM peripherals to sight so far.

Any and all applicable ideas are welcomed now!

Seth

You’ll need the driver to get those pwm entries in /dev. I see one does exist; https://github.com/torvalds/linux/blob/master/drivers/pwm/pwm-pca9685.c, but I dont know whether that exists on your system. You’ll also need an overlay to configure it.

I saw a discussion on the raspberry pi forum, https://forums.raspberrypi.com/viewtopic.php?t=142566, maybe that has some usefull info on getting this to work …

1 Like

Okay…

So, I understand here. Get the driver, install it (however), and then find out how to create an overlay for the pins in question for the DTC and BeagleY-AI.

Gotcha.

Seth

Hi Seth,

I suggest these steps for getting the PCA9685 working at kernel:

  1. setting up an device tree overlay which enables the PCA9685 device from Linux kernel perspective. The driver should be already on-board.
  2. Once kernel loads it, enable PWM channels, and configure them with period and duty cycle.

The device tree overlay source should look like below. The I2C address here used is “0x40” - you’d have to adapt the pca9685@40 and the reg = <0x40> if your board uses a different address. For figuring out the I2C devices connected to the BeagleY-AI there should be instructions available.

/dts-v1/;
/plugin/;
/ {
    compatible = "beagle,am67a-beagley-ai", "ti,j722s";

    fragment@0 {
        target = <&mcu_i2c0>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells=<0>;
            status = "okay";
            pca9685@40 {
                compatible = "nxp,pca9685";
                reg = <0x40>;
            };
        };
    };
};

Compile it with

dtc -@ -I dts -O dtb -o pca9685-overlay.dtbo pca9685-overlay.dts

Add it to the /boot/firmware/extlinux/extlinux.conf, at the bottom using fdtoverlays ....

Once the kernel boots up with it you should find the device somewhere under /sys/bus/i2c/devices/... or /sys/class/pwm/pwmchipX/.... For example:

$ cat /sys/class/pwm/pwmchip0/device/name
pca9685

Then you have to set up the pwm channels of this chip. Servos are using as far as I know always a fixed period of 20ms. The duty length is expected at 1ms…2ms with “0” at 1.5ms. This script could help:

#!/bin/bash
#
# servo_setup.sh - run as root!
#
PWMCHIP=/sys/class/pwm/pwmchip0
CHANNELS="0 1"

# setup period + duty cycle on both pwm0 and pwm1
for id in $CHANNELS 
do
    if [ ! -d $PWMCHIP/pwm$id ]; then
        # create pwm<id> 
        echo $id > $PWMCHIP/export
        sleep 0.5
    fi
    echo 20000000 > $PWMCHIP/pwm$id/period
    echo 1500000 > $PWMCHIP/pwm$id/duty_cycle
done

Then you can control the pwm by echoing to the duty_cyle:

# probably as user "root"...
echo 1700000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
# again "0"-position:
echo 1500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle

I hope that helps!

1 Like

@jgrmpf ,

Thank you. I was off (as usual). I will attempt this idea too. I will report back once things are either configured correctly or if I have another question.

Seth

P.S. Here is something I found in Python from the docs.beagleboard.org pages for the demos section: https://gist.githubusercontent.com/Grippy98/7ef6a75b2dc7a9470bd8c4dfc6b53f0a/raw/5252562d865d61e1142f891041ca080550fe8053/PCA9685.py

I will report back soon…

Thank you again.

Yes I think if the python script serves you as well, it’s easier to set up and also well described as you have mentioned :+1:.

1 Like

:grimacing:

Okay…so.

I found some “errors” but the motor(s) still are without movement. I will try some Python source real quickly and report back.

Oh and:

/sys/class/pwm/pwmchip0/pwm0$ ls
capture  duty_cycle  enable  period  polarity  power  uevent

I usually type something like:

echo period > 1000000
echo duty_cycle > 8500000

and/or with enable too…

Seth

Hi Seth,

regarding your example: as mentioned, for a Servo Motor you must use a PWM period of 20ms or 50Hz. And the duty cycle must be in the range 1…2ms. For the /sys/.../pwmX interface this means:

# servo period: 20ms
echo 20000000 > period
# min duty cycle
echo  1000000 > duty_cycle
# max duty cycle
echo  2000000 > duty_cycle
# "0"  position:
echo  1500000 > duty_cycle
1 Like

Sorry - you wrote “Stepper/DC Motor”. I thought this is about Servo - forget my last post :zipper_mouth_face:

1 Like

I am using a stepper motor. Sorry, we got in miscommunication here.

Seth

P.S. Here is where I am at so far:

/sys/class/pwm/pwmchip2/pwm0

pwmchip2 is or is not i2cdetect -y 2 with these credentials as output?

0x30 

and/or

0x50

errr…sorry. I should have known. My bad too. I got too excited…

On my board it’s 0x40 it depends on how the address pins of the PCA9685 device on your board are configured. Once the kernel takes control of the PCA9685 (-> the overlay gets loaded and the driver gets starte), the device appears as UU in the output of i2cdetect. On my system it looks like:

$ i2cdetect -y -r 1 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: UU -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                 

And no, the “pwmchipX” number is not related with the I2C bus number used by i2cdetect. I’d think I2C bus 1 is the one which is exposed on the BeagleY-AI GPIO pins. So your PCA9685 most likely should appear on I2C bus 1.

I have i2cdetect showing only UU at 0x30 and 0x50.

I tried i2cdetect with the -r on bus 1 and bus 2.

I got some better results. 0x40 quits the running boot when applied.

For whatever reason, that is what happens. Then, one needs to hold the boot/power button down to turn off the board, take the USB C out of the dev. desktop, and then reapply USB C power for networking to get it booting regularly again.

Would I need a separate DTS file for using a stepper or is this DTS file an okay start for using a stepper motor?

Seth

Hi Seth,

I don’t know your setup, but from what you tell I can imagine, that your HAT powers the motor(s) exactly at that time when setting up the PCA9685. The boot failing at that time indicates that the motor(s) draw too much power so that your BeagleY-AI does no more get enough and stops booting.

The overlay is only for the PCA9685. I would try booting without the motors connected and see if the PCA9685 gets detected.
After that check your power supply. Maybe the motors need a separate power source.

Regards
jgrmpf

Hey,

Yeppers, so.

There are two other drivers on the small “Hat”. Some Toshiba TB6612FNG drivers are also on the board:

I got that photo from the docs. at docs.beagleboard.org or more precisely here: Using PCA9685 Motor Drivers — BeagleBoard Documentation

I could not gather too much so far in a way to handle such drivers or the PCA9685. I will keep trying.

Seth

Yeah for some background - I wrote that bit of docs when we were trying to prototype the Drink dress last year so it’s all I2C userspace Python just for simplicity. I hadn’t looked at proper kernel implementation.

If you want to do actual PWM out of the SoC, the IP is shared across K3 so you can try referencing the docs for AM62
https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/08_03_00_19/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/PWM.html

Pinout mapping for PWM here - PWM at BeagleY-AI GPIO Pinout

1 Like

Thank you…I will look into it.

I was researching i2c for some reason in the kernel docs.

Seth

@Grippy98 ,

How would I test to see if my current kernel supports these picks from menuconfig?

Device Drivers --->
   <*> Pulse Width Modulation(PWM) Support --->
      <*> eHRPWM PWM support

I seem to have no idea how to test. But…in some light here, the PWM in /sys/class/pwm/ has pwmchip0 - 7 with some not being available…

And other sections of the beagleboard.org kernel I am using seem to have them available for usage but not in userland applications.

Is there a specific way to test in the ssh terminal application for PWM and if it is indeed ready to be used or would I need to write a kernel with the Device Drivers myself?

Seth

Update

A and Okay here, I seem to have one channel per chip only. As I read the docs more from TI, the two channels are supposed to be brought out to userland for use cases.

What do I need to do, if anything, to bring out the two channels from each chip? Scratch that question…

It seems there are exactly two usable double channels per chip for specific chips only. I got it now… Things are a bit buggy for me on kernel:

6.6.58-ti-arm64-r24

With this image and that kernel, I am getting slips in timing when typing in the ssh terminal:

BeagleBoard.org Debian Bookworm Xfce Image 2025-03-05

heads up to the higher ups here…