BeagleY-AI and GPIO Pins

Hello and Trying Here,

I found a “hat” from a Pi over here called the Stepper Hat (I think). HRB8825 Stepper Motor HAT For Raspberry Pi, Drives Two Stepper Motors, Up To 1/32 Microstepping | Stepper Motor HAT (B)

That is the link to the hat. Right now, I am trying to configure eight GPIO pins for two stepper motors.

I am having a hard time understanding the back and forth.

python3-gpiod is the lib I am using to test GPIO functionality right now.

So, when I use GPIO16 under gpiod, is that actually pin number 36 on the BeagleY-AI?

Transferring from the pin-36 on the BeagleY-AI to the “Hat,” I see P16 but that is for a BCM.

Please view the photo if you are willing to provide feedback:

I guess that is all for now…

Thank you and good day.

Seth

Its been a while back since I touched the bby, do recall I did make my own device tree for that. This is all from memory, map out the pins (balls) from the SoC, map out the Pins on the RPI board. One of the boards I bought has Wiring pi nomenclature on the board, that is not even remotely close. Your sanity will depend on reading schematics and using a VOM on the target. Once you get the it mapped to the ball on the SoC it will start to come together.

Do one at a time, toggle it using gpiod. It will be easier doing one at a time.

I don’t know about using python at this stage, first get it up using c/c++, python is too abstracted out for what you are doing. Once you get a handle on it go back to python and work it over.

1 Like

I have been reviewing the above docs on the Y-AI. It is neat. There are some data parts to the right, subtle and brief, and then allocation of each PIN.

I think this will help. It shows where on the processor the pin comes into light and then what it is called. Transferring the data is my main concern. It seems that Pin-for-Pin compatible ideas are not 100% granted.

This is not an issue.

I am basically trying to adjust these commands into how the BeagleY-AI interrupts the pins:

gpioinfo

That command shows many GPIO pins available. Neat yes but is there a way to interpret the output of gpioinfo?

Seth

P.S. Here is a small excerpt on the build:

That photo is from the docs at the above link… Anyway, off to test more.

A-Okay. I will test this way…

I believe a couple of HAL hardware abstraction layers are present and you need to sift out what you need. Not sure if its WiP or just not documented yet, it looks like it should work smoothly. Pi compatible is an extremely good thing, however with the pin-mux/SoC/ other stuff it looks like its more work than needed to go from point a to point b.

Did try to upload to bbgitlab some examples I will try to find that work and post if for you on here. You will have to use c++ with it. If I find the stuff I will post it for you.

1 Like

Thank you…

Outside of going to test pin for pin with a DC motor or LED, I have been reading the Wiki for the part to get more acquainted with their ideas of the drivers and their work on the building around the drivers onboard.

Seth

P.S. I found on the docs an example to use.

I will also be trying to understand the differences between BBB, BeagleY-AI, and gpiod after the initial testing…

This way, I can say, “Hey, I think I can help you with building around your dilemma for Python3/C/C++ and etc.” Now, I am blind to the fact of translation for now with this board.

update

In the first photo, a GPIO pin is called Analog PWM and why, No Clue. But, it is a GPIO, i.e. thus my rendered state of thinking that four GPIO pins found via gpioinfo could very well be used for this driver set.

Pretty sure they have a few pins turned out of the box, look at the .dts and see what is up. Then you use lgpiod gpiod to toggle them. This way you know what is and what is not working.

1 Like

Smart. Good suggestion. Thank you…

So, I am very reluctant to understand exactly how to exacerbate my coding practice here.

So, I found the source online of course which is listed here: get_chip_info.c « examples - libgpiod/libgpiod.git - C library and tools for interacting with the linux GPIO character device

I think that is as most recent as available.

My current issue within C or Python3 is that calling multiple GPIO pins from the BeagleY-AI all fail.

Without linking -lgpiod within the gcc command for the binary, the errors are plenty. I can really get the error fiasco down about to two or three ideas…

This is the latest-greatest:

// Testing...

