Problems with the SMC02B Motor Controller + ATMega64

Hey,

I’m working with Digilent’s Cerebot, which uses the ATMega64 atmel chip, a SMC02B motor controller and two 100:1 Micro Metal gearhead motors and am having no luck getting the motor controller to respond…for the most part. Every once and a while the second motor (connected to pins 8 and 9) will pulse as if the motor was properly configured followed by nothing. This is also incredibly random and happens very rarely.

Right now I’m working with some fairly simple c code, just initializing the USART and attempting to communicate with the chip:

#include <inttypes.h>  			// included to use the uint8_t type
#include <avr/io.h>				// Allows use of PORTX, PINX, DDRX etc.

// Contains a delay function used in visableDelay
#include <util/delay.h>			

/* ------------------------------------------------------------ */
/*					 Definitions								*/
/* ------------------------------------------------------------ */
#define FOSC 8000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

void USART_Init( unsigned int ubrr )
{
	/* Set baud rate */
	UBRR1H = (unsigned char)(ubrr>>8);
	UBRR1L = (unsigned char)ubrr;

	/* Enable transmitter */
	UCSR1B = (1<<TXEN1);

	UCSR1C = (0<<USBS1);
}

void Tmx( unsigned char data )
{	
	/* Wait for empty transmit buffer */
	while ( !( UCSR1A & (1<<UDRE1)) );

	/* Put data into buffer, sends the data */
	UDR1 = data;
}

void visableDelay(uint8_t cnt)
{
	uint8_t c;

	PORTE = 0xFF;

	for(c = 0; c < cnt; c++)
	{
		_delay_loop_2(0x8000);			
	}

	PORTE = 0x00;
}

void enMot()
{
	// Bring reset high
	PORTB = (1<<PB4);
}

void disMot()
{
	// Reset the device
	PORTB = (0<<PB4);
}

void resetMot()
{
	disMot();

	visableDelay(10);

	enMot();

	visableDelay(100);
}

void initMot()
{
	Tmx(0x80);
	Tmx(0x02);
	Tmx(0x02);
	while ( !( UCSR1A & (1<<UDRE1)) );
}

void debug()
{
	// initialize the port E pins as all 1’s 
	// (a 1 turns the LED on, a 0 turns it off)
	PORTE = 0xFF;
	visableDelay(30);
	PORTE = 0x00;
}

int main(void)
{
	// Set up port E as outputs, port E 
	// bits 4 through 7 are the onboard LEDS
	DDRE = 0xFF;					

	// Set up port b
	DDRB = (1<<DDB4);
	PORTB = (1<<PB4);

	// Initialize serial transmission
	USART_Init(MYUBRR);

	resetMot();

	// Configure the motor
	initMot();
	visableDelay(100);

	resetMot();
	visableDelay(100);
	
	// Go...
	Tmx(0x80);
	Tmx(0x00);
	Tmx(0x00);
	Tmx(0x7F);
}

If anyone has any clue why it’s not even responding to the configuration command, that would help me out a ton.

Thanks,
Berdon

Hello,
Your main() function for the AVR reaches its end after starting to send the last byte, right? This is generally a bad thing to do, since it can cause random behavior like what you described. I’m not sure that that’s the problem, but if you can try putting a while(1); statement or something like that after sending the bytes, maybe you’ll have better luck.

By the way, do you have a way of debugging the serial output? An oscilloscope would be best, but even an LED or a voltmeter on the serial output can be a big help in figuring out what the problem is.

-Paul

During testing I did add a loop near the end to no avail. My serial commands do seem correct when ran through an oscilloscope.

A concern of mine is that the baud rate might not be 9600 since the internal RC oscillator of the ATMega64 is calibrated for 5v but the Cerebot board uses an onboard 3.3v (3.2?) regulator. When connected to my AVRISP it runs at 5v though, so I think that’s probably not the problem, but a concern none the less.

Hello.

The micro motor controller should be able to adjust to whatever baud rate you’re using, even if it’s not exactly 9600. Can you post screenshots from your oscilloscope and pictures of your setup?

- Jan

Yeah, I’m not in the lab right now but will be heading over there soon.

0.1 uF capacitors are across each motors terminals, between ground and Vcc, and between ground and reset. The LED is connected between pin 9 and ground. I’ll post the oscilloscope pictures shortly.



Alright! After a bit of work with the oscilloscope, we figured out that we were sending 6 data bits instead of 8. Coincidentally, the ATMega64 databook says the default settings are for 8 databits but without setting them appropriately, we were only seeing 6…

Thanks for the help!

Great! I’m glad you got it working. Could you post your final code here in case someone else has trouble with the 6-bit/8-bit difference?

Thanks,
-Paul

Absolutely. I’ll post a bit of testing code for both single and dual modes of operation - should be enough to get anyone with an Atmel chip started.