Software > Software

Controlling motors [Urgent]

<< < (12/15) > >>

Mastermime:
Awesome! I just added the delimiter and my problem is solved.  thanks Webbot.

Actually I just ran into a problem.  For some reason, I cannot run both motors at a time.  Check out the video to see what I mean.


VoltX Wireless Test 5

Code I was using


--- Code: ---#include "hardware.h"

#define XBee_Controlled

#define UART0_TX_BUFFER_SIZE 80
#define UART0_RX_BUFFER_SIZE 80

#define TRIANGLE 256
#define START 257
#define L2 258
#define R2 259

#define MOTOR_L_MIN 1
#define MOTOR_L_STOP 64
#define MOTOR_L_MAX 127
#define MOTOR_R_MIN 128
#define MOTOR_R_STOP 192
#define MOTOR_R_MAX 255
#define SIGNAL_MOTORS_OFF 0

uint16_t motorLCurVal;
uint16_t motorRCurVal;
uint16_t motorLTarVal;
uint16_t motorRTarVal;
uint16_t motorVal;

boolean receiving;
#define PACKET_SIZE 3
char packet[] = {0, 0, 0};
int curByte;

// Initialize the hardware
void appInitHardware(void) {

initHardware();

#ifdef XBee_Controlled
rprintfInit(debugSendByte);
delay_ms(10);
#endif

//rprintf("\nHardware initialized.\n\n");
}


// Initialise the software
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
//rprintf("\nAxon Initiated.\n\n");
receiving = false;
motorLCurVal = motorLTarVal = MOTOR_L_STOP;
motorRCurVal = motorRTarVal = MOTOR_R_STOP;
curByte = 0;
}

// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

uint16_t tempbyte = NULL;

#ifdef XBee_Controlled
if(!uartReceiveBufferIsEmpty(UART0)) {
char temp = uartGetByte(UART0);
if (temp == 'A' && !receiving)  //delimiter
{
receiving = true;
curByte = 0;
}
else
{
packet[curByte] = temp;
//rprintf(“Got a byte! %c\n”, temp);
if (curByte == (PACKET_SIZE - 1) )
{
tempbyte = atoi(packet);  //atoi = convert string to packet
receiving = false;
}
curByte++;
}
}
#endif
   

if (tempbyte != NULL) {

if (tempbyte >= MOTOR_L_MIN && tempbyte <= MOTOR_R_MAX)
{
setMotorSpeed(tempbyte);
}
else if (tempbyte== START)
{
pin_toggle(Remoteswitch_relay);
}
else if (tempbyte== TRIANGLE)
{
pin_toggle(led1);
pin_toggle(led2);
pin_toggle(led3);
}

tempbyte = NULL;
}
else
{
motorStopMotor();
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
TICK_COUNT ms = loopStart / 1000; // Get current time in ms
int16_t now = ms % (TICK_COUNT)10000; // 10 sec for a full swing
if(now >= (int16_t)5000){ // Goes from 0ms...5000ms
now = (int16_t)10000 - now; // then 5000ms...0ms
}
return 0;
}


//All the ++ and -- is just to make the robot gradually stop and start
//motorXCurVal is the current speed.
//motorXTarVal is where we want the speed to be.

void motorStopMotor()
{
do {
if (motorLCurVal<MOTOR_L_STOP)
{
motorLCurVal=motorLCurVal+1;
}
else if (motorLCurVal>MOTOR_L_STOP)
{
motorLCurVal=motorLCurVal-1;
}

Sabertooth_uartSendByte(motorLCurVal);
//rprintf("\n StopmotorLCurVal is: %d", motorLCurVal);

if (motorRCurVal<MOTOR_R_STOP)
{
motorRCurVal=motorRCurVal+1;
}
else if (motorRCurVal>MOTOR_R_STOP)
{
motorRCurVal=motorRCurVal-1;
}

Sabertooth_uartSendByte(motorRCurVal);
delay_ms(10);

} while (motorLCurVal!=MOTOR_L_STOP && motorRCurVal!=MOTOR_R_STOP);
}