#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {

  const char *chipname = "gpiochip2";
  struct gpiod_chip *chip;

  unsigned int line_num1 = 18; // I have tried struct which at times works well if it will
  unsigned int line_num2 = 12; // here too and so on...
  unsigned int line_num3 = 16;
  unsigned int line_num4 = 7;
  struct gpiod_line *line;

  int i, ret;

  // Open GPIO chip
  chip = gpiod_chip_open_by_name(chipname);
  if (!chip) {
    perror("Open chip failed\n");
    return 1;
  }

  // Open GPIO lines
  line = gpiod_chip_get_line(chip, line_num1);
  if (!line_num1) {
    perror("Get line failed\n");
    return 1;
  }

  line = gpiod_chip_get_line(chip, line_num2);
  if (!line_num2) {
    perror("Get line failed\n");
    return 1;
  }

  line = gpiod_chip_get_line(chip, line_num3);
  if (!line_num3) {
    perror("Get line failed\n");
    return 1;
  }

  line = gpiod_chip_get_line(chip, line_num4);
  if (!line_num4) {
    perror("Get line failed\n");
    return 1;
  }

  // Open LED lines for output
  ret = gpiod_line_request_output(line_num1, "consumer", 0);
  if (ret < 0) {
    perror("Request line as output failed\n");
    return 1;
  }

  // Open LED lines for output
  ret = gpiod_line_request_output(line_num2, "consumer", 0);
  if (ret < 0) {
    perror("Request line as output failed\n");
    return 1;
  }

  // Open LED lines for output
  ret = gpiod_line_request_output(line_num3, "consumer", 0);
  if (ret < 0) {
    perror("Request line as output failed\n");
    return 1;
  }

  // Open LED lines for output
  ret = gpiod_line_request_output(line_num4, "consumer", 0);
  if (ret < 0) {
    perror("Request line as output failed\n");
    return 1;
  }

  // Blink a LED
  i = 0;
  while (true) {
    ret = gpiod_line_set_value(line_num1, line_num2, line_num3, line_num4) (i & 1) != 0; // complete foolishness here...I have not found out exactly why for now!
    if (ret < 0) {
      perror("Set line output failed\n");
      return 1;
    }
    usleep(1000000);
    i++;
  }

  // Release lines and chip
  gpiod_line_release(line_num1);
  gpiod_line_release(line_num2);
  gpiod_line_release(line_num3);
  gpiod_line_release(line_num4);

  gpiod_chip_close(chip);
  return 0;
}

I am not expecting anyone to debug the source or act like it is even acknowledgeable in a good sense. I am trying to get any feedback to promote two, really four, GPIO pins in gpiod.h.

I will keep trying because if you know me, I keep trying.

Seth

P.S. Anyway, I hope everyone has had a nice time during the weekend(s) of life. Feedback!

update

Okay, so I see 1.6.2 is a bit out-of-the-ordinary. I would rather see a newer version of the libgpiod-dev and gpiod on the already composed/built OSs made by beagleboard.org. Reaching to you and yours for a solid set of examples too. No reason. Just building preferences so far.

Drrrrrrrrr…

Sorry for harassing everyone.

Seth

P.S. I just needed to remember the file on the docs. pages. Blah! Thank you for putting up with me…

1 Like

I got some nifty source to work…

Does it make the motor(s) turn? No, my logic is not quite ready I believe and the pin location(s) needs work.

Seth

P.S. So, four GPIO pins will do it I think. I noticed in the Mode section of the GPIO pin usage, there were three pins on the Wiki for the Stepper Drivers “Hat”.

So, there are out familiar Dir, Step, and Enable pins but then the Mode pin(s) are required (I think).

What I did notice is this idea…

  1. The “Hat” does not power via barrel jack.
  2. The “Hat” powers via a 5v output on the BeagleY-AI.
  3. I can configure the source for now and currently, I am thinking that the pins used are not quite what I need.

I cannot understand. Even my Enable and Dir pins do not act accordingly. I think I am missing something…

Should the 5v PSU pin on the BeagleY-AI control the “Hat?”

1 Like

Hi Seth.

Looking at the schematic for the hat you need to supply it with at least 8.2V for the stepper motor drivers to work (probably more depending on your motors). The Hat has a 5V buck converter powered from it’s input to provide 5V for the Pi/BeagleY that you connect it to, so you do not need 2 different power supplys.

right…

I understand that part. I have a barrel jack at 18v 1A for testing.

So, something I do not understand is this fact:

Would I need to supply the headers of the connectors to where the motors are attached or is the barrel jack enough wattage to supply my needs?

I am not supplying the toggle switch to ON for supplying the BeagleY-AI with PWR.

It is OFF. I highlighted the Vin and GND on the connectors in question…

