Having trouble getting the DSMC to work with a PIC. I’ve looked thru the sample project here pololu.com/docs/0J2/4. I use a C compiler to program the PIC, when that didn’t work i tried the assembly routines (i.e. using the working register and movlw/movwf TXREG) which dont seem to work either.
My uart is correctly configured (8n1, 9600, non-inverted) and i wait for each byte to finish Tx before i send another. Reset is pegged at +5, the motors have their own power supply (commonly grounded w/ PIC) but still no life out of the Serial Motor Controller.
The example project says to turn the WDT off, but i dont see why that should make a difference. Any ideas or thoughts welcome.
How have you verified that your UART is configured correctly? Can you show the smallest piece of code that should work but doesn’t?
We don’t reset the watchdog timer in our example, so it must be disabled. It’s crucial in the sense that without doing so, the project won’t work.
Yep, UART works perfectly. I can easily send/recieve characters and strings from my PC to the PIC and back.
The smallest piece of code that should, but doesn work is here: I use a C function called putc() to send individual chars to the PIC. So i’ll hard code soemthing like
onto the PIC, but the motor controller doesn’t seem to show any signs of life. I reset the motorcontroller everytime by pulling RESET low and give it a few hundred msec to settle down before i use the sequence of putc()s.
It must have something to do w/ WDT but i can’t image why? My program is functionally equivalent to the obstacle avoiding robot example.
I don’t know why you are focused on the WDT. Do you have it enabled? If so, turn it off, at least until you get things working.
The code you posted wasn’t very helpful. I had that “smallest piece” bit in there to head off a 400-line post, but what you posted is not something that would work without other directly relevant code. For instance, there might be something wrong with what you are doing with the reset line. Your post makes it sound like you might be leaving the reset line low or not waiting long enough after raising it.
WDT is enabled by default, and i’m having trouble figuring out the table read/writes to disable it. You mentioned it was crucial in your previous post to disable it - i figure that’s the only thing left to fix?
My program is really quite short, so i’ll go ahead and post it. There are descriptive comments in there…
#pragma CLOCK_FREQ 40000000 //set the clock for 40MHz
void interrupt( void )
//Interrupt triggered by byte Rx on PIC UART. In the ISR, I recieve a 4byte pololu message from the PC and relay it back out on the Tx pin of the UART. The motor controller is connected to the PIC Tx line. This way i can see that Tx/Rx is taking place, even though some of the characters aren't displayable, or they look weird. Such as 0x80 which looks like the European currency symbol.
clear_bit( intcon, T0IF ); //clear TMR0 overflow flag
gets(buffer); // load 4byte pololu command into buffer
int i = 0;
while(buffer[i] != '\0')
putc(buffer[i++]); //4byte msg out to DSMC
//Unfortuntely, that didn't work. I wanted to simplify everythign as much as possible, so i tried 'hard coding' 4x putc commands back to back just to see if i could get it going. I also tried putting these in main(), right after the reset function but no luck.
putc(0x00); //device (0x00 for motors)
putc(0x00); //motor no. zero should always work
putc(0x7f); // max speed
//This doesnt seem to work either. I've checked and rechecked the wiring of the DSMC. Motor supply is separate from logic supply (but with common ground), both motors are hooked up, reset held high thru 4.7k pull-up, PIC Tx connected to serial input of DSMC.
//Configure PortB and Reset DSMC (pin 6)
trisb = 10111110;
trisb.6 = 0; //pull DSMC low
delay_ms(250); //wait 250 millisec
trisb.6 = 1; //reset DSMC
delay_ms(250); //wait for everything to settle
trisc = 128; //Set RC6/TX output and RC7/RX as an input
clear_bit( pir1,RCIF ); //Clear UART interrupt flag
txsta = 0x24; //TXEN = 1, BRGH = 1
rcsta = 0x90; //SPEN = 1, CREN = 1
pie1 = 0x20; //Enable UART receive interrupt
intcon = 0xD0; //Enable global, peripheral and INT0 interrupt
spbrg = 255; //9600
putc(0x0d); // Carriage Return
putc(0x0d); // Carriage Return
while( 1 ); //infinite loop
The motor reset part works fine. Meter reads +5 when PB6 high and +0 otherwise. I believe something goes wrong when TXing the 4byte message to the DSMC. I wish i had a logic analyzer so i could see if the correct values are being sent to the DSMC to remove all doubt.
I’ve also tried getting the DSMC to move by connecting it straight to my USBrs232 adapter instead of the PIC but no luck there either.
Well, you definitely need to get that WDT turned off. In older PICs, that wasn’t something you could do from the program, and it would be news to me if the newer ones let you do it. It should be an option you can set in your programmer (configuration bits in MPLAB, I think, but I don’t know if that’s what you’re using).
I don’t understand your connections. Are your PC and the motor controller connected to the same line? I don’t see how you’re waiting for the transmit buffer to have space; is that taken care of in putc()? It looks like you’re sending all kinds of other stuff to the same serial port (starting with 0x0d, the “PIC Ready>” string, and so on).
The comment about the straight connection to the USB adapter is troubling. I hope you’re not connecting ±10 V signals to a logic-level input.
I’m using sourceboost and the boostc compiler. There’s definately a way to do it, but i haven’t had much of a chance to fool aroudn with it. I’ll get it this weekend maybe.
I should have been more clear on my connections, but you are right. The PIC’s UART Tx is connected to both my USB<>RS232 converter AND the DSMC. So the PIC provides serial input to the DSMC and my PC terminal program at once. So whenever the PIC resets, it sends the “PIC Ready>” message to the PC AND the motor controller. The datasheet says the DSMC ‘ignores’ everything unless is sees a 0x80 so i thought it would be ok to force the DSMC to “listen” to bytes not intended for it. Is that a terrible idea?
As far as the rs232 adapter - no worries. It uses 0-5V logic levels, in fact i normally have it configured at 3V for using XBEE modules.
That’s definitely a problem. The motor controller can work with other motor controllers and compatible devices (such as our servo controllers) on the same line, but they definitely cannot handle extra stuff. The first byte is especially crucial because that’s how the devices determine the baud rate. Once you send something like that 0x0d, the motor controller will have no idea what’s going on.
However, if you first send a valid command and then keep all additional characters with the MSB clear (e.g. regular 7-bit ASCII characters), you should be able to do what you were trying to do.
yup, you were right. It works fine now.