I am using Pololu Low-Voltage Dual Serial Motor Controller in my project. I like it for being very compact and powerful - way better than my old L298-based one.
Today I tested it and found that the M1 channel works only for forward turning. When I send it a command to reverse ($80, $00, $02, $7F) it just stops. This channel responds to “stop” and “forward” commands properly though. The other (M0) channel works fine in all respects. Also the M1 channel LEDs are always dark, but the M0 channel LEDs work fine.
I had an occasion of a short-circuit close to the controller so perhaps I killed one of the chips, but I am not sure though. I tested the 4 power MOSfets by shorting legs 1 and 2 and they react properly, including the one responsible for rearward turning of the M1 motor. So this is likely not a MOSfet failure.
Anyways, is this a code problem, or I damaged the controller? Is there a simple way to fix it? Perhaps by replacing one of the parts?
ref: https://www.pololu.com/catalog/product/120 See code below.
#define MCU_FREQ 8000000UL
//#define F_CPU 20000000//CPU clock for Baby Orangutan
#define F_CPU 8000000//CPU clock for Orangutan
//***Uncomment ONE of the above lines for the specific device***
#define BAUD 2400//baud rate for UART
#define MYUBRR (F_CPU/16/BAUD-1)//baud rate variable for UART hardware
#include <avr/io.h>
#include <avr/interrupt.h>
#include "buzzer.h"
unsigned volatile char dataIn,newSerCmd=0;
void USART_Init(unsigned int ubrr){//Initialize USART hardware & settings for Serial Radio
UBRR0H=(unsigned char)(ubrr>>8);//set buad rate
UBRR0L=(unsigned char) ubrr;
UCSR0B=(1<<TXEN0)|(1<<RXEN0);//enable transmitter & receiver
UCSR0B|=(1<<RXCIE0);//enable receive complete interrupt
UCSR0C=(3<<UCSZ00);//Set frame format for 8bit with 1 stop
}
void USART_Trans(unsigned char dataOut){//Transmit a byte of data over USART
while(!(UCSR0A&(1<<UDRE0)));//wait for transmition to complete
UDR0=dataOut;
}
ISR(USART_RX_vect){//USART Byte reieved
dataIn=UDR0;//grab copy of serial byte
newSerCmd=1;//indicate new byte received
}
int main(){
USART_Init(MYUBRR);//Initialize USART
DELAY_MS(750);
while (1)
{
USART_Trans(0x80); // L rev
USART_Trans(0x00);
USART_Trans(0x00);
USART_Trans(0x3F);
buzzer (600, 100);
DELAY_MS(750);
USART_Trans(0x80); // L stop **
USART_Trans(0x00);
USART_Trans(0x00);
USART_Trans(0x00);
buzzer (1200, 50);
buzzer (900, 100);
DELAY_MS(750);
USART_Trans(0x80); // L fwd
USART_Trans(0x00);
USART_Trans(0x01);
USART_Trans(0x3F);
buzzer (900, 100);
DELAY_MS(750);
USART_Trans(0x80); // R Rev - HERE IT STOPS INSTEAD OF TURNING REVERSE!!!
USART_Trans(0x00);
USART_Trans(0x02);
USART_Trans(0x7F);
buzzer (1200, 100);
DELAY_MS(750);
USART_Trans(0x80); // R stop
USART_Trans(0x00);
USART_Trans(0x02);
USART_Trans(0x00);
buzzer (600, 50);
buzzer (800, 100);
DELAY_MS(750);
USART_Trans(0x80); // R fwd **
USART_Trans(0x00);
USART_Trans(0x03);
USART_Trans(0x7F);
buzzer (1500, 300);
DELAY_MS(750);
}
}
return 0;
}
//************************************************************************************************************
void DELAY_US( uint16_t microseconds ) // delay for specified number of mi?roseconds
{
register uint16_t loop_count;
#if MCU_FREQ == 8000000UL
loop_count = microseconds * 2; /* 8mhz clock, 4 instructions per loop_count */
#elif MCU_FREQ == 1000000UL
loop_count = microseconds / 4; /* 1mhz clock, 4 instructions per loop_count */
#elif MCU_FREQ == 16000000UL
loop_count = microseconds / 4; /* 1mhz clock, 4 instructions per loop_count */
#else
#error MCU_FREQ undefined or set to an unknown value!
loop_count = 0; /* don't really know what to do */
#endif
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" ( loop_count )
: "0" ( loop_count )
);
}
//*************************************** Delay MS *****************************************
void DELAY_MS( uint16_t milliseconds ) //Spin-wait in a loop for the specified number of milliseconds.
{ uint16_t i; for ( i = 0; i < milliseconds; ++i ) DELAY_US( 1000 ); }
//*******************************************************************************************