Propeller Wireless Connectivity
I'm in the robotics club at my university and we're designing a robot to fight other robots. We have a pretty cool "spinning" design that will turn other robots into mush. However, we would like to be able to record sensor data and other things going on internally in the robot. We've thought about using an SD card, but that's kind of a hassle when we are testing it because we would have to put the SD in the robot, do our tests, take the SD out, put it in the computer... etc. We are all lazy...
We already use one of those pre-made robot remote controls that IMO, are kind of crude. I figured that if we are already using some kind of wireless link between the robot and controller, why not make our data logging wireless as well? This way we could do our tests on the robot(different movements), and instantly see the results on the TV screen(via a propeller of course!)
This bring me to the XBee... Anyone have any experience with these?· How about other digital RF means? I'd like to get a discussion of various wireless communication going, involving the propeller as the processor since that's what we are using.
We already use one of those pre-made robot remote controls that IMO, are kind of crude. I figured that if we are already using some kind of wireless link between the robot and controller, why not make our data logging wireless as well? This way we could do our tests on the robot(different movements), and instantly see the results on the TV screen(via a propeller of course!)
This bring me to the XBee... Anyone have any experience with these?· How about other digital RF means? I'd like to get a discussion of various wireless communication going, involving the propeller as the processor since that's what we are using.

