Community
cancel
Showing results for 
Search instead for 
Did you mean: 
idata
Community Manager
2,360 Views

Step motor with Edison using C

Hello,

Is there simple way for contorl Stepmotor form Grove Kit using C?

Following Arduino code works for me, but I have to program it in C:

# define IN1 8

# define IN2 9

# define IN3 10

# define IN4 11

int Steps = 0;

boolean Direction = true;// gre

unsigned long last_time;

unsigned long currentMillis ;

int steps_left=64;

long time1;

void setup()

{

Serial.begin(115200);

pinMode(IN1, OUTPUT);

pinMode(IN2, OUTPUT);

pinMode(IN3, OUTPUT);

pinMode(IN4, OUTPUT);

// delay(1000);

}

void loop()

{

while(steps_left>0){

currentMillis = micros();

if(currentMillis-last_time>=1000){

stepper(1);

time1=time1+micros()-last_time;

last_time=micros();

steps_left--;

}

}

delay(2000);

//Direction=!Direction;

steps_left=4095;

}

void stepper(int xw){

for (int x=0;x

switch(Steps){

case 0:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;

case 1:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, HIGH);

break;

case 2:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 3:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, HIGH);

digitalWrite(IN4, LOW);

break;

case 4:

digitalWrite(IN1, LOW);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 5:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, HIGH);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 6:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

case 7:

digitalWrite(IN1, HIGH);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, HIGH);

break;

default:

digitalWrite(IN1, LOW);

digitalWrite(IN2, LOW);

digitalWrite(IN3, LOW);

digitalWrite(IN4, LOW);

break;

}

SetDirection();

}

}

void SetDirection(){

if(Direction==1){ Steps++;}

if(Direction==0){ Steps--; }

if(Steps>7){Steps=0;}

if(Steps<0){Steps=7; }

}

Unfortunatelly any my translation it into pure C doesnt make stepper to run.

Could anybody help me with translation? Or is there Stepper.h standalone so I could use it like in Arduino IDE? If yes the ony one change would be digitalWrite -> mraa_gpio_write and pin init.

And btw could anybody explain to me, why ol that time stuff in code above is mandatory.

Please, help me.

Thanks,

Paweł

0 Kudos
13 Replies
idata
Community Manager
53 Views

Hello Pawek,

 

 

Could you please let us know the modifications you tried to implement when you translated the code into C. Did you implement the mraa library into it? If you use it, the modifications you'd have to do shouldn't be that extensive. Apart from that you will have to change the micros() method as it doesn't exist in C. You will have to search for a method to display the same information in C.

 

 

-Peter.
idata
Community Manager
53 Views

# include

# include

# include

# include "mraa.h"

# include

# define GPIO_STEPPER1_PIN 10

# define GPIO_STEPPER2_PIN 11

# define GPIO_STEPPER3_PIN 12

# define GPIO_STEPPER4_PIN 13

# define LOW 0

# define HIGH 1

int Steps = 0;

bool Direction = true;

uint64_t last_time;

uint64_t currentMillis ;

int steps_left = 64;

long time1;

mraa_gpio_context stepper_gpio1;

mraa_gpio_context stepper_gpio2;

mraa_gpio_context stepper_gpio3;

mraa_gpio_context stepper_gpio4;

void prepare_gpios()

{

stepper_gpio1 = mraa_gpio_init(GPIO_STEPPER1_PIN);

stepper_gpio2 = mraa_gpio_init(GPIO_STEPPER2_PIN);

stepper_gpio3 = mraa_gpio_init(GPIO_STEPPER3_PIN);

stepper_gpio4 = mraa_gpio_init(GPIO_STEPPER4_PIN);

}

static uint64_t prox_time_ms(void)

{

struct timeval tv;

gettimeofday(&tv, NULL);

return (uint64_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);

}

void SetDirection(){

if(Direction==1){ Steps++;}

if(Direction==0){ Steps--; }

if(Steps>7){Steps=0;}

if(Steps<0){Steps=7; }

}

void stepper(int xw){

int x;

for (x=0;x

switch(Steps){

case 0:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, HIGH);

break;

case 1:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, HIGH);

mraa_gpio_write(stepper_gpio4, HIGH);

break;

case 2:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, HIGH);

mraa_gpio_write(stepper_gpio4, LOW);

break;

case 3:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, HIGH);

mraa_gpio_write(stepper_gpio3, HIGH);

mraa_gpio_write(stepper_gpio4, LOW);

