Я подозревал, что геркон может дребезжать, поэтому решил сначала потренироваться на кошках велосипеде. Там так же имеется геркон.
За основу взял код из дружеской темы: http://www.compcar.ru/forum/showthread.php?t=5871
Т.к. срабатывание геркона приводит к появлению логического нуля я решил использовать attachInterrupt(0, int_on, LOW);
Код: Выделить всё
#define PinA 2
static boolean output = HIGH;
int pulse = 0;
void setup()
{
pinMode(PinA, INPUT);
digitalWrite(PinA, HIGH); // подключить подтягивающий резистор
attachInterrupt(0, int_on, LOW); // настроить прерывание interrupt 0 на pin 2
Serial.begin(9600);
}
void loop()
{
delay(100);
Serial.println(pulse);
}
// обработка прерывания
void int_on()
{
digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
pulse++;
}
Меняем работу с прерыванием на attachInterrupt(0, int_on, CHANGE), получаем от 1 до 5 вызовов за одно прохождение.
RISING дает 2 вызова: первый когда геркон замыкатеся, второй когда размыкается и, наконец FALLING стабильно дает 2 вызова при замыкании геркона.
Интересно получается. Судя по описанию:
LOW - вызов прерывания когда пин устанавливается в 0.
CHANGE - пин меняет состояние (0->1 или 1->0)
RISING - 0 -> 1
FALLING - 1 -> 0
Т.е. по всех случаях кроме CHANGE должен происходить один вызов прерывания за один проход магнита мимо датчика.
В итоге дорабатываю код таким образом, что бы получать один вызов в момент замыкания геркона.
Код: Выделить всё
#define PinA 2
static boolean output = HIGH;
int pulse = 0;
bool prev = false;
void setup()
{
pinMode(PinA, INPUT);
digitalWrite(PinA, HIGH); // подключить подтягивающий резистор
attachInterrupt(0, int_on, FALLING); // настроить прерывание interrupt 0 на pin 2
Serial.begin(9600);
}
void loop()
{
delay(100);
Serial.println(pulse);
}
// обработка прерывания
void int_on()
{
digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
if(!prev)
{
pulse++;
}
prev = !prev;
}