ARDUINO Работа с дистанционным радио-пультом

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
Здравствуйте. Досталась мне на запчасти старая авто-сигнализация Kopel KR-550 (фото приложил), мозги у неё спеклись, а вот приемник работает. Я подключил приемник к ардуино и считал коды кнопок пульта. Но возникла сложность, при удерживании кнопки на пульте сигналы идут постоянным потоком (скрин монитора порта тоже приложил).

Подскажите как сделать чтобы при нажатии и даже долгом зажатии кнопки на пульте функция завязанная на эту кнопку срабатывала лишь раз или даже по принципу триггера (одно нажатие или долгое зажатие включает, а при повторном нажатии/зажатии выключает)?
Поиск в гугл полезных результатов не дал, хотя может я плохо искал, я в этом деле новичок.

Сигналка:
IMG_20180925_220339.jpg

Данные из монитора порта Ардуино:
Screen Shot 09-25-18 at 10.08 PM.PNG
 

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,131
412
Москва
wan-derer.ru
@eXPert, добавить в программу переменную-флаг, которая взводится когда команда пришла. Флаг сбрасывается через некоторое время после того как команда перестала приходить, по таймеру. Реакцию программы на команду завязать на флаг: "если стоит - не исполняем".
На каждую кнопку завести по своему флагу.
 

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
Что-то на вроде кода ниже? Или нет? Я просто больше по Object Pascal (Delphi), а не по C++, так что за косяки и костыли в коде заранее сорри.

C-like:
boolean Btn1 = false;
boolean Btn2 = false;
...


void setup() {

...

}