break;

case 4:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, HIGH);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, LOW);

break;

case 5:

mraa_gpio_write(stepper_gpio1, HIGH);

mraa_gpio_write(stepper_gpio2, HIGH);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, LOW);

break;

case 6:

mraa_gpio_write(stepper_gpio1, HIGH);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, LOW);

break;

case 7:

mraa_gpio_write(stepper_gpio1, HIGH);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, HIGH);

break;

default:

mraa_gpio_write(stepper_gpio1, LOW);

mraa_gpio_write(stepper_gpio2, LOW);

mraa_gpio_write(stepper_gpio3, LOW);

mraa_gpio_write(stepper_gpio4, LOW);

break;

}

SetDirection();

}

}

void start_stepper()

{

if(steps_left>0)

{

currentMillis = prox_time_ms();

if(currentMillis-last_time>=1000)

{

stepper(1);

time1=time1+prox_time_ms()-last_time;

last_time=prox_time_ms();

steps_left--;

}

} else{

sleep(1);

steps_left=4095;

}

}

int main(void)

{

/*initialize mraa libraries*/

mraa_init();

/*Prepare GPIOs and AIOs*/

prepare_gpios();

/*Main loop*/

while(1)

{

/*Print connection state*/

//printf("Connected: %s\r\n", prox_is_connected() ? "yes" : "no");

/*Proximetry Agent Routines*/

//prox_agent_task(); //this endless while loop is mandatory fot that function and it sholudnt be delayed

//so i changed from while to if statment

start_stepper();

/*Simple delay*/

//sleep(1);

}

return 0;

}

Here you are, My problem is that the step motor doesnt move. I only hear noise generated by it it gets hot. On arduino it work flawless.

Thanks for your support Peter,

Paweł

IIstv
New Contributor I
53 Views

I think you should set the direction of the ports to output too:

mraa_gpio_dir (pin,dir)

Istvan

idata
Community Manager
53 Views

mraa_gpio_mode(stepper_gpio1, MRAA_GPIO_STRONG);

mraa_gpio_dir(stepper_gpio1, MRAA_GPIO_OUT);

mraa_gpio_mode(stepper_gpio2, MRAA_GPIO_STRONG);

mraa_gpio_dir(stepper_gpio2, MRAA_GPIO_OUT);

mraa_gpio_mode(stepper_gpio3, MRAA_GPIO_STRONG);

mraa_gpio_dir(stepper_gpio3, MRAA_GPIO_OUT);

mraa_gpio_mode(stepper_gpio4, MRAA_GPIO_STRONG);

mraa_gpio_dir(stepper_gpio4, MRAA_GPIO_OUT);

Sorry. Since control of a step motor is a part of bigger project I had to refactor my code. I simply forgot to paste these lines into my post.

Nevertheless it still does not work. I belive that I translated code from Arduino properly.

Althrought I would appreciate any further support.

Thanks,

Paweł

idata
Community Manager
53 Views

Hi pawek,

This is how I would translate your code into C:

# include

 

# include

 

# include

 

# include

 

# include "mraa/gpio.h"

 

 

# define IN1 8

 

# define IN2 9

 

# define IN3 10

 

# define IN4 11

 

 

typedef int bool;

 

# define true 1

 

# define false 0

 

 

int Steps = 0;

 

bool Direction = true;

 

unsigned long last_time = 0;

 

unsigned long currentMillis;

 

int steps_left=64;

 

int state = 0;

 

long time1 = 0;

 

long time2;

 

long time_b_sec;

 

long time_b_usec;

 

long time_a_sec;

 

long time_a_usec;

 

 

void stepper(int xw);

 

void SetDirection();

 

 

void main()

 

{

 

struct timeval tvalBefore;

 

struct timeval tvalAfter;

 

 

while(steps_left>0)

 

{

 

//currentMillis = micros();

 

//////////////

 

gettimeofday (&tvalBefore, NULL);

 

time_b_sec = tvalBefore.tv_sec;

 

time_b_usec = tvalBefore.tv_usec;

 

currentMillis = (time_a_sec * 1000000L) + time_a_usec;

 

//////////////

 

 

if(currentMillis-last_time >= 1000)

 

{

 

stepper(1);

 

 

//////////////

 

gettimeofday (&tvalAfter, NULL);

 

time_a_sec = tvalAfter.tv_sec;

 

time_a_usec = tvalAfter.tv_usec;

 

time2 = (time_a_sec * 1000000L) + time_a_usec;

 

//////////////

 

 

time1 = time1 + time2 - last_time;//time1 + micros() - last_time;

 

last_time = time2; //micros();

 

 

steps_left--;

 

}

 

}

 

sleep(2);

 

//Direction=!Direction;

 

steps_left=4095;

 

}

 

 

 

