My robot has servos, pwm controlled speed controllers and sensors. I would like to control the robot using an Arduino board that is connected via usb to a raspberry pi.
I currently have it running using firmata on the Arduino, and node-red on the pi. Works pretty slick, but I would like to do even better. I would like to run code on the Arduino, and firmata does not permit that.
I would like to continue to use node-red, as it permits the construction of a really nice web based dashboard for control of the robot.
Node-Red has various serial communication nodes, such as:
Input
Reads data from a local serial port.
It can either wait for a "split" character (default \n). Also accepts hex notation (0x0a).
wait for a timeout in milliseconds from the first character received
wait to fill a fixed sized buffer
It then outputs msg.payload as either a UTF8 ascii string or a binary Buffer object.
If no split character is specified, or a timeout or buffer size of 0, then a stream of single characters is sent - again either as ascii chars or size 1 binary buffers.
Output
Provides a connection to an outbound serial port.
Only the msg.payload is sent.
Optionally the new line character used to split the input can be appended to every message sent out to the serial port.
So, my question is, what format would be the most efficient for formatting serially encoded commands for movement and the return of data such as distance sensors, position sensors, etc?
How should I encode the serial data for commanding, lets say 20 different servos? Should it be a string of 20 pieces of data, of which say 19 are the same as the last time? Or a single unit that can be sorted upon receipt as to what servo it pertains to, and what position it should move to?
Is there going to be a significant speed difference in the various says of decoding the data serially?
Will having a serial read event impact the speed of the code such that sensor data, such as ping sensors, is not read correctly?
Rather than start writing code in the first way I can think of to make this work, anyone have any suggestions on the most efficient way to do this? Anyone know of any examples?
I have found the following example, but I'm not sure if his method was the fastest and less subject to delays in the code.
PART OF THE CODE:
void loop() {
String validCommands = "rsSeEwWbBcd"; // The valid commands we will accept for control
bool cmdComplete = false;
static int parm = 0;
static char command; // Command character
while ((Serial.available() > 0) & (!cmdComplete)) {
char ch = Serial.read();
if (ch != ',') { // Not a comma
if (ch >= '0' && ch <= '9') { // Accumulate the decimal parameter into parm if character read is numeric
parm = parm * 10 + ch - '0';
} else if (validCommands.indexOf(ch) != -1) {
command = ch; // If it's not numeric see if it is one of our valid commands
} else {
Serial.println("Invalid command");
}
} else {
cmdComplete = true; // When we get a comma the command is complete
}
}
if (cmdComplete) {
cmdComplete = false;
// Do the action depending on the character received.
switch (command) {
case 'r': // r just read the sensors and write their values to serial output, don't move
break;
case 's': // s moves the shoulder forwards
moveShoulder(FORWARD);
break;
case 'S': // S moves the shoulder backwards
moveShoulder(BACKWARD);
break;
case 'e': // e moves the elbow down
moveElbow(FORWARD);
break;
case 'E': // E moves the elbow up
moveElbow(BACKWARD);
break;
case 'w': // w moves the wrist down
moveWrist(FORWARD);
break;
case 'W': // W moves the wrist up
moveWrist(BACKWARD);
break;
case 'b': // b turns the base clockwise (looking down)
moveBase(FORWARD);
break;
case 'B': // B turns the base anti-clockwise (looking down)
moveBase(BACKWARD);
break;
case 'c': // c toggles the clamp open and closed
clamp();
break;
case 'd': // Set the duration of motor run time
duration = parm;
motorTime = motor[duration];
break;
default:
break;
}
readsensors(); // Read sensors and publish after every command
command = 'r'; // If user only specifies a number and a comma or just a comma pretend they meant r
parm = 0;
}
All credit for above code to "Jim's Blog"
http://jekw.co.uk/2014/01/06/arduino-code-for-the-robot-arm/