[solved]stepper motor with firmata, arduino

Hi!

I am trying to control a stepper motor with the firmata in OF

This is the way to control the stepper motor in Arduino:

  
void loop(){  
  
digitalWrite(dirpin, HIGH);    //HIGH or LOW change direction.  
   
delay(100) ; //100 milliseconds  
  
  for (int i = 0; i<4000; i++)       //Iterate for 4000 microsteps  
  {  
  
digitalWrite(steppin, LOW);     
digitalWrite(steppin, HIGH);  //This LOW to HIGH change is what  
//creates the "Rising Edge" so the driver knows when to step.  
  
delayMicroseconds(40);//speed//0.04 milliseconds  
  }  

I ve tried to do the same in OF with the help of the firmata exemple. I don’t find how to have a delay time in microseconds.

  
void testApp::updateArduino()  
{  
  
ard.update();  
ard.sendDigital(7, ARD_HIGH);  //7 is the direction pin number  
  
ofSleepMillis(100);  
for (int i = 0; i< 4000 ; i++)        // Iterate for 4000 microsteps.  
{  
ard.sendDigital(6,ARD_LOW); //6 is the step pin number  
ard.sendDigital(6,ARD_HIGH);  
ofSleepMillis(4); //this is wrong, I need 0,04 milliseconds   
}  
}  
  

With ofSleepMillis(4); the stepper movement is very very slow
I looked how to control microseconds in C++ maybe the nanosleep() function is a solution, but I don’t find how to use it in Open Frameworks.

Maybe the solution is something easy
Maybe the firmata is not the best way to use a stepper motor with OF??

thank you for your help!

Paul

Communication with the Arduino isn’t going to be fast enough to allow you to send microsecond commands. You might want to either use an alternate version of Firmata within your Arduino, alter the Firmata program on your Arduino (as done here: http://www.instructables.com/id/Control-…-h-Firmata/) or control it an ofSerial instance. If you do the last then you could simply send a position, receive it in the Arduino, and then set the stepper w/in your Arduino as shown in the ofSerial example that’s in the of/other folder. On the Arduino side, it’s much easier to control a stepper using a Stepper library too (check this out: http://www.arduino.cc/en/Tutorial/Stepper). Hopefully that gets you pointed in the right direction.

Thanks a lot Joshua for your help!!
If it can help someone, here is the code I use to control two steppers at the same time:

  
void testApp::setup(){  
  
  
  
ard.connect("COM5", 57600);//PC control  
bSetupArduino	= false;  
  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
    if ( ard.isArduinoReady())  
    {  
  
        // 1st: setup the arduino if haven't already:  
        if (bSetupArduino == false)  
        {  
            setupArduino();  
            bSetupArduino = true;	// only do this once  
        }  
        // 2nd do the update of the arduino  
        updateArduino();  
    }  
  
}  
  
void testApp::setupArduino()  
{  
  
        for (int i = 0; i < 13; i++)  
    {  
        ard.sendDigitalPinMode(i, ARD_OUTPUT);  
    }  
  
    ard.sendDigitalPinMode(5, ARD_OUTPUT);// dir x  
    ard.sendDigitalPinMode(9, ARD_OUTPUT); //dir y  
    ard.sendDigitalPinMode(4, ARD_OUTPUT);// Switch y  
    ard.sendDigitalPinMode(3, ARD_OUTPUT);//Switch  x  
    //  
    ard.sendDigital(3, ARD_LOW);  
    ard.sendDigital(4, ARD_LOW);  
  
}  
  
  
//--------------------------------------------------------------  
  
void testApp::updateArduino()  
{  
ard.update();  
  
  
if(mouseX>40 && mouseX<60 &&  mouseY>20 && mouseY<40){       // cout<<"up"<<endl;  
    ard.sendDigital(9, ARD_LOW);//dir  
    }  
       if(mouseX>40 && mouseX<60 &&  mouseY>80 && mouseY<100){  
         //down  
    ard.sendDigital(9, ARD_HIGH);//dir  
        }  
  
  
    if ((mouseX>40 && mouseX<60 &&  mouseY>20 && mouseY<40)||(mouseX>40 && mouseX<60 &&  mouseY>80 && mouseY<100))//UP  
    {  
    ard.sendDigital(4, ARD_LOW);  
    }else{  
        ard.sendDigital(4, ARD_HIGH);  
        }  
  
    ////////////////////////////:  
  
    if(mouseX>10 && mouseX<30 &&  mouseY>50 && mouseY<70){  
    //left  
    ard.sendDigital(5, ARD_HIGH);//dir  
  
    }  
  
    if(mouseX>70 && mouseX<100 &&  mouseY>50 && mouseY<70){  
    //right  
    ard.sendDigital(5, ARD_LOW);//dir  
    }  
  
    if((mouseX>70 && mouseX<100 &&  mouseY>50 && mouseY<70)||(mouseX>10 && mouseX<30 &&  mouseY>50 && mouseY<70)){  
ard.sendDigital(3, ARD_LOW);  
}else{  
    ard.sendDigital(3, ARD_HIGH);  
}  
  
  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
    ofSetColor(20,20,20);  
    ofRect(40,20,20,20);  
    ofRect(40,80,20,20);  
    ofRect(10,50,20,20);  
    ofRect(70,50,20,20);  
  
}  

In Arduino my code is:

  
#include <Firmata.h>  
  
#define XstepPin 6           //Step pin  
#define XdirPin 5                //Direction pin  
#define YstepPin 10           //Step pin  
#define YdirPin 9                //Direction pin  
int switchPinY = 4;                 //step or not  
int switchPinX = 3;          //step or not  
  
int potPin = 1;  //potentiometer control speed  
int speedValue = 100;  
  
  
  
byte previousPIN[2];  // PIN means PORT for input  
byte previousPORT[2];  
  
void outputPort(byte portNumber, byte portValue)  
{  
// only send the data when it changes, otherwise you get too many messages!  
    if(previousPIN[portNumber] != portValue) {  
        Firmata.sendDigitalPort(portNumber, portValue);  
        previousPIN[portNumber] = portValue;  
        Firmata.sendDigitalPort(portNumber, portValue);  
    }  
}  
  
void setPinModeCallback(byte pin, int mode) {  
    if(pin > 1) { // don't touch RxTx pins (0,1)  
        pinMode(pin, mode);  
          
    }  
}  
  
void digitalWriteCallback(byte port, int value)  
{  
    byte i;  
    byte currentPinValue, previousPinValue;  
  
    if(value != previousPORT[port]) {  
        for(i=0; i<8; i++) {  
            currentPinValue = (byte) value & (1 << i);  
            previousPinValue = previousPORT[port] & (1 << i);  
            if(currentPinValue != previousPinValue) {  
                digitalWrite(i + (port*8), currentPinValue);  
            }  
        }  
        previousPORT[port] = value;  
    }  
}  
  
void setup()  
{  
    Firmata.setFirmwareVersion(0, 1);  
    Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);  
    Firmata.attach(SET_PIN_MODE, setPinModeCallback);  
    Firmata.begin(57600);  
  
}  
  
  
void loop()  
{  
    outputPort(0, PIND &~ B00000011); // pins 0-7, ignoring Rx/Tx pins (0/1)  
    outputPort(1, PINB); // pins 8-13  
    while(Firmata.available()) {  
        Firmata.processInput();  
    }  
  
speedValue = analogRead(potPin);  
  
  
  
if(digitalRead(switchPinX)==0){  
    
  
  
  for (int i = 0; i<4000; i++)    
  {  
  
digitalWrite(XstepPin, LOW);     
digitalWrite(XstepPin, HIGH);    
  
delayMicroseconds(speedValue);  
  }  
  
}else {  
digitalWrite(XstepPin,LOW);   
digitalWrite(XstepPin,LOW);   
}  
  
if(digitalRead(switchPinY)==0){  
  
  for (int i = 0; i<4000; i++)    
  {  
  
digitalWrite(YstepPin, LOW);     
digitalWrite(YstepPin, HIGH);    
delayMicroseconds(speedValue);  
  }  
  
}else {  
digitalWrite(YstepPin,LOW);  
digitalWrite(XstepPin,LOW);   
  
}  
     
}  

I might need to improve the last part folowing dan thompson example (http://danthompsonsblog.blogspot.com/20-…-orial.html)
But it’s working.