1
\$\begingroup\$

I am making a an ATTiny85 IR receiver, programmed with an Arduino Uno.

I'm using a modified version of this code (because the other IR libraries I found weren't compatible).

It's working... sort of. It will respond to anything out of my Universal remote, but I would like it to only respond to one button.

I have the IR sensor connected to 5V, Ground, and ATTiny pin 1 (literally 6), and an LED with capacitor to 4 (literally 3) and ground. 99% percent sure it's not an issue with the components.

If I run the code with the same sensors on my Arduino Uno, it works flawlessly and consistently. The key printed to Serial when I press the power button, for example, is always 2704.

With the ATTiny85, I get values all over the place. From the 0 to thousands. I pressed the power button two dozen times and got 2704 once.

So the variable here is the chip.

I have a hunch it has to do with the ATTiny being unable to measure the times between pulses accurately, but I don't really know how to fix this (calibration? A better external crystal?) and would like some input before I order and then sit around waiting for more components.

It seems possible, because this person built a robot that is controlled with the D-pad on a remote control—but they didn't post their code, schematic, or explain how they made it in very much detail. Other people have asked.

Thank you very much!

Also, here is my code:

int ir_pin = 1;                         //Sensor pin 1 wired through a 220 ohm resistor
int led_pin = 4; //"Ready to Receive" flag, not needed but nice
int start_bit = 2000;                   //Start bit threshold (Microseconds)
int bin_1 = 1000;                           //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)

int led_state = HIGH;

void setup() {
  pinMode(led_pin, OUTPUT);             //This shows when we're ready to receive
  pinMode(ir_pin, INPUT);
  digitalWrite(led_pin, led_state);
  Serial.begin(9600);

}

void loop() {
int key = getIRKey();             //Fetch the key
  if ( key != -1) {
    Serial.println(key);
    //if (key == 2704) {
       led_state = !led_state;
       digitalWrite(led_pin, led_state);
       delay(1000);
    //}
  }
}

int getIRKey() {
int data[12];
while(pulseIn(ir_pin, LOW) < 2200) { //Wait for a start bit
}
data[0] = pulseIn(ir_pin, LOW);       //Start measuring bits, I only want low pulses
data[1] = pulseIn(ir_pin, LOW);
data[2] = pulseIn(ir_pin, LOW);
data[3] = pulseIn(ir_pin, LOW);
data[4] = pulseIn(ir_pin, LOW);
data[5] = pulseIn(ir_pin, LOW);
data[6] = pulseIn(ir_pin, LOW);
data[7] = pulseIn(ir_pin, LOW);
data[8] = pulseIn(ir_pin, LOW);
data[9] = pulseIn(ir_pin, LOW);
data[10] = pulseIn(ir_pin, LOW);
data[11] = pulseIn(ir_pin, LOW);

for(int i=0;i<=11;i++) {                 //Parse them
  if(data[i] > bin_1) {                 //is it a 1?
      data[i] = 1;
  }  else {
      if(data[i] > bin_0) {           //is it a 0?
        data[i] = 0;
      } else {
       data[i] = 2;                     //Flag the data as invalid; I don't know what it is!
      }
  }
}

for(int i=0;i<=11;i++) {                 //Pre-check data for errors
  if(data[i] > 1) {
      return -1;                           //Return -1 on invalid data
  }
}

int result = 0;
int seed = 1;
for(int i=11;i>=0;i--) {                //Convert bits to integer
  if(data[i] == 1) {
      result += seed;
  }
  seed = seed * 2;
}

return result;                             //Return key number
}
\$\endgroup\$
2
  • \$\begingroup\$ Maybe spurious pulses due to interference or similar issues with power supply? are you using the same VCC line, or are you using the integrated regulator for the Uno and somethnig else for the tiny85? Try powering the tiny85 with the VCC taken from the Uno board, so that is is as regulated as the Uno. Also, the functions from Arduino are not always THAT efficient, they may be sucking way more cycles then you expect (jeelabs.org/2010/01/06/pin-io-performance). Be sure that no other interrupts or similar are being fired in the Tiny85, check the fuses well. \$\endgroup\$
    – FarO
    Commented Jul 1, 2015 at 13:25
  • \$\begingroup\$ @kotsklont please see electronics.stackexchange.com/help/how-to-answer \$\endgroup\$
    – Voltage Spike
    Commented Jul 15, 2016 at 22:40

2 Answers 2

2
\$\begingroup\$

Chances are that your attiny runs with the default 1MHz internal clock. Because it works flawlessly on your Arduino, you could start by changing the fuse settings of your tiny AVR to also run at 16MHz.

\$\endgroup\$
4
  • \$\begingroup\$ At 16Mhz it still responds to any IR signal, but not the specific signal from the power button, and additionally Serial doesn't work. \$\endgroup\$
    – bookcasey
    Commented Mar 24, 2015 at 22:36
  • \$\begingroup\$ Are you sure your ATTiny is running at 16MHz ? Did you use an external crystal (you can't run your AVR at 16MHz with the internal 8MHz clock) ? Then, did you change the fuse settings (AVRDUDE arguments : -U lfuse:w:0x7f:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m) ? \$\endgroup\$
    – Rom Ain
    Commented Mar 24, 2015 at 23:37
  • \$\begingroup\$ I tried this option after reading your answer: ATTiny85 @ 16 Mhz (internal PLL; 4.3 V BOD) I don't have an external crystal right now. \$\endgroup\$
    – bookcasey
    Commented Mar 25, 2015 at 0:40
  • \$\begingroup\$ I checked the datasheet and you are right, you can select the high frequency PLL clock as a system clock source. Just to be sure that everything is ok according to clock, I would simply try to blink a LED every second and see if it is really blinking every second. \$\endgroup\$
    – Rom Ain
    Commented Mar 25, 2015 at 1:18
0
\$\begingroup\$

Had the same problem, pulseIn only works on pin 7 on attiny25 /45 /85.

From nitwit99 on AVRfreaks.net:

The correct fix is to use pin 7 (INT0, arduino pin 2) as the Rx input

Because:

The ATtiny85 has only one external interrupt (not counting pinchange interrupts). Have a look at the datasheet. The external interrupt is called INT0 (interrupt 0) and is on PORTB2, which is physical pin 7 on the PDIP8 packaged ATtiny85, and is pin 2 in the Arduino IDE.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Answer is a bit late and not explained in detail. Short answers without details run the risk of downvotes or deletion. Example: Why is pin 7 better as the Rx input? Also if you list a quoted source you need to provide a link to that source. \$\endgroup\$
    – user105652
    Commented Jul 15, 2016 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.