void loop() {

if ([получили код кнопки 1]) {

[действие для кнопки 1]

Btn1 = true;

}


if (Btn1 == true) {

delay(1000); // 1000 это к примеру, я не знаю сколько нужно поставить...

Btn1 = false;

}
 

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,131
412
Москва
wan-derer.ru
@eXPert, ты пройди по этому коду руками, учитывая что он исполняется в цикле. Что получится? Действие будет выполняться каждый раз когда получена команда. Ты никак не используешь флаг.
 

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
@Wan-Derer, этот код я сам написал, просто как я говорил ранее, я больше по Delphi и при написании кода уже даже подсознательно руководствуюсь принципами языка Object Pascal. И я честно не знаю куда вставлять этот код, так как в коде ардуино есть только setup(), который выполняется единожды при запуске самой ардуино и собственно loop(), который выполняется в цикле. Вот я и предположил использовать код именно в loop() т.к. я не знаю куда ещё его можно поместить чтобы он работал постоянно.
В Delphi то все проще, код выполняется при поступлении команды (нажатие кнопки, срабатывание таймера, вызов из другого кода и т.д.), а вот как реализовать нужный код в ардуино я не знаю, если бы все писалось на Delphi, я бы за пару минут написал весь код, а тут я в тупике.
 

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,131
412
Москва
wan-derer.ru
@eXPert, тут дело не в си или паскале, а в том что ты пишешь для МК, а не для компьютера. И в данном случае надо писать процедурно (хотя Ардуино может и в ООП: С++, всякие конструкторы программ из кубиков и пр.). Просто представь, что всё находящееся в луп исполняется сверху вниз, команда за командой. Когда луп закончится, МК перепрыгнет на его начало, и так и будет выполнять бесконечно.
 

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
В общем подвожу итоги по коду (пока не проверял на самой Arduino, скоро проверю). Спасибо великой FLProg и Библиотекам Пользователей для этой программы, а то я наверно писал бы код месяца 2-3. Так как хоть какой-то помощи получить на форуме не удалось(((. И так сам код привожу ниже. Модуль INT + 2 я написал сам, его код тоже прикрепил. Так же прикрепил файлы проекта Arduino IDE (Test1.ino) и проекта FLProg 4.0 (в архиве Test_1.zip), а так же прикрепил библиотеку для FLProg (Модуль RF_RS, файл FLProg_RF_CODE.zip), этот модуль использует библиотеку Arduino - RCSwitch.

Схема FLProg:
Screen Shot 10-03-2018 = 20.51.18.PNG

C-like:
#include <RCSwitch.h>

long code_118707015_1;
int IND_118707015_1;
bool new_D_118707015_1;
bool press_118707015_1;
bool new_T_118707015_1;
bool press_T_118707015_1;
RCSwitch mySwitch_118707015_1= RCSwitch();
int button_118707015_1;
int last_button_118707015_1;
int Interval_118707015_1= 200;
long first_click_Millis_118707015_1; // таймер начала нажатия
long previousMillis_118707015_1; // таймер последнего нажатия
bool press_trig_118707015_1;
int INT_IN_112101050_1;
bool BLN_IN_112101050_1;
int INT_OUT_112101050_1;
int _PWDC = 0;
bool _trgt2 = 0;
bool _trgt2I = 0;
bool _trgt5 = 0;
bool _trgt5I = 0;
bool _trgt7 = 0;
bool _trgt7I = 0;
bool _dms1Q0 = 0;
bool _dms1Q1 = 0;
bool _dms1Q2 = 0;
bool _dms1Q3 = 0;
bool _dms1Q4 = 0;
bool _dms1Q5 = 0;
bool _trgt1 = 0;
bool _trgt1I = 0;
bool _trgt4 = 0;
bool _trgt4I = 0;
bool _trgt6 = 0;
bool _trgt6I = 0;
void setup()
{
TCCR2A = 0x00;
TCCR2B =  0x07;
TIMSK2=0x01;
TCNT2=100;
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);

  mySwitch_118707015_1.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2

}
void loop()
{_PWDC = 0;





//Плата:1

new_D_118707015_1 = 0;
new_T_118707015_1 = 0;

if (mySwitch_118707015_1.available()) code_too_button_118707015_1();                            //Проверяем код на совпадение со списком

if ( button_118707015_1 != 0)                                                                    // Если кнопка нажата
    {
      press_118707015_1 = 1;
      previousMillis_118707015_1 = millis();
      IND_118707015_1 = button_118707015_1;
      if ( last_button_118707015_1 !=  button_118707015_1)                                               // Если нажата новая
        {
          new_D_118707015_1 = 1;
          first_click_Millis_118707015_1 = millis();
          press_trig_118707015_1 = false;
          last_button_118707015_1 =  button_118707015_1;
         }
      else                                                                           //Если нажата предыдущая
        {
          if (millis() - first_click_Millis_118707015_1  >=   1800 )   press_trig_118707015_1 = true;  // Если кнопка зажата дольше установленного времени включаем триггер выхода (press_T_118707015_1)
        }
     button_118707015_1 = 0;
    }



else                                                                                  // Если не нажата
    {
     if ( last_button_118707015_1 !=0)                                                      // Если была нажата
        { 
         if ((millis() - previousMillis_118707015_1)  >= ( Interval_118707015_1 +10 ))           //Если интервал между посылками + допуск прошли
           {
            if ( !press_trig_118707015_1 ) new_T_118707015_1 = 1;                                  // Если бала нажата но не зажата
            press_trig_118707015_1 = false;
            press_118707015_1 = 0;
            press_T_118707015_1 = 0;
            first_click_Millis_118707015_1 = 0;
            last_button_118707015_1 =0;
           }
        }
    }

              //Сброс выходов

if ( 800 >0)                                                       // Если время сброса больше "0"
    {
     if ( previousMillis_118707015_1 !=0)
        {
          if (millis() -  previousMillis_118707015_1 >=  800 )              // Если истекло время сброса
            {
             previousMillis_118707015_1 = 0;
             IND_118707015_1  = 0;
             code_118707015_1 = 0;
            }
        }
    }
press_T_118707015_1 = press_trig_118707015_1;

INT_IN_112101050_1 = IND_118707015_1;
BLN_IN_112101050_1 = press_T_118707015_1;
if (INT_IN_112101050_1 >= 2 && BLN_IN_112101050_1 == 1) {
INT_OUT_112101050_1 = INT_IN_112101050_1 + 2;
} else {
INT_OUT_112101050_1 = INT_IN_112101050_1;
}
if((INT_OUT_112101050_1 == 0)){_dms1Q0 = 1;}else {_dms1Q0 = 0;}
if((INT_OUT_112101050_1 == 1)){_dms1Q1 = 1;}else {_dms1Q1 = 0;}
if((INT_OUT_112101050_1 == 2)){_dms1Q2 = 1;}else {_dms1Q2 = 0;}
if((INT_OUT_112101050_1 == 3)){_dms1Q3 = 1;}else {_dms1Q3 = 0;}
if((INT_OUT_112101050_1 == 4)){_dms1Q4 = 1;}else {_dms1Q4 = 0;}
if((INT_OUT_112101050_1 == 5)){_dms1Q5 = 1;}else {_dms1Q5 = 0;}
bool  _tmp7 = _dms1Q5;
if (_tmp7)  { if (! _trgt7I) _trgt7 = ! _trgt7; }
_trgt7I = _tmp7;
digitalWrite(8, _trgt7);
bool  _tmp6 = _dms1Q4;
if (_tmp6)  { if (! _trgt6I) _trgt6 = ! _trgt6; }
_trgt6I = _tmp6;
digitalWrite(7, _trgt6);
bool  _tmp5 = _dms1Q3;
if (_tmp5)  { if (! _trgt5I) _trgt5 = ! _trgt5; }
_trgt5I = _tmp5;
digitalWrite(6, _trgt5);
bool  _tmp4 = _dms1Q2;
if (_tmp4)  { if (! _trgt4I) _trgt4 = ! _trgt4; }
_trgt4I = _tmp4;
digitalWrite(5, _trgt4);
bool  _tmp2 = _dms1Q1;
if (_tmp2)  { if (! _trgt2I) _trgt2 = ! _trgt2; }
_trgt2I = _tmp2;
digitalWrite(4, _trgt2);
bool  _tmp1 = _dms1Q0;
if (_tmp1)  { if (! _trgt1I) _trgt1 = ! _trgt1; }
_trgt1I = _tmp1;
digitalWrite(3, _trgt1);




}

ISR(TIMER2_OVF_vect)
{ TCNT2=100;
if(_PWDC >= 1000){asm volatile ("jmp 0x0000");}else{_PWDC = _PWDC+1;};
}
void code_too_button_118707015_1()
{
long value;
value = mySwitch_118707015_1.getReceivedValue();                    // Получем код
code_118707015_1 = value;                                                       //Выводим кон на выход


                                                  //Здесь заменяем коды и индексы на свои

    if (value == 1408908) button_118707015_1 = 0; // Btn 1
    else if (value == 1408899) button_118707015_1 = 1; // Btn 2
    else if (value == 1408911) button_118707015_1 = 2; // Btn 3
    else if (value == 1408904) button_118707015_1 = 3; // Btn 4


mySwitch_118707015_1.resetAvailable();
}

C-like:
// INT_IN (Integer) вход
// BLN_IN (Boolean) вход
// INT_OUT (Integer) выход

if (INT_IN >= 2 && BLN_IN == 1) {
INT_OUT = INT_IN + 2;
} else {
INT_OUT = INT_IN;
}
 

Вложения

Изменено:

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
А так же мой первый и второй код по работе с пультом на 4 кнопки (4 канала), предупреждаю сразу в этих кодах КУЧА костылей и Delay'ев, т.к. делал давно и особо не изучал как лучше или не лучше, а просто делал чтоб хоть как то работало.


C-like:
const int B_btn_pin = PA1;
const int D_btn_pin = PA2;
const int A_btn_pin = PA3;
const int C_btn_pin = PA4;

boolean A_on_off = false;
boolean B_on_off = false;
boolean C_on_off = false;
boolean D_on_off = false;

void setup() {
  pinMode(B_btn_pin, INPUT_ANALOG);
  pinMode(D_btn_pin, INPUT_ANALOG);
  pinMode(A_btn_pin, INPUT_ANALOG);
  pinMode(C_btn_pin, INPUT_ANALOG);
 
  pinMode(PB12, OUTPUT);
  pinMode(PB13, OUTPUT);
  pinMode(PB14, OUTPUT);
  pinMode(PB15, OUTPUT);
}

void loop() {

  int A_press = analogRead(A_btn_pin);
  int B_press = analogRead(B_btn_pin);
  int C_press = analogRead(C_btn_pin);
  int D_press = analogRead(D_btn_pin);
 
  if (A_press  > 1000) {
    A_on_off = !A_on_off;
    digitalWrite(PB12, A_on_off);
    delay(1000);
  }

  if (B_press  > 1000) {
    B_on_off = !B_on_off;
    digitalWrite(PB13, B_on_off);
    delay(1000);
  }
 
  if (C_press  > 1000) {
    C_on_off = !C_on_off;
    digitalWrite(PB14, C_on_off);
    delay(1000);
  }

  if (D_press  > 1000) {
    D_on_off = !D_on_off;
    digitalWrite(PB15, D_on_off);
    delay(1000);
  }
}

C-like:
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

boolean A_on_off = true;
boolean B_on_off = false;
boolean C_on_off = false;
boolean D_on_off = false;
int i=0;
int timer;
boolean A_timer;
boolean B_timer;
boolean C_timer;
boolean D_timer;
boolean t15 = false;
boolean t30 = false;
boolean t60 = false;
boolean t120 = false;
unsigned long timing;
unsigned long Time;
unsigned long Wait15=15000;

void setup() {
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  digitalWrite(3, true);
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

void loop() {
 
  if (mySwitch.available()) {
if (mySwitch.getReceivedValue()==8377280)
{
    A_on_off = !A_on_off;
    digitalWrite(3, A_on_off);
    delay(700);
 
}

if (mySwitch.getReceivedValue()==8377136)
{
    B_on_off = !B_on_off;
    digitalWrite(4, B_on_off);
    delay(700);
 
}

if (mySwitch.getReceivedValue()==8377100)
{
    C_on_off = !C_on_off;
    digitalWrite(5, C_on_off);
    delay(700);
 
 
}

if (mySwitch.getReceivedValue()==8377091)
{
    D_on_off = !D_on_off;
    digitalWrite(6, D_on_off);
    delay(700);
 
}

if (mySwitch.getReceivedValue()==8377292)
{
  timer=analogRead(A1);

  if (analogRead(A2) > 500) { A_timer=true; } else { A_timer=false; }
  if (analogRead(A3) > 500) { B_timer=true; } else { B_timer=false; }
  if (analogRead(A4) > 500) { C_timer=true; } else { C_timer=false; }
  if (analogRead(A5) > 500) { D_timer=true; } else { D_timer=false; }

  if (timer > 1010 && timer < 1040){ 
  timerstart();
  t15=true;
  Serial.println("Timer 15 Sec Start!");
  }
  if (timer > 990 && timer < 1000){
  timerstart();
  t30=true;
  }
 
  if (timer > 960 && timer < 980){
  timerstart();
  t60=true;
  }
 
  if (timer > 940 && timer < 959){
  timerstart();
  t120=true;
  }
  delay(700);
}

if (mySwitch.getReceivedValue()==8377148)
{
i=i+1;
if (i==4) i=0;
if (i== 1){
  digitalWrite(4, true);
  digitalWrite(5, false);
  digitalWrite(6, false);
}
if (i==2){
  digitalWrite(4, false);
  digitalWrite(5, true);
  digitalWrite(6, false);
}
if (i==3){
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, true);
}
if (i==0){
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
}
delay(700);
}

if (mySwitch.getReceivedValue()==8377283)
{
    digitalWrite(3, false);
    digitalWrite(4, false);
    digitalWrite(5, false);
    digitalWrite(6, false);
    delay(700);
 
}
if (mySwitch.getReceivedValue()==8377103)
{
  digitalWrite(3, true);
  digitalWrite(4, true);
  digitalWrite(5, true);
  digitalWrite(6, true);
  delay(700);
}

mySwitch.resetAvailable();
    
  }


if (t15==true){ 
 if (millis() - timing > 15000){ 
  timing = millis();
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
  t15=false;
  timing = 0;
 }
}
 if (t30==true){
 if (millis() - timing > 30000){ 
  timing = millis();
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
  t30=false;
  timing = 0;
 }
 }
 if (t60==true){
 if (millis() - timing > 60000){ 
  timing = millis();
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
  t60=false;
  timing = 0;
 }
 }
 if (t120==true){
 if (millis() - timing > 120000){ 
  timing = millis();
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
  t120=false;
  timing = 0;
 }
}

}

void timerstart(){
if (A_timer == true){
  digitalWrite(3, true);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, false);
}
 if (B_timer == true){
  digitalWrite(3, false);
  digitalWrite(4, true);
  digitalWrite(5, false);
  digitalWrite(6, false); 
 }
 if (C_timer == true){
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, true);
  digitalWrite(6, false); 
 }
 if (D_timer == true){
  digitalWrite(3, false);
  digitalWrite(4, false);
  digitalWrite(5, false);
  digitalWrite(6, true);
}   
 }
 

eXPert

✩✩✩✩✩✩✩
14 Авг 2018
22
0
И так первая версия кода оказалась фуфлом, версия 3 (2ю выкладывать не буду, там только перепутаны коды кнопок (как и в первой кстати)) уже Beta, но требует доработки, работает, хоть и не совсем так как хотелось бы. Так что прошу помощи в доработке, т.к. разбираюсь в коде не очень.
Выкладываю сам код для ардуинки, исходник проекта FLProg и видео работы тестовой станции с данным кодом, а так же немного измененную схему FLProg и измененный код моего самопального модуля (INT + 2 в FLProg). А помощь требуется в следующем: Все 4 кнопки работают нормально, но у меня 6 выходов, 4 завязаны на кнопки, а вот ещё 2 должны срабатывать при долго нажатии 2х кнопок, но тпроблема в том, что эта фуеция хоть и работает, но при долгом зажатии включаются и при отпускании отключаются и те два канала которые завязаны на кратковременное нажатие этих кнопок, в общем нужно как то от этой неурядицы избавится, по сему обращаюсь к местным специалистам за помощью и надеюсь в этот раз мне помогут не только "я объяснил, а дальше понимай как хочешь" (данное высказывание не относится не к кому то конкретному, а скорее ко всем кто считает что после Delphi остальные языки программирования (не важно микроконтроллеров или прог для каких-либо ОС) даются легко и не принужденно.

Вот ссылка на видеозапись теста.

Схема FLProg:
Screen Shot 10-05-18 at 09.25 PM.PNG

C-like:
if (INT_IN == 3 && BLN_IN == 1) {
INT_OUT = 5;
} else if (INT_IN == 4 && BLN_IN == 1) {
INT_OUT = 6;
} else {
INT_OUT = INT_IN;
}
 

Вложения