void setMotorSpeed(uint16_t byte)
{
if (byte >= MOTOR_L_MIN && byte <= MOTOR_L_MAX)
{
motorLTarVal = byte;
do {
if (motorLCurVal < motorLTarVal)
{
Sabertooth_uartSendByte(++motorLCurVal);
}
else
{
Sabertooth_uartSendByte(--motorLCurVal);
}

} while (motorLCurVal != motorLTarVal);
}
else if (byte >= MOTOR_R_MIN && byte <= MOTOR_R_MAX)
{
motorRTarVal = byte;
do {
if (motorRCurVal < motorRTarVal)
{
Sabertooth_uartSendByte(++motorRCurVal);
}
else
{
Sabertooth_uartSendByte(--motorRCurVal);
}
delay_ms(10);

} while (motorRCurVal != motorRTarVal);
}
}


--- End code ---

Webbot:
Just looking at your code:-
The atoi function looks at data in packet - but suppose you've just written a '6' and '4' in there. The answer to atoi will be 64? Not always- if it previously had '256' then it will now have '646'. The '64' being new and the trailing '6' being old stuff.

So you need to make sure that since 'packet' is being treated as a string that you write a zero terminator in there.
change
--- Code: --- char packet[] = {0, 0, 0};
--- End code ---
to
--- Code: ---char packet [PACKET_SIZE+1]
--- End code ---
to allow for this extra 'end of string char'

Then change:
--- Code: ---packet[curByte] = temp;
--- End code ---
to add the end of string character ie
--- Code: ---packet[curByte] = temp; packet[curByte+1]='\0';
--- End code ---

Mastermime:
You would be correct if I didn't buffer every number with 0's. but like for 64, I actually send 064. So it always is full with the correct #. You wouldn't know this b/c its on the arduino side of things. Not thats its bad practice, but thats not our problem for the packet response. Helpful though.  Sorry I should've mentioned that. 

When this odd phenomenon occurs, the red led on the Sabertooth lights up.  I dont think this is the source of my problem because I believe that lights due to high startup current.  This is very odd.  I've had a lot of odd problems!

Admin:

--- Quote ---I dont think this is the source of my problem because I believe that lights due to high startup current.
--- End quote ---
To verify the hardware isn't the problem, write a simple program that commands both motors to run together.

Webbot:

--- Quote from: Mastermime on February 18, 2013, 11:41:39 PM ---You would be correct if I didn't buffer every number with 0's. but like for 64, I actually send 064. So it always is full with the correct #. You wouldn't know this b/c its on the arduino side of things. Not thats its bad practice, but thats not our problem for the packet response. Helpful though.  Sorry I should've mentioned that. 

--- End quote ---

Yes - but you are storing the three digits in memory and the 'atoi' function keeps on going until it finds something that is not a digit. ie 'atoi' works with a string not an array of characters. A string is the same as an array of characters except that it has an extra zero at the end to makrk the end of the string.

You probably have no idea what data is living in memory immediately after the 3 'packet' bytes.
For example: if you had
char packet[3] = { '0','0','1'} and this was followed in memory by something else say like:
char foobar[] = { '3', '2', '1'}
then when you do 'atoi(packet)' you would get back 1321 which is probably not what you expect.

Even worse foobar could be a variable and so the atoi may sometimes do what you want and at other times not.

Don't forget - only the compiler know that 'packet' is 3 digits long - at runtime the 'atoi' function just takes its first byte to be the start of a, potentially, infinitely long list of characters.

To fix your code then you MUST declare packet as 4 bytes rather than 3 and make sure that the last byte is a zero (ie the number 0 not the character '0' - ie you can use packet[3]=0 or packet[3]='\0')


Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version