#define MESSAGE_TYPE_SIMPLE 0 #define MESSAGE_TYPE_ADVANCED 1 #define HETXPIN PINB5 // output 13 on arduino // variables used for receiving the messages unsigned int pulseWidth = 0; unsigned int latchStage = 0; signed int bitCount = 0; byte bit = 0; byte prevBit = 0; // variables for storing the data received unsigned long sender = 0; unsigned int recipient = 0; byte command = 0; bool group = false; // variables for sending messages byte messageType; unsigned int messageCount; void setup(){ } void send(unsigned int s, unsigned int r, byte c){ // disable all interrupts TIMSK1 = 0; // reset variables messageCount = 0; latchStage = 0; bitCount = 0; bit = 0; prevBit = 0; pulseWidth = 10000; // set data to transmit sender = s; recipient = r; command = c; // specify encoding messageType = MESSAGE_TYPE_SIMPLE; initSend(); } void initSend(){ // ensure the transmitter pin is set for output DDRB |= _BV(HETXPIN); // the value that the timer will count up to before firing the interrupt OCR1A = (pulseWidth * 2); // toggle OC1A on compare match TCCR1A = _BV(COM1A0); // CTC mode: top of OCR1A, immediate update of OCR1A, TOV1 flag set on MAX TCCR1B |= _BV(WGM12); // enable timer interrupt for timer 1, disable input capture interrupt TIMSK1 = _BV(OCIE1A); } /** * The timer interrupt handler. * * This is where the message is transmitted. * * The timer interrupt is used to wait for the required length of time. Each call of this * function toggles the output and determines the length of the time until the function is * called again. * * Once the message has been transmitted this class will switch back to receiving. */ ISR(TIMER1_COMPA_vect) { if(messageType == MESSAGE_TYPE_SIMPLE) { if(!prevBit && bitCount != 25) { PORTB |= _BV(HETXPIN); } else { PORTB &= ~_BV(HETXPIN); } if(bitCount % 2 == 0) { // every other bit is a zero bit = 0; } else if(bitCount < 8) { // sender bit = ((sender & _BV((bitCount - 1) / 2)) != 0); } else if(bitCount < 16) { // recipient bit = ((recipient & _BV((bitCount - 9) / 2)) != 0); } else if(bitCount < 24) { // command bit = ((command & _BV((bitCount - 17) / 2)) != 0); } if(bitCount == 25) { // message finished bitCount = 0; messageCount++; pulseWidth = 10000; if(messageCount == 5) { // go back to receiving messageCount = 0; TCCR1A = 0x00; TCCR1B = 0x02; TIMSK1 = _BV(ICIE1); return; } } else { if(prevBit && bit || !prevBit && !bit) { pulseWidth = 375; } else { pulseWidth = 1125; } if(prevBit) { bitCount++; } prevBit = !prevBit; } } // set the next delay OCR1A = (pulseWidth * 2); } void loop(){ // in my test situation the sender ID=7 the receiver ID=12 the ON command=11 send(7,12,11); delay(2000); // wait 2 sec send(7,12,7); delay(2000); }