Pages: [1]   Go Down
Author Topic: Sending data from processing to arduino  (Read 1533 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I'm trying to send data from a processing sketch to my Arduino Uno, using serial, in order to control the speeds of two motors, that need to run at separate speeds. I'm using the controlP5 library for processing with two sliders ranging from 0 to 255. What I would like to achieve is for my computer to send data prefixed by 'L' or 'R' to indicate the motor and the value of the speed desired, e.g 'L127'.

I have been looking for a while and I can't figure how to do this. I'm not fully sure of the difference between strings and bytes or which would be better for my task?

If you could point me in the direction of two things that would be great:

1. How to send this data from processing?
2. How to interpret this data on the arduino, so basically decide which motor to affect by the 'L' or 'R' and then apply the value.

Thanks in advance,

Fin
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
1. How to send this data from processing?
You have an instance of the SerialPort class? It has a write() method that can be used to send data the serial port.

Quote
What I would like to achieve is for my computer to send data prefixed by 'L' or 'R' to indicate the motor and the value of the speed desired, e.g 'L127'.
I'd recommend changing the order. "127L" tells you that you can stop reading when you get an L or R. With the L or R on the front, when do you stop reading?

The atoi() function will convert "127L" to an integer value, 127. "L127" is harder to deal with. Not much harder, but why make it any harder than it needs to be?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
1. How to send this data from processing?
You have an instance of the SerialPort class? It has a write() method that can be used to send data the serial port.

I'm happy with this, I have the serial communication working fine. Would I type: myPort.write(Right + 'L') where Right is the value between 0-255?

Quote
The atoi() function will convert "127L" to an integer value, 127.

I'm reasonably new to Arduino, so bear with me! Would I initialize an integer for the motor speed and use for example "rightmotorspeed = atoi (serialreadvalue)"? How would I then determine between the left and right motor? What function would be required for this?

Thanks for your help!  smiley
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Would I initialize an integer for the motor speed and use for example "rightmotorspeed = atoi (serialreadvalue)"?
That depends on that serialreadvalue is. If it is an array of chars, and is properly null terminated, yes. If not, no.

Quote
How would I then determine between the left and right motor? What function would be required for this?
Again, this depends on how you are getting the serial data. If the data is stored in a NULL terminated array of chars, then strlen() on that array will give the length. The upper index is then one less than the length. The character at that position will be 'L' or 'R'.

Code:
char inData[16];
byte index = 0;
// some code to fill the array
int servoVal = atoi(inData);
char servoLtr = inData[index-1];

If you send "147R", then inData will contain "127R\0", index will be 4, servoVal will be 127, and servoLtr will be inData[3], or 'R'.
Logged

Miami/Florida
Offline Offline
Sr. Member
****
Karma: 14
Posts: 350
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

On Processing:

//Define your variables here
import processing.serial.*;                 //imports serial library
int Com=0;                                         //Sets which Port from the list will be used.

void setup()
{
size(Width,Height);
frameRate(30);
blah; //whatever else you may need here.
blah;//whatever else you may need here
CPort = new Serial(this, Serial.list()[Com], 115200);              //Define CPort and baud rate here.
SendOrderToArduino();
}

void draw()
{
blah; //Your things here.
blah;
blah;
}


void SendOrderToArduino()
{
if(you want motor to move left==true)
{
Order=5;
}
if(you want motor to move right==true)
{
Order=10;
}
CPort.write(order);
}


On Arduino:
void setup()
{
blah;
blah;
Serial.begin(115200); //begins serial Communication with computer at 115200 bps.
}

void loop()
{
CheckOrder();
}

void CheckOrder()
{
if(Serial.available()>0)
{
Order=Serial.read();
if(Order==5)
{
MoveMotorLeft();
}
if(Order==10)
{
MoveMotorRight();
}
Order=0;
}


Logged

Perseverance is 90% of the solution. The remaining 10% is more perseverance.

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys,

Thanks for all your help so far. I'm trying to use the atoi function as suggested by PaulS, but I'm having some problems.
I've decided to send the data from Processing to the arduino in this format: "127,255" with 127 and 255 being the speeds of the left and right motor respectively, so it only sends one bunch of serial data for both motors.

This may sound a bit cheeky, but can you see any problems with my code, unfortunately I don't have my Arduino at home at the moment, and I'm dying to know whether it will work!

Code:
#include <AFMotor.h>
AF_DCMotor rightmotor1(1);
AF_DCMotor rightmotor2(3);
AF_DCMotor leftmotor1(2);
AF_DCMotor leftmotor2(4);

String leftmotor;
String rightmotor;

int Leftmotor;
int Rightmotor;

int index = 0;
String serialval = "";
char inChar;

void setup() {

Serial.begin(9600);
rightmotor1.setSpeed(0);
rightmotor2.setSpeed(0);
leftmotor1.setSpeed(0);
leftmotor2.setSpeed(0);
}

void loop() {

while (Serial.available() > 0) { 
inChar = (char)Serial.read();
serialval += inChar;
}

index = serialval.indexOf(",");

leftmotor =  serialval.substring(0, index);
rightmotor = serialval.substring(index + 1);

Leftmotor = leftmotor.toInt();
Rightmotor = rightmotor.toInt();

rightmotor1.setSpeed(Rightmotor);
rightmotor2.setSpeed(Rightmotor);
leftmotor1.setSpeed(Leftmotor);
leftmotor2.setSpeed(Leftmotor);
}
« Last Edit: February 28, 2013, 01:22:27 pm by fin3rz » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but can you see any problems with my code
Yes. You assume that what is in the serial buffer is a complete packet, and only a single packet. Not good assumptions to be making.

You are using the String class, to avoid learning about C strings (NULL terminated arrays of chars). Not a good idea with the present issues with the String class.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think I understand what you mean, but I don't know know how to go about rectifying it, could you suggest some code that would help? Thanks for your help again!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 640
Posts: 50331
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to add a start of packet marker and an end of packet marker to what is sent. Instead of sending "100, 150", for instance, send "<100, 150>". Then, use code like this:
                                                                                                                   
Code:
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
To read the data. Where it says "Process the packet" is where you should use strtok() and atoi() to extract "100" and "150" as tokens, and convert them to 100 and 150.
Logged

Pages: [1]   Go Up
Jump to: