Go Down

Topic: Sending Full Words from Serial Monitor (Read 4838 times) previous topic - next topic

zoomkat

Quote
Just in case you were wondering, here's my code. The goal of this project is to make a serial controlled RC car.
I can't seem to figure out what's wrong with it.


I suggest you start over from scratch, starting with explaining how the arduino sends commands that make your motors operate (do you have a motor controller?). I think what I've seen is overly complicated for what you are trying to do.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

andrewf

#46
Jun 10, 2011, 02:12 am Last Edit: Jun 10, 2011, 02:14 am by andrewf Reason: 1
I would try to do that, but I can't seem to figure out a method for sending a packet. PaulS helped me out a TON with all the serial reading and parsing. I am not sure if that part just needs refinement, or if everything needs refinement.
I don't quite see the point of this bit of code thought

Code: [Select]
if(index < 30)
    {
      inData[index] = inByte;
      inData[index+1] = '\0';
    }


zoomkat

Quote
I would try to do that, but I can't seem to figure out a method for sending a packet.


Well, early on I posted the below which shows how to send a "packet" containing data using the serial monitor, parsing the packet for the desired data, and creating an integer value from a string value in the packet. If you have control of the format of the data to send to the arduino, you should be able to simplify things over what you are trying now. Have you made code that causes your motor to operate sending a single character? If so, post it as that may clear up some of the mystery of your motor control hardware.

http://arduino.cc/forum/index.php/topic,62526.msg453217.html#msg453217
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

andrewf

Yesterday I was playing around a little bit and came to this. All I enter is "r".


Code: [Select]
#include <AFMotor.h>

AF_DCMotor motor1(1);
char rout = 'a';

void setup()
{
  Serial.begin(9600);
  Serial.println("Motor 1 running.");
}

void loop()
{
  rout = Serial.read();
  if(rout == 'r')
  {
  motor1.setSpeed(255);
  motor1.run(FORWARD);
  delay(10000);
  motor1.run(RELEASE);
  Serial.println("Run complete.");
  }
}

andrewf

Koomkat -- Your code does not seem to apply to what I am doing. I am trying to take a string separated by commas with the direction followed by the speed followed by the duration. Your code just takes one long number which encompasses two values. I don't see how that would apply to a word being included in my packet.

zoomkat

Quote
I don't see how that would apply to a word being included in my packet.


Well, from this statement, you probably need to drop back to basics. I would think that sending a string like 2r0807500, where 2 is the motor to control, r is to run it in reverse, 080 would be the speed 80 for it to run, and 7500 would be the delay of 7.5 sec., would be easier to work with. A string like this can easily be captured, the data parts captured into variables using string functions, and then the commands processed by "AFMotor", what ever that is. I think you would easier understand simple string operations than the 48 previous "array" post that have not produced working code.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

zoomkat

Try the below approach with the serial monitor. Works with windows, YMMV with another OS.

Code: [Select]

// send a string like 1r0807500 or 3f25510000 containing motor data

String readString, mt, dr, sd, dy;

void setup() {
  Serial.begin(9600);
  Serial.println("motor-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1); 
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {
      Serial.println(readString); //see what was received
     
      // expect a string like 1r0807500 containing motor data     
      mt = readString.substring(0, 1);
      dr = readString.substring(1, 2);
      sd = readString.substring(2, 5);
      dy = readString.substring(5, 10);
     
      Serial.println("======string data==============");
      Serial.println();
      Serial.println(mt);  //print to serial monitor to see results
      Serial.println(dr);
      Serial.println(sd);
      Serial.println(dy);
      Serial.println();
      Serial.println("======conversions==============");
      Serial.println();
     
      Serial.println("motor moving is " + (mt));
      if (dr == 'r') dr = "reverse";
      if (dr == 'f') dr = "foward";
      Serial.println("motor direction is " + (dr));
     
     
      int n1; //declare as number 
      int n2;
     
      char carray1[10]; //magic needed to convert string to a number
      sd.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1);
      Serial.print("motor speed is ");
      Serial.println(n1);
     
      char carray2[10];
      dy.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2);
      Serial.print("motor delay is ");
      Serial.println(n2);
     
    readString="";
  }
}

Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

zoomkat

I have no way to test this, but you can try it to see if you can control speed and direction of motor 1.

Code: [Select]

// send a string like 1r0807500 or 3f25510000 containing motor data
#include <AFMotor.h>
AF_DCMotor motor1(1);

String readString, mt, dr, sd, dy;

void setup() {
  Serial.begin(9600);
  Serial.println("motor-test-21"); // so I can keep track of what is loaded
  Serial.println("Motor 1 running.");
}

void loop() {

  while (Serial.available()) {
    delay(1); 
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {
      Serial.println(readString); //see what was received
     
      // expect a string like 1r0807500 containing motor data     
      mt = readString.substring(0, 1);
      dr = readString.substring(1, 2);
      sd = readString.substring(2, 5);
      dy = readString.substring(5, 10);
     
      Serial.println("======string data==============");
      Serial.println();
      Serial.println(mt);  //print to serial monitor to see results
      Serial.println(dr);
      Serial.println(sd);
      Serial.println(dy);
      Serial.println();
      Serial.println("======conversions==============");
      Serial.println();
     
      Serial.println("motor moving is " + (mt));
      if (dr == 'r') dr = "REVERSE";
      if (dr == 'f') dr = "FOWARD";
      Serial.println("motor direction is " + (dr));
     
     
      int n1; //declare as number 
      int n2;
     
      char carray1[10]; //magic needed to convert string to a number
      sd.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1);
      Serial.print("motor speed is ");
      Serial.println(n1);
     
      char carray2[10];
      dy.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2);
      Serial.print("motor delay is ");
      Serial.println(n2);
     
      motor1.setSpeed(n1);
      motor1.run(dr);
      delay(n2);
      motor1.run(RELEASE);
      Serial.println("Run complete.");

      readString="";
  }
}

Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

