Software > Software

Controlling motors [Urgent]

<< < (2/15) > >>

Admin:
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   :P


--- Quote from: Mastermime on February 04, 2013, 10:37:21 PM ---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.

--- End quote ---
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

--- End quote ---
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?

Mastermime:
Thank you for the response Admin.

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.


Bad news-  No commands are being read by the Axon II

So I think I should first work on turning the relay on off

Mastermime:
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?

Mastermime:
I've updated some code, but still no luck.

Axon II Code


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

#define XBee_Controlled
//#define USB_Controlled

#define UART0_TX_BUFFER_SIZE 4
#define UART0_RX_BUFFER_SIZE 4

#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

int motorLCurVal;
int motorRCurVal;
int motorLTarVal;
int motorRTarVal;
int motorVal;



// Initialise the hardware
void appInitHardware(void) {
initHardware();

}


// Initialise the software
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
motorLCurVal = motorLTarVal = MOTOR_L_STOP;
motorRCurVal = motorRTarVal = MOTOR_R_STOP;
}

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

int tempbyte = NULL;

#ifdef XBee_Controlled
//tempbyte=XbeeGetByte;
if(!uartReceiveBufferIsEmpty(UART0)) {
int tempbyte = uartGetByte(UART0);
        }
#endif

if (tempbyte != NULL) {

if (tempbyte >= MOTOR_L_MIN && tempbyte <= MOTOR_R_MAX)
{
setMotorSpeed(tempbyte);
}
else if (tempbyte==START)
{
pin_low(Remoteswitch_relay);
}
else
{
motorStopMotor();
}

}

delay_ms(100);

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
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;
}

//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

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

Sabertooth_uartSendByte(motorLCurVal);
delay_ms(50);

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

Sabertooth_uartSendByte(motorRCurVal);
delay_ms(50);

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

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

} 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(100);

} while (motorRCurVal != motorRTarVal);
}
}

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

void motorMoveMotor(int motorL, int motorR) // motorL and motorR are -1 for reverse, 0 for stop, 1 for forward

motorStopMotor();
delay_ms(100);
motorInt=(63*motorVal)/100;
motorLTarVal=64+motorInt;

if (motorL<0)
{
motorLTarVal=64-motorInt;
}

motorRTarVal=192+motorInt;

if (motorR<0)
{
motorRTarVal=192-motorInt;
}

do {
if (motorLCurVal<motorLTarVal)
{
motorLCurVal=motorLCurVal+1;
}
else if (motorLCurVal>motorLTarVal)
{
motorLCurVal=motorLCurVal-1;
}

motors_uartSendByte(motorLCurVal);
delay_ms(50);

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

motors_uartSendByte(motorRCurVal);
delay_ms(50);

} while (motorLCurVal!=motorLTarVal && motorRCurVal!=motorRTarVal);

}
*/

--- End code ---

Arduino Code


--- Code: ---/* NOTES:
 * 0-127 Motor Left (1-63: forward, 64: stop, 65-127: reverse)
 * 128-255 Motor Right (128-191: forward, 192: stop, 193-255: reverse)
 */


#include <GPSXClass.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
//#include <XBee.h>
#include <Servo.h>
#include <Sabertooth.h>
// LCD SCREEN
#define LCD_COLS 20
#define LCD_ROWS 4
#define BACKLIGHT_ON 'HIGH'
#define BACKLIGHT_OFF 'LOW'
// XBEE
#define DATA_LED 10
#define STATUS_LED 11
#define ERROR_LED 12
#define REMOTE_XBEE_ADDR 0x1874 //TODO
#define RESPONSE_WAIT 5000
#define DEBUG false
// PS2 SEND
#define TRIANGLE 256
#define START 257
#define L2 258
#define R2 259
#define JOYSTICK_LOW 90
#define JOYSTICK_HIGH 160

#define DELAY 100
#define SERIAL_BPS 9600

