cheverecamachidoche 13 Posted February 28, 2012 Share Posted February 28, 2012 Hi everyone Im a noob with msp430 and Im having troubles with serial comunication with a pololu maestro servocontroller, I got serial comunnication with an arduino board an it was easy but with the msp430 has been imposible for me. I dont know where is the problem and i cant get the serial comunication, please If someone can tell me whats wrong with the code I'll be so grateful, thank you. #include "msp430g2553.h" unsigned char TxByte=0; unsigned int result; unsigned int del; void in(); void main(void) { WDTCTL = WDTPW + WDTHOLD; P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_1; // ACLK = 32.768kHz (PAG. 435 SLAU144) UCA0BR0 = 0x03; // Baud rate de 9600, 32kHz/9600 = 3.41 (PAG. 435 SLAU144) UCA0BR1 = 0x00; //(PAG. 435 SLAU144) UCA0MCTL = UCBRS1 + UCBRS0; // Modulacion UCBRSx = 3 (PAG. 435 SLAU144) UCA0CTL1 &= ~UCSWRST; // Inicializa USCI (PAG. 451 SLAU144) while (1) { in(0,1000); //in(num servo, position) for (del=10000; del>0x01; del--); } } void in(unsigned int servo, unsigned int angle) { //bytes to servocontroller TxByte |= 0xAA; //envia byte de inicio (170 en decimal) TxByte |= 0x0C; //numero de dispositivo (12 por default) TxByte |= 0x04; //byte de comando TxByte |= servo; //numero de servo TxByte |= (((angle>>7)&0x3f)); TxByte |= (angle&0x7f); UCA0TXBUF = TxByte; } Quote Link to post Share on other sites
turd 31 Posted February 28, 2012 Share Posted February 28, 2012 Try this: #include "msp430g2553.h" unsigned char TxByte = 0; unsigned int result; unsigned int del; void in(unsigned int servo, unsigned int angle); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600 UCA0BR1 = 0; // Set upper half of baud select to 0 UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Start USCI while (1) { in(0, 1000); //in(num servo, position) __delay_cycles(10000); //__bis_SR_register(CPUOFF + GIE); //Enter LPM0 with interrupts } } void in(unsigned int servo, unsigned int angle) { //bytes to servocontroller TxByte |= 0xAA; //envia byte de inicio (170 en decimal) TxByte |= 0x0C; //numero de dispositivo (12 por default) TxByte |= 0x04; //byte de comando TxByte |= servo; //numero de servo TxByte |= (((angle >> 7) & 0x3f)); TxByte |= (angle & 0x7f); while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = TxByte; } Remember to use the correct pin: What are you using to program the chip, CCS, IAR or MSPGCC? cheverecamachidoche 1 Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 28, 2012 Author Share Posted February 28, 2012 I tried and is the same it doesnt work, I use CCS v4. Any advice? Quote Link to post Share on other sites
turd 31 Posted February 28, 2012 Share Posted February 28, 2012 Is this what you are using? Are you running the servocontroller at 5V? Are you running the MSP430G2553 at ~3.3V? Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 28, 2012 Author Share Posted February 28, 2012 Yes Im using that model of servo controller and Im running the MSP430G2553 at 3.3V and the servo controller is running at 5V, but Im using and sparkFun logic level converter to get the interface between the MSP430G2553 and the servo controller. Quote Link to post Share on other sites
turd 31 Posted February 28, 2012 Share Posted February 28, 2012 Here is another attempt: #include "msp430g2553.h" const unsigned char setup[] = {0x80, 0x01, 0x01, 0x00, 0x01}; const unsigned char pos_1[] = {0x80, 0x01, 0x04, 0x00, 13, 127}; const unsigned char pos_2[] = {0x80, 0x01, 0x04, 0x00, 35, 127}; unsigned char i; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600 UCA0BR1 = 0; // Set upper half of baud select to 0 UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Start USCI for(i = 0; i < 5; i++) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = setup[i]; } __delay_cycles(100000); while (1) { for(i = 0; i < 6; i++) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = pos_1[i]; } __delay_cycles(100000); for(i = 0; i < 6; i++) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = pos_2[i]; } __delay_cycles(100000); } } Does it doing anything? Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 28, 2012 Author Share Posted February 28, 2012 It Quote Link to post Share on other sites
RobG 1,892 Posted February 28, 2012 Share Posted February 28, 2012 //bytes to servocontroller TxByte |= 0xAA; //envia byte de inicio (170 en decimal) TxByte |= 0x0C; //numero de dispositivo (12 por default) TxByte |= 0x04; //byte de comando TxByte |= servo; //numero de servo TxByte |= (((angle>>7)&0x3f)); TxByte |= (angle&0x7f); UCA0TXBUF = TxByte; } First of all, you are incorrectly assigning value to TxByte, do not OR it. Second, shouldn't you be sending each byte individually? Something like that: //bytes to servocontroller while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = 0xAA; //envia byte de inicio (170 en decimal) while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = 0x0C; //numero de dispositivo (12 por default) while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = 0x04; //byte de comando while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = servo; //numero de servo while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = (((angle>>7)&0x3f)); while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = (angle&0x7f); } This could be optimized by adding a loop of course. Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 28, 2012 Author Share Posted February 28, 2012 I think that is correct but im a begginer and im learning jeje, here is a code that shows how to control a servo controller via serial commands using a pic, this is an example of the pololu servo controller webpage. #include<18f4550.H> #fuses HSPLL, NOMCLR, PUT, BROWNOUT, BORV43, NOWDT, NOPROTECT, NOLVP #fuses NODEBUG, USBDIV, PLL5, CPUDIV1, VREGEN, CCP2B3 #use delay(clock=48000000) #define TTL_TX1 PIN_C6 #define TTL_RX1 PIN_C7 #use rs232(xmit=TTL_TX1, rcv=TTL_RX1, bits=8, parity=N) void main() { delay_ms(2000); while(true) { // Send a Set Target command using the Pololu protocol. putc(0xAA); // Start Byte putc(0x0C); // Device ID = 12 putc(0x04); // Command = Set Target putc(0x00); // Channel = 0 putc(0x20); // Target position = 1000 us (typical minimum for servos) putc(0x1F); delay_ms(1000); // Send another Set Target command using the Pololu protocol. putc(0xAA); putc(0x0C); putc(0x04); putc(0x00); putc(0x70); // Target position = 1500 us (typical neutral for servos) putc(0x2E); delay_ms(1000); } } Quote Link to post Share on other sites
RobG 1,892 Posted February 28, 2012 Share Posted February 28, 2012 Yep, this is exactly what my code snipped above does. putc(0xXX) - is a function call that sends one char while(!(IFG2 & UCA0TXIFG)) - this is a loop that will execute until TX buffer is ready for another byte UCA0TXBUF = 0xXX - put the char in the buffer and send // Send a Set Target command using the Pololu protocol.putc(0xAA); // Start Byte putc(0x0C); // Device ID = 12 putc(0x04); // Command = Set Target putc(0x00); // Channel = 0 putc(0x20); // Target position = 1000 us (typical minimum for servos) putc(0x1F); You could also create putc function: void putc(char c) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = c; } One more thing, you do have crystal soldered, right? cheverecamachidoche 1 Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 28, 2012 Author Share Posted February 28, 2012 Ok this is the last code with the putc function, yes I soldered the crystal but is the same. #include "msp430g2553.h" unsigned char TxByte=0; unsigned int result; unsigned int del; void putc(char c); void in(unsigned int servo, unsigned int angle); void main(void) { WDTCTL = WDTPW + WDTHOLD; P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_1; // ACLK = 32.768kHz (PAG. 435 SLAU144) UCA0BR0 = 0x03; // Baud rate de 9600, 32kHz/9600 = 3.41 (PAG. 435 SLAU144) UCA0BR1 = 0x00; //(PAG. 435 SLAU144) UCA0MCTL = UCBRS1 + UCBRS0; // Modulacion UCBRSx = 3 (PAG. 435 SLAU144) UCA0CTL1 &= ~UCSWRST; // Inicializa USCI (PAG. 451 SLAU144) while (1) { in(0,1000); //in(num servo, position) for (del=10000; del>0x01; del--); } } void putc(char c) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = c; } void in(unsigned int servo, unsigned int angle) { //bytes to servocontroller putc(0xAA); //envia byte de inicio (170 en decimal) putc(0x0C); //numero de dispositivo (12 por default) putc(0x04); //byte de comando putc(servo); //numero de servo putc(((angle>>7)&0x3f)); putc(angle&0x7f); } Any other advice? Quote Link to post Share on other sites
RobG 1,892 Posted February 28, 2012 Share Posted February 28, 2012 OK, try one more thing, add P1SEL2 = BIT1 + BIT2; The code you have works for me with the line above and 1MHz DCO. cheverecamachidoche 1 Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 29, 2012 Author Share Posted February 29, 2012 I added the P1SEL2 line and change the clock to DCO, Now is working and this is the final code #include "msp430g2553.h" unsigned char TxByte=0; unsigned int result; unsigned int del; void putc(char c); void in(unsigned int servo, unsigned int angle); void main(void) { WDTCTL = WDTPW + WDTHOLD; P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSWRST; UCA0CTL1 |= UCSSEL_2; UCA0BR0 = 0x78; UCA0BR1 = 0x00; UCA0MCTL = UCBRS_1 + UCBRF_0; UCA0MCTL = UCBRS2; UCA0CTL1 &= ~UCSWRST; // Inicializa USCI (PAG. 451 SLAU144) while (1) { in(0,100); //in(num servo, position) for (del=10000000; del>0x01; del--); in(0,5000); //in(num servo, position) for (del=10000000; del>0x01; del--); } } void putc(char c) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = c; } void in(unsigned int servo, unsigned int angle) { //bytes to servocontroller putc(0xAA); //envia byte de inicio (170 en decimal) putc(0x0C); //numero de dispositivo (12 por default) putc(0x04); //byte de comando putc(servo); //numero de servo putc(((angle>>7)&0x3f)); putc(angle&0x7f); } RobG and turd Thank you very much!!! :clap: Quote Link to post Share on other sites
turd 31 Posted February 29, 2012 Share Posted February 29, 2012 I'm glad it's working Do you have any cool plans for it? Quote Link to post Share on other sites
cheverecamachidoche 13 Posted February 29, 2012 Author Share Posted February 29, 2012 If everything goes well It will be an hexapod robot jeje, thanks again Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.