Jump to content

Raspberry pi c++ stepper motor

Hi I am trying to use the wiring pi library to use a stepper motor with c++ for a project in my engineering class. I am not very experienced in programing so I tried to basically convert the code from a video that used python into c++, I am using different pins however but that's the only way i could get it to feel like it was trying to move. I can feel the motor trying to move but it's not actually moving any visible amount.

 

video: 

 

 

 

my code:

 

#include <wiringPi.h>
#include <iostream>

using namespace std;

void Sleep()
{
    for (int i = 0; i < 1000; i++)
    {

    }
}

int main(void)
{

    wiringPiSetup();

    int uPin[4] = { 5, 6, 10, 11 };

    for (int i = 0; i < 4; i++)
    {
        pinMode (uPin, OUTPUT);
        digitalWrite (uPin, 0);
    }

    int seq[8][4] = { {1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,1,0}, {0,0,1,1}, {0,0,0,1}, {1,0,0,1} };

    for (int i = 0; i <= 512; i++)
    {
        for (int step = 0; step <= 8; step++)
        {
            for (int pin = 0; pin <= 4; pin++)
            {
                digitalWrite(uPin[pin], seq[step][pin]);
                Sleep();
                cout << "slept \n";
            }
        }
    }


    return 0;
}

Link to comment
Share on other sites

Link to post
Share on other sites

10 hours ago, BaconStorm said:

#include <wiringPi.h>
#include <iostream>

using namespace std;

void Sleep()//I'd put this at the bottom of your program, but that's just me
{
    for (int i = 0; i < 1000; i++)
    {
//can you guarantee the time it will take to run through each iteration of the loop?
    }
}

int main(void)//putting void in the parameter list of a function is not how you define the return type of a function. proper syntax is return_type function_name (parameter list) {}
{

    wiringPiSetup();

    int uPin[4] = { 5, 6, 10, 11 };
/*
const int pin1 = 5;
const int pin2 = 6;
const int pin3 = 10;
const int pin4 = 11;

^^I suggest declaring pins as constants because they need to be consistant through the program or else things will fuck up. They shouldn't change anyway, but it's good practice to declare as constants.
*/
    for (int i = 0; i < 4; i++)
    {
        pinMode (uPin, OUTPUT);//it looks like you're declaring an array as a pin, I don't think that works. Perhaps with the Pi, but it doesn't work like that in Arduino C. See above comments for suggested definitions
        digitalWrite (uPin, 0);//typical usage of a digitalWrite is LOW or HIGH, not 0 or 1, but this probably works.
    }

    int seq[8][4] = { {1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,1,0}, {0,0,1,1}, {0,0,0,1}, {1,0,0,1} };//ngl, no idea what the hell is going on here. I think this is how you're trying to fire the phases of the steppers? If so, this will probably result in a pretty jerky or noisy opperation of the motor. 

  //the following nested forloops are gross. Sorry, I don't make the rules. Is this how the library suggests controlling the motors?
    for (int i = 0; i <= 512; i++)
    {
        for (int step = 0; step <= 8; step++)
        {
            for (int pin = 0; pin <= 4; pin++)
            {
                digitalWrite(uPin[pin], seq[step][pin]);
                Sleep();
                cout << "slept \n";//not sure what you're cout-ing to, I'm guessing this is an embeded system without a console, but I'm not sure.
            }
        }
    }


    return 0;
}

 

I added a bunch of comments highlighting what I think is going on and what I think is wrong. For the most part, this looks like an Arduino program, but with a bit more traditional C++.  Also Adafruit has a hat for controlling stepper motors, perhaps you can use some libraries or information from their guides in adapting your program.

ASU

Link to comment
Share on other sites

Link to post
Share on other sites

I agree with @Hackentosher, connecting the io directly from the pi is 'not so good' you really need a driver that can deliver some current to your motors. Make sure your stepper driver is 3.3vdc compatible, and is hooked up to an external power supply, I think the onboard vReg of the pi can only handle 500ma, and each of the io is like 2-5ma (I need fact checked). Also, the wireing pi lib has builtin delay functions. @Hackentosher is right, you can't accurately time your delays if you blindly loop. @BaconStorm, your off to a good start, time and patience is how you become good at something.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, CodeNova said:

I agree with @Hackentosher, connecting the io directly from the pi is 'not so good' you really need a driver that can deliver some current to your motors. Make sure your stepper driver is 3.3vdc compatible, and is hooked up to an external power supply, I think the onboard vReg of the pi can only handle 500ma, and each of the io is like 2-5ma (I need fact checked). Also, the wireing pi lib has builtin delay functions. @Hackentosher is right, you can't accurately time your delays if you blindly loop. @BaconStorm, your off to a good start, time and patience is how you become good at something.

Oh yeah I forgot about that, the GPIO on the pi output practically no current, but steppers can pull a good bit of current, especially under load. 

ASU

Link to comment
Share on other sites

Link to post
Share on other sites

Thank you both, I will definitely be getting a motor shield. Do yall have any recommendations? 

Also in response to what the cout is couting to, I have it plugged into a monitor at the moment.

Link to comment
Share on other sites

Link to post
Share on other sites