void stepper(int xw)

 

{

 

int x;

 

 

mraa_gpio_context gpio1;

 

mraa_gpio_context gpio2;

 

mraa_gpio_context gpio3;

 

mraa_gpio_context gpio4;

 

 

gpio1 = mraa_gpio_init(IN1);

 

gpio2 = mraa_gpio_init(IN2);

 

gpio3 = mraa_gpio_init(IN3);

 

gpio4 = mraa_gpio_init(IN4);

 

 

mraa_gpio_dir(gpio1, MRAA_GPIO_OUT);

 

mraa_gpio_dir(gpio2, MRAA_GPIO_OUT);

 

mraa_gpio_dir(gpio3, MRAA_GPIO_OUT);

 

mraa_gpio_dir(gpio4, MRAA_GPIO_OUT);

 

 

for (x = 0; x < xw; x = x + 1)

 

{

 

switch(Steps)

 

{

 

case 0:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, !state);

 

break;

 

case 1:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, !state);

 

mraa_gpio_write(gpio4, !state);

 

break;

 

case 2:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, !state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

case 3:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, !state);

 

mraa_gpio_write(gpio3, !state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

case 4:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, !state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

case 5:

 

mraa_gpio_write(gpio1, !state);

 

mraa_gpio_write(gpio2, !state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

case 6:

 

mraa_gpio_write(gpio1, !state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

case 7:

 

mraa_gpio_write(gpio1, !state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, !state);

 

break;

 

default:

 

mraa_gpio_write(gpio1, state);

 

mraa_gpio_write(gpio2, state);

 

mraa_gpio_write(gpio3, state);

 

mraa_gpio_write(gpio4, state);

 

break;

 

}

 

SetDirection();

 

}

 

}

 

 

void SetDirection()

 

{

 <...

idata
Community Manager
53 Views

Hi,

Unfortunately, code you provided doesn't work. I checked why and it turbned out that your currentMilis value is 0 all the time. Never mind, I had changed it to my function and it now "works" same way as mine. Step motor still doesn't move.

I find out something suspicious. You can see it in attached film. Edison, when I use C have ~1 sec delay between switch-case statment executnion. And Arduino doesnt. If I add infinite loop in stepper function, so it work without that delay, step motor only squeak.

Printf function responsible for printing message is one line above for loop in stepper() function.

Thanks,

Paweł

Code:

# include

# include

# include

# include "mraa.h"

# include

# define LOW 0

# define HIGH 1

# define IN1 8

# define IN2 9

# define IN3 10

# define IN4 11

# define true 1

# define false 0

int Steps = 0;

bool Direction = true;

unsigned long last_time = 0;

unsigned long currentMillis;

int steps_left=64;

int state = 0;

long time1 = 0;

long time2;

static long prox_time_ms(void)

{

struct timeval tv;

gettimeofday(&tv, NULL);

return (uint64_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000);

}

void stepper(int xw);

void SetDirection();

mraa_gpio_context gpio1;

mraa_gpio_context gpio2;

mraa_gpio_context gpio3;

mraa_gpio_context gpio4;

int main()

{

gpio1 = mraa_gpio_init(IN1);

printf("Initialized gpio1\n");

gpio2 = mraa_gpio_init(IN2);

printf("Initialized gpio2\n");

gpio3 = mraa_gpio_init(IN3);

printf("Initialized gpio3\n");

gpio4 = mraa_gpio_init(IN4);

printf("Initialized gpio4\n");

mraa_gpio_dir(gpio1, MRAA_GPIO_OUT);

mraa_gpio_dir(gpio2, MRAA_GPIO_OUT);

mraa_gpio_dir(gpio3, MRAA_GPIO_OUT);

mraa_gpio_dir(gpio4, MRAA_GPIO_OUT);

printf("All to out\n");

while(1){

while(steps_left>0)

{

currentMillis = prox_time_ms();

if(currentMillis-last_time >= 1000)

{

stepper(1);

time2 = prox_time_ms();

time1 = time1 + time2 - last_time;

last_time = time2;

steps_left--;

}

}

sleep(2);

Direction=!Direction;

steps_left=4095;

}

return 0;

}

void stepper(int xw)

{

int x;

printf("steps %d\n",Steps);

for (x = 0; x < xw; x = x + 1)

{

switch(Steps)

{

case 0:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, HIGH);

break;

case 1:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, HIGH);

mraa_gpio_write(gpio4, HIGH);

break;

case 2:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, HIGH);

mraa_gpio_write(gpio4, LOW);

break;

case 3:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, HIGH);

