Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of football_project by
Radio.cpp
- Committer:
- elmbed
- Date:
- 2016-01-09
- Revision:
- 44:4ad6133987ed
- Parent:
- 38:76e49d045a3b
- Child:
- 52:060fdec99780
- Child:
- 56:dccf9b22d594
File content as of revision 44:4ad6133987ed:
#include <RFM69.h>
#include <SPI.h>
#include "types.h"
#include "TA.h"
#define RADIO_STARTUP_ID 99
#define NETWORKID 101 //the same on all nodes that talk to each other
#define FREQUENCY RF69_915MHZ
//#define IS_RFM69HW //NOTE: uncomment this ONLY for RFM69HW or RFM69HCW
#define ENCRYPT_KEY "EncryptKey123456" // use same 16byte encryption key for all devices on net
#define ACK_TIME 50 // max msec for ACK wait
#define LED 9 // Anardino miniWireless has LEDs on D9
#define SERIAL_BAUD 115200
#define VERSION "1.0"
#define MSGBUFSIZE 64 // message buffersize, but for this demo we only use:
// 1-byte NODEID + 4-bytes for time + 1-byte for temp in C + 2-bytes for vcc(mV)
//RFM69::RFM69(PinName PinName mosi, PinName miso, PinName sclk,slaveSelectPin, PinName int)
RFM69 radio(P0_24,P0_23,P0_25,P0_28,P0_7);
static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network
extern "C" void writeToPhone(char *format, ...);
extern unsigned long millis();
#ifdef MASTER
static bool is_master = true;
#else
static bool is_master = false;
#endif
static int my_node_id = NODE_ID;
struct node_id_mapping
{
int mac;
int node_id;
};
struct extended_message
{
Message m;
int mac;
};
static node_id_mapping nodes[10] = {0};
static int node_idx = 0;
static int my_mac = 0;
void radio_init()
{
radio.initialize(FREQUENCY, my_node_id, NETWORKID);
radio.encrypt(0);
radio.promiscuous(promiscuousMode);
}
static int get_node_id(int mac)
{
for (int i = 0; i < node_idx; ++i)
{
if (nodes[i].mac == mac)
{
return nodes[i].node_id;
}
}
return 0;
}
static void slave_process(extended_message *em)
{
if (em->m.command == 'R')
{
// We have been given a node id
my_node_id = em->m.value;
writeToPhone("NID: %d\r\n", my_node_id);
// Now reset the radio :)
radio_init();
}
}
static void master_process(Message *m)
{
byte payload[10] = {0};
int node_id = 0;
if (m->command == 'S')
{
// Message from a cone requesting an ID.
// The payload should be part of the MAC address
node_id = 0;
if (node_idx == 0)
{
node_id = 2;
}
else
{
node_id = nodes[node_idx-1].node_id + 1;
}
int node_found = get_node_id(m->value);
if (node_found == 0)
{
nodes[node_idx].node_id = node_id;
nodes[node_idx++].mac = m->value;
}
else
{
node_id = node_found;
}
// Send the cone it's ID
extended_message em;
em.m.cone = 99;
em.m.command = 'R';
em.m.value = node_id;
em.mac = m->value;
payload[0] = (byte)em.m.command;
payload[4] = (byte)em.m.value & 255;
payload[3] = (byte)(em.m.value >> 8);
payload[2] = (byte)(em.m.value >> 16);
payload[1] = (byte)(em.m.value >> 24);
payload[8] = (byte)em.mac & 255;
payload[7] = (byte)(em.mac >> 8);
payload[6] = (byte)(em.mac >> 16);
payload[5] = (byte)(em.mac >> 24);
radio.send(em.m.cone, payload, sizeof(payload));
writeToPhone("SND: %d %d 0x%x\r\n", em.m.cone, node_id, em.mac);
}
}
void radio_send(Message *m)
{
static byte payload [6] = {0};
if (m == NULL)
{
return;
}
//writeToPhone("SM: %c to: %d frm: %d (%d)\r\n", m->command, m->cone, NODE_ID, m->value); /// DEBUG-only message
payload[0] = (byte)m->command;
payload[4] = (byte)m->value & 255;
payload[3] = (byte)(m->value >> 8);
payload[2] = (byte)(m->value >> 16);
payload[1] = (byte)(m->value >> 24);
payload[5] = (byte)'%';
radio.send(m->cone, payload, sizeof(payload));
}
bool radio_receive_complete()
{
return radio.receiveDone();
}
bool radio_receive(Message *m)
{
Message lm;
extended_message em;
if (m == NULL)
{
return false;
}
if (radio.receiveDone())
{
if (radio.DATALEN < 6)
{
return false;
}
lm.cone = radio.SENDERID;
lm.command = radio.DATA[0];
lm.value = ((int)radio.DATA[1] << 24);
lm.value |= ((int)radio.DATA[2] << 16);
lm.value |= (((int)radio.DATA[3]) << 8);
lm.value |= (radio.DATA[4]);
if (is_master && lm.command == 'S')
{
// Don't pass on radio startup messages
master_process(&lm);
return false;
}
else if (!is_master && radio.TARGETID == RADIO_STARTUP_ID)
{
em.mac = (int)radio.DATA[8] & 0xff;
em.mac |= (int)radio.DATA[7] << 8;
em.mac |= (int)radio.DATA[6] << 16;
em.mac |= (int)radio.DATA[5] << 24;
writeToPhone("RP: 0x%x\r\n", em.mac);
if (em.mac != my_mac)
{
writeToPhone("DM 0x%x\r\n", em.mac);
return false; // This message was meant for someone else
}
memcpy(&em.m, &lm, sizeof(Message));
slave_process(&em);
}
else if (radio.TARGETID == my_node_id)
{
memcpy(m, &lm, sizeof(Message));
writeToPhone("GM: %d %c %d\r\n", radio.SENDERID, m->command, m->value); /// DEBUG-only message
return true;
}
}
return false;
}
bool radio_ack_received(int cone)
{
return radio.ACKReceived(cone);
}
void radio_loop(int mac)
{
static unsigned long last_send = 0L;
unsigned long current = millis();
Message m;
if (my_mac == 0)
{
my_mac = mac;
}
if (is_master)
{
return; // Only needed for slave cones
}
if (my_node_id != RADIO_STARTUP_ID && current - last_send > 1000L)
{
writeToPhone("NID: %d\r\n", my_node_id);
last_send = current;
}
// Send out an i'm here message
if (my_node_id != RADIO_STARTUP_ID || current - last_send < 1000L)
{
return;
}
m.command = 'S';
m.cone = 1;
m.value = my_mac;
writeToPhone("SNM\r\n");
last_send = current;
radio_send(&m);
}
