PDA

View Full Version : Propeller Wireless Connectivity



Philldapill
01-05-2009, 12:12 AM
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.

John Abshier
01-05-2009, 12:21 AM
I have used XBee as a wireless serial link to my PC from my robots. On the robot side I just use Full Duplex serial to send state information (x, y, speed, sensor readings, etc). On the PC side I just use a terminal program.

John Abshier

Leon
01-05-2009, 01:12 AM
I like the new Nordic nRF24L01+. SFE has some modules using it that I've just tried with a PIC, they work very well. They have an SPI interface.

Leon

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle

jazzed
01-05-2009, 01:59 AM
I've used SFE's bluetooth gold module successfully from my pc up to about 30ft with free line-of-sight with PST or Hyperterm.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve

TJHJ
01-05-2009, 03:27 AM
Transiver set from parallax?

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

Philldapill
01-05-2009, 04:52 AM
Thanks everybody! I didn't know there were so many solutions out there...

@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?

Leon
01-05-2009, 05:35 AM
They are quite cheap, about $2 each. They need a few other parts, mainly for matching the output to the antenna. I suppose the Propeller could supply the 16 MHz, if there isn't too much jitter. Most wireless mice and keyboards use the older nRF24L01. It's best to use the parts and PCB layout in the data sheet.

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

SRLM
01-05-2009, 11:08 AM
@TJHJ

There're no longer sold because RF Digital stopped producing them... I had to ask too here. (http://forums.parallax.com/showthread.php?p=755918)

Philldapill
01-05-2009, 01:39 PM
Just FYI, free chips and PCB's to anyone who will write code for that Nordic device. I am very interested in it, and would love to see some code made for the propeller!

Leon
01-05-2009, 06:47 PM
Here's the code for my test programs:




/*
** 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[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