// GLOBAL VARIABLES
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //TODO


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Initialize
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void setup()
{
initPSX(); //Get PS2 controller ready
initLCD(); //Get LCD ready
initXBee(); //Get XBee Wireless Transmitter ready
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Main
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void loop()
{
    //PS2 Controller Input
    readPS2Input();

delay(DELAY);
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Helpers
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

void initPSX()
{
PSX.mode(PSX_PAD1, MODE_ANALOG, MODE_LOCK);
PSX.motorEnable(PSX_PAD1, MOTOR1_DISABLE, MOTOR2_DISABLE);
// Poll current state once.
PSX.updateState(PSX_PAD1);
}

void initLCD()
{
lcd.begin(LCD_COLS, LCD_ROWS);
lcd.clear();
lcd.setCursor(0,0);
//lcd.print("Robot Started");
}

void initXBee()
{
Serial.begin(9600);
}

void readPS2Input()
{
  Serial.begin(9600);
 
PSX.updateState(PSX_PAD1);

if(PRESSED_TRIANGLE(PSX_PAD1))
{
if (DEBUG) Serial.println("Triangle pressed");
else sendData(TRIANGLE);
}
if(PRESSED_START(PSX_PAD1))
{
if (DEBUG) Serial.println("Start pressed");
else sendData(START);
}
if(IS_DOWN_L2(PSX_PAD1))
{
if (DEBUG) Serial.println("L2 down");
else sendData(L2);
}
if(IS_DOWN_R2(PSX_PAD1))
{
if (DEBUG) Serial.println("R2 down");
else sendData(R2);
}

int leftStick = ANALOG_LEFT_Y(PSX_PAD1);
int rightStick = ANALOG_RIGHT_Y(PSX_PAD1);
if(leftStick < JOYSTICK_LOW)
{
if (DEBUG)
{
Serial.print("LEFT TRIGGER FORWARD: ");
Serial.println(ANALOG_LEFT_Y(PSX_PAD1), DEC);
}
else sendData(map(leftStick, 0, JOYSTICK_LOW, 127, 65));
}
if(leftStick > JOYSTICK_HIGH)
{
if (DEBUG)
{
Serial.print("LEFT TRIGGER BACKWARDS: ");
Serial.println(ANALOG_LEFT_Y(PSX_PAD1), DEC);
}
else sendData(map(leftStick, JOYSTICK_HIGH, 255, 63, 1));
}
if(rightStick < JOYSTICK_LOW)
{
if (DEBUG)
{
Serial.print("RIGHT TRIGGER FORWARDS: ");
Serial.println(ANALOG_RIGHT_Y(PSX_PAD1), DEC);
}
else sendData(map(rightStick, 0, JOYSTICK_LOW, 255, 193));
}
if(rightStick > JOYSTICK_HIGH)
{
if (DEBUG)
{
Serial.print("RIGHT TRIGGER BACKWARDS: ");
Serial.println(ANALOG_RIGHT_Y(PSX_PAD1), DEC);
}
else sendData(map(rightStick, JOYSTICK_HIGH, 255, 191, 128));
}
}

void sendData(int sendVal)
{
Serial.print(sendVal, DEC);
delay(10);
}
--- End code ---

Also, here is my hardware.h file

--- Code: ---/*
This file has been auto-generated by WebbotLib tools V1.1
** DO NOT MODIFY BY HAND **
*/
#ifndef _HARDWARE_H_
#define _HARDWARE_H_

#if !defined (_LIB_HARDWARE_C_)  && !defined(_LIB_HARDWARE_CPP_)
#define BUILDING_LIBRARY
#define _LIB_HARDWARE_C_
#endif

#ifndef F_CPU
#warning No CPU speed specified - assuming running at 16000000
#define F_CPU 16000000
#endif

#if F_CPU != 16000000
# warning "Board runs at 16000000 but you have defined a different value"
#endif

#if defined (__AVR_ATmega640__)
#else
# error You must set the device to the ATmega640
#endif

#define FLASH_SIZE 65536
#define RAM_SIZE 8192
#define EEPROM_SIZE 4096
#define _NUM_PCINT_PINS 9

// Include library files
#include <libdefs.h>
#include <core.h>
#include <timer.h>
#include <a2d.h>
#include <rprintf.h>
#include <led.h>
#include <stdlib.h>
#include <avr/eeprom.h>
#include <switch.h>
#include <errors.h>
#include <uart.h>
#include <segled.h>
#include <Motors/DimensionEngineering/Sabertooth.h>
#include <iopin.h>
#include <servos.h>
#include "lib/lib_timerdef.h"
#include "lib/lib_iopins.h"
#ifdef __cplusplus
extern "C" {
#endif

// ------------------- uart1 -------------------
extern MAKE_WRITER(uart1SendByte);
extern MAKE_READER( uart1GetByte);

// Create hardware UART uart1
extern HW_UART _uart1;
#define uart1 &_uart1
#define UART1 uart1

// ------------------- Xbee -------------------
extern MAKE_WRITER(XbeeSendByte);
extern MAKE_READER(XbeeGetByte);

// Create hardware UART Xbee
extern HW_UART _Xbee;
#define Xbee &_Xbee
#define UART0 Xbee

// ------------------- Sabertooth_uart -------------------
extern MAKE_WRITER(Sabertooth_uartSendByte);

// Create hardware UART Sabertooth_uart
extern HW_UART _Sabertooth_uart;
#define Sabertooth_uart &_Sabertooth_uart
#define UART2 Sabertooth_uart

// ----------- Define the ADC channels ----------
#define ADC0 ADC_NUMBER_TO_CHANNEL(0)
#define ADC1 ADC_NUMBER_TO_CHANNEL(1)
#define ADC2 ADC_NUMBER_TO_CHANNEL(2)
#define ADC3 ADC_NUMBER_TO_CHANNEL(3)
#define ADC4 ADC_NUMBER_TO_CHANNEL(4)
#define ADC5 ADC_NUMBER_TO_CHANNEL(5)
#define ADC6 ADC_NUMBER_TO_CHANNEL(6)
#define ADC7 ADC_NUMBER_TO_CHANNEL(7)
#define ADC8 ADC_NUMBER_TO_CHANNEL(8)
#define ADC9 ADC_NUMBER_TO_CHANNEL(9)
#define ADC10 ADC_NUMBER_TO_CHANNEL(10)
#define ADC11 ADC_NUMBER_TO_CHANNEL(11)
#define ADC12 ADC_NUMBER_TO_CHANNEL(12)
#define ADC13 ADC_NUMBER_TO_CHANNEL(13)
#define ADC14 ADC_NUMBER_TO_CHANNEL(14)
#define ADC15 ADC_NUMBER_TO_CHANNEL(15)
extern const uint8_t NUM_ADC_CHANNELS;

// ----------- My devices -----------------------
extern SWITCH button;
extern SEGLED led_display;
extern MARQUEE marquee;
#define Temp_sensor1 ADC0
#define Temp_sensor2 ADC2
#define Bat_monitor ADC4
extern LED led_ext1;
extern LED led_ext2;
extern LED leds_int;
extern SABERTOOTH_MOTOR motor_1;
extern SABERTOOTH_MOTOR motor_2;
extern SABERTOOTH_DRIVER Sabertooth;
#define Remoteswitch_relay L6
extern SERVO servo;
extern SERVO_DRIVER Servo;
#define Xbee5v E6

void initHardware(void);
#ifdef __cplusplus
}
#endif
#endif

// undefine all ports so the user cannot change them directly
#undef PORTA
#undef DDRA
#undef PINA
#undef PORTB
#undef DDRB
#undef PINB
#undef PORTC
#undef DDRC
#undef PINC
#undef PORTD
#undef DDRD
#undef PIND
#undef PORTE
#undef DDRE
#undef PINE
#undef PORTF
#undef DDRF
#undef PINF
#undef PORTG
#undef DDRG
#undef PING
#undef PORTH
#undef DDRH
#undef PINH
#undef PORTJ
#undef DDRJ
#undef PINJ
#undef PORTK
#undef DDRK
#undef PINK
#undef PORTL
#undef DDRL
#undef PINL

// Undefine timer registers to stop users changing them
#undef TCNT0
#undef TCCR0B
#undef OCR0A
#undef OCR0B
#undef TCNT1
#undef TCCR1B
#undef OCR1A
#undef OCR1B
#undef OCR1C
#undef TCNT2
#undef TCCR2B
#undef OCR2A
#undef OCR2B
#undef TCNT3
#undef TCCR3B
#undef OCR3A
#undef OCR3B
#undef OCR3C
#undef TCNT4
#undef TCCR4B
#undef OCR4A
#undef OCR4B
#undef OCR4C
#undef TCNT5
#undef TCCR5B
#undef OCR5A
#undef OCR5B
#undef OCR5C

--- End code ---


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.

Wiring Info
I have my sabertooth, S1 connected to T (Uart 2) on Axon II

I have my Xbee connected to Uart0 on Axon II

Admin:

--- Quote from: Mastermime on February 05, 2013, 11:48:18 PM ---First thing I did wrong, was I sent 0 as triangle, but my motors still should've turned regardless.

--- End quote ---
I have no idea what sending '0 as triangle' means lol


--- Quote ---Is there a way to look at the output of a UART (Sabertooth) port?  I can use an FTDI cable, cant I?

--- End quote ---
yeap


Rather than giving you the answer, I'll tell you how to debug software like this. What you need to do is add output data that you can see.

Add in rprintf commands here and there in your code, and then view it with Hyperterminal using your FTDI cable. For example:


--- Code: ---rprintf("\n motorRCurVal is: %d", motorRCurVal);
delay_ms(100);//use this so it doesn't output a billion times per second
--- End code ---

You 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. :P

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version