Author
Topic: Controlling motors [Urgent] (Read 5643 times)

I am in need of urgent help controlling my motors (Sabertooth 2x25) from a PS2 controller over Xbee wireless. There is probably a small mistake in my code. When I turn the robot on the motors propel forward until it gets to full speed and then it slowly stops and propel backwards until it gets to full speed. It also does the same thing with my servo

return 0;}//code by Tzankoff//code for gradual stopping and starting//motorXCurVal is the current speed. //motorXTarVal is where we want the speed to be.//motorVal, in this case, is running on a scale of 1 to 10. Thus, 1 is 10% of maximum //speed, 2 is 20%, and so on. NOT USED

/* This is weird and seems unecessarily complicated. Basically the same thing above I think. Not sure why it stopsthe motor before moving it as well, seems logically incorrect. Should move from CurSpeed -> TarSpeed, notCurSpeed -> Stop -> TarSpeed. Keeping this around incase I am wrong.

// -------- Start Switch/Button-------// Switch/Button - see switch.h// To test if it is pressed thenif(SWITCH_pressed(&button)){// pressed}// To test if it is released thenif(SWITCH_released(&button)){// released}// -------- End Switch/Button-------

// -------- Start Marquee-------// Marquee - see 'segled.h'// Before using the Marquee you need to redirect rprintf to write to it// This can be done usingWriter old = rprintfInit(marqueeGetWriter(&marquee));// All rprintf output will then be sent to the marquee but will not// display until an end-of-line eg "\n" has been sent. Example:-// rprintf("Hello World\n");// If the endDelay is non-zero then the marquee will scroll// forever or until you call: marqueeStop(&marquee);// If the endDelay is zero then the marquee will stop once// the entire line has been shown ('one-shot' mode)// In 'one-shot' mode then you may want to make sure that// a previous line has finished before you display a second line.// This can be done as follows:-marqueeSetEndDelay(&marquee,0); // Make sure we are in one-shot modeif(marqueeIsActive(&marquee)==FALSE){ if(loopCount==1){rprintf("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); }else{rprintf("Loop=%u\n",(unsigned)loopCount); // Put the loop count }}// Restore rprintf back to its previous locationrprintfInit(old);// -------- End Marquee-------

// -------- Start LED-------// The LED can be manipulated using the calls in led.h// To turn the LED on:-LED_on(&led_ext1);// To turn the LED off:-LED_off(&led_ext1);// -------- End LED-------

// -------- Start LED-------// The LED can be manipulated using the calls in led.h// To turn the LED on:-LED_on(&led_ext2);// To turn the LED off:-LED_off(&led_ext2);// -------- End LED-------

// -------- Start LED-------// The LED can be manipulated using the calls in led.h// To turn the LED on:-LED_on(&leds_int);// To turn the LED off:-LED_off(&leds_int);// -------- End LED-------

// -------- Start Digital Output-------// Set the pin highpin_high(Remoteswitch_relay); // Set the pin lowpin_low(Remoteswitch_relay); // Toggle the pin ie high->low, or low->highpin_toggle(Remoteswitch_relay); // Output a high pulse of 1000uspin_pulseOut(Remoteswitch_relay,1000,TRUE);// -------- End Digital Output-------

// -------- Start Digital Output-------// Set the pin highpin_high(Xbee5v); // Set the pin lowpin_low(Xbee5v); // Toggle the pin ie high->low, or low->highpin_toggle(Xbee5v); // Output a high pulse of 1000uspin_pulseOut(Xbee5v,1000,TRUE);// -------- End Digital Output-------

// -------- Start Actuators -------// To control your.motors/servos then see actuators.h in the manual// To retrieve the required speed of motor_1 use:// DRIVE_SPEED speed=act_getSpeed(motor_1);// To set the required speed of motor_1 use:// act_setSpeed(motor_1,speed);// This example will move the motors back and forth using the loopStart time:TICK_COUNT ms = loopStart / 1000;// Get current time in msint16_t now = ms % (TICK_COUNT)10000; // 10 sec for a full swingif(now >= (int16_t)5000){// Goes from 0ms...5000msnow = (int16_t)10000 - now;// then 5000ms...0ms}// Map it into DRIVE_SPEED rangeDRIVE_SPEED speed = interpolate(now, 0, 5000, DRIVE_SPEED_MIN, DRIVE_SPEED_MAX);// Set speed for all motors/servosact_setSpeed(&motor_1,speed);act_setSpeed(&motor_2,speed);act_setSpeed(&servo,speed);// -------- End Actuators -------

Break down the hardware and software into smaller functional blocks then test and debug each block.1- Is there an issue between the Axon, Arduino and Sabertooth? Which processor is actually controlling the Sabertooth?

2- Is there a communication issue on the serial link? Get the serial data link working between the processors without the XBees by hard wiring the serial line between the two processors.

3- Is there an XBee setup and communication issue? Get the XBees working with a simple to test code. One way is just send data one way then send the data back (remote Echo).

4- Is the PS2 controller interface correct? Have you tested and confirmed this?

5- Is the command protocol is the serial communication chain working correctly? Hard code values at the receiving end to test that code is correctly using the commands. Echo the command back to ensure they are getting received intact.

6- Also use a PC (or MAC or Linx) serial data port to test the serial to each processor. Send commands to mimic the data from the PC to each processor. Send the PS2 data to the PC to test if the data is being send properly. Show us a block diagram of the system and what connects to what. So far we can only guess.

Is there an issue between the Axon, Arduino and Sabertooth? Which processor is actually controlling the Sabertooth?

The Axon II is controlling the Sabertooth 2x25

Quote

2- Is there a communication issue on the serial link? Get the serial data link working between the processors without the XBees by hard wiring the serial line between the two processors.

I have tested and commands are properly being sent from one Xbee to another. So you're saying I should just put a wire between tx and rx and vice versa on the Arduino and Axon II, right? I don't think that's the problem, but it may be. I think there is an error in my code.

Quote

3- Is there an XBee setup and communication issue? Get the XBees working with a simple to test code. One way is just send data one way then send the data back (remote Echo).

See above.

Quote

6- Also use a PC (or MAC or Linx) serial data port to test the serial to each processor. Send commands to mimic the data from the PC to each processor. Send the PS2 data to the PC to test if the data is being send properly. Show us a block diagram of the system and what connects to what. So far we can only guess.

Yep, that's exactly how I've been debugging. Through XCTU and the Arduino serial monitor

I must also add the Marquee is blinking randomly even though I didn't program it to or at least I don't think I did. Does this mean the Axon could be resetting? Just a guess.

Also I have a remote switch I'm having issues with too. How it works Xbee Digital Output > to MOSFET (connects grounds) > energize relay coil and now power can flow to the Sabertooth. When I connect to a 12v signal, everything turns on, but when I connect it to the digital output, the relay makes a loud buzzing sound. Any ideas what this could be? Sorry for all the issues

The fact that your motors and servos are ramping up and then reversing is definitely a software bug. I see a lot of ++ and -- in your code, in while loops. I'd bet that is the source of it. I recommend commenting your code so that you can work through it logically in your head, and so we can follow your code easier too

I must also add the Marquee is blinking randomly even though I didn't program it to or at least I don't think I did. Does this mean the Axon could be resetting? Just a guess.

Possibly. I'd check your battery voltages. The schematic in your other post only showed one battery. Try using a separate battery for your microcontroller and see if this still happens.

Quote

Also I have a remote switch I'm having issues with too. How it works Xbee Digital Output > to MOSFET (connects grounds) > energize relay coil and now power can flow to the Sabertooth. When I connect to a 12v signal, everything turns on, but when I connect it to the digital output, the relay makes a loud buzzing sound. Any ideas what this could be? Sorry for all the issues

You mean with 12V connected to the relay, it works fine? But when you connect the MOSFET output to the relay it makes the buzzing noise?

Is it possible that the MOSFET output isn't 12V, but lower? Or the MOSFET output is pulsing a square wave for some odd reason? Got a oscope to measure it?

I have Good news and bad news. Good news- all my wiring is correct. The Sabertooth turns on as it should because I set the pin high and the marquee is not blinking erratically. The status led blinks when I turn the corresponding Xbee on. The motors are not shooting off when the Sabertooth turns on which is good.

Ok so I know it hasn't something to do with the Axon II. First thing I did wrong, was I sent 0 as triangle, but my motors still should've turned regardless. Is there a way to look at the output of a UART (Sabertooth) port? I can use an FTDI cable, cant I?

//motorXCurVal is the current speed. //motorXTarVal is where we want the speed to be.//motorVal, in this case, is running on a scale of 1 to 10. Thus, 1 is 10% of maximum //speed, 2 is 20%, and so on. NOT USED

/* This is weird and seems unecessarily complicated. Basically the same thing above I think. Not sure why it stopsthe motor before moving it as well, seems logically incorrect. Should move from CurSpeed -> TarSpeed, notCurSpeed -> Stop -> TarSpeed. Keeping this around incase I am wrong.

At first the status LED is solid (constantly lit), but when I send a command from the PS2 controller, the Status LED blinks so it knows something is going through. Admin and others, What am I doing wrong?? There must be a small thing Im missing.

rprintf("\n motorRCurVal is: %d", motorRCurVal);delay_ms(100);//use this so it doesn't output a billion times per secondYou can also use the numbered LED to show a certain number when it's running a certain subset of code. This lets you know what the software is doing behind the scenes.

And just skimming through your code I noticed this very serious bug:int motorRTarVal;motorRTarVal=192+motorInt;

The int type only ranges from −128 to 127, so having 192 + anything means your variable is going out of bounds.

Ah ok. I just hooked up my ftdi cable to my corresponding Xbee on the controller because in my code it says send rprintf to XbeeSendByte. It says "value received: -17404" Where the heck is that number coming from and how can I fix it? I should probably set my rprintf output to UART3 because Xbees are half duplex, therefore how can it transmit and receive data at the same time, right?

//motorXCurVal is the current speed.//motorXTarVal is where we want the speed to be.//motorVal, in this case, is running on a scale of 1 to 10. Thus, 1 is 10% of maximum //speed, 2 is 20%, and so on. NOT //USED

Ah ok. I just hooked up my ftdi cable to my corresponding Xbee on the controller because in my code it says send rprintf to XbeeSendByte. It says "value received: -17404" Where the heck is that number coming from and how can I fix it?

I should probably set my rprintf output to UART3 because Xbees are half duplex, therefore how can it transmit and receive data at the same time, right?

You can't transmit and receive at the same time with half duplex. Your code will need to allow for both sides to take turns. You could have it transmit only 3 seconds of data, and then stop transmitting again until it's received a new message from the other side. Many ways to do it . . .

Error 11 is a receive buffer overflow (see the errors.h file in WebbotLib). This happens when you send a bunch of data but the mcu doesn't process it before the buffer overflows.

Try increasing buffer size in Project Designer. If your baud isn't matching, the 'random junk' can quickly fill a small buffer. Have your mcu repeat back what it sees to verify baud (if you aren't sure).

Yeah right now I have my receive buffer and transmit buffer on the Xbee set to zero. What should I set it to and also should i set a buffer on the other UART ports as well?

Last question, currently my baud rate is at 9600, would increasing my baud rate help too?

//motorXCurVal is the current speed. //motorXTarVal is where we want the speed to be.//motorVal, in this case, is running on a scale of 1 to 10. Thus, 1 is 10% of maximum //speed, 2 is 20%, and so on. NOT //USED

//code below by Tzankoff//motorXCurVal is the current speed.//motorXTarVal is where we want the speed to be.//motorVal, in this case, is running on a scale of 1 to 10. Thus, 1 is 10% of maximum //speed, 2 is 20%, and so on. NOT USED

/* This is weird and seems unecessarily complicated. Basically the same thing above I think. Not sure why it stopsthe motor before moving it as well, seems logically incorrect. Should move from CurSpeed -> TarSpeed, notCurSpeed -> Stop -> TarSpeed. Keeping this around incase I am wrong.

}*/So my argument is, if this is part of Tzankoffs final code, it must've worked. Is my friends logic (his explanation at top) correct and should I include this code? I'm having trouble following it. Also I forgot to mention when you said 192 was out of bounds, that part was in this commented out section.

