Added nRF wireless communication
This commit is contained in:
parent
97f2e7c607
commit
792b615091
|
@ -19,6 +19,14 @@
|
|||
// version MEGA02_1 Changes because of a change in protocoll for AC 241 (nr of archers and E and F shooters) and added functionality: emergency stop, add archers E and F. Changes for signal robustness. (0 (0000) is sent as 12 (1100) to prevent decoding issues when 3 times 0 is sent (000000000000)
|
||||
|
||||
#include "utils.h"
|
||||
#include <SPI.h>
|
||||
#include <RF24.h>
|
||||
|
||||
/****************** User Config ***************************/
|
||||
uint64_t device_address = 0x0110104334LL;
|
||||
/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 40 (CE) & 41 (CSN) */
|
||||
RF24 radio(40, 41);
|
||||
/**********************************************************/
|
||||
|
||||
// Commands data structures
|
||||
enum PanelSide_t
|
||||
|
@ -43,7 +51,7 @@ struct cfg_t
|
|||
|
||||
struct trafficvalue_t
|
||||
{
|
||||
uint8_t cmd : 3; // < 0b111
|
||||
uint8_t cmd : 3; // < 0b111
|
||||
BuzzerStatus_t buzzer : 1;
|
||||
uint8_t TrafficLightLeft : 3;
|
||||
uint8_t TrafficLightRight : 3;
|
||||
|
@ -53,7 +61,7 @@ struct trafficvalue_t
|
|||
|
||||
struct statevalue_t
|
||||
{
|
||||
uint8_t cmd : 4; // = 0b1111
|
||||
uint8_t cmd : 4; // = 0b1111
|
||||
uint8_t abcd : 3; // unclear meaning
|
||||
uint8_t competition : 3; // unclear meaning
|
||||
uint8_t : 3;
|
||||
|
@ -114,7 +122,8 @@ union ReceivedCommand_t {
|
|||
//const uint8_t segment[16] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00, 0x3f, 0x00, 0x00, 0x73}; //0,1,2,3,4,5,6,7,8,9,-, , , , ,P
|
||||
const uint8_t segment[16] = {0xbe, 0x82, 0x6e, 0xea, 0xd2, 0xf8, 0xfc, 0x8a, 0xfe, 0xfa, 0x40, 0x0, 0xbe, 0x0, 0x0, 0x5e}; //0,1,2,3,4,5,6,7,8,9,-, , , , ,P
|
||||
|
||||
boolean dataAvailable(char &digit) {
|
||||
boolean dataAvailable(char &digit)
|
||||
{
|
||||
if (Serial1.available())
|
||||
{
|
||||
digit = Serial1.read(); // Read serial buffer
|
||||
|
@ -129,6 +138,51 @@ boolean dataAvailable(char &digit) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
boolean parseCommand(ReceivedCommand_t &ReceivedCommand)
|
||||
{
|
||||
// A command is received
|
||||
char digit;
|
||||
|
||||
// Parse command from nRF packets
|
||||
if (radio.available())
|
||||
{
|
||||
char inputString[6] = {0};
|
||||
// Variable for the received timestamp
|
||||
radio.read(&inputString, 5);
|
||||
|
||||
ReceivedCommand.raw = atoi(inputString);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dataAvailable(digit))
|
||||
{
|
||||
/* ** Buffer to store received char **
|
||||
* Data is an integer string terminated with newline '\n'
|
||||
* */
|
||||
static String inputString = "";
|
||||
|
||||
// Check if string terminator
|
||||
if (digit == '\r')
|
||||
{
|
||||
// Make string conversion
|
||||
ReceivedCommand.raw = inputString.toInt();
|
||||
inputString = "";
|
||||
|
||||
// Now decode command and apply to the panel
|
||||
// Refer to documentation for command structure
|
||||
}
|
||||
else // if (char) digit != '\n'
|
||||
{
|
||||
inputString += digit;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LR_PIN, INPUT_PULLUP);
|
||||
|
@ -157,94 +211,94 @@ void setup()
|
|||
|
||||
// Communication w/XBEE
|
||||
Serial1.begin(9600);
|
||||
|
||||
// Communication with nRF24
|
||||
radio.begin();
|
||||
// Set the PA Level low to prevent power supply related issues since this is a
|
||||
// getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
|
||||
radio.setPALevel(RF24_PA_LOW);
|
||||
// Setup for the USB module
|
||||
radio.setDataRate(RF24_2MBPS);
|
||||
radio.setCRCLength(RF24_CRC_16);
|
||||
radio.setRetries(15, 15);
|
||||
radio.setChannel(40);
|
||||
radio.setPayloadSize(32);
|
||||
|
||||
radio.openReadingPipe(1, device_address);
|
||||
|
||||
// Start the radio listening for data
|
||||
radio.startListening();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// A command is received
|
||||
char digit;
|
||||
if (dataAvailable(digit))
|
||||
if (parseCommand(ReceivedCommand))
|
||||
{
|
||||
/* ** Buffer to store received char **
|
||||
* Data is an integer string terminated with newline '\n'
|
||||
* */
|
||||
static String inputString = "";
|
||||
|
||||
// Check if string terminator
|
||||
if (digit == '\r')
|
||||
// Parsing of DIGITS command
|
||||
if (ReceivedCommand.d.cmd == 0b0)
|
||||
{
|
||||
// Make string conversion
|
||||
ReceivedCommand.raw = inputString.toInt();
|
||||
inputString = "";
|
||||
|
||||
// Now decode command and apply to the panel
|
||||
// Refer to documentation for command structure
|
||||
|
||||
// Parsing of DIGITS command
|
||||
if (ReceivedCommand.d.cmd == 0b0)
|
||||
// Parse command only if is same side as this panel (or comamnd says to override)
|
||||
if (ReceivedCommand.d.sideOverride || (ReceivedCommand.d.side == cfg.PanelSide))
|
||||
{
|
||||
// Parse command only if is same side as this panel (or comamnd says to override)
|
||||
if (ReceivedCommand.d.sideOverride || (ReceivedCommand.d.side == cfg.PanelSide))
|
||||
{
|
||||
CATPORT(MIDDIGIT_PORT) = segment[ReceivedCommand.d.mDigit];
|
||||
CATPORT(RIGHTDIGIT_PORT) = segment[ReceivedCommand.d.rDigit];
|
||||
// Turn on dot between minutes and seconds only if count is in minutes and its digit is a representable value (not dash)
|
||||
CATPORT(LEFTDIGIT_PORT) = segment[ReceivedCommand.d.lDigit];
|
||||
|
||||
if (ReceivedCommand.d.lDigit != CHAR_DASH && ReceivedCommand.d.minutes)
|
||||
digitalWrite(DOTS_PIN, HIGH);
|
||||
else
|
||||
digitalWrite(DOTS_PIN, LOW);
|
||||
}
|
||||
}
|
||||
// Parsing of TRAFFIC command
|
||||
else if (ReceivedCommand.t.cmd == 0b001)
|
||||
{
|
||||
// Set buzzer depending on mute switch
|
||||
if (cfg.BuzzerStatus == BUZZER_ON)
|
||||
{
|
||||
digitalWrite(HORNP_PIN, ReceivedCommand.t.buzzer);
|
||||
}
|
||||
CATPORT(MIDDIGIT_PORT) = segment[ReceivedCommand.d.mDigit];
|
||||
CATPORT(RIGHTDIGIT_PORT) = segment[ReceivedCommand.d.rDigit];
|
||||
// Turn on dot between minutes and seconds only if count is in minutes and its digit is a representable value (not dash)
|
||||
CATPORT(LEFTDIGIT_PORT) = segment[ReceivedCommand.d.lDigit];
|
||||
|
||||
// Set Traffic lights depending on side switch
|
||||
if (cfg.PanelSide == RIGHT)
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(0)); // green right side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(1)); // orange right side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(2)); // red right side
|
||||
|
||||
CATPORT(TRAFLIGHT_PORT) = ( ReceivedCommand.t.TrafficLightRight & _BV(0) ? 0b11 << 6 : 0) |
|
||||
( ReceivedCommand.t.TrafficLightRight & _BV(1) ? 0b1001 << 2 : 0) |
|
||||
( ReceivedCommand.t.TrafficLightRight & _BV(2) ? 0b11 << 3 : 0);
|
||||
}
|
||||
if (ReceivedCommand.d.lDigit != CHAR_DASH && ReceivedCommand.d.minutes)
|
||||
digitalWrite(DOTS_PIN, HIGH);
|
||||
else
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(0)); // green left side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(1)); // orange left side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(2)); // red left side
|
||||
digitalWrite(DOTS_PIN, LOW);
|
||||
}
|
||||
}
|
||||
// Parsing of TRAFFIC command
|
||||
else if (ReceivedCommand.t.cmd == 0b001)
|
||||
{
|
||||
// Set buzzer depending on mute switch
|
||||
if (cfg.BuzzerStatus == BUZZER_ON)
|
||||
{
|
||||
digitalWrite(HORNP_PIN, ReceivedCommand.t.buzzer);
|
||||
}
|
||||
|
||||
CATPORT(TRAFLIGHT_PORT) = ( ReceivedCommand.t.TrafficLightLeft & _BV(0) ? 0b11 << 6 : 0) |
|
||||
( ReceivedCommand.t.TrafficLightLeft & _BV(1) ? 0b1001 << 2 : 0) |
|
||||
( ReceivedCommand.t.TrafficLightLeft & _BV(2) ? 0b11 << 3 : 0);
|
||||
}
|
||||
// Set Traffic lights depending on side switch
|
||||
if (cfg.PanelSide == RIGHT)
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(0)); // green right side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(1)); // orange right side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightRight & _BV(2)); // red right side
|
||||
|
||||
// Set ABCD(EF)
|
||||
digitalWrite(A_PIN, ReceivedCommand.t.ArcherGroups & _BV(0) ); //A
|
||||
digitalWrite(B_PIN, ReceivedCommand.t.ArcherGroups & _BV(1) ); //B
|
||||
digitalWrite(C_PIN, ReceivedCommand.t.ArcherGroups & _BV(2) ); //C
|
||||
digitalWrite(D_PIN, ReceivedCommand.t.ArcherGroups & _BV(3) ); //D
|
||||
digitalWrite(AC_PIN, ReceivedCommand.t.ArcherGroups & (_BV(0) | _BV(2))); //AC
|
||||
digitalWrite(BD_PIN, ReceivedCommand.t.ArcherGroups & (_BV(1) | _BV(3))); //BD
|
||||
// EF not implemented in this hardware
|
||||
/*
|
||||
CATPORT(TRAFLIGHT_PORT) = (ReceivedCommand.t.TrafficLightRight & _BV(0) ? 0b11 << 6 : 0) |
|
||||
(ReceivedCommand.t.TrafficLightRight & _BV(1) ? 0b1001 << 2 : 0) |
|
||||
(ReceivedCommand.t.TrafficLightRight & _BV(2) ? 0b11 << 3 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(0)); // green left side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(1)); // orange left side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightLeft & _BV(2)); // red left side
|
||||
|
||||
CATPORT(TRAFLIGHT_PORT) = (ReceivedCommand.t.TrafficLightLeft & _BV(0) ? 0b11 << 6 : 0) |
|
||||
(ReceivedCommand.t.TrafficLightLeft & _BV(1) ? 0b1001 << 2 : 0) |
|
||||
(ReceivedCommand.t.TrafficLightLeft & _BV(2) ? 0b11 << 3 : 0);
|
||||
}
|
||||
|
||||
// Set ABCD(EF)
|
||||
digitalWrite(A_PIN, ReceivedCommand.t.ArcherGroups & _BV(0)); //A
|
||||
digitalWrite(B_PIN, ReceivedCommand.t.ArcherGroups & _BV(1)); //B
|
||||
digitalWrite(C_PIN, ReceivedCommand.t.ArcherGroups & _BV(2)); //C
|
||||
digitalWrite(D_PIN, ReceivedCommand.t.ArcherGroups & _BV(3)); //D
|
||||
digitalWrite(AC_PIN, ReceivedCommand.t.ArcherGroups & (_BV(0) | _BV(2))); //AC
|
||||
digitalWrite(BD_PIN, ReceivedCommand.t.ArcherGroups & (_BV(1) | _BV(3))); //BD
|
||||
// EF not implemented in this hardware
|
||||
/*
|
||||
digitalWrite(6, (((statevalue >> 7) & B00000111) != 2) and (trafficvalue & 0x4000)); //E
|
||||
digitalWrite(7, (((statevalue >> 7) & B00000111) != 2) and (trafficvalue & 0x8000)); //F
|
||||
digitalWrite(A15, (((statevalue >> 7) & B00000111) == 2) and (trafficvalue & 0x4000)); //green right arrow for fita finals
|
||||
digitalWrite(39, (((statevalue >> 7) & B00000111) == 2) and (trafficvalue & 0x8000)); //green left arrow for fita finals
|
||||
*/
|
||||
|
||||
// Set not{A,B,C,D,(E,F)}
|
||||
/*if (cfg.abcd != 6)
|
||||
// Set not{A,B,C,D,(E,F)}
|
||||
/*if (cfg.abcd != 6)
|
||||
{
|
||||
uint8_t notABCD_on = 0;
|
||||
// not A is on if archer group A is not selected
|
||||
|
@ -271,18 +325,13 @@ void loop()
|
|||
digitalWrite(notC_PIN, HIGH);
|
||||
digitalWrite(notD_PIN, HIGH);
|
||||
}*/
|
||||
}
|
||||
// Parsing of STATE command
|
||||
else if (ReceivedCommand.s.cmd == 0b1111)
|
||||
{
|
||||
cfg.abcd = ReceivedCommand.s.abcd;
|
||||
cfg.competition = ReceivedCommand.s.competition;
|
||||
cfg.GroupsNumber = ReceivedCommand.s.GroupsNumber;
|
||||
}
|
||||
}
|
||||
else // if (char) digit != '\n'
|
||||
// Parsing of STATE command
|
||||
else if (ReceivedCommand.s.cmd == 0b1111)
|
||||
{
|
||||
inputString += digit;
|
||||
cfg.abcd = ReceivedCommand.s.abcd;
|
||||
cfg.competition = ReceivedCommand.s.competition;
|
||||
cfg.GroupsNumber = ReceivedCommand.s.GroupsNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue