Go Down

Topic: Processing + arduino + stepperLab3 (Read 811 times) previous topic - next topic

kerimil

I want to send data from processing to arduino over serial. I know how to set things up but I have no idea what should I send. Do I need to send a string ?

I guess it must be something pretty basic. I uploaded example from stepperlab3 library (controlling step motor with serial commands) to arduino
It works perfectly ok when I type in commands manually via serial monitor (so for example "g 200" tells the arduino to move the step motor to position 200). What I don't know is why I can't even send a similar command from processing

like this:
Code: [Select]
myPort.write("G 200");
let alone send "G " and then the value of a variable

I am leaning towards the conclusion that either I can't send the right data type (would string be ok?) or I need something to send the data once and then wait a while till arduino accepts that as a complete message


anyway here is the example I uploaded on arduino
Code: [Select]
/* stepper library StepperLab3
/*
* conrol stepper motor with serial commands
*
* KHM Lab3 2010
* Kunsthochschule fuer Medien Koeln
* Academy of Media Arts Cologne
* http://interface.khm.de

*/

#include <Metro.h>

// import stepper library
#include <StepperLab3.h>
// create instance for stepper
StepperLab3 myStepper;

// poti value
int potiValue = 0;

int ledGreen= 5;
int pinLsSens=15;
int motor1_1= 8;
int motor1_2= 10;
int motor2_1= 9;
int motor2_2= 11;

int cnt;
int posi=2400;
int rock;

// separateString
char buff[50];
char st1[10];
char st2[10];
char st3[10];
int arg1;
int arg2;
int arg3;
int ibuf;

boolean f_receive=false;
boolean f_message=false;
boolean f_continu=false;

// metros //
Metro comTimeout= Metro(1000);


// this block is executed one time when programm starts
void setup(){
  Serial.begin(115200);
  Serial.println("Serial Command stepperLab3 library");
  Serial.println("Input: CommandChar blank parameter CR");
 
  Serial.println("g <position>  // goto positon");
  Serial.println("n             // find 0 positon");
  Serial.println("s <speed>     // set speed, steps per second");
  Serial.println("g <power>     // set motor power 0..1023");
  Serial.println("t <steps>     // set number ramp steps");
  Serial.println("r             // read positon");
  Serial.println("m <mode>      // stepmode full 1 half 0");
  Serial.println("u <sw>        // rocker on 1 off 0");

  pinMode(ledGreen,OUTPUT);  // LED pin
  pinMode(pinLsSens,INPUT);  // switch

  digitalWrite(pinLsSens,1);

  myStepper.attach(motor1_1,motor1_2,motor2_1,motor2_2);

  myStepper.setPower(1023);
  myStepper.setSpeed(700);
}


// this block is executed in a loop after setup is called one time
void loop(){

  // read poti (value between 0 and 1023)
  potiValue = analogRead(1);

  receive_serial_message();   // Receive serial
  if (f_message){     // if message complete
    f_message=false;
    arg2=atoi(st2);
    arg3=atoi(st3);  // ascii to integer
    st1[0] = st1[0] & 0x5f;  // first cahr into uppercase

    switch (st1[0] ) {
    case 'G': 
      Serial.print("goto:"); 
      Serial.println(arg2); 
      myStepper.absoluteSteps(arg2);
      posi=arg2;
      break;

    case 'N':  // Goto Null Position
      Serial.println("goto null ");
      go_null();
      break;

    case 'S': // Set Stepper Speed
      Serial.print("set speed:");
      Serial.println(arg2);
      myStepper.setSpeed(arg2);
      break;

    case 'P': // Set Stepper Motor Tourque
      Serial.print("set sower:");
      Serial.println(arg2);
      myStepper.setPower(arg2);
      break;

    case 'T': // Set Stepper Ramp Steps
      Serial.print("ramp steps:");
      Serial.println(arg2);
      myStepper.setRampSteps(arg2);
      break;

    case 'R': // read Stepper position
      Serial.print("pos:");
      Serial.println(myStepper.getSteps());
      break; 

    case 'M': // set Mode
      if (arg2) {
        Serial.println("full step");
        myStepper.setFullStep();
      }
      else
      {
        Serial.println("half step");
        myStepper.setHalfStep();
      }
      break;   

    case 'U': // read Stepper position
      Serial.print("rocker:");
      Serial.println(arg2);
      rock = arg2;
      break; 
    }

    Serial.print(st1);
    Serial.print(":");
    Serial.print(st2);
    Serial.println();
  }


  delay(1);
  if (cnt % 500 == 0) {
    digitalWrite(ledGreen,!digitalRead(ledGreen));  // blink led
  }
  cnt++;

  if (rock) rocker();


}
//*********************************************************************
void go_null() {  // goto switch position

  myStepper.absoluteSteps(20);
  while( myStepper.stepReady() == 0);
  delay(200);
  myStepper.rotate(1);
  while(digitalRead(pinLsSens)==1);
  myStepper.rotate(0);

}