andrewf

#53
Jun 10, 2011, 03:24 pm Last Edit: Jun 10, 2011, 08:16 pm by andrewf Reason: 1
I took what you said into consideration. I totally redid the code (with a lot of help from your code  XD). I am about to test it. It looks pretty good. I decided it was a better idea to have one string. It simplifies everything.
In case you were wondering, the AFMotor.h library is for the Adafruit motor shield.
Here is my code:

Code: [Select]
#include <AFMotor.h>

String readString, mdirection, mspeed, duration;

AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

int rightLEDs = 9;
int leftLEDs = 10;


void setup()
{
  pinMode(rightLEDs, OUTPUT);
  pinMode(leftLEDs, OUTPUT);
  digitalWrite(rightLEDs, HIGH);
  digitalWrite(leftLEDs, HIGH);
  Serial.begin(9600);
  Serial.println("RC Car Project Mark II connected.");
}

void loop()
{
  while (Serial.available())
  {
    delay(1); 
    if (Serial.available() > 0)
    {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c;         //makes the string readString
    }
  }

  if (readString.length() > 0)
  {
    // expect a string like f20005000 containing the direction, speed, and duration     
    mdirection = readString.substring(0, 1); //get the first one characters
    mspeed = readString.substring(1, 4);     //get the next three characters
    duration = readString.substring(4, 9);
   
    if(mdirection == 'f') mdirection = "FORWARD";
    if(mdirection == 'r') mdirection = "REVERSE";

    int n1;
    int n2;

    char carray1[9];
    mspeed.toCharArray(carray1, sizeof(carray1));
    n1 = atoi(carray1);

    char carray2[9];
    duration.toCharArray(carray2, sizeof(carray2));
    n2 = atoi(carray2);

    if(mdirection == "FORWARD")
    {
      Serial.print("Running forward at " + (n1));
      Serial.print(" / 255 speed for " + (n2 / 1000));
      Serial.println(" seconds.");
      motor1.setSpeed(n1);
      motor2.setSpeed(n1);
      motor3.setSpeed(n1);
      motor4.setSpeed(n1);
     
      motor1.run(FORWARD);
      motor2.run(FORWARD);
      motor3.run(FORWARD);
      motor4.run(FORWARD);
     
      delay(n2);
     
      motor1.run(RELEASE);
      motor2.run(RELEASE);
      motor3.run(RELEASE);
      motor4.run(RELEASE);
    }
     
    if(mdirection == "REVERSE")
    {
      Serial.print("Running backwards at " + (n1));
      Serial.print(" / 255 speed for " + (n2 / 1000));
      Serial.println(" seconds.");
      motor1.setSpeed(n1);
      motor2.setSpeed(n1);
      motor3.setSpeed(n1);
      motor4.setSpeed(n1);
     
      motor1.run(BACKWARD);
      motor2.run(BACKWARD);
      motor3.run(BACKWARD);
      motor4.run(BACKWARD);
     
      delay(n2);
     
      motor1.run(RELEASE);
      motor2.run(RELEASE);
      motor3.run(RELEASE);
      motor4.run(RELEASE);
    }
   
    readString="";
  }
}

andrewf


zoomkat

Quote
Tested! Works like a charm!


That's good to hear. Now that you have something fairly simple that works, you can experiment with the code.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

andrewf


Waruma

Zoomkat -

I've been trying to follow what your code you posted above is doing.  I think I'm understanding it finally.  My question is why does it work in the Arduino serial monitor, but it won't work any other serial monitor windows I try.  I'd like to be able to communicate serially to my Arduino, but I don't necessarily want to open up a sketch just to get to the Arduino serial monitor...  Any suggestions?

Code: [Select]

// zoomkat 8-6-10 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;


void setup() {
Serial.begin(9600);
        pinMode(13, OUTPUT);
        Serial.println("serial test 0021"); // so I can keep track of what is loaded
        }

void loop() {

        while (Serial.available()) {
        delay(1); 
    char c = Serial.read();
        readString += c;
        }
       
      if (readString.length() >0) {
      Serial.println(readString);
     
    if (readString == "on") {
digitalWrite(13, HIGH);
        Serial.println("Led On");
    }
   if (readString == "off") {
digitalWrite(13, LOW);
        Serial.println("Led Off");
    }
        readString="";
   }
}


Thanks,

PaulS

Quote
My question is why does it work in the Arduino serial monitor, but it won't work any other serial monitor windows I try.

It really would help if you described what other serial monitor windows you are referring to, on what OS, and what you type and what the Arduino seems to see.

zoomkat

Quote
but it won't work any other serial monitor windows I try.


More than likely your other serial monitor sends the individual characters as you type them instead of all at once when you hit the enter key.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Go Up