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:
- AntonLS
- Date:
- 2016-01-19
- Revision:
- 65:7addf8506bdb
- Parent:
- 64:8886b5e4ab57
- Child:
- 67:5650f461722a
File content as of revision 65:7addf8506bdb:
#include <RFM69.h>
#include <SPI.h>
#include "types.h"
#include "TA.h"
#include "DataStore.hh"
#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();
extern bool is_master;
struct node_id_mapping
{
int mac;
int node_id;
};
struct extended_message
{
Message m;
int mac;
};
/*
int get_node_id()
{
return my_node_id == RADIO_STARTUP_ID ? 0 : my_node_id;
}
*/
static node_id_mapping nodes[10] = {0};
static int node_idx = 0;
static int my_mac = 0;
void radio_init()
{
radio.initialize(FREQUENCY, datastore_node_id(), NETWORKID);
radio.encrypt(0);
radio.promiscuous(promiscuousMode);
}
/* Gets the node ID which is associated with the
* given mac. If no ID has been given then zero
* is returned.
*
* @param mac - the mac address if the cone
* @returns ID if found else zero
*/
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;
}
/* Process a radio startup message from the master.
*
* @param em - the message from the master
*/
static void slave_process(extended_message *em)
{
if (em->m.command == 'R')
{
// We have been given a node id
datastore_set_node_id(em->m.value);
if( Dbg ) writeToPhone("NID: %d\r\n", datastore_node_id());
// Now reset the radio :)
radio_init();
}
}
/* Process a radio startup message from a slave.
*
* @param m - the message from the slave
*/
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));
if( Dbg ) 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;
}
//if( Dbg ) writeToPhone("SM: %c to: %d frm: %d (%d)\r\n", m->command, m->cone, NODE_ID, m->value);
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;
if( Dbg ) writeToPhone("RP: 0x%x\r\n", em.mac);
if (em.mac != my_mac)
{
if( Dbg ) 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 == datastore_node_id())
{
memcpy(m, &lm, sizeof(Message));
if( Dbg ) writeToPhone("GM: %d %c %d\r\n", radio.SENDERID, m->command, m->value);
return true;
}
}
return false;
}
bool radio_ack_received(int cone)
{
return radio.ACKReceived(cone);
}
/* This is only needed for the slave cones, the master
* cone will just return.
*
* If the slave cone doesn't have a valid node ID send out
* the node ID request message to the master cone.
*
* @param mac - the mac address for this cone (currently the first two bytes)
*/
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 (datastore_node_id() != RADIO_STARTUP_ID && current - last_send > 1000L)
{
if( Dbg ) writeToPhone("NID: %d\r\n", datastore_node_id());
last_send = current;
}
// Send out an i'm here message
if (datastore_node_id() != RADIO_STARTUP_ID || current - last_send < 1000L)
{
return;
}
m.command = 'S';
m.cone = 1;
m.value = my_mac;
if( Dbg ) writeToPhone("SNM\r\n");
last_send = current;
radio_send(&m);
}
