Приветствую вас изобретатели.
Проблема в Прерывании. Идея была в том, что в проге использую две функции:
по включению и выключению.
То есть, разный алгоритм включения и выкл.
attachInterrupt(pin, PTTon, FALLING);
attachInterrupt(pin, PTTof, RISING);
RISING прерывание вызывается только при смене значения на порту с LOW на HIGH
FALLING прерывание вызывается только при смене значения на порту с HIGH на LOW
Заметил, написав так, действие не происходит, используя RISING происходит дважды при нажатии и отжатии кнопки.
пришлось пользоваться CHANGE и логикой (внешней переменной) при действии проверяется её значение и выполняется действие с её дальнейшем изменением.
http://www.youtube.com/watch?v=5aCN3r4x9p0
У кого какие идеи есть?
void PTTon()
{
if (PTT == LOW)
{
digitalWrite(led, HIGH);
delay(5000);
digitalWrite(led, LOW);
delay(5000);
digitalWrite(led, HIGH);
PTT = !PTT;
}
else
{
digitalWrite(led, LOW);
PTT = !PTT;
}
}
Внешние прерывание Логическая ошибка.
- Mr.Kubikus
- Сотрудник ПАКПАК
- Сообщения: 1020
- Зарегистрирован: 22 окт 2010, 23:57
Re: Внешние прерывание Логическая ошибка.
Привет!
На прерывания можно забить. Они для решения этой задачи не нужны.
Вариант 1. Используем обычный конечный автомат с двумя состояниями.
Вариант 2. Для тех кто не проникся конечными автоматами делаем все на IFах.
Ну и не забываем подтянуть вход МК к VCC или GND. Иначе будем ловить радиоэфир.
На прерывания можно забить. Они для решения этой задачи не нужны.
Вариант 1. Используем обычный конечный автомат с двумя состояниями.
Код: Выделить всё
#define BTN_PIN 1
int btnMemState = LOW;
void setup() {
pinMode(BTN_PIN, INPUT);
}
void func1() {
return;
}
void func2() {
return;
}
void loop() {
int btnValue = LOW;
btnValue = digitalRead(BTN_PIN);
switch (btnMemState) {
case LOW:
// Ловим переход 0->1
if (btnValue == HIGH) {
btnMemState = HIGH;
func1();
}
break;
case HIGH:
// Ловим переход 1->0
if (btnValue == LOW) {
btnMemState = LOW;
func2();
}
break;
default:
break;
}
delay(25); // Не убираем иначе поймаем дребезг контактов, если на входе кнопка.
}
Код: Выделить всё
#define BTN_PIN 1
int btnMemState = LOW;
void setup() {
pinMode(BTN_PIN, INPUT);
}
void func1() {
return;
}
void func2() {
return;
}
void loop() {
int btnNewState = LOW;
btnNewState = digitalRead(BTN_PIN);
if (btnNewState != btnMemState) {
// Ловим переход 0->1
if (btnNewState == HIGH) {
func1();
}
// Ловим переход 1->0
if (btnNewState == LOW) {
func2();
}
}
btnMemState = btnNewState;
delay(25); // Не убираем иначе поймаем дребезг контактов, если на входе кнопка.
}
Re: Внешние прерывание Логическая ошибка.
Это хорошо, но прерывание выполняется сразу после действия, помимо основной задачи.
вписать в тело программы можно, но там идет задержка. ~1.5 сек.
По библиотеке BTN_PIN ознакомлюсь.
вписать в тело программы можно, но там идет задержка. ~1.5 сек.
По библиотеке BTN_PIN ознакомлюсь.
- Mr.Kubikus
- Сотрудник ПАКПАК
- Сообщения: 1020
- Зарегистрирован: 22 окт 2010, 23:57
Re: Внешние прерывание Логическая ошибка.
Рекомендую пересмотреть алгоритм главного цикла. Длительность исполнения ГЦ=1,5 сек - это не гуд.
BTN_PIN - это не библиотека, а макроопределение. После строки "#define BTN_PIN 1" компилятор будет подставлять "1" везде, где встретит BTN_PIN.
BTN_PIN - это не библиотека, а макроопределение. После строки "#define BTN_PIN 1" компилятор будет подставлять "1" везде, где встретит BTN_PIN.
Re: Внешние прерывание Логическая ошибка.
Проблему вроде решил.
Задача:
Решить проблему с внешним прерыванием, при нажатии с HIGH на LOW выполнение одной последовательности при отпуске с LOW на HIGH другую.
Решить её функцией прерывания не удалось.
Решение:
В Функции прерывания идет проверка на состояние входа того же, что и вход прерывания.
volatile boolean PTT = LOW;
int pin = 0;
attachInterrupt(pin, PTTon, CHANGE);
void PTTon()
{
if (PTT == LOW && digitalRead(2) == LOW)
{
digitalWrite(led, HIGH);
PTT == HIGH;
}
else if (PTT == HIGH)
{
digitalWrite(led, LOW);
PTT = LOW;
}
Задача:
Решить проблему с внешним прерыванием, при нажатии с HIGH на LOW выполнение одной последовательности при отпуске с LOW на HIGH другую.
Решить её функцией прерывания не удалось.
Решение:
В Функции прерывания идет проверка на состояние входа того же, что и вход прерывания.
volatile boolean PTT = LOW;
int pin = 0;
attachInterrupt(pin, PTTon, CHANGE);
void PTTon()
{
if (PTT == LOW && digitalRead(2) == LOW)
{
digitalWrite(led, HIGH);
PTT == HIGH;
}
else if (PTT == HIGH)
{
digitalWrite(led, LOW);
PTT = LOW;
}
Re: Внешние прерывание Логическая ошибка.
Как Вставить текст Програмы.
- Mr.Kubikus
- Сотрудник ПАКПАК
- Сообщения: 1020
- Зарегистрирован: 22 окт 2010, 23:57
Re: Внешние прерывание Логическая ошибка.
Отладочная програма.
Только для прерывания, бегущая строка, для отслеживания процесов в нутри проги.
Только для прерывания, бегущая строка, для отслеживания процесов в нутри проги.
Код: Выделить всё
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int led = 13;
int pin = 0;
volatile boolean PTT = LOW;
byte degree[8] = { // значек Градуса.
B00110,
B01001,
B01001,
B00110,
B00000,
B00000,
B00000,
};
byte p20[8] = { // биты заполнения LCD
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
};
byte p40[8] = {
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
};
byte p60[8] = {
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
};
byte p80[8] = {
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
};
byte p100[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
};
void setup ()
{
lcd.begin();
pinMode(led, OUTPUT);
pinMode(pin, INPUT);
attachInterrupt(pin, PTTon, CHANGE);
// функция теста экрана
lcd.setCursor(0, 0);
lcd.print(" R K 5 D ");
}
void loop()
{
lcd.setCursor(0, 1);
lcd.print(" ");
for (int i=0; i < 16; i++)
{
lcd.createChar(0,p20);
lcd.createChar(1,p40);
lcd.createChar(2,p60);
lcd.createChar(3,p80);
lcd.createChar(4,p100);
for (int j=0; j < 5; j++)
{
lcd.setCursor(i,1);
lcd.write(j);
delay(80); // скорость
}
if (PTT == HIGH)
{
lcd.setCursor(13, 0);
lcd.print("PTT");
}
else
{
lcd.setCursor(13, 0);
lcd.print(" ");
}
}
}
void PTTon()
{
if (PTT == LOW && digitalRead(2) == LOW)
{
digitalWrite(led, HIGH);
PTT = HIGH;
}
else if (PTT == HIGH)
{
digitalWrite(led, LOW);
PTT = LOW;
}
else
{
digitalWrite(led, LOW);
PTT = LOW;
}
}