//*********************************************************************
void receive_serial_message() {

  if (f_receive){
    if (comTimeout.check() == 1) {
      f_receive = false;
      buff[0]='\0';
      ibuf=0;
      Serial.println("timeout");
    }
  } 

  if ( Serial.available() > 0) {     // if there are bytes waiting on the serial port
    comTimeout.reset();             // message must be finished within timeout time
    comTimeout.interval(200);
    f_receive = true;
    char inByte = Serial.read();   // read a byte
    buff[ibuf]=inByte;             // add to buffer 
    ibuf++;
    buff[ibuf]='\0';
    if (ibuf >= 50) ibuf=0;        // limit buffer size
    // Serial.println(buff);
    if ((inByte == '.') ||(inByte == '*') || ( inByte == '\n') || ( inByte == '\r')) { // wait for message termination character
      separateString();       // separate message string into 3 substrings
      f_message=true;        // message avail now flag
      buff[0]='\0';          // clear message receive
      ibuf=0;
      f_receive = false;

    }

  }
}
//*********************************************************************
void separateString() {
  st1[0]='\0';
  st2[0]='\0';
  st3[0]='\0';
  int pos=0;
  int p1 =0;
  int cnt=0;
  char stc[2]="";
  for (int ii=0; ii<= strlen(buff); ii++) {
    if ((buff[ii] >= '-')  ) { //  Separator == all chars < ' '
      stc[0] = buff[ii];
      cnt++;
      if (cnt <= 5) {
        switch (pos){
        case 0:
          strcat(st1,stc);
          break;
        case 1:
          strcat(st2,stc);
          break;
        case 2:
          strcat(st3,stc);
          break;
        default:
          break;
        }
      }  // if < 5 len arguments

    }
    else     {
      cnt=0;
      pos++;
    }
    while ((buff[ii]  <'-') && (buff[ii+1] < '-') && (ii <= strlen(buff))) {
      ii++;
    }
  }
}

//*********************************************************************
// drives stepper left and right
void rocker() {
  static int state;
  static int cwait;

  switch (state) {
  case 0:
    myStepper.absoluteSteps(posi);
    state=1;
    break;
  case 1:
    if (myStepper.stepReady()) {
      if (cwait == 0) {
      myStepper.absoluteSteps(0);
       state=2;
      }
    }
    break;
  case 2:
    if (myStepper.stepReady()) {
      if (cwait == 0) state=0;
    }
    break;
  }
 
  if (myStepper.stepReady() ==0) cwait=500;
  if (cwait > 0 ) cwait--;
 
}





I want to send data from processing to arduino over serial. I know how to set things up but I have no idea what should I send. Do I need to send a string ?


PaulS

Quote
I know how to set things up but I have no idea what should I send

You get to define that.

Quote
Do I need to send a string ?

That's one way. Binary data would be the other.

Quote
What I don't know is why I can't even send a similar command from processing

You can. If Processing and the Arduino are connected to the same port.

Quote
let alone send "G " and then the value of a variable

You have my permission to do that, too.

Quote
anyway here is the example I uploaded on arduino

And the Processing code?

f_receive doesn't convey any kind of information. readyToReceive or something like that fould be much better.

Code: [Select]
    buff[ibuf]=inByte;             // add to buffer 
    ibuf++;
    buff[ibuf]='\0';

Good thing that you are checking that there is room in the array for the character and the NULL.

The separateString function is unnecessarily complicated. It re-implements what the strtok() function does. Why not use professionally developed, tested functionality?


kerimil

Quote
You can. If Processing and the Arduino are connected to the same port
they are

It's not my code - it's an example provided with stepplab 3 library. Don't assume I am good at it - I am not.
Ohh and sending strings using command
myPort.Write("G 200") doesn't work
not sure why ?

I assume processing sends "G 200" as 'G' then '(space)' then '2' and finally two '0'.
Therefore arduino receives strings consisting of 5 chars 'G',' ','2','0','0'

PaulS

Quote
I assume processing sends "G 200" as 'G' then '(space)' then '2' and finally two '0'.
Therefore arduino receives strings consisting of 5 chars 'G',' ','2','0','0'

That's exactly the way that it works.

The receive function on the Arduino is collecting the characters back into a string. However that function expects the incoming data to be terminated by a , *, carriage return, or line feed - none of which you are sending.

Try myPort.Write("G 200*") instead.

kerimil

Perfect! it works

Now what do I do if I want to send "G " as a string and then the value of a varible and finally end it with '*'



PaulS

Quote
Now what do I do if I want to send "G " as a string and then the value of a varible and finally end it with '*'

Code: [Select]
int val = 36;
myPort.write("G ");
myPort.write(val);
myPort.write("*");

kerimil

#6
Oct 16, 2011, 08:08 pm Last Edit: Oct 16, 2011, 08:45 pm by kerimil Reason: 1
Yup it works. I realized I have to convert int to string to get this to work right.

Code: [Select]
val = (mouseX);

myPort.write("G ");
myPort.write(str(val));
myPort.write("*");


Thx I spent like 10 hours trying to work this out. I was expecting that carriage return might have somethign to do with it but I couldn't find anything on that

anyway I am posting the processing code I used... maybe someone will have exactly the same problem

Code: [Select]

import processing.serial.*;
int val;

Serial myPort;  // Create object from Serial class


void setup()
{
  size(1000, 200);
 
 
  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 115200);
    println(Serial.list());
   
}

void draw() {

  background(255);
 

val = (mouseX);
println(val);
float val1;
val1 = map(val, 0, 500, -800, 0);
myPort.write("G ");
myPort.write(str(val1));
myPort.write("*");


  }

Go Up