for 32-bit difference machine i developed a simple firmware on the arduino side to control two servo motors and one. it had to be lightweight and fast, to withstand continual changes at 10-30fps.
here is a video of the piece working built on the 64-bits wks day (may14th) @ who galeria during my 64-bits exihibit.
32-bit difference machine - motionpainting from Andre Sier on Vimeo.
the arduino code listens for continual changes in x and y pos, sometimes ink power changes. the blobs traffic is being logged realtime @ uunniivveerrssee.net so that a special hack can take place during upcoming work (thanks, tiago;). if you do stop by the gallery, please move as you wish in front of the camera!
since it's computer vision controlling the robot (through my flob library and processing), there is a lot of messages per frame, i think i am in the borderline of flooding the serial line, because very sporadically (once every 10minutes of continuous action or so) the power doesn't switch off. perhaps i can fix it simply by echoing more zeros, you know, just to be sure the zero power message which is sent only once, wasn't lost, by opposition of the x and y messages which fill up 97+% of the serial pipeline
this is the code i developed, with debug activated.
the serial protocol takes messages like 'x0127,', and only these kinds of messages. there is a char that selects the value to change, the value, and the comma to indicate end of message. simple and fast.
rest:
#include <Servo.h>
// 32-bits difference machine -- arduino firmware mydebugv
// AS, mar2011
// for messages like "x9999," comma terminated // x0180, // y0070, // p0800, // p1023,byte incomingByte = 0; // for incoming serial data
byte messagein[5] = {
0, 0, 0, 0, 0 }; // comand byte1 byte2 byte3 byte 5
int messageidx = 0;
byte messagereset[5] = {
0, 0, 0, 0, 0 }; // comand byte1 byte2 byte3 byte 5int vals[3] = {
0,0,0};Servo xservo, yservo;
#define XSERVOPIN 10
#define YSERVOPIN 11
#define POWERHIGH 6
#define POWERLOW 5void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode(13,OUTPUT);
pinMode(POWERHIGH,OUTPUT);
pinMode(POWERLOW,OUTPUT);
xservo.attach(XSERVOPIN);
yservo.attach(YSERVOPIN);
zero();
establishContact();
}void loop() {
delay(5);// process into message array
while (Serial.available() > 0) {
incomingByte = Serial.read();
// Serial.print("got ");
// Serial.print(incomingByte);
// Serial.print(" ");
// Serial.println(messageidx);if(incomingByte == ','){ //terminator,
// process message here
switch(messagein[0]){
case 'x':
vals[0] = toInt1000(messagein);
writeXservo(vals[0]);
Serial.println("execed x");break;
case 'y':
vals[1] = toInt1000(messagein);
writeYservo(vals[1]);
Serial.println("execed y");
break;
case 'p':
vals[2] = toInt1000(messagein);
writePower(vals[2]);
Serial.println("execed p");
break;
// default: break;}
//debug
Serial.print("message: ");
for(int i=0;iSerial.print(messagein[i]);
}
Serial.println();//debug
Serial.print("values: ");
for(int i=0;i<3;i++){
Serial.print(vals[i],DEC);
Serial.print(" ");
}
Serial.println();//reset
messageidx = 0;
break;//
}
else {
messagein[messageidx] = incomingByte;
messageidx=(messageidx+1)%5; //++;
}}
}
void writePower(int val){
digitalWrite(POWERLOW, 0);
analogWrite(POWERHIGH, val);
}void writeXservo(int val){
xservo.write(val);
delay(25);
}
void writeYservo(int val){
yservo.write(val);
delay(25);
}int toInt1000(byte* b){
int v = 0;
v += ((b[1]-48)*1000);
v += ((b[2]-48)*100);
v += ((b[3]-48)*10);
v += (b[4]-48);
return v;
}void establishContact() {
while (Serial.available() <= 0) {
Serial.print('A', BYTE); // send a capital A
delay(300);
}
}void zero(){
writeXservo(0);
writeYservo(100);
writePower(0);
}
then from other programs i can link up to the arduino and send the robot data. this will come handy for other stuff..
here is a simple p5 example to talk to this firmware
// test 32b dif mach
// as - mar 2011import processing.serial.*;
Serial serial;
void setup() {
serial = new Serial(this, Serial.list()[0], 9600);
sendMessage('x',25);
sendMessage('y',25);
sendMessage('p',255);
delay(1500);
sendMessage('p',0);
sendMessage('x',145);
sendMessage('y',125);
sendMessage('p',255);
delay(1500);
sendMessage('p',0);
}void sendMessage(char om, int val){
char[] message = {om,0,0,0,0,55};
String valstr = nf(val,4);
for(int i=0; i<4;i++){
message[i+1] = valstr.charAt(i);
}
// println(message);
// println(valstr);
for(int i=0; i < message.length; i++){
serial.write(message[i]);
}
}
the 32-bit difference machine installation consists of 1 ps3 camera sending frames to 1 computer sending serial to 1 motoruino controlling an old car water system and a couple of servos with a head mounted endian ink gun (the 'bot). using the motoruino made it easier to deploy the final bot, 'cause i simply used a 12v power src with a 5v regulator for the servos and the motoruino controls the internal lm293 h-bridge to feed power to the water-ink system. a word of thanks to guilherme martins, for building the motoruino and helping me with the circuitry. it was very fast to deploy this code on this hardware, mostly just patching the connections instead of loosing time to build an arduino base shield with all the electronics of the regulator, hbridge, and all these links.
hope you enjoy the code and that is somewhat useful. let me know if it helps, if you find huge improvements!;)