UPDATED CODE HERE
Hello! as you can probably tell, my last post was written in a fury of incoherency, but I needed to get the code out there so it is what it is.
The main focus of this post is to showcase the arduino program. The visual basic in the video is very simple, and there will be much more on that later.
This below program will take a string of characters fed to the arduino and split them into usable parts. This is a very valuable tool for working with serial and arduino. It’s pretty well commented, but if you have any questions, PLEASE leave a comment. I’d love to see some conversation here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
const char EOPmarker = '.'; //This is the end of packet marker char serialbuf[32]; //This gives the incoming serial some room. Change it if you want a longer incoming. #include // we'll need this for subString #define MAX_STRING_LEN 20 // like 3 lines above, change as needed. #include //we'll need this for the lcd LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //pins for the lcd, I set it up using the ladyada tutorial. void setup(){ lcd.begin(16, 2); Serial.begin(9600); //changing this to other speeds has not been tested using this meathod } void loop() { if (Serial.available() > 0) { //makes sure something is ready to be read lcd.clear(); //clears for incoming stuff, won't clear if there isin't data to be read static int bufpos = 0; //starts the buffer back at the first position in the incoming serial.read char inchar = Serial.read(); //assigns one byte (as serial.read()'s only input one byte at a time if (inchar != EOPmarker) { //if the incoming character is not the byte that is the incoming package ender serialbuf[bufpos] = inchar; //the buffer position in the array get assigned to the current read bufpos++; //once that has happend the buffer advances, doing this over and over again until the end of package marker is read. } else { //once the end of package marker has been read serialbuf[bufpos] = 0; //restart the buff bufpos = 0; //restart the position of the buff lcd.write(subStr(serialbuf, ",", 1)); //witres the first bit of content before the first comma (or other seperator) to the lcd. You could also do math or anything else with these. You could use atoi to change them to integers. lcd.write("|separator|"); //this signifies that the first seperation has occured lcd.write(subStr(serialbuf, ",", 2)); //same thing as 2 lines above, but with the second parts. this can be repeated } } } // below is just function logic, which I do not fully understand. but it works. char* subStr (char* input_string, char *separator, int segment_number) { char *act, *sub, *ptr; static char copy[MAX_STRING_LEN]; int i; strcpy(copy, input_string); for (i = 1, act = copy; i <= segment_number; i++, act = NULL) { sub = strtok_r(act, separator, &ptr); if (sub == NULL) break; } return sub; } //esologic.com //Thanks to http://arduino.cc/forum/index.php?topic=119429 |
So for example if you inputted
[code]
123,456.
[/code]
it would output
[code]
123|separator|456
[/code]
to the lcd, or the serial monitor if you tweaked the code.
Now for the code in the video. The only different part about this is that it writes the two values to the servos.
1 |
const char EOPmarker = ‘.’; //This is the end of packet marker
char serialbuf[32]; //This gives the incoming serial some room. Change it if you want a longer incoming.
#include // we’ll need this for subString
#define MAX_STRING_LEN 20 // like 3 lines above, change as needed.
#include //we’ll need this for the lcd
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //pins for the lcd, I set it up using the ladyada tutorial.
#include
Servo left_servo;
Servo right_servo;
int left_servo_pos;
int right_servo_pos;
void setup(){
lcd.begin(16, 2);
left_servo.attach(2);
right_servo.attach(3);
Serial.begin(9600); //changing this to other speeds has not been tested using this meathod
}
void loop() {
if (Serial.available() > 0) { //makes sure something is ready to be read
lcd.clear(); //clears for incoming stuff, won’t clear if there isin’t data to be read
static int bufpos = 0; //starts the buffer back at the first position in the incoming serial.read
char inchar = Serial.read(); //assigns one byte (as serial.read()’s only input one byte at a time
if (inchar != EOPmarker) { //if the incoming character is not the byte that is the incoming package ender
serialbuf[bufpos] = inchar; //the buffer position in the array get assigned to the current read
bufpos++; //once that has happend the buffer advances, doing this over and over again until the end of package marker is read.
}
else { //once the end of package marker has been read
serialbuf[bufpos] = 0; //restart the buff
bufpos = 0; //restart the position of the buff
left_servo_pos = atoi(subStr(serialbuf, “,”, 1));
lcd.write(“Left Servo:”);
lcd.write(subStr(serialbuf, “,”, 1)); //witres the first bit of content before the first comma (or other seperator) to the lcd
left_servo.write(left_servo_pos);
lcd.setCursor(0, 1);
right_servo_pos = atoi(subStr(serialbuf, “,”, 2));
lcd.write(“Right Servo:”); //this signifies that the first seperation has occured
lcd.write(subStr(serialbuf, “,”, 2)); //same thing as 2 lines above, but with the second parts. this can be repeated
right_servo.write(right_servo_pos);
}
}
}
// below is just function logic, which I do not fully understand. but it works.
char* subStr (char* input_string, char *separator, int segment_number) {
char *act, *sub, *ptr;
static char copy[MAX_STRING_LEN];
int i;
strcpy(copy, input_string);
for (i = 1, act = copy; i <= segment_number; i++, act = NULL) {
sub = strtok_r(act, separator, &ptr);
if (sub == NULL) break;
}
return sub;
}
//esologic.com
//Thanks to http://arduino.cc/forum/index.php?topic=119429