Comments
John Abshier
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
http://www.parallax.com/Store/Accessories/Communication/tabid/161/CategoryID/36/List/0/Level/a/ProductID/111/Default.aspx?SortField=ProductName%2cProductName
or
http://www.rfdigital.com/
parallax used to sell a transiver made by them, but do not anymore I had a set and they work great, super simple. Not sure why.
TJ
@Leon, I REALLY like those ones from NORDIC. How much are they? It says they come in a 4mmx4mm QFN? Only requires an external crystal? Can the propeller provide the 16Mhz? How much are they?
I'm getting quite good range with the SFE modules - between the third and first floors where I live, although it depends on the orientation. The little ceramic antennas on the modules aren't very efficient. Inside a room the orientation doesn't matter. I'll check them outside tomorrow, and get some idea of the maximum range.
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
Post Edited (Leon) : 1/4/2009 9:48:52 PM GMT
There're no longer sold because RF Digital stopped producing them... I had to ask too here.
/* ** Tx.c ** Transmit test program for PIC18F4520 and nRF24L01 or nRF24L01+ ** Uses the Microchip C18 compiler ** Based on SFE code for the CC5X code in 24L01demo_V01.c */ #include <p18cxxx.h> #include <spi.h> #include <timers.h> // Pragmas #pragma config OSC = INTIO67 #pragma config PWRT = ON //#pragma config MCLRE = OFF #pragma config BOREN = OFF //function prototypes void init(void); void transmit_data(void); void configure_transmitter(void); unsigned char spi_Send_Read(unsigned char); unsigned char spi1_send_read_byte(unsigned char byte); void dly(unsigned int); // Defines #define SPI_SCK LATCbits.LATC3 // Clock pin, PORTC pin 3 #define SPI_SO LATCbits.LATC5 // Serial output pin, PORTC pin 5 #define SPI_SI PORTCbits.RC4 // Serial input pin, PORTC pin 4 #define SPI_CSN LATCbits.LATC2 // CSN output pin, PORTC pin 2 #define SPI_CE LATCbits.LATC1 // CE output pin, PORTC pin 1 #define SPI_IRQ PORTBbits.RB0 // IRQ input pin, PORTB pin 0 #define SPI_SCALE 4 // postscaling of signal #define LED LATAbits.LATA0 #define PB PORTAbits.RA1 // Macros #define nop() _asm nop _endasm void main(void) { init(); configure_transmitter(); while (1) { transmit_data(); LED = 1; dly(63973); //200 ms delay LED = 0; dly(40000); //3.27 s delay nop(); } } void init(void) { // run internal oscillator at 8 MHz OSCCON = OSCCON | 0x70; while (OSCCONbits.IOFS == 0) ; PORTA = 0x00; ADCON1 = 0x0F; // set up PORTA to be digital I/Os TRISA = 0x02; // PORTA<7.2,0> outputs PORTA<1> input TRISCbits.TRISC3 = 0; // SDO output TRISCbits.TRISC5 = 0; // SCK output TRISCbits.TRISC2 = 0; // CSN output TRISCbits.TRISC1 = 0; // CE output TRISBbits.TRISB0 = 1; // IRQ input OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1 OpenTimer0( TIMER_INT_OFF & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256 ); } void configure_transmitter(void) { unsigned char i, j, data, cmd; SPI_CE = 0; SPI_CSN = 0; // PTX, CRC enabled, mask a couple of ints spi_Send_Read(0x20); spi_Send_Read(0x38); SPI_CSN = 1; SPI_CSN = 0; //auto retransmit off spi_Send_Read(0x24); spi_Send_Read(0x00); SPI_CSN = 1; SPI_CSN = 0; //address width = 5 spi_Send_Read(0x23); spi_Send_Read(0x03); SPI_CSN = 1; SPI_CSN = 0; //data rate = 1MB spi_Send_Read(0x26); spi_Send_Read(0x07); SPI_CSN = 1; SPI_CSN = 0; //set channel 2, this is default but we did it anyway... spi_Send_Read(0x25); spi_Send_Read(0x02); SPI_CSN = 1; //set address E7E7E7E7E7, also default... spi_Send_Read(0x30); for (j = 0; j < 5; j++) { spi_Send_Read(0xE7); } SPI_CSN = 1; SPI_CSN = 0; //disable auto-ack, RX mode //shouldn't have to do this, but it won't TX if you don't spi_Send_Read(0x21); spi_Send_Read(0x00); SPI_CSN = 1; } void transmit_data(void) { unsigned char i, data, cmd; SPI_CSN = 0; //clear previous ints spi_Send_Read(0x27); spi_Send_Read(0x7E); SPI_CSN = 1; SPI_CSN = 0; //PWR_UP = 1 spi_Send_Read(0x20); spi_Send_Read(0x3A); SPI_CSN = 1; SPI_CSN = 0; //clear TX fifo //the data sheet says that this is supposed to come up 0 after POR, but that doesn't seem to be the case spi_Send_Read(0xE1); SPI_CSN = 1; SPI_CSN = 0; //4 byte payload spi_Send_Read(0xA0); spi_Send_Read(0x34); spi_Send_Read(0x33); spi_Send_Read(0x32); spi_Send_Read(0x31); SPI_CSN = 1; //Pulse CE to start transmission SPI_CE = 1; dly(65000); //delay 69 ms SPI_CE = 0; } unsigned char spi_Send_Read(unsigned char byte) { SSPBUF = byte; while(!DataRdySPI()) ; return SSPBUF; } void dly(unsigned int c) { INTCONbits.TMR0IF = 0; WriteTimer0(c); while (INTCONbits.TMR0IF == 0) ; }/* ** Rx.c ** Receive test program for PIC18F4520 and nRF24L01 or nRF24L01+ ** Uses the Microchip C18 compiler ** Based on SFE code for the CC5X code in 24L01demo_V01.c ** ** The LED is flashed five times when data are received. ** The received data in the buffer may be checked using the ** debugger Watch window.*/ #include <p18cxxx.h> #include <spi.h> #include <timers.h> // Pragmas #pragma config OSC = INTIO67 #pragma config PWRT = ON #pragma config MCLRE = OFF #pragma config BOREN = OFF //function prototypes void init(void); void reset_RX(void); void configure_RX(void); unsigned char spi_Send_Read(unsigned char); void dly(unsigned int); // Defines #define SPI_SCK LATCbits.LATC3 // Clock pin, PORTC pin 3 #define SPI_SO LATCbits.LATC5 // Serial output pin, PORTC pin 5 #define SPI_SI PORTCbits.RC4 // Serial input pin, PORTC pin 4 #define SPI_CSN LATCbits.LATC2 // CSN output pin, PORTC pin 2 #define SPI_CE LATCbits.LATC1 // CE output pin, PORTC pin 1 #define SPI_IRQ PORTBbits.RB0 // IRQ input pin, PORTB pin 0 #define SPI_SCALE 4 // postscaling of signal #define LED LATAbits.LATA0 #define PB PORTAbits.RA1 // Macros #define nop() _asm nop _endasm void main(void) { unsigned char i; init(); configure_RX(); while(1) { if (SPI_IRQ == 0) //wait for anything { for (i = 0; i < 5; i++) //flash LED 5 times if data received { LED = 1; dly(63973); // 200 ms delay LED = 0; dly(63973); // 196 ms } dly(63973); // 196 ms reset_RX(); } } } // initialise 18F4520 void init(void) { // run internal oscillator at 8 MHz OSCCON = OSCCON | 0x70; while (OSCCONbits.IOFS == 0) ; PORTA = 0x00; ADCON1 = 0x0F; // set up PORTA to be digital I/Os TRISA = 0x02; // PORTA<7.2,0> outputs PORTA<1> input TRISCbits.TRISC3 = 0; // SDO output TRISCbits.TRISC5 = 0; // SCK output TRISCbits.TRISC2 = 0; // CSN output TRISCbits.TRISC1 = 0; // CE output TRISBbits.TRISB0 = 1; // IRQ input OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1 OpenTimer0( TIMER_INT_OFF & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256 ); } //configure nRF24L01 for receive void configure_RX(void) { unsigned char i, j; SPI_CSN = 0; SPI_CE = 0; //PRX, CRC enabled spi_Send_Read(0x20); spi_Send_Read(0x39); SPI_CSN = 1; SPI_CSN = 0; //disable auto-ack for all channels spi_Send_Read(0x21); spi_Send_Read(0x00); SPI_CSN = 1; SPI_CSN = 0; //address width = 5 bytes spi_Send_Read(0x23); spi_Send_Read(0x03); SPI_CSN = 1; SPI_CSN = 0; //data rate = 1MB spi_Send_Read(0x26); spi_Send_Read(0x07); SPI_CSN = 1; SPI_CSN = 0; //4 byte payload spi_Send_Read(0x31); spi_Send_Read(0x04); SPI_CSN = 1; SPI_CSN = 0; //set channel 2 spi_Send_Read(0x25); spi_Send_Read(0x02); SPI_CSN = 1; SPI_CSN = 0; //set address E7E7E7E7E7 spi_Send_Read(0x30); for (j = 0; j < 5; j++) spi_Send_Read(0xE7); SPI_CSN = 1; SPI_CSN = 0; //PWR_UP = 1 spi_Send_Read(0x20); spi_Send_Read(0x3B); SPI_CSN = 1; SPI_CE = 1; } void reset_RX(void) { unsigned char i, j; unsigned char buffer; //Read RX payload SPI_CSN = 0; spi_Send_Read(0x61); for (j = 0; j < 4; j++) { buffer[noparse][[/noparse]j] = spi_Send_Read(0); } SPI_CSN = 1; //Flush RX FIFO SPI_CSN = 0; spi_Send_Read(0xE2); SPI_CSN = 1; SPI_CSN = 0; //reset int spi_Send_Read(0x27); spi_Send_Read(0x40); SPI_CSN = 1; } unsigned char spi_Send_Read(unsigned char byte) { SSPBUF = byte; while(!DataRdySPI()) ; return SSPBUF; } void dly(unsigned int c) { INTCONbits.TMR0IF = 0; WriteTimer0(c); while (INTCONbits.TMR0IF == 0) ; }It uses the C18 peripheral libraries. It should be quite easy to convert it into Spin.
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
Post Edited (Leon) : 1/5/2009 10:54:15 AM GMT