BeagleY-AI and GPIO Pins

Full-step…

I set the mode steps to 0.0.0 which is full-step. It has me fooled so far. I do not know what else to test…

It may just be a bum driver or bum Hat. I contacted Waveshare online to see if there are any steps to take outside of what I am already doing.

Seth

P.S. I appreciate your replies and dedication to helping people on this forum (me for instance).

Also…

In /etc/udev/rules.d/*, there is an 85- about GPIO for the gpiochip(N) chips that are available. I do not know exactly what is going on for now in that specific file. The /dev/gpiochip(N) files are commented out with # marks which made me think that the files were unusable.

Anyway, I might just get another driver away from Waveshare Stepper (B) Hats for now. I just cannot configure it for whatever reason. Argh.

@bbbpaul ,

Okay and so…

  1. The headers for loose wire coming from the Stepper Motor(s) are not A1 A2, B1 B2. Blah.
  2. The headers for loose wire are actually A1 B1, A2 B2. Blah.
  3. I moved on from those headers entirely.

Now, I have a direct connection from the Stepper Motor to the Connector via wires that are Connector “Ended.”

a. The Hat is powered.
b. The pins are working from the BeagleY-AI from the GPIO peripheral.
c. I am stuck with nothing moving still.

I guess it is not supposed to work? Who knows?

Seth

P.S. Thank you for your help thus far. There is a trick, i.e. I am sure of it but it eludes me so far.

update and Source

What does this line do specifically?

gpiod_line_set_value(line1, (val & 0x01) != 0);

Bit One and etc. but what does the & do in relation to bit one?

That line is a bit messy.
The first parameter is obviously a reference to the gpio pin itself which is type struct gpiod_line *.
The second parameter is a value which should evaluate to a boolean. The & is the AND operator, so (val & 0x01) simply masks off the lowest bit of val, so this part of the expression will toggle between 0 and 1 as val increments. The != 0 part means the afore mentioned 0/1 toggle will evaluate to true or false and is actually not really even needed here, though it is required when we are ANDing with something other than 0x01.

P.S. The function prototype has parameter 2 as an int, but in our specific case 0 or 1 is required to set the pin high or low.

We haven’t discussed the motor wiring as a source of error.
From the documentation, A1/A2 is winding A and B1/B2 is winding B.
Perhaps try buzzing out the wires to the motor with a multimeter to verify that the wires connected to A do actually go to one winding and the wires connected to B go to the other.

You could also check the voltage on these windings, if you haven’t already, to see if or how they change as you apply step pulses to the step pin.

I tested the bare wire connectors on the headers with a DMM for continuity only while the motor was not powered.

The odd thing so far is that the GPIO for enable does nothing. It does not excite the motor with either 0 or 1 as an argument.

The silkscreen on the bare wire headers show what I discussed. A1, B1 and then A2, B2 instead of A1, A2 and then B1, B2 which is why I was fooled.

I am powering the Hat with 5v and GND from the BeagleY-AI to the exact pins in which they would be attached if the Hat was attached to the BeagleY-AI.

The LED shines on the Hat when I connect it this way.

Now, I was thinking…

  1. Would I need an additional level translator?
  2. How would I in fact translate via wiring?
  3. and…if it is the circuit on the. Oh…?

Hmm. I see now.

Schematic_HAT_ONE

The darn connection is not 1 to 1 on the RPi GPIO which this Hat was intended to be used.

So, I actually have GPIOs 13 (pin 33), 6 (pin 31), and 12 (pin 32) on the BeagleY-AI which is then wired to “GPIOs” 12 (GPIO), 13 (GPIO), and 19 (Nothing) as can be seen in the photo.

I am not familiar with the Pi. So, even with Waveshare saying that 19 is a GPIO to be used, it is not?

Oh well, off to try to wire 11, 12, and 13 on the Hat from the GPIOs that work on the BeagleY-AI. Argh…

Seth

Also, that highlighted section, D19, seems to be the only enable Pin from the Wiki.

I think. I know 19 is an Enable pin but that would mean 35 which is PCM pin on the BeagleY-AI would need to be a GPIO.

Seth

Thank you for making me understand the Boolean affect to the & symbol which is not a use case after a pointer. Blah.

Also…

I think I may have got it this time. BCM is a chip, I guess. While the header is something completely different and then the naming scheme from the header is called something else…blah.

Seth

P.S. That neat print of . is cool and I liked the way it was done. I read about that idea too.

Just an update here:

#######
Update It

When the board (BeagleY-AI) is powered via the Headers on the Hat, it works.

Seth

P.S. I can run the source once USB-C and the ON switch is set to ON. The current sensed is located on the PSU but nothing happens with the motor. The PSU cycles showing it is providing current.

You dont need level translators, the chip works with 3.3V logic
You dont need to worry about whether the beagley pins are gpio or not - out-of-the-box, they are (at least on mine).
The GPIOs on pins 32, 33 and 35 of the 40 pin header are connected to the correct pins on the chip (enable, direction, step), and work with the test code we’ve been working with so far, so you dont need to worry about signals not routed correctly.

Are you seeing any voltage across the motor coils? With enable high, you should. The voltages should change when the step pin gets a pulse.

PS not to overcomplicate things at this stage, but the step pin, whilst correctly connected to a gpio right now, would eventually be best connected to a pin configured as hardware pwm or timer - ideally a PRU. This might be the source of some confusion if you see references to pwm as one of the control signals.
Bit banging a gpio to step a stepper motor in linux is likely to be pretty awful. But dont think about this yet - lets just get the motor working first.

1 Like

Just to reiterate…

  1. The Hat needs to be powering the BeagleY-AI to support usage.
  2. Is a USB-C to USB 3.0 cable with the PSU to the Hat that powers the BeagleY-AI too much current?

I was receiving 0.1A from the PSU after powering the BeagleY-AI from the Hat and then using a USB-C cable for programming and networking.

Seth

@bbbpaul ,

Do I need to have 5v and 3.3v connected to/from the Hat?

Would I only need 3.3v connected? Something seems iffy so far and I cannot describe it.

Seth

P.S. Here!

UPDATE and in the most sincere way!

It works! So, it was an ON button that needed to be ON instead of OFF for powering the Hat and BeagleY-AI.

Should I need to power the BeagleY-AI with the Hat?

Congratulations!

The documentation says the hat can power a RPi. I dont know whether the beagley can be powered via the 40 pin header, I vaguely recall seeing something on this forum that confirms you can.

1 Like

The BeagleY-AI has not released “magic smoke” yet. Phew.

Seth

P.S. I better turn it off before I get something irregular…

Also sir, @bbbpaul , is using some of your source here okay if I plan on making a small donative docs. section for the BeagleY-AI and with source?

If not, I understand. I can give you the credit of the derivative source if I change it up to suit the needs of users around here…

That’s fine - it’s not really mine, just an update on something you posted which appeared to be based on sample code from the libgpio project, if I remember correctly.

1 Like

Well,

You taught me two things about C with the additions you added:

  for (val=0; val<100; val++) {
    putchar('.');
    fflush(stdout);
...

gpiod_line_set_value(line2, (val & 0x02) != 0);

The putchar(''); was nothing I have used before today. Usually, I used scanf for displaying output during an interactive set of source but using putchar is way different.

It creates a char or set of char to be displayed immediately upon its read within the source but does not work without fflush(stdout); for some reason. This is what I could not attain.

I read about what the differences were at the time but did not see their combination of the two work in tandem with knowing the reason(s) why they worked together.

And the (val & 0x02) != 0) section still evades my research. I know what you typed about it but I still may not use it correctly. So, is it like this:

(val & 0x02) != 0) means the unsigned int val; and its lowest bit are not equal to zero, i.e. thus jumping 1 to 0 and back to 1 and then repeating while it increments or decrements.

Um, exactly how would I interpret the bits or bytes of an unsigned int? Does C/C++ call for specific amounts of bits per unsigned int no matter its value?

I think the second question has an answer of four bytes while we are programming in C.

I think the first question has an answer of _________?

I think this is where I am faltering within the source for now. I am not interpreting the bits/bytes as anything useful. Would I need to evaluate the datasheet of the drivers for reviewing how to interpret the bytes within our source?

Seth

P.S. If you choose to not answer, fair enough. I will attempt ideas in future times and keep learning.

printf() is quite expensive so putchar() is far better to output a single char within a loop. The char will always be emitted eventually, but the system may choose to buffer it for a while - the fflush() flushes the buffer immediately.

When using boolean operators such as ‘&’, always think of the data as binary (or hex), hence the 0x. The 0x means hex (which is just a convienient way of representing binary). 0x1 (hex) is 0b0001, 0x2 is 0b0010, 0x4 is 0b0100 etc.
0x01 masks off all but the lowest bit, 0x02 all but the 2nd lowest bit, 0x04 the 3rd lowest etc.
(0b0010 & 0bnnnn) = 0b00n0, so just the 2nd to lowest bit. If you run the code I posted and watch the gpios, you can see this in action.

I like to represent the int size in my 0x notation - one hex digit is 4 bits so 0x01 is 8 bit data, 0x0001 is 16 etc. even though mathematicaly they all represent the same number.

1 Like

Hey There,

I have been messing with the calculator to better inform myself on what you are describing here. Mostly, none of which I already can articulate well.

Seth

P.S. I am trying to understand.

What is the 32-bits hexadecimal notation? I have been trying to configure this idea.

Not quite sure what the question is …
0xb28c8060 would be a 32 bit integer - 4 bits per digit x 8 digits = 32 bits.

1 Like

No issue. I was getting wishy-washy with questioning.

Seth

P.S. Aw! Thank you…

Hey @bbbpaul ,

Seth here. Would you think that using a void function like this idea is incorrect?

void GPIO_One(int Gpio) {

I keep reading about how to create void functions for the main function but so much data and I am backlogged in ideas…

Seth

P.S. Here is the entire source:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

void GPIO_One(int Gpio) {
    FILE *bright;
    bright = fopen("/sys/class/leds/m1_high/brightness", "w");
    fseek(bright, 0, SEEK_SET);
    fprintf(bright, "%d", 1 * Gpio);
    fclose(bright);
}

void setupPWM(int enable) {
    FILE *pwm;
    pwm = fopen("/dev/beagle/pwm/P9_16/enable", "w");
    fseek(pwm, 0, SEEK_SET);
    fprintf(pwm, "%d", 1 * enable);
    fclose(pwm);
}

void setupPeriod(int period_one) {
    FILE *period;
    period = fopen("/dev/beagle/pwm/P9_16/period", "w");
    fseek(period, 0, SEEK_SET);
    fprintf(period, "%d", 10 * period_one);
    fclose(period);
}

void pwm_duty(int the_duty_multiplier) {
    FILE *duty;
    duty = fopen("/dev/beagle/pwm/P9_16/duty_cycle", "w");
    fseek(duty, 0, SEEK_SET);
    fprintf(duty, "%d", 100 * the_duty_multiplier);
    fclose(duty);
}

int testInteger = 0;

int main() {
    printf("Setting up\n");
    setupPWM(0);

   while(1) {
        printf("Enter an integer, Please: ");
        scanf("%d", &testInteger);
        if (testInteger >= 3) {
            setupPWM(1);
            setupPeriod(140);
            pwm_duty(8);
            GPIO_One(1);
        }
        usleep(2500);

        if (testInteger < 2) {
            setupPWM(0);
            setupPeriod(80);
            pwm_duty(8);
            GPIO_One(0);
        }

        usleep(2500);
    }
    pwm_duty(0);
    setupPWM(0);
    GPIO_One(0);
    return 0;
}