A couple of issues with my IR code. Delay() and crystal settings.

I have tried to make my own IR transmitter and receiver code.

Currently, the Tx is an ATtiny85 with the IR led on PB1 with a 16Mhz crystal.

Here is the code. It uses Timer1 to make a square wave signal with a set period (38Khz).
The LED is turned on and off using the TCCR1A register.

/*
         8Mhz internal clock = 1/(8E6) period = 1.25e-7 seconds = 0.125uS
         38Khz period = 1/38E3 = 26.3uS
          26.3us / 0.125us = 210.4 ticks per period
          half period = 105 ticks...

         16Mhz external clock = 1/(16E6) period = 6.25E-8 seconds = 0.0625uS
         38Khz period = 1/38E3 = 26.3uS
          26.3us / 0.125us = 420 ticks per period
          half period = 210 ticks...
*/
#define crystal 16

// Byte value for TCCR1A register to turn LED on with 38Khz carrier.
#define on  B00010001   
# define off 0

void setup() {
  DDRB = 0
         | (1 << PB1); //Set pin PB1 as output

  if (crystal == 16) {
    OCR1A = 210;    // Counter Max...clock cycles before pin is toggled.
  }
  else if (crystal == 8) {
    OCR1A = 105;
  }
}

void loop() {

  for ( unsigned int num = 0; num < 64000; num++) {
    send_uint(num);
    delay(100);
  }
}

void send_uint(unsigned int x) {
 unsigned int mask = 0b1000000000000000;
 // Use the mask to shift bits out...
 
  TCCR1 = on;
  delayMicroseconds(300);
  TCCR1 = off;
  delayMicroseconds(900);

  while (mask) {

    if (mask & x) { // A 1 bit = A High, Low, High, Low.
      TCCR1 = on;
      delayMicroseconds(300);
      TCCR1 = off;
      delayMicroseconds(300);
      TCCR1 = on;
      delayMicroseconds(300);
      TCCR1 = off;
      delayMicroseconds(300);
    }
    else {            // A 0 bit = A High followed by nada.
      TCCR1 = on;
      delayMicroseconds(300);
      TCCR1 = off;
      delayMicroseconds(900);
    }
    mask = mask >> 1;
  }

}

Here is my Rx Code using a TSOP38238 IR receiver.
TSOP Datasheet

I noticed the required “cycles” being 10 per burst. So set the ON time for the LED on the Tx as 300us…giving a small headway over the datasheet 264ish uS.

#define bits 16
static unsigned long timeout_time = (bits+1) * 2000;
unsigned long data = 0;
volatile boolean iflag = false;
unsigned long t_start = 0;
unsigned long t_now = 0;
boolean timeout = false;

void setup() {

  pinMode(2, INPUT);
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(2), fallISR, FALLING);
}
void loop() {
  timeout = false;
  unsigned long data = 0;
  iflag = false;
  byte count = 0;
  while (!iflag) {}    // Wait for an initial start bit...
  t_start = micros();   // timeout reference time.
  iflag = false;         // Reset the interrupt flag.

  while (!timeout && (count < bits)) {    // While the timeout is false ...(packet is of set time length)
    count++;
    while (!iflag) {}     //wait for a signal
    iflag = false;
    delayMicroseconds(1050); // wait for the second pulse...

    if (iflag) {          // If there was a second pulse...
      data += 1;          //Add 1 to end of data.
      iflag = false;      // Reset the flag ready for next detection...
    }
    data = data << 1;        // shift left ready for next reading...

    if (micros() - t_start > timeout_time) {
      timeout = true;
    }
  }
  data = data >> 1;
  Serial.print(data);
  Serial.print("   ");
  Serial.println(data, BIN);
}

void fallISR() {

  iflag = true;

}

Example Serial output I get when using 16Mhz:

5756   1011001111100
5757   1011001111101
5758   1011001111110
5759   1011001111111
5760   1011010000000
5761   1011010000001
5762   1011010000010
5763   1011010000011
5764   1011010000100
5765   1011010000101
5766   1011010000110
5767   1011010000111
5768   1011010001000
5769   1011010001001
5770   1011010001010
5771   1011010001011
5772   1011010001100
5773   1011010001101
5774   1011010001110
5775   1011010001111
5776   1011010010000
5777   1011010010001
5778   1011010010010

My issues are as follows:

  1. On using the 8Mhz internal oscillator of the ATtiny85…I get rubbish. I DO get data…but it is all crap.
  2. I can not seem to use any speed faster than sending data every 100ms. I tried “50ms” delay between sends and get no Serial Output at all.

I think it may have something to do with over saturating the reciever.
Worst case is I send about 30 cycles every 1 bit. I send 16 bits…so about 30 x 16 = 480 cycles in a packet transmission.

If I send 10 packets (100ms delay) I am already pushing the TSOP over its spec? That is 4800 cycles a second…the data sheet says this:

Is there a question hidden in there somewhere or is this just a project Report?

JaBa: Is there a question hidden in there somewhere or is this just a project Report?

I stated my 2 issues. I can not seem to increase the frequency I send packets. The 8mhz internal oscillator setting causes malformed packets.

I'd use a scope to check the received codes and the test frames in real time. For the frame test add a digital output that goes high while waiting for the end of the bit frame.

DrDiettrich: I'd use a scope to check the received codes and the test frames in real time. For the frame test add a digital output that goes high while waiting for the end of the bit frame.

Thanks. Sadly I only own an old 2ch analog HAMEG scope but will suffice for the frames. I need to learn to use the thing properly. I assume it has a "trigger" function so I can view the actual packets as soon as the first bit arrives/is sent.

Hameg is great, used one myself for many years :-)

The 2 channels require some thought for proper trigger. Send short packages, then tune the time base so that the second channel also starts at the begin of a package. Or output a trigger signal in code, on some output pin.