Openbeacon Axbo Example Code
From OpenPCD
Example Source Code
The following program is a simple example for initializing the NRF24L01 of the Sputnik and putting it into receive mode to receive all packages from the aXbo motion sensors. Every package which is received is sent out via RS232 protocol 38400, 8,n,1 on the optional buzzer output on the Sputnik (see schematic), which is not used on the PCB v0.2. The program is sending only the first package to the PC and is filtering all packages which are just sent for dealing with air collisions. The program was written for the Hitech PICC compiler and compiles with the free version of it. The included serial.c is part of the compiler and copyright by Hitech. It needs to be modified to use RA1 as TX for the RS232 protocol.
#include <pic.h> #include <string.h> __CONFIG (0x00d4); #include "serial.c" #define LED_OFF RC5=0 #define LED_ON RC5=1 #define BUZZER_ON RA1=1 #define BUZZER_OFF RA1=0 #define BUTTON_STATE RA0 #define TMR1H_3ms ((65511)>>8)&0xFF #define TMR1L_3ms (65511)&0xFF //for the NRF24L01 #define IRQ_STATE RA2 #define MISO_STATE RC2 #define SCK_LOW RC0=0 #define SCK_HIGH RC0=1 #define MOSI_LOW RC1=0 #define MOSI_HIGH RC1=1 #define CSN_LOW RC3=0 #define CSN_HIGH RC3=1 #define CE_LOW RC4=0 #define CE_HIGH RC4=1 #define BUF_LEN 4 unsigned char buffer[18] = { 0 }; unsigned char print_buffer[18] = { 'A' }; unsigned char SPI (unsigned char command, unsigned char size, unsigned char *buffer, unsigned char rw) { signed char b = 8; unsigned char last_status = 0; CSN_LOW; for (b = 7; b >= 0; b--) { if (command & (1 << (b))) { MOSI_HIGH; } else { MOSI_LOW; } SCK_HIGH; if (MISO_STATE == 1) { last_status |= (1 << (b)); } SCK_LOW; } while (size > 0) { if (rw) { buffer[size - 1] = 0; }; for (b = 7; b >= 0; b--) { if (rw == 0) { //write MOSI=dataoutput if (buffer[size - 1] & (1 << (b))) { MOSI_HIGH; } else { MOSI_LOW; } SCK_HIGH; } else { //read MISO=datainput SCK_HIGH; if (MISO_STATE == 1) { buffer[size - 1] |= (1 << (b)); } } SCK_LOW; } size--; } CSN_HIGH; return last_status; } void wait_3ms () { TMR1H = TMR1H_3ms; TMR1L = TMR1L_3ms; TMR1ON = 1; SLEEP (); } static void interrupt isr (void) { if (TMR1IF) { TMR1IF = 0; TMR1ON = 0; } if (RAIF) { //by RFID chip or Button RAIF = 0; if (IRQ_STATE == 0) { RAIE = 0; } } } void send_data (void) { unsigned char i; for (i = 0; i < (BUF_LEN << 1); i++) { putch (print_buffer[i]); print_buffer[10 + i] = print_buffer[i]; } putch ('\r'); putch ('\n'); } char dec2hex (char c) { c = c & 0x0f; if (c < 10) { return c + 48; } else { return c + 55; } } int main (void) { unsigned char i = 0; unsigned char channel = 49; unsigned char buffer_state = 10; //internal RC oscillator, 8MHz OSCCON = 0x71; //disable CVref to save power VREN = 0; //set RAx to digital input CMCON0 = 0x07; ANSEL = 0x00; //digital //I/O config TRISC = 0x04; //only RC2 is input TRISA = 0x3D; //only RA1 write - rest is input //disable pullups to save energy WPUA = 0x00; //everything off by default BUZZER_OFF; LED_OFF; //global interrupts on GIE = 1; //peripheral interrupts on PEIE = 1; //interrupts from PORTA on RAIE = 1; RAIF = 0; //enable interrupt for timer1 TMR1IE = 1; TMR1IF = 0; //clear interrupt flag //external clock for timer1, prescalor 4, no sync T1CON = 0x2E; //interrupt on high-low level flank on RA2 IOCA |= 0x04; RAIE = 0; CSN_HIGH; CE_LOW; SCK_LOW; wait_3ms (); //configuring for receiving //CONFIG=0 - deleted every configuration buffer[0] = 0; SPI (0x20 | 0x00, 1, &buffer[0], 0); //Flush RX buffers SPI (0xE2, 0, &buffer[0], 0); buffer[0] = 0; //EN_AA=0 - Enhanced Shockburst: disabled SPI (0x20 | 0x01, 1, &buffer[0], 0); //EN_RXADDR - Enable RX Addresses: pipe 0 buffer[0] = 0x01; SPI (0x20 | 0x02, 1, &buffer[0], 0); //SETUP_AW=1 - RX/TX Address Field Width: 0x00=2byte buffer[0] = 0x00; SPI (0x20 | 0x03, 1, &buffer[0], 0); //RX_ADDR_P0=12321 - receive address of datapipe 0, one time on buffer[0] = 0xBB; buffer[1] = 0xBB; buffer[2] = 0xBB; buffer[3] = 0xBB; buffer[4] = 0xBB; SPI (0x20 | 0x0A, 5, &buffer[0], 0); //RX_PW_P0 - number of bytes for the RX FIFO: 4byte buffer[0] = BUF_LEN; SPI (0x20 | 0x11, 1, &buffer[0], 0); //RF_CH=00 - rf channel: frequency channel=0 buffer[0] = channel; SPI (0x20 | 0x05, 1, &buffer[0], 0); //RF_SETUP=1 - rf setup register: 1mbps, -12dbm, low-noise amplifier(lna) gain buffer[0] = 0x00; SPI (0x20 | 0x06, 1, &buffer[0], 0); //CONFIG=0x3F - RX interrupt, enable CRC 2bytes, Power up, PRX mode buffer[0] = 0x3F; SPI (0x20 | 0x00, 1, &buffer[0], 0); //Flush RX buffer SPI (0xE2, 0, &buffer[0], 0); //STATUS - clear interrupts: RX_DR, TX_DR, MAX_RT; buffer[0] = 0x70; SPI (0x20 | 0x07, 1, &buffer[0], 0); wait_3ms (); CE_HIGH; RAIE = 0; //Receive while (1) { //SLEEP(); if (IRQ_STATE == 0) { do { //read status SPI (0x00 | 0x07, 1, &buffer[0], 1); buffer_state = buffer[0]; if ((buffer_state & 0x0E) != 0x0E) { //1. read buffer SPI (0x61, BUF_LEN, &buffer[0], 1); for (i = 0; i < BUF_LEN; i++) { print_buffer[0 + (i << 1)] = dec2hex (buffer[i] >> 4); print_buffer[1 + (i << 1)] = dec2hex (buffer[i]); //putch(' '); } //2. reset interrupt flag //clear interrupt flag in status register buffer[0] = 0x70; SPI (0x20 | 0x07, 1, &buffer[0], 0); if ((print_buffer[6] != print_buffer[16]) || (print_buffer[7] != print_buffer[17])) { send_data (); } else { if ((print_buffer[16] == '4') && ((print_buffer[17] == '0') || (print_buffer[17] == '4') || (print_buffer[17] == '5') || (print_buffer[17] == '6') || (print_buffer[17] == '7'))) { if ((print_buffer[0] == print_buffer[10]) && (print_buffer[1] == print_buffer[11]) && (print_buffer[2] == print_buffer[12]) && (print_buffer[3] == print_buffer[13]) && (((print_buffer[4] == print_buffer[14]) && (print_buffer[5] >= print_buffer[15])) || (print_buffer[4] > print_buffer[14]))) { print_buffer[14] = print_buffer[4]; print_buffer[15] = print_buffer[5]; } else { send_data (); } } else if ((print_buffer[16] == '4') && (print_buffer[17] == '1')) { if ((print_buffer[4] != print_buffer[14]) || (print_buffer[5] != print_buffer[15])) { send_data (); } } else { send_data (); } } } } while ((buffer_state & 0x0E) != 0x0E); } } }