Need help, program won't work
Hi everyone, I am relatively new to this. I have the activity bot and I wrote a program to be used with the 2-axis joystick. I have an automated driving program that I would like to run in one cog, then, when I turn on the xbee transmitter, it will allow me to take over the robot and drive. Once I turn off the xbee transmitter, I want the robot to once again resume or restart the driving cog.
So far the program works to a point. When I turn on the robot, it starts with the automated driving sequence which will repeat indefinitely. I can then choose to turn on the xbee transmitter, and the cog_end function shuts down the driving cog, and then I can drive the robot however I wish. But when I turn off the transmitter, how do I get it to re-initiate the automatic driving sequence? I have tried plugging in the cog_run function in numerous places and it just won't do it. It seems like once I enter into the While(1) xbee loop, that's it, I can't get out. Please help! I am pulling my hair out after hours of trying to make it work hahaha
Here is the code below:
#include "simpletools.h" // Include libraries
#include "fdserial.h"
#include "abdrive.h"
#include "wavplayer.h"
#include "servo.h"
#include "ping.h"
fdserial *xbee;
int yep;
int turn;
void driving();
int main() // Main function
{
xbee = fdserial_open(9, 8, 0, 9600 ); // Begin the serial connection ( this is why we
// needed the jumper cables connected to pins 8 and 9 )
char data; // Create the variable that will be used to hold
int *cog = cog_run(driving, 128);
while (1) // Repeat this forever or until loss of power
{
data = fdserial_rxChar( xbee ); // Set data to the data received from the XBee board
if ( data == 'f' ) // If the data incoming is telling the robot to move forward
{
cog_end(cog);
drive_speed( -300, -300 ); // Move forward at 1/2 speed
}
else if ( data == 'b' ) // If the data incoming is telling the robot to move backward
{
cog_end(cog);
drive_speed( 50, 50 ); // Move backward at 1/2 speed
}
else if ( data == 'l' ) // If the data incoming is telling the root to turn left
{
cog_end(cog);
drive_speed( -100, 0 ); // Turn left in a spin turn at 1/2 speed
}
else if ( data == 'r' ) // If the data incoming is telling the robot to turn right
{
cog_end(cog);
drive_speed( 0, -100 ); // Turn right in a spin turn at 1/2 speed
}
else if ( data == 's' ) // If the data incoming is telling the robot to stop
{
cog_end(cog);
drive_speed( 0, 0 ); // Stop
}
}
}
void driving()
{
while(1)
{
yep = rand() %3;
if(yep == 0)
{
drive_speed(-100, -100);
pause(1000);
drive_speed(-64, -30);
pause(500);
drive_speed(64, -64);
pause(2000);
drive_speed(-50, -50);
pause(300);
drive_speed(50, 50);
pause(300);
drive_speed(-64, 64);
pause(2000);
drive_speed(64, 30);
pause(500);
drive_speed(100, 100);
pause(1000);
drive_speed(100, -100);
pause(3000);
drive_speed(-50, -50);
pause(500);
drive_speed(64, 0);
pause(700);
drive_speed(0, 64);
pause(700);
drive_speed(-50, -50);
pause(1000);
drive_speed(50, 50);
pause(1000);
drive_speed(0, -64);
pause(700);
drive_speed(-64, 0);
pause(700);
drive_speed(50, 50);
pause(500);
drive_speed(-100, 100);
pause(3000);
}
if(yep == 1)
{
drive_speed(-10, -30);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(10, 30);
pause(1000);
drive_speed(-30, -10);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(30, 10);
pause(1000);
}
if(yep == 2)
{
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(670);
drive_speed(15, 5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(-15,-5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(5, 15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(500);
drive_speed(-5,-15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
}
}
}
So far the program works to a point. When I turn on the robot, it starts with the automated driving sequence which will repeat indefinitely. I can then choose to turn on the xbee transmitter, and the cog_end function shuts down the driving cog, and then I can drive the robot however I wish. But when I turn off the transmitter, how do I get it to re-initiate the automatic driving sequence? I have tried plugging in the cog_run function in numerous places and it just won't do it. It seems like once I enter into the While(1) xbee loop, that's it, I can't get out. Please help! I am pulling my hair out after hours of trying to make it work hahaha
Here is the code below:
#include "simpletools.h" // Include libraries
#include "fdserial.h"
#include "abdrive.h"
#include "wavplayer.h"
#include "servo.h"
#include "ping.h"
fdserial *xbee;
int yep;
int turn;
void driving();
int main() // Main function
{
xbee = fdserial_open(9, 8, 0, 9600 ); // Begin the serial connection ( this is why we
// needed the jumper cables connected to pins 8 and 9 )
char data; // Create the variable that will be used to hold
int *cog = cog_run(driving, 128);
while (1) // Repeat this forever or until loss of power
{
data = fdserial_rxChar( xbee ); // Set data to the data received from the XBee board
if ( data == 'f' ) // If the data incoming is telling the robot to move forward
{
cog_end(cog);
drive_speed( -300, -300 ); // Move forward at 1/2 speed
}
else if ( data == 'b' ) // If the data incoming is telling the robot to move backward
{
cog_end(cog);
drive_speed( 50, 50 ); // Move backward at 1/2 speed
}
else if ( data == 'l' ) // If the data incoming is telling the root to turn left
{
cog_end(cog);
drive_speed( -100, 0 ); // Turn left in a spin turn at 1/2 speed
}
else if ( data == 'r' ) // If the data incoming is telling the robot to turn right
{
cog_end(cog);
drive_speed( 0, -100 ); // Turn right in a spin turn at 1/2 speed
}
else if ( data == 's' ) // If the data incoming is telling the robot to stop
{
cog_end(cog);
drive_speed( 0, 0 ); // Stop
}
}
}
void driving()
{
while(1)
{
yep = rand() %3;
if(yep == 0)
{
drive_speed(-100, -100);
pause(1000);
drive_speed(-64, -30);
pause(500);
drive_speed(64, -64);
pause(2000);
drive_speed(-50, -50);
pause(300);
drive_speed(50, 50);
pause(300);
drive_speed(-64, 64);
pause(2000);
drive_speed(64, 30);
pause(500);
drive_speed(100, 100);
pause(1000);
drive_speed(100, -100);
pause(3000);
drive_speed(-50, -50);
pause(500);
drive_speed(64, 0);
pause(700);
drive_speed(0, 64);
pause(700);
drive_speed(-50, -50);
pause(1000);
drive_speed(50, 50);
pause(1000);
drive_speed(0, -64);
pause(700);
drive_speed(-64, 0);
pause(700);
drive_speed(50, 50);
pause(500);
drive_speed(-100, 100);
pause(3000);
}
if(yep == 1)
{
drive_speed(-10, -30);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(10, 30);
pause(1000);
drive_speed(-30, -10);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(30, 10);
pause(1000);
}
if(yep == 2)
{
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(670);
drive_speed(15, 5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(-15,-5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(5, 15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(500);
drive_speed(-5,-15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
}
}
}
Comments
Please take a look at what I did below and help me to understand why this will not work. The program loads fine, and the robot drives. When I hit backwards, it initiates the automated sequence, but when I press forward the cog does not end. So even though I can drive, the motion keeps getting interrupted by the simultaneous running of the cog. Does what am I saying make sense?
In other words, I made an int cog, then put cog_run under the "b" value and cog_end under the "f" value. The cog starts fine when I hit backwards, but won't END when I hit forward. What gives??
See below..
#include "simpletools.h"
#include "fdserial.h"
#include "abdrive.h"
#include "wavplayer.h"
#include "servo.h"
#include "ping.h"
fdserial *xbee;
int yep;
int turn;
int cog;
void driving();
int main()
{
xbee = fdserial_open(9, 8, 0, 9600 );
char data;
while (1)
{
data = fdserial_rxChar( xbee );
if ( data == 'f' )
{
cog_end(cog);
drive_speed( -300, -300 );
}
else if ( data == 'b' )
{
int *cog = cog_run(driving, 128);
}
else if ( data == 'l' )
{
drive_speed( -100, 0 );
}
else if ( data == 'r' )
{
drive_speed( 0, -100 );
}
else if ( data == 's' )
{
drive_speed( 0, 0 );
}
}
}
void driving()
{
while(1)
{
yep = rand() %3;
if(yep == 0)
{
drive_speed(-100, -100);
pause(1000);
drive_speed(-64, -30);
pause(500);
drive_speed(64, -64);
pause(2000);
drive_speed(-50, -50);
pause(300);
drive_speed(50, 50);
pause(300);
drive_speed(-64, 64);
pause(2000);
drive_speed(64, 30);
pause(500);
drive_speed(100, 100);
pause(1000);
drive_speed(100, -100);
pause(3000);
drive_speed(-50, -50);
pause(500);
drive_speed(64, 0);
pause(700);
drive_speed(0, 64);
pause(700);
drive_speed(-50, -50);
pause(1000);
drive_speed(50, 50);
pause(1000);
drive_speed(0, -64);
pause(700);
drive_speed(-64, 0);
pause(700);
drive_speed(50, 50);
pause(500);
drive_speed(-100, 100);
pause(3000);
}
if(yep == 1)
{
drive_speed(-10, -30);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(10, 30);
pause(1000);
drive_speed(-30, -10);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(30, 10);
pause(1000);
}
if(yep == 2)
{
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(670);
drive_speed(15, 5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(-15,-5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(5, 15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(500);
drive_speed(-5,-15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
}
}
}
The link below shows how I did something like that.
forums.parallax.com/discussion/161769/activitybot-sirc-control-whiskers
The program drives the activitybot using a Sony remote. But if it hits something the function whisker (which is running all the time in its own cog) sets a flag (bumpflg) to 1 which tells the main cog to ignore any remote control commands while the whisker code is controlling the bot. When bumpflg is set to 0 the code below lets the remote control.
Hope this helps
Tom
#include "simpletools.h"
#include "fdserial.h"
#include "abdrive.h"
#include "wavplayer.h"
#include "servo.h"
#include "ping.h"
fdserial *xbee;
int yep;
int turn;
int *cogremote;
volatile int bumpflg;
void remote();
int Lspd, Rspd = 0;
int main()
{
bumpflg = 0;
cogremote = cog_run(remote, 100);
while(1)
{
yep = rand() %3;
if(yep == 0)
{
drive_speed(-100, -100);
pause(1000);
drive_speed(-64, -30);
pause(500);
drive_speed(64, -64);
pause(2000);
drive_speed(-50, -50);
pause(300);
drive_speed(50, 50);
pause(300);
drive_speed(-64, 64);
pause(2000);
drive_speed(64, 30);
pause(500);
drive_speed(100, 100);
pause(1000);
drive_speed(100, -100);
pause(3000);
drive_speed(-50, -50);
pause(500);
drive_speed(64, 0);
pause(700);
drive_speed(0, 64);
pause(700);
drive_speed(-50, -50);
pause(1000);
drive_speed(50, 50);
pause(1000);
drive_speed(0, -64);
pause(700);
drive_speed(-64, 0);
pause(700);
drive_speed(50, 50);
pause(500);
drive_speed(-100, 100);
pause(3000);
}
if(yep == 1)
{
drive_speed(-10, -30);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(10, 30);
pause(1000);
drive_speed(-30, -10);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(-15, -15);
pause(1000);
drive_speed(-30, -30);
pause(300);
drive_speed(0, 0);
pause(4000);
drive_speed(30, 30);
pause(300);
drive_speed(15, 15);
pause(1000);
drive_speed(0, 0);
pause(500);
drive_speed(30, 10);
pause(1000);
}
if(yep == 2)
{
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(670);
drive_speed(15, 5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(-15,-5);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(5, 15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(500);
drive_speed(-5,-15);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(-10, 10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(500);
drive_speed(10,10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(3000);
drive_speed(10, -10);
pause(750);
pause(3000);
pause(890);
pause(1679);
pause(3800);
drive_speed(0,0);
pause(1200);
pause(2000);
pause(1000);
drive_speed(-10,-10);
pause(2000);
pause(1000);
drive_speed(0,0);
pause(750);
}
if( ! bumpflg) drive_ramp(Lspd, Rspd);
}
}
void remote()
{
xbee = fdserial_open(9, 8, 0, 9600 );
char data;
bumpflg = 1;
while (1)
{
if(! input (data = fdserial_rxChar( xbee )));
bumpflg = 1;
if ( data == 'f' )
{
drive_speed( -300, -300 );
}
else if ( data == 'b' )
{
drive_speed( 50, 50 );
}
else if ( data == 'l' )
{
drive_speed( -100, 0 );
}
else if ( data == 'r' )
{
drive_speed( 0, -100 );
}
else if ( data == 's' )
{
drive_speed( 0, 0 );
}
bumpflg = 0;
}
}
Unfortunately, despite my greatest efforts and the help of Tom, I am unable to do this. Either the predetermined driving program keeps running and when I try to remote control the movement is all herky jerky because the wheels are getting simultaneous commands from the drive program and my remote. Alternatively, I can initiate the drive program and when the xbee turns on, it will end the drive program, but then it will not restart after I turn off the xbee.
I feel like this should not be very difficult, and it probably isn't to someone who knows what they are doing. Unfortunately, I am not such a person
-Deepak
I have a couple of questions.
1. How do you get an "s" in the remote function?
2. Why do you have so many "pause" functions between changes in drive speed in the main program? Can't you just use one?
Tom
You are right, there only needs to be one pause between changes. I had previously had multiple servo movements which I deleted and I wanted to keep the timing of the total pauses the same to preserve the drive pattern. That is the only reason.
The "s" in the remote function was from the joystick activity bot tutorial on the parallax website that I uploaded onto my joystick propeller board.
I am pasting code below. I have trimmed it down to the basic problem.
Using the code below, when I turn on the robot, it initiates the drive cog. This sets it into a pattern of turning round and round in a circle. When I turn on the xbee propeller board, the robot stops (because I have cog_end under the "s" function which simultaneously tells the robot to have drive_speed(0, 0) AND also tells it to end the driving cog). Now, how do I get the driving cog to start back up again when I turn off the xbee board? I'm not sure the bumpflg method will work, but that is probably because I am not understanding things correctly. Thank you so much and sorry to keep posting all this code stuff!
Independent of that, there's a version of the serial character receive function that will check to see if a character is available, but it doesn't block waiting for one, so you can check to see if there is one, and if not, do your "non-xbee" code. I'd set it up like this:
Doing that saves you running another cog.
I believe there's a pin on the XBee that will tell you if you have a connection or not - you could use that to decide whether or not to use the last xbee command or the "default behavior", like this: (note, I don't know which pin this would be for you, so you'll need to adapt that part)
Is that what you're trying to accomplish?
I then make some suggested changes.
I suggest using the joystick "s" value as the trigger to turn control from the joystick back to the random function, at least until you get the bot to work accepting commands from the XBee.
The modified code is shown below:
In the code you posted there was no closing "}" for main. I think that may have been a typo when copying the code to the post. When I am writing code with a lot of bracketed sections I will usually comment the ending } for sections that have a lot of code between starting and ending brackets. When I'm done & it works, I can remove the comments.
I don't think that you need Lspd & Rspd since you are putting the speed numbers into the drive speed command. I used them and the "drive_ramp(Lspd, Rspd)" command because I was adding speed each time the remote called for a change. (although Lspd & Rspd may still be useful; see my last comments about conflicts.)
In your original remote() function, at the end you had a statement "bumpflg = 0". That was executed every time you went through the while loop. So the program set a speed from the XBee, but at the end of the loop gave back control to Rand. Moving the statement up just below the drive_speed(0,0) as I show should allow the XBee to remain in control until an "s" is sent. When "s" is sent, the bot should stop and control will be given back to Rand (you might want to add a small pause before setting bumpflg =1 0 so it will transition smoother).
One problem I see is that in main() since there are so many statements and long pauses between the "if(! bumpflg)" and the end of the loop, I think there will still be conflict between rand and the joystick. For example lets say that rand is executing yep = 1, there will be almost 20 seconds of drive movement controlled by yep = 1 before XBee can have exclusive control. You would either have to add a delay in remote (check bumpflg) and have the main program set bumpflg = 1 at the end of each loop to give Xbee a chance to take control. There is probably a better way to check that if for example you used arrays of drive and pause commands and just used a while loop for each one, something like:
There would still be some conflicts due to the length of the pauses, but if you make each pause 1/10 what it is now the while "y" loop shown above would minimize the time for a possible conflict.
You would have to load the arrays in the variable declarations, but it would also make the code easier to read and modify.
EDIT: Since the code above uses "if yep = 1", you don't need 2 dimensional arrays which I try to avoid when loading them in declarations. Just use Lspd_1[x], Rspd_1[x] and delay_1[x] for yep = 1, and Lspd_2[x] etc. for yep = 2 etc.
hope this helps or at least gives you some other ideas.,
Tom
Jason, thank you so much. I completely agree, I do not know how to symbolize or monitor when the xbee is OFF. The program needs to be able to detect if XBEE off then do some other action. I looked up online and also checked my wiring. It appears that I have the xbee DO going to Pin 9, and the DI going to Pin 8 on the robot. The same is true on the transmitter side.
Using your second program, I plugged in the number 8 where you had put 15, and I ran the program. The robot does correctly receive data and drives beautifully. But once again, when I turn off the xbee, it does not resort back to drive_speed(100, -100). It just sits still. If I turn Xbee back on, it again begins to follow my commands. I still am unable to get it to start a different action once xbee is off.
Tom, thank you so much! I am still too novice to really understand what is happening in the program you wrote. When I plug it in, the robot will drive correctly. However, in the default "s" position (when the joystick is in the neutral position), the robot moves very herky jerky. Once I implement forward, backwards, left or right, it drives perfectly. But in the default stop position it is clearly receiving conflicting commands or something. However, when I turn off the xbee it does resume the automatic driving sequence which is cool!
I will keep playing around, but admit that I am out of my league. I feel that this is very close, and yet I am so far away hahahaha
Thank you both so much for the help. Any other suggestions you have would be greatly appreciated, but I understand if you have devoted as much time as you can tolerate to this. Thanks again!
-Deepak
But that makes another problem. The auto mode doesn't turn on until "bumpflg =0".
If you can I'd suggest adding 2 buttons (tact switches) to the board with the joystick. The tutorials show how to wire them up. Use 1 to turn on auto mode and the other to turn on joystick mode. When a button is pressed have the Xbee send the data to the board on the robot and just have one set bumpflg =0 and the other bumpflg = 1.
Another way is to use a sequence of joystick motions to = transfer back to auto and another sequence to restart using the joystick . For example, b, f, b (or some sequence you wouldn't use when driving). You would have a variable, let's call it "offnum". It would start =0. In the part of the code where "b" is run, you would check its value. If 1, reset it to 0. Otherwise you would add 1 to it. If it then equaled 3, you would set drive_speed(0,0), offnum =0, and bumpflg = 0. In "f" if offnum = 1, you would add another 1 to it. If anything else, just reset offnum =0.
You might have to play with the code to get the details to work. But the issue is how to send a use-auto / use-joystick code from the joystick board to the robot.
Another way is to use a timer like roscoe suggested. But I'm not sure how to do that.
Tom
Instead of "s", I put it under "b". So now, I turn on the robot, it engages in the automatic drive program. When I turn on xbee, the robot stops, but mildly twitches until full control is given over to xbee (like you said Tom). Once full control is given over, the robot drives forward, and turns left and right without interruption. If I hit backwards "b", the automatic drive program is again engaged. So if I hit backwards while simultaneously turning off xbee, the robot will go back to it's automatic program!
I am going to add a tact switch like you suggested, so that I can restore the reverse function and drive in all four directions. Then when I want to go to automatic driving, I can hit the tact button and take it from there.
One quick question, there is not enough room on the breadboard for two tact buttons and the joystick. Any suggestions?
Thank you Tom and Jason, I really really appreciate the help. This thing is so awesome now, definitely could never have done this by myself!
I'm not sure how to mount the tact switches. I didn't realize that the joystick was so large. One thing you can try is to get a piece of foamcore art board and a small breadboard. Cut the foam core large enough to fit both the Activity Board with the joystick and the small bread board. You can temporarily screw the ABoard to foam core and use a small piece of double backed foam tape to hold the small breadboard so you can remove them later. Otherwise make the board look good and mount it permanently. Then you can put the tact switches on the small breadboard and connect jumpers to the Activity Board pin connectors.
I find that once I write a program and get it working, I keep "optimizing" it. Once you get everything working how you want you might want to use the looping method I suggested to get rid of the jittter when switching to joystick control. You might also be able to figure out a couple of modifications so that you don't have to turn off the joystick board, but just use the switches to switch from one mode to the other.
I recommend cleaning up the comments so they reflect how the statement is actually working. That way when you look at or modify the program in the future they won't be confusing. (voice of experience)
Enjoy,
Tom
Using my earlier version as a starting point, you'd modify it like this:
With this code, if your joystick always sends 's' when stopped, or 'f' when forward, etc, and sends even once every 10th of a second, the above code will respond like it does normally. As soon as you turn off the joystick and it stops sending, the commandTimer value will start counting down, and when it reaches zero, the auto/default thing takes over. The next time you get a new command (which will happen if you turn the xbee on again) the commandTimer resets and you get normal control again.
I modified and tweaked the code. I added a tact switch as was suggested and the thing works freakin amazingly. I push the tact switch and simultaneously turn off xbee and the robot goes back to its autodrive function. That freed up the backwards button so now I can drive in all directions.
Put in some random movements for the head servo and lights to add a little extra action. Code is below. Thank you both so much, I am very happy so far with how it is turning out! Also, how did you both learn this language so well? A lot of the commands you are using are not in the tutorials. If I am interested in learning more, do I need to take a class? Or is there some guide online I can learn from (such as command timer, newchar ! etc. etc.). Thanks again to both of you!
Also, I have two pictures of the robot and joystick controller. Is there a way to attach those to a post?
-Deepak
As for how to get good, C/C++ has been around a long time. There are probably online courses, or local colleges that would teach programming classes. I learned C on my own, reading voraciously and experimenting to start with. Then I started working in video games and learned through the job. Read a lot of other people's code, troll places like CodeProject.com, and so on. It takes practice. Generally you learn best by doing, so you're going about it the right way so far.
In the late 1970's and 1980's I did a lot of programming in BASIC, both as a hobby and at work. I had learned FORTRAN in college, but didn't use it much after that. In my hobby, I was also exposed a little to FORTH and C. I liked both of those languages because they were not wordy and had some neat capabilities. But I didn't have much of a chance to use them. Eventually, my home computer (Compucolor 2) died and couldn't be fixed or replaced, and I also changed jobs where I didn't do programming any more.
Skip ahead 30 years
A couple things happened a couple of years ago. I started using my Android tablet to make some photography programs in Forth, and got interested in programming again. Then I was searching the web to find a robot kit as a Christmas present for one of my nephews, and found Parallax. I bought him a BOE BOT, and bought myself an ActivityBot since I thought it would be a good way to learn C.
I did the tutorials, and started combining different tutorials, like my program that uses the SIRC as a remote control combined with whiskers in a different cog to handle bumping into things. I also started reading the documentation in the SimpleIDE library folders, and that gave me ideas of commands I could use to improve my programs (shorten, speed-up, use less memory). The link to the current Simple library is here:
https://propsideworkspace.googlecode.com/hg/Learn/Simple%20Libraries%20Index.html
There is also the Propeller C library here for more advance features (but start with the SimpleIDE ones first).:
https://sites.google.com/site/propellergcc/documentation/libraries/propeller-h-library
As I read these forums, I came up with other ideas of things I wanted to do, such as use my android tablet to control the ActivityBot and sensors. That meant that I had to learn to read sensor data sheets, different C commands, and different Propeller features (like the counters).
I also read other peoples code. That's how I originally learned BASIC - translating programs for other computers to my Compucolor 2.
There are a lot of programs in Spin in the Propeller Tool Libraryfor different sensors. I had to learn Spin to be able to convert them to C. I still am trying to learn Spin. I bought the Propeller Education Kit Book (also available as free download) to help me learn Spin, and I found that I ended up converting the Spin programs in that book to C.
You are essentially doing what I did with the tutorials - combining and changing things to do what you want. Keep it up and read up on C to see how to improve your programs. One thing I would suggest first is to try to use different types of loops to shorten your programs (for loops, while loops with incrementing the argument similar to what I suggested in an earlier post.) Just make sure you save the program that works.
If you have an android device, I found the "C programming book" free ap below to be useful. It can be read to get an idea of the different C statements, and has a good reference. Note that there are many free C programming aps, just find one that is good for you.
Tom
amazon.com/OneForMe-Learn-C-Programming-Reference/dp/B009M4RGNY/ref=sr_1_14?s=mobile-apps&ie=UTF8&qid=1456850039&sr=1-14&keywords=c+programming+book
-Deepak
Only thing one has to keep in mind is that to drive forward you need negative numbers, and to drive backwards you need positive numbers.