I was thinking that either Vin and GND or the barrel jack was all that was needed but not both.

Seth

P.S. Anyway, thank you for replying and making me understand these ideas.

The barrel jack and screw connectors are the same. Just a different way to connect power.
You can buzz it out with a DVM to check.

1 Like

A-Okay Ben,

I will keep testing.

Seth

P.S. I will stick with the barrel jack for now.

Does Mode need all three GPIO pins attached to handle movement of a stepper motor with this Hat?

I do some initialization at first, I then call for the gpiod.h calls, and then finally try to perform some logic.

I do not have three GPIO pins for the Mode.

Seth

P.S. I guess I can always try… Outside of the fact that there is something seriously wrong with my wiring (most likely), I need to make the logic better and better jots of notes beside what does what…

update

  1. Wiring completed
  2. Working on Source again…
  3. Trying to make addition a reality

The mode pins of the driver are set by the dip switches on the Hat. They are can be connected to header pins if you want to control this by software, but then you will need to solder some resistors onto the board. I suggest you just stick with the DIP switches to start with.

hat

1 Like

Okay…I just asked in the discord under beagley-ai .

I will attempt it without the Mode pins and resistors. I was receiving some negative feedback on the source with six GPIO pins allocated from the beagley-ai.

Seth

P.S. Ben, I will look up some ideas on logic source for attempting to push the rotor.

As I understand it, hold Dir while Step is being called so that my Enable pin is High.

Hey Ben,

So, I have been doing some light research and found that making a library is not so easy.

C does not have vectors but I can emulate them with data and dynamic arrays. So, I will be using the C++ binding to gpiod.h.

More research on the binding will need to take place, too.

See, I thought it was as easy as plastering some C source in a particular format within a couple lines.

As my research continues, I have noticed this idea of a couple lines is not very realistic.

Seth

P.S. I will keep you updated. So far, in the C language (no specification really), I have been able to start, stop, and deploy a good bit of source with the libgpiod-dev lib with success on the beagley-ai. This does not include Stepper Motor functions and/or routines for making the actual motor turn… So, in time, I will keep trying to update this page with findings.

Hey Ben,

I have tried multiple times via source to handle a stepper with libgpiod-dev and python3-gpiod.

I am failing without resolve. I really cannot find out why…

I changed udev, I changed source repeatedly (almost to the point I am running in circles), and then tested the connections:

  1. I noticed with python3-gpiod via an apt install, one would need to use something along these lines:
import gpiod 
import time 

gpio14 = gpiod.find_line('GPIO14') 
gpio14.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=0) 

while True: 
   gpio14.set_value(1) 
   time.sleep(1) 
   gpio14.set_value(0) 
   time.sleep(1)

I got that from the docs. pages for GPIO under the header BeagleY-AI.

Anyway, I read the rationale and I am thinking that using 'GPIO14' as the object instead of the variable is a “lose-lose.”

I say that with the most kindest regards. Still, is it 100% necessary that I attempt programming the BeagleY-AI in that format? For instance, I have other source that now is garbage and can be transferred easily but I do not know the steps to take.

  1. The other source goes like this:
#!/usr/bin/python3

import time
import gpiod

# Replace with the actual GPIO chip and line numbers
chip = gpiod.Chip("/dev/gpiochip2")

LINE1 = chip.get_line(18)

LINE2 = chip.get_line(12)

LINE3 = chip.get_line(16)

LINE1.request(consumer="STEP", type=gpiod.LINE_REQ_DIR_OUT)
LINE2.request(consumer="STEP", type=gpiod.LINE_REQ_DIR_OUT)
LINE3.request(consumer="STEP", type=gpiod.LINE_REQ_DIR_OUT)

LINE3.set_value(1)

try:
    while True:
        LINE1.set_value(1)
        time.sleep(1)
        LINE1.set_value(0)
        time.sleep(1)
except KeyboardInterrupt:
    LINE3.set_value(0)

I am trying to promote a simple motor to move but because of “something,” I am failing.

I have not tracked down how hard it is mentally/physically to deal with steppers and drivers but am currently trying with no luck.

Seth

P.S. Also, I am receiving an error like /dev/gpiochip2 is not existing with C/C++ source:

The opening is failing...
: No such file or directory

And…that is with this source.

// Testing...

#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

#ifndef CONSUMER
#define CONSUMER        "Consumer"
#endif