I gather (via email) that you have sorted this out. Some info may help others ....

RE "I get WebbotLib Error 11 and I don't know what it means..." - first look in 'errors.h' to get a bit more info. Don't forget you've got the src code for WebbotLib so you could find exactly why you get the error.

@Admin jwatte is 100% correct. An int is 16 bits on all avr compilers ie an int16_t.

Edit:I also note that driveSpeed you are setting is very specific to the Sabertooth - ie you are assuming the sabertooth is running in 'simple' mode where motor1: 1=full reverse,64 is stop,127 is full fwd and for motor2: 128 is full reverse,192 is stop, 255 is full fwd.I see that by your defines:

Seems you are trying to convert Arduino code that only works with the Sabertooth into WebbotLib code? It doesn't work like that. In WebbotLib you set a drive speed from -127 (full reverse), 0=stop, +127=full fwd and WebbotLib turns it into the relevant numbers that are sent to the Sabertooth.Unlike Arduino this means you can swap the Sabertooth to a different controller and not have to change your code.

Seems you are trying to convert Arduino code that only works with the Sabertooth into WebbotLib code? It doesn't work like that. In WebbotLib you set a drive speed from -127 (full reverse), 0=stop, +127=full fwd and WebbotLib turns it into the relevant numbers that are sent to the Sabertooth.Unlike Arduino this means you can swap the Sabertooth to a different controller and not have to change your code.

Thanks. I will definitely keep this in mind later, but first I have to focus on getting the right bytes from XBee.

I just performed a test and I noticed different patterns when I press different buttons. I am only looking at the rprintf (added it, not in code though right after tempbyte = uartGetByte(UART0);