If you want to support multiple simultaneous radios you will need a static ISR for each one. You can have an array of them and dole them out as radios get added. Here is how that might look. The ISR's are at the bottom. (I merged the .h and .cpp into a single .ino for testing).
NOTE: I have compiler warnings set to ALL and there are a number of warnings that look like they indicate coding mistakes (like "A << 8 + B" which I think is parsing as "A << (8 + B)").
#include <EEPROM.h>
#define MAX_CHANGES 132
#define PULSE_DURATION 100
class Radio
{
public:
Radio();
void send(unsigned short destination, char * message, unsigned short source = 0, byte ttl = 255);
void setPin(int pin);
void setPairPin(int pin);
void masterBroadcastPin(int pin);
int isAvailable();
void resetAvailable();
char * getMessage();
void enableReceive();
void enableReceive(int pin);
void setSerial(unsigned short serial);
typedef struct HighLowPulses
{
int high;
int low;
};
static void receiveISR0();
static void receiveISR1();
static void receiveISR2();
static void receiveISR3();
private:
static Radio *radios[4];
static void(*ISRList[4])();
static byte radioCount;
byte radioIndex; // Index into ISR tables
int pin;
int repeat;
int pairPin;
unsigned short counter;
unsigned short serial;
int tolerance;
int available = 0;
char * message;
unsigned long changes[MAX_CHANGES];
HighLowPulses start = {4, 2}; //4 high 2 low to start transmission
HighLowPulses stop = {2, 4}; //2 high 4 low to stop transmission
HighLowPulses separator = {3, 3}; //separates id, occurrence and code
HighLowPulses one = {3, 1}; //3 high 1 low to send binary 1
HighLowPulses zero = {1, 3}; //1 high 3 low to send binary 0
unsigned short getCounter();
static inline unsigned int diff(int A, int B);
void incrementCounter();
void resetCounter();
void masterBroadcast();
void registerMaster(unsigned short master);
unsigned short getMaster();
unsigned long getHash(unsigned short serial, unsigned short counter);
bool validateHash(unsigned short serial, unsigned short counter, unsigned long hash);
void transmit(HighLowPulses levels);
void receive();
int parseMessage(int changeCount);
};
byte Radio::radioCount = 0;
void(*ISRList[])() = {Radio::receiveISR0, Radio::receiveISR1, Radio::receiveISR2, Radio::receiveISR3};
static inline unsigned int Radio::diff(int A, int B)
{
return abs(A - B);
}
Radio::Radio()
{
repeat = 2;
tolerance = 10;
message = calloc(1, sizeof(char));
radioIndex = radioCount++;
radios[radioIndex] = this;
}
void Radio::setPin(int pin)
{
pinMode(pin, OUTPUT);
pin = pin;
}
void Radio::setPairPin(int pin)
{
pinMode(pin, INPUT_PULLUP);
pairPin = pin;
}
//void masterBroadcastPin(int pin){
// pinMode(pin, INPUT_PULLUP);
// attachInterrupt(pin, masterBroadcast, FALLING)
//}
int Radio::isAvailable()
{
return available;
}
void Radio::resetAvailable()
{
available = 0;
free(message);
message = calloc(1, sizeof(char));
}
char * Radio::getMessage()
{
return message;
}
void Radio::enableReceive(int pin)
{
pinMode(pin, INPUT);
attachInterrupt(pin, ISRList[radioIndex], CHANGE);
}
void Radio::enableReceive()
{
enableReceive(pin);
}
unsigned short Radio::getCounter()
{
return EEPROM.read(2) << 8 + EEPROM.read(3);
}
void Radio::incrementCounter()
{
unsigned short counter = getCounter();
if (counter & 0b1111111111111111)
{
resetCounter();
}
else
{
counter++;
EEPROM.write(2, (byte) (counter & 0b1111111100000000) >> 8);
EEPROM.write(3, (byte) counter & 0b0000000011111111);
}
}
void Radio::resetCounter()
{
EEPROM.write(2, 0);
EEPROM.write(3, 0);
}
void Radio::masterBroadcast()
{
send(0, 0);
}
void Radio::registerMaster(unsigned short master)
{
EEPROM.write(0, (byte) (counter & 0b1111111100000000) >> 8);
EEPROM.write(1, (byte) counter & 0b0000000011111111);
}
unsigned short Radio::getMaster()
{
return EEPROM.read(0) << 8 + EEPROM.read(1);
}
unsigned long Radio::getHash(unsigned short serial, unsigned short counter)
{
//__________________________________________
}
bool Radio::validateHash(unsigned short serial, unsigned short counter, unsigned long hash)
{
unsigned long calculatedHash = getHash(serial, counter);
return calculatedHash == hash;
}
void Radio::setSerial(unsigned short serial)
{
serial = serial;
}
void Radio::send(unsigned short destination, char * message, unsigned short source = 0, byte ttl = 255)
{
int i = 0;
int bit;
unsigned short counter = getCounter();
unsigned long hash = getHash(serial, counter);
if (source == 0)
{
source = serial;
}
for (i; i < repeat; i++)
{
transmit(start);
bit = sizeof(ttl) * 8 - 1;
while (bit >= 0)
{
if (ttl & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
transmit(separator);
bit = sizeof(source) * 8 - 1;
while (bit >= 0)
{
if (source & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
transmit(separator);
bit = sizeof(destination) * 8 - 1;
while (bit >= 0)
{
if (destination & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
transmit(separator);
bit = sizeof(counter) * 8 - 1;
while (bit >= 0)
{
if (counter & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
transmit(separator);
bit = sizeof(hash) * 8 - 1;
while (bit >= 0)
{
if (hash & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
transmit(separator);
int messageLen = strlen(message);
int i = 0;
for (i; i < messageLen; i++)
{
bit = sizeof(message) * 8 - 1;
while (bit >= 0)
{
if (message[i] & 1 << bit)
{
transmit(one);
}
else
{
transmit(zero);
}
bit--;
}
}
transmit(stop);
//Delay next transmission
delayMicroseconds(PULSE_DURATION * 2);
}
incrementCounter();
}
void Radio::transmit(HighLowPulses levels)
{
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
delayMicroseconds(PULSE_DURATION * levels.high);
digitalWrite(pin, LOW);
delayMicroseconds(PULSE_DURATION * levels.low);
}
int Radio::parseMessage(int changeCount)
{
if (diff(changes[1], start.high * PULSE_DURATION) < tolerance && diff(changes[2], start.low * PULSE_DURATION) < tolerance)
{
Serial.println("Sync received");
Serial.println(changeCount);
int i = 0;
for (i; i < changeCount; i++)
{
Serial.print(i);
Serial.print(":");
Serial.println(changes[i]);
}
return 1;
}
return 0;
}
void Radio::receive()
{
static unsigned long lastTime = 0;
static int changeCount = 0;
unsigned long time = micros();
int duration = time - lastTime;
if (changeCount > MAX_CHANGES)
{
changeCount = 0;
time = 0;
}
changes[changeCount] = duration;
changeCount++;
lastTime = time;
parseMessage(changeCount);
}
void Radio::receiveISR0()
{
radios[0]->receive();
}
void Radio::receiveISR1()
{
radios[1]->receive();
}
void Radio::receiveISR2()
{
radios[2]->receive();
}
void Radio::receiveISR3()
{
radios[3]->receive();
}