
Updating the Versalino Rove Controller Sketch to accept 4 Byte VirtuabotixPackets
So some of you may have been wondering about the VirtuabotixPacket theme that a lot of my recent posts have been following. The Versalino Rove is one of the big projects that I developed the packet system for, and after spending most of yesterday working on the latest control sketch I finally have a rover controller sketch that accepts packets readily.
If you aren’t familiar with it, the Versalino Rove is a system that I developed around the Versalino Uno (an Arduino Compatible board that I designed a while back) to make for a modular and extendable robotics platform that you can use as a rover, or take apart to turn into a number of other awesome projects.
Up until this point the Versalino Rove has used a simple set of single byte commands for it’s operations, and for the most part there haven’t really been any problems doing things that way. That is until the challenge of integrating analog controls (like an analog stick on the Versalino Control board) reared it’s ugly head. That, and some research into some existing Android based control apps I chose to change the VirtuabotixPacket system to include an additional byte to allow 4 byte messages, and to replace the entire rover control system with one that is packet based.
[wdsm_ad id=”89″ class=” ” ]
Pretty much all of the code in the Rover Controller sketch was kept the same, but there were some crucial changes made to the top and the entire checkCommands() function was rewritten (honestly more simply) to achieve the new functionality. Below is what was added to the header area of the Versalino Rove Controller sketch:
//######################## PACKETPROCESSING STUFF
#include
char conversionBuffer[5];//this is where we will store our ASCII data
//remember you always need to be at least 1 more than your number of characters
//so that you can store a null character to indicate the end of the string.
int myLeftrate=0;//this is where we will store the left conversion
int myRightrate=0;//this is where we will store the right conversion
struct VirtuabotixPacket {
boolean received;
char target;
char msg1;
char msg2;
char msg3;
char msg4; //this is where we add the new message byte.
};
VirtuabotixPacket myPacket;
boolean listenforcommand()
{
if(Serial.available() >=7) //this line was >= 6 we changed it to >= 7
{
if(Serial.read()=='|' && Serial.read()=='|')
{
myPacket.received=true;
myPacket.target=Serial.read();
myPacket.msg1=Serial.read();
myPacket.msg2=Serial.read();
myPacket.msg3=Serial.read();
myPacket.msg4=Serial.read();//<-added
//We added the line above to read in the extra message byte into msg4.
}
else myPacket.received=false;
} else myPacket.received=false;
return myPacket.received;
}
//################################## END PACKETPROCESSING STUFF
Basically this is all of the code required to import the proper ASCII to INT libraries, and additionally the code required to store and decode 4 byte message VirtuabotixPacket data for use later in our code. The only items in the code above that aren't gone over in detail in any of the recent packet guides would be the myLeftrate, and myRightrate integers which are simply places to store the most recent speeds received for our motors (right and left).
Below is the code that replaces the entire checkCommands() function from the old Versalino Controller sketch. If you look you will notice that we follow the standard while(listenforcommands()) loop that we made in our first VirtuabotixPacket article, and we only have 3 targets listed R, L, and A where R packets controls the right wheel, L packets control the left Wheel, and A packets controls the AI (for now just turning it on and off or toggling it).
void checkCommands()
{
while(listenforcommand())//loop while messages are still in the queue
{
if (myPacket.received==true && myPacket.target=='R')
{
conversionBuffer[0]=myPacket.msg1;
conversionBuffer[1]=myPacket.msg2;
conversionBuffer[2]=myPacket.msg3;
conversionBuffer[3]=myPacket.msg4;
conversionBuffer[4]=0;
myRightrate = atoi(conversionBuffer);
myMotorMaster.drive(COILA, myRightrate);
Serial.print("Message received right");
Serial.println(myRightrate, DEC);
directControl=true;//set ourselves to direct control mode
}
if (myPacket.received==true && myPacket.target=='L')
{
conversionBuffer[0]=myPacket.msg1;
conversionBuffer[1]=myPacket.msg2;
conversionBuffer[2]=myPacket.msg3;
conversionBuffer[3]=myPacket.msg4;
conversionBuffer[4]=0;
myLeftrate = atoi(conversionBuffer);
myMotorMaster.drive(COILB, myLeftrate);
Serial.print("Message received Left ");
Serial.println(myLeftrate, DEC);
directControl=true; //set ourselves to direct control mode
}
if (myPacket.received==true && myPacket.target=='A')
{
if(myPacket.msg1=='T') directControl=!directControl;//toggle mode
if(myPacket.msg1=='E') directControl=false;//enable automatic mode
if(myPacket.msg1=='D') directControl=true;//disable automatic mode
}
}
}
[wdsm_ad id="89" ]
Now obviously changing the data type that the Versalino Rove can use means that the Versalino Rove application won't be able to control it anymore right? Well actually you will be able to type full strings into the Versalino Rove application on the "control" tab in the Set Serial Commands section within the next few hours, and I plan on adding a button to switch to packet mode or legacy mode to make things easier soon.

The next step is to write a control application to take input from the Versalino Control board and format that data into packets that are appropriate for controlling the rover.
Comment(4)
Comments are closed.
Just what I was looking for, thank you for posting.