int main(int argc, char **argv)
{
        char *chipname = "/dev/gpiochip2";

        unsigned int line_num1 = 18;    // Direction
        unsigned int line_num2 = 12;    // Step
        unsigned int line_num3 = 16;    // Enable

        unsigned int val;

        struct gpiod_chip *chip;

        struct gpiod_line *line1;
        struct gpiod_line *line2;
        struct gpiod_line *line3;

        int i, ret1, ret2, ret3;

        chip = gpiod_chip_open_by_name(chipname);
        if (!chip) {
                perror("The opening is failing...\n");
                goto end;
        }

        line1 = gpiod_chip_get_line(chip, line_num1);
        if (!line1) {
                perror("Get line failed\n");
                goto close_chip;
        }

        line2 = gpiod_chip_get_line(chip, line_num2);
        if (!line2) {
                perror("Get line failed\n");
                goto close_chip;
        }

        line3 = gpiod_chip_get_line(chip, line_num3);
        if (!line3) {
                perror("Get line failed\n");
                goto close_chip;
        }

        ret1 = gpiod_line_request_output(line1, CONSUMER, 0);
        if (ret1 < 0) {
                perror("Request line as output failed\n");
                goto release_line;
        }

        ret2 = gpiod_line_request_output(line2, CONSUMER, 0);
        if (ret2 < 0) {
                perror("Request line as output failed\n");
                goto release_line;
        }

        ret3 = gpiod_line_request_output(line3, CONSUMER, 0);
        if (ret3 < 0) {
                perror("Request line as output failed\n");
                goto release_line;
        }

        /* Blink 20 times */
        val = 0;
        ret3 = gpiod_line_set_value(line3, val=1);
        if (ret3 | val == 1) {
                line_num1 = 1;
                line_num2 = (1 / 8);

                sleep(2);

                line_num1 = 0;
                line_num2 = (1 / 8);


        } else {
                line_num1 = 0;
                line_num2 = 0;

        }

release_line:
        gpiod_line_release(line3);
close_chip:
        gpiod_chip_close(chip);
end:
        return 0;
}

Okay there…I have tried and after compilation, I can run the file binary but that error resides.

update

I think the error is due to not having an allowance in the GPIO chardev udev rules.

I am not sure now, i.e. as I need to alter udev some more and find out myself but for now, it is not plug-in, create source, and then watch the motor(s) spin freely.

That is what I expect that source to do. I expect that source to spin the motor via software and then upon canceling the file running, I expect the software controlled motor to stop.

The chip will not even open for usage. Is this a udev result or my poor source?

Hi @silver2row, did you read the wiki page?

Stepper Motor HAT  | Raspberry Pi (BCM)
A1A2B1B2 direction | 13
A1A2B1B2 step      | 19
A1A2B1B2 enable    | 12
A1A2B1B2 mode      | 16 17 20
A3A4B3B4 direction | 24
A3A4B3B4 step      | 18
A3A4B3B4 Dir       |  4
A3A4B3B4 mode	   | 21 22 27

Try with this one:

import gpiod
import time

# Motor 1
m1_step = gpiod.find_line('GPIO19') # P19 -> hat 35 -> GPIO19
m1_step.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=0)
m1_direction = gpiod.find_line('GPIO13') # P13 -> hat 33 -> GPIO13
m1_direction.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=0)
m1_enable = gpiod.find_line('GPIO12') # P12 -> hat 32 -> GPIO12
m1_enable.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=1)

# Motor 2
m2_step = gpiod.find_line('GPIO18') # P24 -> hat 12 -> GPIO18
m2_step.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=0)
m2_direction = gpiod.find_line('GPIO24') # P24 -> hat 18 -> GPIO24
m2_direction.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=0)
m2_enable = gpiod.find_line('GPIO4') # P4 -> hat 7 -> GPIO4
m2_enable.request(consumer='beagle', type=gpiod.LINE_REQ_DIR_OUT, default_val=1)


m1_enable.set_value(0) # enable motor 1
m2_enable.set_value(0) # enable motor 2

m1_direction.set_value(0) # motor 1 forward
m2_direction.set_value(1) # motor 2 backward

while True:
    m1_step.set_value(1)
    m2_step.set_value(1)
    time.sleep(0.1)
    m1_step.set_value(0)
    m2_step.set_value(0)
    time.sleep(0.1)

1 Like