I changed my main method based off your recommendations (I don't have the motor shield yet)

 

int main(void)
{

    wiringPiSetup();

    const int pin1 = 5;
    const int pin2 = 6;
    const int pin3 = 10;
    const int pin4 = 11;

    pinMode (pin1, OUTPUT);
    digitalWrite (pin1, 0);

    pinMode (pin2, OUTPUT);
    digitalWrite (pin2, 0);

    pinMode (pin3, OUTPUT);
    digitalWrite (pin3, 0);

    pinMode (pin4, OUTPUT);
    digitalWrite (pin4, 0);

    int seq[8][4] = { {1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,1,1,0}, {0,0,1,0}, {0,0,1,1}, {0,0,0,1}, {1,0,0,1} };

    for (int i = 0; i <= 512; i++)
    {
        for (int step = 0; step < 8; step++)
        {
            for (int pin = 0; pin < 4; pin++)
            {
                if(pin == 0)
                    {
                    digitalWrite(pin1, seq[step][pin]);
                    Sleep;
                    cout << "slept pin1 \n";
                    }
                if(pin == 1)
                    {
                    digitalWrite(pin2, seq[step][pin]);
                    Sleep;
                    cout << "slept pin2 \n";
                if(pin == 2)
                    {
                    digitalWrite(pin3, seq[step][pin]);
                    Sleep;
                    cout << "slept pin3 \n";
                    }
                if(pin == 3)
                    {
                    digitalWrite(pin4, seq[step][pin]);
                    Sleep;
                    cout << "slept pin4 \n";
                    }


                    }


            }
        }
    }


    return 0;
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

I realized I didn't need the if statements in the loop so i got rid of them 

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, BaconStorm said:

Sorry that one wasn't really necessary I realized if i removed the if statements it would work the same and then it does go through all  the pins. however no improvement it actually moving

 

post a pic of your 'breadboard' or wiring diagram/schematic. Edit: and the motor your using.

Link to comment
Share on other sites

Link to post
Share on other sites

I am planing to switch to a pi zero for this project but I had the b+ laying around so that has been what I have been using for now. Thank you so much I will definitely use that one and get a pi zero asap so I can test with it.

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, BaconStorm said:

I am planing to switch to a pi zero for this project but I had the b+ laying around so that has been what I have been using for now. Thank you so much I will definitely use that one and get a pi zero asap so I can test with it.

A motor part number would help, your steppers might need more juice.

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, BaconStorm said:

i'm using the 28byj-48

That 'pi hat' should be perfect then.

Link to comment
Share on other sites

Link to post
Share on other sites

3 hours ago, BaconStorm said:

I realized I didn't need the if statements in the loop so i got rid of them 

/*
 CodeNova
 stepper motor test, for BaconStorm
 3/13/2019
 
 Notes to self:
 sudo gpio readall
 g++ -Wall -o steptest steptest.cpp -lwiringPi
*/

#include <stdio.h>
#include <wiringPi.h>

#define FORWARD		1
#define BACKWARD	0

const int SPEED = 500;
const int PINS[4] = {22,23,24,25};
const bool STEPS[8][4] = {
	{HIGH, LOW, HIGH, LOW},	//0
	{HIGH, LOW, LOW, LOW},	//1
	{HIGH, LOW, LOW, HIGH},	//2
	{LOW, LOW, LOW, HIGH},	//3
	{LOW, HIGH, LOW, HIGH},	//4
	{LOW, HIGH, LOW, LOW},	//5
	{LOW, HIGH, HIGH, LOW},	//6
	{LOW, LOW, HIGH, LOW},	//7
	};

void initPins(const int index);
void halfStep(int &index, bool dir);
void debugPrint(void);

int main(void)
{
	printf("CodeNova, Stepper Test\n");
	int index = 0;		//step index counter
	
	wiringPiSetup(); 	//setup wireing pi
	initPins(index);	//init pins, start at 0

	//forward 10 halfsteps
	printf("* Forward Test *\n");
	for(int i = 0; i < 10; i++)
	{	
		halfStep(index, FORWARD);
		delay(SPEED);
		printf("index: %d\n", index);	//debug index counter
	}
	
	//backward 10 halfsteps
	printf("* Backward Test *\n");
	for(int i = 0; i < 10; i++)
	{
		halfStep(index, BACKWARD);
		delay(SPEED);
		printf("index: %d\n", index);	//debug index counter
	}	
	
	printf("Test FIN\n");
	return 0;
}

void initPins(const int index)
{
	for(int i = 0; i < 4; i++)
	{
		printf("init-ing pin %d, OUTPUT\n", PINS[i]);	//debug output
		pinMode(PINS[i], OUTPUT);						//set IO to output
		digitalWrite(PINS[i], STEPS[index][i]);			//write to IO
	}
	debugPrint();										//print IO state, debug
	printf("index: %d\n", index);						//print index number, debug
}

void halfStep(int &index, bool dir)
{
	index = dir ? ((index+1)%8) : ((index+7)%8);	//add|sub index based on direction
	
	for(int i = 0; i < 4; i++)
		digitalWrite(PINS[i], STEPS[index][i]);		//write to IO	
	
	debugPrint();									//print IO state, debug
}

void debugPrint(void)
{
	for(int i = 0; i < 4; i++)
		printf("%d", digitalRead(PINS[i])); //read the new io state
	printf("\n");
}

Hope this helps.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×