LV Dual Serial Motor Controller fails to reverse

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


//*******************************************************************************************

Hello,

If the LEDs aren’t doing anything, the controller is likely damaged beyond simple repair. Also, your test might have damaged the board more since shorting the gates to ground would also mean shorting the gate drivers to ground. Did that channel ever work?

- Jan

Jan, Would you advice me to try to replace the MA3238 chip anyways? Looks like the MOSfets are OK and if PIC were damaged - the controller behavior would be much worse. Also I’d appreciate an advice on less damaging way to check mosfets.
PS: I will order a replacement anyways, it’s just I am now in Russia and won’t get it for 2 weeks.

The LEDs are connected right to the PIC, so if they’re not doing anything, the PIC is probably bad (it could be just the I/O pins if they got shorted out, and the rest of the PIC might be working). In general, it’s difficult to test components in a circuit, so I don’t really have any advice for you on the MOSFET testing. In my experience, they’ve usually broken in a way that they can’t turn off, so that’s detectable by seeing the short from drain to source.

That 2 week delay sucks. Before you had that short-circuit incident, was the unit working correctly?

- Jan

Jan,
Thank you for the excuse not to re-solder a 28-pin chip. :slight_smile: Anyways, I will use the next 2 weeks for something else useful.
The controller was working fine originally. It was probably damaged when I has a short close to it.