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
}
-
\$\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– FarO2015年07月01日 13:25:18 +00:00Commented Jul 1, 2015 at 13:25
-
\$\begingroup\$ @kotsklont please see electronics.stackexchange.com/help/how-to-answer \$\endgroup\$Voltage Spike– Voltage Spike ♦2016年07月15日 22:40:53 +00:00Commented Jul 15, 2016 at 22:40
2 Answers 2
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.
-
\$\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– bookcasey2015年03月24日 22:36:48 +00:00Commented 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– Rom Ain2015年03月24日 23:37:36 +00:00Commented 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– bookcasey2015年03月25日 00:40:20 +00:00Commented 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– Rom Ain2015年03月25日 01:18:51 +00:00Commented Mar 25, 2015 at 1:18
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.
-
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– user1056522016年07月15日 21:56:17 +00:00Commented Jul 15, 2016 at 21:56