I would make this part faster:
// Send the user data
for (unsigned char i = 0; i < numBytes; i++)
{
unsigned int mask = 0x01; //mask to send bits
for (char j = 0; j < 8; j++)
{
unsigned int c = data[i] & mask;
switch( c )
{
case 0:
sendzero();
break;
case 1 :
sendone();
break;
}
mask = mask << 1; //get next bit
}//end of byte
}//end of data
my version:
// Send the user data
for (unsigned char i = 0; i < numBytes; i++) {
for (uint8_t mask = 0x01; mask; mask <<= 1) {
if (data[i] & mask) {
sendone();
} else {
sendzero();
}
}//end of byte
}//end of data
This not only make the code more compact but also faster.
delayMicroseconds(HALF_BIT_INTERVAL);
This does wait at least 4 us even if the parameter is less than 4.
To get a more constant timing I would declare the sendone and sendzero methods inline.