mraa_gpio_write(gpio3, HIGH);

mraa_gpio_write(gpio4, LOW);

break;

case 4:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, HIGH);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, LOW);

break;

case 5:

mraa_gpio_write(gpio1, HIGH);

mraa_gpio_write(gpio2, HIGH);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, LOW);

break;

case 6:

mraa_gpio_write(gpio1, HIGH);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, LOW);

break;

case 7:

mraa_gpio_write(gpio1, HIGH);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, HIGH);

break;

default:

mraa_gpio_write(gpio1, LOW);

mraa_gpio_write(gpio2, LOW);

mraa_gpio_write(gpio3, LOW);

mraa_gpio_write(gpio4, LOW);

break;

}

SetDirection();

}

}

void SetDirection()

{

if(Direction==1)

Steps = Steps + 1;

if(Direction==0)

Steps = Steps - 1;

if(Steps>7)

Steps = 0;

if(Steps<0)

Steps = 7;

}

IIstv
New Contributor I
53 Views

while(steps_left>0)

{

currentMillis = prox_time_ms();

if(currentMillis-last_time >= 1000)

{

stepper(1);

time2 = prox_time_ms();

time1 = time1 + time2 - last_time;

last_time = time2;

steps_left--;

}

}

  • The body of the if(currentMillis-last_time >= 1000) is not executed for the first 1000ms.
  • After this time the currentMillis - last_time will go over 1000 and the body of the if() will be executed.
  • Then last_time will be moved to present time, and the 1000ms silence starts over again.

I have no hardware to test it, but it very much looks to me like the motor gets one pulse per second.

idata
Community Manager
53 Views

In my code I found a minor issue in the line 44. Instead of :

currentMillis = (time_a_sec * 1000000L) + time_a_usec;

It should be:

currentMillis = (time_b_sec * 1000000L) + time_b_usec;

I tested this with some LEDs and it is sending some signals. Could you please check it again to see if it changes anything?

-Peter.

idata
Community Manager
53 Views

Hi,

After Peterschange this is what happens:

I've closed almost whole main function into endless loop so motor should move all the time.

Now there isnt any delay but still motor doesn't move. After second go through infinite loop it seems that no signal is send.

@if You may be right, but exactly the same code run on Arduino or even on Edison programmed with Arduino without any issue.

Thanks guys for support,

Paweł

EDIT:

Yes it is about exactly the same code. On arduino I run the code form my first post. On Edison using C there is code written by Peter.

I will give it a try.

My hardwere:

- Edison with Grove Starter Kit Shield on Arduino board

- Arduino Uno (I use it just for conviniene, I have tested that on Edison Arduino code work as good as on standalone UNO)

Now everything execute more fluent and nicer bot stil doenst work.

IIstv
New Contributor I
53 Views

The first code (Arduino) was timed on microseconds, where the wait lasts for 1000us, so the pulse period is 1ms.

The last (Edison) code in post 6 was timed in milliseconds. That is why my test on the Edison showed a 1s pulse period. (1000 ms).

I am not familiar with the grove kit. What is the driver board before the motor? (The one with the leds?) Did you use it with the Arduino Uno too?

What is the position of J9 jumper on the Edison Arduino breakout board?

idata
Community Manager
53 Views

Oh my God. Thank you. It was all about that time. I changed if(currentMillis-last_time >= 100) ->>>> if(currentMillis-last_time >= 1) and now it finally works.

Thank you!

Paweł

IIstv
New Contributor I
53 Views

Glad you've managed.

Istvan

IIstv
New Contributor I
53 Views

I have loaded the last full program source posted, on an Edison Arduino board.

I can confirm what I said in 7: the function stepper(1) runs once in every second. To make it faster, change the value in the line:

if(currentMillis-last_time >= 1000)

to 100.

With this setting I can see more convenient pulses on the oscilloscope. One stepper() in every 0.1s

The video is a bit strange. Is it about the same code? What hardware exactly?

Istvan

Reply