Обработка ИК диода должна построена быть на прерывании! Соответственно должен быть подключен к лапе контролера с фиксацией факта изменения уровня на входе.
Вид для печати
Обработка ИК диода должна построена быть на прерывании! Соответственно должен быть подключен к лапе контролера с фиксацией факта изменения уровня на входе.
Так и есть, смотри скетч
Цитата:
attachInterrupt(0, FrontDown, FALLING);
Добавил прерывание на 3 цифровой порт (attachInterrupt(1, irReceive, FALLING)). Функция один раз вызывается. Почему только один?
И при добавлении второго прерывания у меня перестает работать первое прерывание, контролирующее якрость лампы. По умолчанию она должна включаться. Если второе прерывание отключить - лампа включается, если вернуть второе прерывание - лампа не включается. Нельзя использовать сразу 2 прерывания?
И подскажите, для чего переменной dim volatile? Разве не один поток проходит через прерывания?Код:int AC_pin = 10; // выход для симистора
volatile uint16_t dim = 33 * 5;
uint8_t dimmer;// уровень димирования (0-255) 0 = max, 255 = min
int irPin = 3;
int start_bit = 2200; //Start bit threshold (Microseconds)
int bin_1 = 1000; //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)
void setup()
{
Serial.begin(9600);
pinMode(AC_pin, OUTPUT);
attachInterrupt(1, irReceive, FALLING);
// attachInterrupt(0, FrontUp, RISING);
}
// Функция обработки прерывания на подъем
void FrontUp()
{
Serial.println("FrontUp");
detachInterrupt(0);
delayMicroseconds(dim+1200); // отсекаем лишнее
digitalWrite(AC_pin, HIGH); // включить симистор
delayMicroseconds(20); // короткая пауза, чтобы обеспечить включение симистора
digitalWrite(AC_pin, LOW); // выключение симистора(он выключится когда полупериод достигнет нуля)
attachInterrupt(0, FrontDown, FALLING);
}
// Функция обработки прерывания на спад
void FrontDown()
{
detachInterrupt(0);
delayMicroseconds(dim); // отсекаем лишнее
digitalWrite(AC_pin, HIGH); // включить симистор
delayMicroseconds(20); // короткая пауза, чтобы обеспечить включение симистора
digitalWrite(AC_pin, LOW); // выключение симистора(он выключится
attachInterrupt(0, FrontUp, RISING);
}
void irReceive()
{
Serial.println("irReceive");
/*int key = getIRKey();
if (key != 0)
{
if (key == 144)
{
dim = 33 * 2;
Serial.println("HIGH");
}
else if (key == 145)
{
dim = 33 * 255;
Serial.println("LOW");
}
delay(15);
}*/
}
void loop()
{
}
int getIRKey() {
int data[12];
int i;
while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit
for(i = 0 ; i < 11 ; i++)
data[i] = pulseIn(irPin, LOW); //Start measuring bits, I only want low pulses
for(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
return -1; //Flag the data as invalid; I don't know what it is! Return -1 on invalid data
}
int result = 0;
for(i = 0 ; i < 11 ; i++) //Convert data bits to integer
if(data[i] == 1) result |= (1<<i);
return result; //Return key number
}
Любая переменная используемая в обработчике прерывания должна быть volatileЦитата:
И подскажите, для чего переменной dim volatile? Разве не один поток проходит через прерывания?
Chip, не подскажешь почему в вышеприведенном коде функция irReceive вызывается только один раз?
Я использую TSOP382 и выходную ногу завел на 3 цифровой порт. Первоначально, напряжение на выходе 2.3В. Когда я нажимаю на кнопку оно падает до 1.8В.
http://data1.floomby.com/files/share...U0LUS3v89Q.png
Сигналы от приемника при нажатии на кнопку вроде идут.
Зависает, так как нельзя использовать в обработчике Вашего прерывания Serial.print и delay
Может имеет смысл использовать библиотеку <IRremote.h>, она вроде на втором прерывании.
Вот тут у меня скетч завалялся для считывания пульта и вывода результата на LCD.
PHP код:
#include <IRremote.h>
int RECV_PIN = 9; //вход ИК приемника
IRrecv irrecv(RECV_PIN);
decode_results results;
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
void setup()
{
lcd.begin(16, 2);
Serial.begin(115200);
irrecv.enableIRIn(); // включить приемник
}
void loop() {
if (irrecv.decode(&results))
{
if ((results.value > 0) && (results.value < 0xFFFFFFFF))
{
lcd.clear();
lcd.print(results.value);
Serial.println(results.value);
}
irrecv.resume();
}
}
Меня не покидает вопрос, почему на схеме резисторы (82к) стоят по два, паралельно, а не по одному 41к ? Видимо специально так сделано, а объясните пожалуйста, почему?
Для увеличения рассеиваемой мощности
Умножаем падение напряжения на ток