IR-управление в режиме удержания

Patrik
Offline
Зарегистрирован: 15.05.2013

Собрал вот такой скетч с функцией включения пинов в тригерном режиме:

#include <IRremote.h> // 

int RECV_PIN = 2; //vkhod IK priyemnika
IRrecv irrecv(RECV_PIN);
decode_results results;
int a=0; // peremennaya pereklyucheniya rezhima , pri nazhatii knopki ona prinimayet znacheniye +1
int b=0; //

void setup()
{
irrecv.enableIRIn(); // vklyuchit? priyemnik

pinMode(3, OUTPUT);
pinMode(5, OUTPUT); // naznachayem piny kak vykhody
} 
void loop() {
if (irrecv.decode(&results)) {
delay(300); // zaderzhka pered vypolneniyem opredeleniya knopok , chtoby izbezhat? bystroye dvoynoye nazhatiye

if (results.value == 0xCD1A) {a=a+1;} // obrabotka nazhitya klavishi , zdes? peremennaya prinimayet znacheniye +1
if (results.value == 0xCD9A) {b=b+1;} //kod knopki pulta
// nachinayem vklyuchat? svetodiody na pinakh
if (a==1){digitalWrite(3, HIGH);} else {digitalWrite(3, LOW); a=0;} // deystviye posle nazhatiya knopki , yesli peremennaya stala ravna 1 to
if (b==1){digitalWrite(5, HIGH);} else {digitalWrite(5, LOW); b=0;} // proizvesti pereklyucheniye pina v rezhim HIGH, yesli zhe net to vernut? peremennuyu v iskhodnoye sostoyaniye

{ //
delay(50); //pauza mezhdu povtorami //
} //
irrecv.resume(); // 

}

}

Как написать аналогичный скетч с режимом удержания кнопки (горит при нажатие, гаснет при отпускание кнопки)?.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

тоже ломал голову. дело в том что когда я делал управление танком ик пультом и через терминал смотрел коды пульта от телека и не только все пульты первую команду выдают свою а при дальшейшем нажатии FFFFFF. может конечно библиотека не очень была, незнаю. попытался сделать условие удрежания последней команды если идет команда FFFFFF. не получилось. не держит. может на самом деле там не чисто FFFFFF а сплошной поток F был. незнаю. ну или больше символов и изза этого не отрабатывала. в итоге забил. сделал триггер и кнопку сброса всех кнопок

Patrik
Offline
Зарегистрирован: 15.05.2013

jeka_tm пишет:

тоже ломал голову. дело в том что когда я делал управление танком ик пультом и через терминал смотрел коды пульта от телека и не только все пульты первую команду выдают свою а при дальшейшем нажатии FFFFFF. может конечно библиотека не очень была, незнаю. попытался сделать условие удрежания последней команды если идет команда FFFFFF. не получилось. не держит. может на самом деле там не чисто FFFFFF а сплошной поток F был. незнаю. ну или больше символов и изза этого не отрабатывала. в итоге забил. сделал триггер и кнопку сброса всех кнопок

А как сделать кнопку сброса? 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да просто. я делал так.

нажимаю вперед- оба двигателя вперед

нажимаю назад-оба двигателя назад

нажимаю влево- левый назад, правый вперед

нажимаю вправо-левый вперед, правый назад

нажимаю среднюю кнопку (ее сделал для сброса)- все двигатели стоп

управление неудобное скажу честно, но для теста пойдет

потом прикрутил к ардуине беспроводной джойстик от PS2, стоит в районе 300 рублей

http://www.ebay.com/itm/Black-2-4Ghz-Wireless-Game-Pad-Game-Controller-Joystick-For-PS2-With-Receiver-/111093953985?pt=US_Video_Game_Controllers&hash=item19ddb735c1

библиотеку и скетч могу дать. теперь он у меня и вперед, и вперед и одновременно налево, и все с регулировкой скорости, то есть может быстро ехать а можно и помедленее, и в повороте можно немного сбросить скорость

вечером фотки выложу своего танка с пушкой гаусса

к тому же скоро решу вопрос с ардуино на атмега8, будет очень маленькая плата, и драйвер на 74HC00 и  транзисторых сборках. тоже поделюсь как опробую в железе. в протеусе все гуд

а дальше хочу сделать управление с телефона на андройде по блютуз. вроде как проблемм пока никаких не нашел. блютуз вчера пришел. скоро буду тестить.

блютуз стоит 160 рублей плата. питание 3.3 в и логические уровни 3.3. есть напаянные на плату переходник с питанием 5В и логикой 5В, но стоит почти на 100 рублей дороже. я подумал стабилизатор и 4 резистора+плата не стоят 100 рублей и купил вот эту:

http://www.ebay.com/itm/New-High-Quality-Wireless-Bluetooth-Transceiver-Module-RS232-TTL-Antenna-/280766901603?pt=AU_B_I_Electrical_Test_Equipment&hash=item415f02ed63

программы на google play имеются, у многих в свободном доступе библиотеки

например эти:

https://play.google.com/store/apps/details?id=appinventor.ai_picoware.BTBotControlLite&feature=search_result

https://play.google.com/store/apps/details?id=org.projectproto.btjoystick&feature=search_result

https://play.google.com/store/apps/details?id=com.ebarch.ipgamepad&feature=search_result

 

Patrik
Offline
Зарегистрирован: 15.05.2013

Скинь конечно. Управление джостиком от PS2 очень интересно. 

Я только так и не понял, как сделать сброс всех кнопок...

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Patrik пишет:

Скинь конечно. Управление джостиком от PS2 очень интересно. 

Скину завтра. можно использовать как проводной так и беспроводной (беспроводной конечно интереснее)

тестировал на 10 метров через 2 стены межкомнатные. в принципе достаточно

Patrik пишет:

Я только так и не понял, как сделать сброс всех кнопок...

ну не знаю. попробую по другому. вперед назад налево направо это понятно. а сброс это на самом деле не сброс а просто остановить все двигатели. то есть ничего не подавать, а точнее подать 0 на все четыре входа драйвера

 

 

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

тот пульт питается от 4 мизинчиковых батареек, что очень недобно.

советую переделать по li-ion аккумулятор 

удобно использовать модуль зарядки 

http://www.ebay.com/itm/KDQ10-NEW-5V-USB-CHARGING-BOARD-CHARGER-MODULE-FOR-1A-LITHIUM-BATTERY-SCA-1706-/370846534295?pt=Battery_Chargers&hash=item56582d0a97

и какой нибудь преобразователь 5В, например этот

http://www.ebay.com/itm/1PC-New-1A-3V-to-5V-DC-DC-Converter-Step-Up-Boost-Module-/380655215690?pt=AU_B_I_Electrical_Test_Equipment&hash=item58a0d1a44a

от 5 вольт нормально работает

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Библиотека для джойстика

http://yadi.sk/d/Os8hIZO26QM3k

а вот скетч на работе. завтра если не удалил выложу

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

как и обещал скетчи для пульта от PS2

1 вариант управление аналоговым джойстиком

#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

//13 Clock       зеленый
//12 Data        серый
//11 Command     синий
//10 Attention   коричневый
//   3.3V        белый
//   GND         черный

int error = 0; 
byte type = 0;
byte vibrate = 0;
boolean L_napr = 2;
byte L_drive = 3;
boolean R_napr = 4;
byte R_drive = 5;
byte X;
byte Y;
boolean XN;
boolean YN;

void setup(){
  error = ps2x.config_gamepad(13,11,10,12, true, true);   //Настройка выводов: (clock, command, attention, data, Pressures?, Rumble?)
  pinMode(L_napr, OUTPUT);
  pinMode(L_drive, OUTPUT);
  pinMode(R_napr, OUTPUT);
  pinMode(R_drive, OUTPUT);
}


void loop(){

  ps2x.read_gamepad(false, vibrate);
  //===========================================================================================
  //                                        Граничные условия для X и Y
  //===========================================================================================

  if (ps2x.Analog(PSS_RX) == 128){
    X = 0;
  } 
  if (ps2x.Analog(PSS_RX) < 128){
    X = 255-ps2x.Analog(PSS_RX)*2;
    XN = 0;
  }
  if (ps2x.Analog(PSS_RX) > 128){
    X = ps2x.Analog(PSS_RX)*2-255;
    XN = 1;
  }    
  if (ps2x.Analog(PSS_RY) == 128){
    Y = 0;
  } 
  if (ps2x.Analog(PSS_RY) < 128){
    Y = 255-ps2x.Analog(PSS_RY)*2;
    YN = 1;
  }
  if (ps2x.Analog(PSS_RY) > 128){
    Y = ps2x.Analog(PSS_RY)*2-255;
    YN = 0;
  }    

  //===========================================================================================
  //                                        Остановка
  //===========================================================================================
  if (X == 0 && Y == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, 0);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, 0);
  }
  //===========================================================================================
  //                                        Только вперед
  //===========================================================================================
  if (Y > 0 && YN == 1){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-Y);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-Y);
  }
  //===========================================================================================
  //                                        Только назад
  //===========================================================================================  
  if (Y > 0 && YN == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, Y);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, Y);
  }
  //===========================================================================================
  //                                        Только вправо
  //===========================================================================================  
  if (X > 0 && Y == 0 && XN == 1){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-X);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, 0);
  }
  //===========================================================================================
  //                                        Только влево
  //===========================================================================================  
  if (X > 0 && Y == 0 && XN == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, 0);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-X);
  }
  //===========================================================================================
  //                                        Вперед налево
  //===========================================================================================  
  if (X > 0 && Y > 0 && XN == 0 && YN == 1){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, X);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-Y);
  }
  //===========================================================================================
  //                                        Вперед направо
  //===========================================================================================  
  if (X > 0 && Y > 0 && XN == 1 && YN == 1){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-Y);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, X);
  }
  //===========================================================================================
  //                                        Назад налево
  //===========================================================================================  
  if (X > 0 && Y > 0 && XN == 0 && YN == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, 255-X);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, Y);
  }
  //===========================================================================================
  //                                        Назад направо
  //===========================================================================================  
  if (X > 0 && Y > 0 && XN == 1 && YN == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, Y);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, 255-X);
  }


}

2 вариант с крестиком. мне лично больше понравился так как проще сделать полный ход с небольшим поворотом. с аналоговым тяжелее. сам попробуешь написать программу поймешь

#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

//13 Clock       зеленый
//12 Data        серый
//11 Command     синий
//10 Attention   коричневый
//   3.3V        белый
//   GND         черный

int error = 0; 
byte type = 0;
byte vibrate = 0;
boolean L_napr = 2;
byte L_drive = 3;
boolean R_napr = 4;
byte R_drive = 5;
byte UP;
byte DOWN;
byte LEFT;
byte RIGHT;


void setup(){
  error = ps2x.config_gamepad(13,11,10,12, true, true);   //Настройка выводов: (clock, command, attention, data, Pressures?, Rumble?)
  pinMode(L_napr, OUTPUT);
  pinMode(L_drive, OUTPUT);
  pinMode(R_napr, OUTPUT);
  pinMode(R_drive, OUTPUT);

}


void loop(){

  ps2x.read_gamepad(false, vibrate);
  //===========================================================================================
  //                                        Граничные условия для X и Y
  //===========================================================================================
  if(ps2x.Button(PSB_PAD_UP)) {         
    UP = ps2x.Analog(PSAB_PAD_UP);
  }  
  else {
    UP = 0;
  }
  if(ps2x.Button(PSB_PAD_DOWN)) {         
    DOWN = ps2x.Analog(PSAB_PAD_DOWN);
  }
  else {
    DOWN = 0;
  }
  if(ps2x.Button(PSB_PAD_LEFT)) {         
    LEFT = ps2x.Analog(PSAB_PAD_LEFT);
  }
  else {
    LEFT = 0;
  }
  if(ps2x.Button(PSB_PAD_RIGHT)) {         
    RIGHT = ps2x.Analog(PSAB_PAD_RIGHT);
  }
  else {
    RIGHT = 0;
  }



  //===========================================================================================
  //                                        Остановка
  //===========================================================================================
  if (UP == 0 && DOWN == 0 && LEFT == 0 && RIGHT == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, 0);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, 0);
  }

  //===========================================================================================
  //                                        ВПЕРЕД
  //===========================================================================================
  if (UP > 0 && DOWN == 0 && LEFT == 0 && RIGHT == 0){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-UP);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-UP);
  } 
  //===========================================================================================
  //                                        НАЗАД
  //===========================================================================================
  if (UP == 0 && DOWN > 0 && LEFT == 0 && RIGHT == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, DOWN);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, DOWN);
  }
  //===========================================================================================
  //                                        НАЛЕВО
  //===========================================================================================
  if (UP == 0 && DOWN == 0 && LEFT > 0 && RIGHT == 0){
   digitalWrite(L_napr, LOW);
  analogWrite(L_drive, LEFT);
  digitalWrite(R_napr, HIGH);
  analogWrite(R_drive, 255-LEFT);
  }
  //===========================================================================================
  //                                        НАПРАВО
  //===========================================================================================
  if (UP == 0 && DOWN == 0 && LEFT == 0 && RIGHT > 0){
   digitalWrite(L_napr, HIGH);
  analogWrite(L_drive, 255-RIGHT);
  digitalWrite(R_napr, LOW);
  analogWrite(R_drive, RIGHT);
  }
  //===========================================================================================
  //                                        ВПЕРЕД НАЛЕВО
  //===========================================================================================
  if (UP > 0 && DOWN == 0 && LEFT > 0 && RIGHT == 0){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-UP+LEFT*2);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-UP);
  }
  //===========================================================================================
  //                                        ВПЕРЕД НАПРАВО
  //===========================================================================================
  if (UP > 0 && DOWN == 0 && LEFT == 0 && RIGHT > 0){
    digitalWrite(L_napr, HIGH);
    analogWrite(L_drive, 255-UP);
    digitalWrite(R_napr, HIGH);
    analogWrite(R_drive, 255-UP+RIGHT*2);
  }
  //===========================================================================================
  //                                        НАЗАД НАЛЕВО
  //===========================================================================================
  if (UP == 0 && DOWN > 0 && LEFT > 0 && RIGHT == 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, DOWN-LEFT*2);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, DOWN);
  }
  //===========================================================================================
  //                                        НАЗАД НАПРАВО
  //===========================================================================================
  if (UP == 0 && DOWN > 0 && LEFT == 0 && RIGHT > 0){
    digitalWrite(L_napr, LOW);
    analogWrite(L_drive, DOWN);
    digitalWrite(R_napr, LOW);
    analogWrite(R_drive, DOWN-RIGHT*2);
  }

  delay(20);
}

dimka
dimka аватар
Offline
Зарегистрирован: 21.09.2012


Patrik пишет:

Как написать аналогичный скетч с режимом удержания кнопки (горит при нажатие, гаснет при отпускание кнопки)?.

/* урок от Дмитрия Осипова. http://www.youtube.com/user/d36073?feature=watch
 v.01 Arduino IR Управление с ИК пульта в режиме удержания кнопки
 Version 0.1 2013/07/02
 
 После того как я выложил видео 
 1/6 Управление Arduino с ИК пульта - начало
 http://www.youtube.com/watch?v=PjR9jlP4644
 поступило немало  просьб такого содержания
 (Антон Палыч 
 Дмитрий, огромная благодарность за Ваш труд! Все просто и доходчиво.
 Скачал Ваш пример "urok ot Dmitriya Osipova - upravleniye Arduino IK pulоtom"
 Все работает но у меня возник вопрос. Как сделать, 
 что бы кнопка определенного пина работала в режиме удержания а не в режиме "триггер" как в уроке?
 То есть нажимая и удерживая кнопку пульта напряжение идет, отпуская исчезает.)
 //
 Поначалу я думал все это будет сделать очень легко и просто, а потом выяснилось что тут
 много подводных камней.
 в видео я подробно все это изложу
v.01 Arduino IR Управление с ИК пульта в режиме удержания кнопки
https://www.youtube.com/watch?v=AjIASUNiWkY
 
 *******************************************************************
 
 
 Скачать библиотеку IRremote для ИК пульта
 https://disk.yandex.ru/public/?hash=yNz1au3lm3/yyMHOYtnZ2UGSf19wTvYBZnkx...
 
 скетч arduino чтобы узнать код кнопки ИК пульта
 sketch arduino buttons on the remote to learn the code
 https://disk.yandex.ru/public/?hash=KzLtuC1ljISPaCoXw03D6mbiKea8spktcWL5... 
 
 4/6 как ? узнать код - кнопки своего ИК пульта
 http://www.youtube.com/watch?v=InZuGntH_wk
 
 Arduino Розетки, Управление любым ИК пультом, (программируемые на лету) socket IR remote control
 http://www.youtube.com/watch?v=Nx6DUQ7Tx1w
 
 усилитель ИК инфракрасного сигнала IR infrared signal amplifier на одном транзисторе Arduino
 http://www.youtube.com/watch?v=3EYxONWSyR4
 
 */

#include <IRremote.h> // это скачанная библиотека

int RECV_PIN = 11; //вход ИК приемника
IRrecv irrecv(RECV_PIN);
decode_results results;

//eventTime, для паузы,  вместо delay,будем использовать функцию millis. 
unsigned long eventTime=0;
//индикация таймера
int timer = 12;

int L13 = 13; //пины управляющие моторами, светодиодами, или реле, чем угодно.
int L2 = 2;
int L3 = 3;
int L4 = 4;
int L5 = 5;
int L6 = 6;
int L7 = 7;
int L8 = 8;

void setup(){
  irrecv.enableIRIn(); // включить приемник

  pinMode(L13, OUTPUT); // назначаем пины как выходы
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT); 
  pinMode(L4, OUTPUT);
  pinMode(L5, OUTPUT);
  pinMode(L6, OUTPUT);
  pinMode(L7, OUTPUT);
  pinMode(L8, OUTPUT);

  pinMode(timer, OUTPUT);
} 
void loop() {
  // Эта конструкция нужна чтобы конвертировать пульсирующий (-) с (ИК) преемника сигнал в постоянный.
  //После появление и пропадания сигнала, состояние сразу не меняется! а ждет  100 миллисекунд.
  //Если 100 миллисекунд не прошло, и поступил еще один сигнал с пульта, тогда таймер заново запускается на 100 миллисекунд.

  //Проще говоря, пока кнопка на пульте нажата таймерПИН остается вКлюченным, если кнопка на пульте отпущена таймерПИН вЫключен.

  // Читаем данные с (ИК) преемника. В момент приема данных у (ИК) приемника на выходе появляется пульсирующий (-)отрицательный сигнал
  if (digitalRead(RECV_PIN) == LOW) 
    //  Если обнаружен отрицательный сигнал запускаем таймер,и включаем таймерПИН //(timer, HIGH);
    eventTime=millis(),digitalWrite(timer, HIGH);
  //  Продолжительность работы таймера >100 миллисекунд. И ТаймерПИН выключаем //(timer, LOW)
  if(millis()-eventTime>100) digitalWrite(timer, LOW)
    //  и вЫключаем все
    ,digitalWrite(L13, LOW),digitalWrite(L2, LOW),digitalWrite(L3, LOW)
      ,digitalWrite(L4, LOW),digitalWrite(L5, LOW),digitalWrite(L6, LOW),digitalWrite(L7, LOW),digitalWrite(L8, LOW);

  if (irrecv.decode(&results)) {
    //ВАЖНО !!! ( 1000809 ) это код кнопки №1 - моего (ИК)! (инфракрасного пульта)!, -
    //-у вашего пульта будет другой код, замените на свой!
    // У моего пульта при нажатии на одну и ту же кнопку, могут отсылаться два разных (КОДА) сигнала,  чтобы обойти эту проблему
    //я использовал Логический оператор "или" (||) if (results.value == 0x1000809 || results.value == 0xF7283C77
    // Теперь неважно какой код отправлен  с кнопки пульта, первый или второй
    // Если ваша кнопка пульта не страдает раздвоением личности, можете написать так if (results.value == 0x1000809 

    //Только при условии если, (Одновременно),Обнаружен поступивший код кнопки
    // и выключен ТаймерПИН,"и" "&&" (digitalRead(timer) == HIGH)
    // включаем нужный нам pin, digitalWrite(L13, HIGH);

    if (results.value == 0x1000809 || results.value == 0xF7283C77 && (digitalRead(timer) == HIGH) )digitalWrite(L13, HIGH); 
    if (results.value == 0x1008889 || results.value == 0x757FB4DF && (digitalRead(timer) == HIGH) )digitalWrite(L2, HIGH);
    if (results.value == 0x1004849 || results.value == 0xB33B4597 && (digitalRead(timer) == HIGH) )digitalWrite(L3, HIGH); 
    if (results.value == 0x100C8C9 || results.value == 0x3C03E507 && (digitalRead(timer) == HIGH) )digitalWrite(L4, HIGH);
    if (results.value == 0x1002829 || results.value == 0xE705551F && (digitalRead(timer) == HIGH) )digitalWrite(L5, HIGH); 
    if (results.value == 0x100A8A9 || results.value == 0xA4A58EC7 && (digitalRead(timer) == HIGH) )digitalWrite(L6, HIGH);
    if (results.value == 0x1006869 || results.value == 0xE2E45F7F && (digitalRead(timer) == HIGH) )digitalWrite(L7, HIGH); 
    if (results.value == 0x100E8E9 || results.value == 0x6BACFEEF && (digitalRead(timer) == HIGH) )digitalWrite(L8, HIGH);

    irrecv.resume(); 
  }
}





 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Я видел видео этого человека и использовал его библиотеку. только вот у него 1 из 3 пультов выдавал при долгом нажатии один и тот же код , а 2 других после своего кода выдавал если держать дальше FFFFFFFF. у меня дома ни один пульт так и не выдавал свой код постоянно. может дело конечно в библиотеке. поэтому я незнаю. я конечно его не пробовал этот код по возможности попробую. но врядли

Patrik
Offline
Зарегистрирован: 15.05.2013

Димка, спасибо! Очень благодарен за видео и примеры. 

Все проверил. Все работает!

dimka
dimka аватар
Offline
Зарегистрирован: 21.09.2012

Patrik пишет:

Димка, спасибо! Очень благодарен за видео и примеры. 

Все проверил. Все работает!

v.01 Arduino IR motor Управление моторами с ИК пульта и Скоростью ШИМ (PWM) Pan & Tilt
 Version 0.1 2013/07/06
 
 Управляем с помощью инфракрасного IR любого пульта, двумя моторами, подключенными 
 через микросхему L293D.
 так же можем менять скорость вращения моторов, чем дольше удерживаем 
 кнопку нажатой, тем быстрее крутится мотор.
 с применением (ШИМ. PWM)сигнала.
 
/* урок от Дмитрия Осипова. http://www.youtube.com/user/d36073?feature=watch
 v.01 Arduino IR motor Управление моторами с ИК пульта и Скоростью ШИМ (PWM) Pan & Tilt
 Version 0.1 2013/07/06
 
 Управляем с помощью инфракрасного IR любого пульта, двумя моторами, подключенными 
 через микросхему L293D.
 так же можем менять скорость вращения моторов, чем дольше удерживаем 
 кнопку нажатой, тем быстрее крутится мотор.
 с применением (ШИМ. PWM)сигнала.
в видео я подробно все это изложу
v.01 Arduino IR motor Управление моторами с ИК пульта и Скоростью ШИМ (PWM) Pan & Tilt
https://www.youtube.com/watch?v=0VvIiu0LUbA
 
 *******************************************************************
 
 
 Скачать библиотеку IRremote для ИК пульта
 https://disk.yandex.ru/public/?hash=yNz1au3lm3/yyMHOYtnZ2UGSf19wTvYBZnkx...
 
 скетч arduino чтобы узнать код кнопки ИК пульта
 sketch arduino buttons on the remote to learn the code
 https://disk.yandex.ru/public/?hash=KzLtuC1ljISPaCoXw03D6mbiKea8spktcWL5... 
 
 4/6 как ? узнать код - кнопки своего ИК пульта
 http://www.youtube.com/watch?v=InZuGntH_wk
 
 Arduino Розетки, Управление любым ИК пультом, (программируемые на лету) socket IR remote control
 http://www.youtube.com/watch?v=Nx6DUQ7Tx1w
 
 1/6 Управление Arduino с ИК пульта - начало
 http://www.youtube.com/watch?v=PjR9jlP4644
 
 v.01 Arduino IR Управление с ИК пульта в режиме удержания кнопки
 https://www.youtube.com/watch?v=AjIASUNiWkY
 
 L293D — драйвер двигателей двухканальный Микросхема
 http://www.youtube.com/watch?v=4e3LEfyS3lQ
 
 
 1/3 поворотная видеокамера Pan & Tilt How to Build Your Own remote control
 http://www.youtube.com/watch?v=zNoWkGWF7uA
 
 2/3 поворотная видеокамера Pan & Tilt How to Build Your Own remote control
 http://www.youtube.com/watch?v=fORD4hUcfYM
 
 3/3 поворотная видеокамера Pan & Tilt How to Build Your Own remote control
 http://www.youtube.com/watch?v=Ku93NDyGcvY
 
 
 1/5 Pan & Tilt How to Build Your Own remote control поворотная видеокамера
 http://www.youtube.com/watch?v=w89IhXHsKSs
 
 2/5 Pan & Tilt How to Build Your Own remote control поворотная видеокамера
 http://www.youtube.com/watch?v=hSKYPZ4WEKU
 
 3/5 Pan & Tilt How to Build Your Own remote control поворотная видеокамера
 http://www.youtube.com/watch?v=QPy9V47dJbA
 
 4/5 Pan & Tilt How to Build Your Own remote control поворотная видеокамера
 http://www.youtube.com/watch?v=RlG7Qmq4TOg
 
 5/5 Pan & Tilt How to Build Your Own remote control поворотная видеокамера
 http://www.youtube.com/watch?v=HzzbM2fr5GM
 
 Самый дешевый Arduino Uno 5$ Minimal Atmega328 without Arduino Board
 http://www.youtube.com/watch?v=joSc-AT8o5k
 */

#include <IRremote.h> // это скачанная библиотека
int RECV_PIN = 6; //вход ИК приемника
IRrecv irrecv(RECV_PIN);
decode_results results;

//eventTime, для паузы,  вместо delay,будем использовать функцию millis. 
unsigned long eventTime=0;

int timer_PIN = 13; //индикация таймера


// motor_PWM_PIN Чтобы управлять скоростью вращения электромоторов, с помощью ШИМ (PWM).
//напряжение постепенно увеличивается (от 0V to 5V)
// подключаем к микросхеме L293D  (драйвер двигателей двухканальный)
//Сигнал подаём на ENABLE (1)и(2), (к ножки 1 и 9 микросхемы L293D).
int motor_PWM_PIN = 5;

// переменная для  хранения(ШИМ. PWM)сигнала.Импульсов
// уставливаем начально значение (ШИМ. PWM)сигнала в 80 
//Только после достижения(ШИМ. PWM)сигнала от 0 к 80,
//мотор начинает двигаться, проверил опытным путём 
//Чтобы не терять время впустую, сразу Стартуем с 80
int position_PWM = 80;


//motor_ подключяем к (к ножкам INPUT 1,2,3,4 микросхемы L293D).
int motor_up = 10; // мотор вверх
int motor_down = 9; // мотор вниз
int motor_left = 7; // мотор лево
int motor_right = 8; // мотор право

void setup(){
  irrecv.enableIRIn(); // включить приемник
  pinMode(motor_PWM_PIN, OUTPUT);
  pinMode(timer_PIN, OUTPUT);
} 
void loop() {
  // Эта конструкция нужна чтобы конвертировать пульсирующий (-) с (ИК) преемника сигнал в постоянный.
  //После появление и пропадания сигнала, состояние сразу не меняется! а ждет  100 миллисекунд.
  //Если 100 миллисекунд не прошло, и поступил еще один сигнал с пульта, тогда таймер заново запускается на 100 миллисекунд.

  //Проще говоря, пока кнопка на пульте нажата таймерПИН остается вКлюченным, если кнопка на пульте отпущена таймерПИН вЫключен.

  // Читаем данные с (ИК) преемника. В момент приема данных у (ИК) приемника на выходе появляется пульсирующий (-)отрицательный сигнал
  if (digitalRead(RECV_PIN) == LOW) 
    //  Если обнаружен отрицательный сигнал запускаем таймер,и включаем таймерПИН //(timer_PIN, HIGH);
    eventTime=millis(),digitalWrite(timer_PIN, HIGH);
  //  Продолжительность работы таймера >100 миллисекунд.
  //Если не было сигнала с пульта в течение 100 миллисекунд. То ТаймерПИН вЫключаем //(timer_PIN, LOW)
  if(millis()-eventTime>100) digitalWrite(timer_PIN, LOW)
    //  и вЫключаем все PINы.
    ,digitalWrite(motor_up, LOW),digitalWrite(motor_down, LOW),digitalWrite(motor_left, LOW)
      ,digitalWrite(motor_right, LOW),digitalWrite(motor_PWM_PIN, LOW),position_PWM = 80;

  if (irrecv.decode(&results)) {
    //ВАЖНО !!! ( 1000809 ) это код кнопки №1 - моего (ИК)! (инфракрасного пульта)!, -
    //-у вашего пульта будет другой код, замените на свой!
    // У моего пульта при нажатии на одну и ту же кнопку, могут отсылаться два разных (КОДА) сигнала,  чтобы обойти эту проблему
    //я использовал Логический оператор "или" (||) if (results.value == 0x1000809 || results.value == 0xF7283C77
    // Теперь неважно какой код из 2 отправлен  с кнопки пульта, первый или второй
    // Если ваша кнопка пульта не страдает раздвоением личности, можете написать так if (results.value == 0x1000809 
    //также мною замечено при использование разных ИК приемников частотой 36,или 38, кГц, библиотека IRremote
    // выдает Разные коды
    //В конце концов сделать 4 "или" (||), чтобы можно было управлять с двух разных пультов

    //Только при условии если, (Одновременно),Обнаружен поступивший код кнопки
    // и выключен ТаймерПИН,"и" "&&" (digitalRead(timer_PIN) == HIGH)
    // включаем нужный нам pin, например digitalWrite(motor_left, HIGH);

    if (results.value == 0x1000809 || results.value == 0xF7283C77 || results.value == 0xE14405A || results.value == 0x3C7BE0E6
      && (digitalRead(timer_PIN) == HIGH) )digitalWrite(motor_left, HIGH);


    if (results.value == 0x1008889 || results.value == 0x757FB4DF || results.value == 0xE14C0DA || results.value == 0xFC0B7A4E 
      && (digitalRead(timer_PIN) == HIGH) )digitalWrite(motor_right, HIGH);


    if (results.value == 0x1004849 || results.value == 0xB33B4597 || results.value == 0xE14E0FA || results.value == 0xED884524 
      && (digitalRead(timer_PIN) == HIGH) )digitalWrite(motor_down, HIGH); 


    if (results.value == 0x100C8C9 || results.value == 0x3C03E507 || results.value == 0xE14F0EA || results.value == 0x70E7155A 
      && (digitalRead(timer_PIN) == HIGH) )digitalWrite(motor_up, HIGH);


    // Если включен timer_PIN
    if(digitalRead(timer_PIN) == HIGH)
      // шаг приращения Скорости мотора
      // читаем состояние переменной position_PWM и к ней прибавляем по + 1 (ШИМ PWM) сигнала
      // Чем больше значение, тем быстрее будет разгоняться мотор
      position_PWM = position_PWM + 1, 
      //Записываем данные из position_PWM в motor_PWM_PIN
      analogWrite(motor_PWM_PIN, position_PWM);

    // чтобы после достижение максимума  > 255 , не сбрасывалось опять на 0, motor_PWM_PIN, оставляем вКлюченным
    if (position_PWM > 255) digitalWrite(motor_PWM_PIN, HIGH);


    irrecv.resume(); 
  }
}








 

 

Patrik
Offline
Зарегистрирован: 15.05.2013

Димка, спасибо! Информация бесценная и очень полезная. Дмитрий а ты не хотел собрать маленький ЧПУ-станок на базе Arduino? Вот ссылка посмотри: http://www.estlcam.com/

Patrik
Offline
Зарегистрирован: 15.05.2013

Дмитрий, скажите как написать скетч в режиме триггера, что бы нажатие на последующую кнопку останавливало работу работающих пинов? 

Пример: Имеем две кнопки ">>-вправо", "<<- влево" и два светодиода на пинах 5, 6. 

Нажимаем на кнопку ">>-вправо" загорается светодиод на пине 5.  Далее нажимаем кнопку "<<-влево" эта команда сначала должна отключить работающий светодиод на 5-м пине (отключение первой команды ">>-вправо") и зажечь уже свой светодиод на пине 6. 

Тоесть перед выполнением своей команды кнопка должна сначала сбросить выполнение команд других уже работающих кнопок.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Заносите нажатие кнопки в массив (пин), а при необходимости проходите его "гася" пины и обнуляете значения.

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

Заносите нажатие кнопки в массив (пин), а при необходимости проходите его "гася" пины и обнуляете значения.

Можно на примере?

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012
int myArray[10]={0,0,0,0,0,0,0,0,0,0};

int i;
for (i = 0; i < 10; i = i + 1) {
  if(myArray[i] == 1) {
       myArray[i] = 0;
       digitalWrite(i, LOW);
  }
  
}

//где-то в коде включаем кнопку

myArray[myPin] = 1;
digitalWrite(myPin, HIGH);

 

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

int myArray[10]={0,0,0,0,0,0,0,0,0,0};

int i;
for (i = 0; i < 10; i = i + 1) {
  if(myArray[i] == 1) {
       myArray[i] = 0;
       digitalWrite(i, LOW);
  }
  
}

//где-то в коде включаем кнопку

myArray[myPin] = 1;
digitalWrite(myPin, HIGH);

 

Смотрите, у меня вот такой скетч, он управляет пинами с ИК-пульта в режиме триггер. Как подружить Ваши команды с моими?

 

01 #include <IRremote.h> //
02  
03 int RECV_PIN = 2; //vkhod IK priyemnika
04 IRrecv irrecv(RECV_PIN);
05 decode_results results;
06 int a=0; // peremennaya pereklyucheniya rezhima , pri nazhatii knopki ona prinimayet znacheniye +1
07 int b=0; //
08  
09 void setup()
10 {
11 irrecv.enableIRIn(); // vklyuchit? priyemnik
12  
13 pinMode(3, OUTPUT);
14 pinMode(5, OUTPUT); // naznachayem piny kak vykhody
15 }
16 void loop() {
17 if (irrecv.decode(&results)) {
18 delay(300); // zaderzhka pered vypolneniyem opredeleniya knopok , chtoby izbezhat? bystroye dvoynoye nazhatiye
19  
20 if (results.value == 0xCD1A) {a=a+1;} // obrabotka nazhitya klavishi , zdes? peremennaya prinimayet znacheniye +1
21 if (results.value == 0xCD9A) {b=b+1;} //kod knopki pulta
22 // nachinayem vklyuchat? svetodiody na pinakh
23 if (a==1){digitalWrite(3, HIGH);} else {digitalWrite(3, LOW); a=0;} // deystviye posle nazhatiya knopki , yesli peremennaya stala ravna 1 to
24 if (b==1){digitalWrite(5, HIGH);} else {digitalWrite(5, LOW); b=0;} // proizvesti pereklyucheniye pina v rezhim HIGH, yesli zhe net to vernut? peremennuyu v iskhodnoye sostoyaniye
25  
26 //
27 delay(50); //pauza mezhdu povtorami //
28 //
29 irrecv.resume(); //
30  
31 }
32  
33 }

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Вы код не из ворда случайно вставляли? Редактировать его нет никакой возможности )))) Если Вы будете "правильно" (тут реальный вброс на много страниц флуда :) форматировать код, то его будет легче (и Вам тоже) читать. Как пример посмотрите как у меня отформатирован if. У Вас значения а и b не могут принимать значения > 1, поэтому 4 if-a можно сократить до двух

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

Вы код не из ворда случайно вставляли? Редактировать его нет никакой возможности )))) Если Вы будете "правильно" (тут реальный вброс на много страниц флуда :) форматировать код, то его будет легче (и Вам тоже) читать. Как пример посмотрите как у меня отформатирован if. У Вас значения а и b не могут принимать значения > 1, поэтому 4 if-a можно сократить до двух

Из блокнота). Я реально не понимаю, что мне нужно делать в данном скетче. Я пробывал else {digitalWrite(5, LOW); b=0;} при нажатие на кнопку управляющую пином 3. При такой комбинации противоположный пин гаснет как надо но вот, что бы запустить следущий пин нужно отжимать всеровно кнопку пина 5. Вобщем данная комбинация не подходит. Если не трудно помоги?!

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

В комментариях есть поле "code" - туда надо вставлять прямо из скетча, он сам прваильно отформатирует. Вы знаете как на бумаге правильно составлять алгоритмы? Это я не к тому что я такой умный :) Вам написать скетч или Вы хотите разобраться научиться?

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

В комментариях есть поле "code" - туда надо вставлять прямо из скетча, он сам прваильно отформатирует. Вы знаете как на бумаге правильно составлять алгоритмы? Это я не к тому что я такой умный :) Вам написать скетч или Вы хотите разобраться научиться?

Хочу и то и другое)

С процесингом все очень плохо. Радует одно, что было еще хуже.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

почитайте вот это http://mini-soft.ru/soft/vba/r_2.php и попробуйте нарисовать свой алгоритм на бумажке

И код свой из скетча вставьте сюда правильно, тогда я смогу его менять :)

Patrik
Offline
Зарегистрирован: 15.05.2013

#include <IRremote.h>  

int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
int a=0; 
int b=0; 

void setup()
{
irrecv.enableIRIn(); 

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);

} 

void loop() {
    if (irrecv.decode(&results)) {
    delay(300); 

    if (results.value == 0x1000809) {a=a+1;} 
    if (results.value == 0x1008889) {b=b+1;} 
  
    if (a==1){digitalWrite(3, HIGH);} else {digitalWrite(3, LOW); a=0;} 
    if (b==1){digitalWrite(5, HIGH);} else {digitalWrite(5, LOW); b=0;} 

    { 
delay(50); 
} //
irrecv.resume(); 

}

}

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

так мы уличшим читаемость:

 

#include <IRremote.h>  

int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
int a=0; 
int b=0; 

void setup()
{
irrecv.enableIRIn(); 

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);

} 

void loop() {
    if (irrecv.decode(&results)) {
        delay(300); 

        if (results.value == 0x1000809) {
               a=a+1;
        } 

        if (results.value == 0x1008889) {
               b=b+1;
        } 
  
        if (a==1) {
               digitalWrite(3, HIGH);
        } else {
              digitalWrite(3, LOW);
              a=0;
        } 
        
       if (b==1) {
             digitalWrite(5, HIGH);
       } else {
             digitalWrite(5, LOW);
             b=0;
       } 

      delay(50); 
   } 
   
   irrecv.resume(); 

}

смотри, у тебя переменные a и b как только принимают значение 1, так сразу выполняется ниже условия и они сбрасываются на 0, значит мы можем действия запихнуть в один if

#include <IRremote.h>  

int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
irrecv.enableIRIn(); 

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);

} 

void loop() {
    if (irrecv.decode(&results)) {
        delay(300); 

        if (results.value == 0x1000809) {
               digitalWrite(5, LOW);
               digitalWrite(3, HIGH);
        } 

        if (results.value == 0x1008889) {
               digitalWrite(3, LOW);
               digitalWrite(5, HIGH);
        } 
  

      delay(50); 
   } 
   
   irrecv.resume(); 

}

 

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

так мы уличшим читаемость:

 

#include <IRremote.h>  

int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
int a=0; 
int b=0; 

void setup()
{
irrecv.enableIRIn(); 

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);

} 

void loop() {
    if (irrecv.decode(&results)) {
        delay(300); 

        if (results.value == 0x1000809) {
               a=a+1;
        } 

        if (results.value == 0x1008889) {
               b=b+1;
        } 
  
        if (a==1) {
               digitalWrite(3, HIGH);
        } else {
              digitalWrite(3, LOW);
              a=0;
        } 
        
       if (b==1) {
             digitalWrite(5, HIGH);
       } else {
             digitalWrite(5, LOW);
             b=0;
       } 

      delay(50); 
   } 
   
   irrecv.resume(); 

}

смотри, у тебя переменные a и b как только принимают значение 1, так сразу выполняется ниже условия и они сбрасываются на 0, значит мы можем действия запихнуть в один if

#include <IRremote.h>  

int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
irrecv.enableIRIn(); 

pinMode(3, OUTPUT);
pinMode(5, OUTPUT);

} 

void loop() {
    if (irrecv.decode(&results)) {
        delay(300); 

        if (results.value == 0x1000809) {
               digitalWrite(5, LOW);
               digitalWrite(3, HIGH);
        } 

        if (results.value == 0x1008889) {
               digitalWrite(3, LOW);
               digitalWrite(5, HIGH);
        } 
  

      delay(50); 
   } 
   
   irrecv.resume(); 

}

 

Почемуто не первый не второй скетч не работают.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

первый это твой, просто с пробелами и отступами

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

первый это твой, просто с пробелами и отступами

Я знаю. Только он тоже почему то перестал работать((( Тот который некоректированный работает.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Он уже в самом первом варианте нерабочий был - смотрим строки 26-28 из ниоткуда фигурные скобки. чтото при копировании потерялось )))

Patrik
Offline
Зарегистрирован: 15.05.2013

JollyBiber пишет:

Он уже в самом первом варианте нерабочий был - смотрим строки 26-28 из ниоткуда фигурные скобки. чтото при копировании потерялось )))

У меня не получается(((

madmax96
Offline
Зарегистрирован: 22.09.2011
#include <IRremote.h>  
 
int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean a = false; 
boolean b = false; 
 
void setup()
{
  irrecv.enableIRIn(); 
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
 
 
void loop() 
{
    if (irrecv.decode(&results))
    {
     delay(300); 
 
      if (results.value == 0xDE010FC6)
       a=true;
      if (results.value == 0xDE010FE6) 
       b=true; 
  
      if (a)
      {
       digitalWrite(3, HIGH);
       digitalWrite(5, LOW);
       a = false;
       b = false;
      }
      
      if (b)
      {
       digitalWrite(5, HIGH);
       digitalWrite(3, LOW);
       a = false;
       b = false;
      }
      
delay(50); 
 
irrecv.resume(); 
 
}
 
}
madmax96
Offline
Зарегистрирован: 22.09.2011
#include <IRremote.h>  
 
int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean a = false; 
boolean b = false; 
 
void setup()
{
  irrecv.enableIRIn(); 
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
 
 
void loop() 
{
    if (irrecv.decode(&results))
    {
     delay(300); 
 
      if (results.value == 0xDE010FC6)
       a=true;
      if (results.value == 0xDE010FE6) 
       b=true; 
  
      if (a && b)
      {
       digitalWrite(3, LOW);
       digitalWrite(5, LOW);
       a = false;
       b = false;
      }
      
      if (b && !a)
      {
       digitalWrite(5, HIGH);
       digitalWrite(3, LOW);
      }
      
       if (!b && a)
      {
       digitalWrite(5, LOW);
       digitalWrite(3, HIGH);
      }
      
delay(50); 
 
irrecv.resume(); 
 
}
 
}
Patrik
Offline
Зарегистрирован: 15.05.2013

madmax96 пишет:

#include <IRremote.h>  
 
int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean a = false; 
boolean b = false; 
 
void setup()
{
  irrecv.enableIRIn(); 
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
 
 
void loop() 
{
    if (irrecv.decode(&results))
    {
     delay(300); 
 
      if (results.value == 0xDE010FC6)
       a=true;
      if (results.value == 0xDE010FE6) 
       b=true; 
  
      if (a)
      {
       digitalWrite(3, HIGH);
       digitalWrite(5, LOW);
       a = false;
       b = false;
      }
      
      if (b)
      {
       digitalWrite(5, HIGH);
       digitalWrite(3, LOW);
       a = false;
       b = false;
      }
      
delay(50); 
 
irrecv.resume(); 
 
}
 
}

Максим, спасибо! Ты прям в точку попал. Супер-скетч! 

madmax96
Offline
Зарегистрирован: 22.09.2011
#include <IRremote.h>  
 
int RECV_PIN = 11; 
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean a = false; 
boolean b = false; 
 
void setup()
{
  irrecv.enableIRIn(); 
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, INPUT_PULLUP);
 
 
void loop() 
{
    if (irrecv.decode(&results))
    {
     delay(300); 
 
      if (results.value == 0xDE010FC6)
       a=true;
      if (results.value == 0xDE010FE6) 
       b=true; 
  
      if (a && b || !digitalRead(6))
      {
       digitalWrite(3, LOW);
       digitalWrite(5, LOW);
       a = false;
       b = false;
      }
      
      if (b && !a)
      {
       digitalWrite(5, HIGH);
       digitalWrite(3, LOW);
      }
      
       if (!b && a)
      {
       digitalWrite(5, LOW);
       digitalWrite(3, HIGH);
      }
      
    
delay(50); 
 
irrecv.resume(); 
 
}
 
}
JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

я наверняка зануда, но Вы бы не могли объяснить зачем в этом скетче переменные a и b?

madmax96
Offline
Зарегистрирован: 22.09.2011

Я переделал то, что меня попросили. Потому сильно ничег оне менял. В переменную a сохраняем как бы статус первой кнопки пульта, в переменную b - статус второй. 

Hleb13
Offline
Зарегистрирован: 16.04.2015

#include <IRremote.h> 

int RECEIVE_PIN = 7; 
int LED = 1; 

IRrecv irrecv(RECEIVE_PIN); 

decode_results results; 


void setup() { 

    Serial.begin(9600); 

    irrecv.enableIRIn(); // Start the receiver 

} 

 
void loop() { 
 
    if (irrecv.decode(&results)) { 

            if ((results.value == 0xC || results.value == 0x80C) && LED == 1) {digitalWrite(8,(!digitalRead(8))); LED = 0;} 

        irrecv.resume(); 

    } 

    else {LED = 1;} 

} 

Подскажите, пожалуйста. Можно реализовать смешанный режим (удержания и тригерный). Объясню на примере:

Есть светодиод и пульт. Пришел сигнал с пульта - светодиод включился, отпустили кнопку пульта, нажали еще раз - светодиод погас. При удержании кнопки светодиод включается и выключается. Нужно усложнить задачу:

Нажимаем на кнопку пульта - светодиод включается, не отпуская удерживаем кнопку - ничего не происходит (светодиод горит), отпускаем кнопку - светодиод продолжает гореть, нажимаем еще раз кнопку - светодиод гаснет, удерживаем кнопку - ничего не происходит (светодиод не горит).

Хочется релизовать включение обычного бытового телевизора, ведь если мы его включаем и удерживаем кнопку, то телевизор просто включается и далее ничего не происходит. Мне же пока удалось добиться, что при удержании кнопки светодиод включается и сразу же выключается, что не является допуститмым.

evgen66
Offline
Зарегистрирован: 19.06.2015

Dimka, делаю клиент на ESP8266, который принимает коды от пульта и отправляет состояние нажатой/отжатой кнопки на сервер. На сервер приходят сообщения с частотой примерно 0,5 сек, что состояние кнопки меняется, хотя кнопка удерживается. При этом timerPin тоже меняет свое значение (BTN12=1 BTN12=0 BTN12=1 BTN12=0 BTN12=1 BTN12=0 BTN12=1 BTN12=0)

Не хватает мне знаний, где искать. Если этот код без клиентской части и отправлять значения просто в Serial то все четко.

#include <IRremoteESP8266.h> 
#include <ESP8266WiFi.h>

WiFiClient client;

const char* ssid     = "****";
const char* password = "****";

const char* host = "192.168.100.63";
const int Port = 2400;

//переменные для ИК приемника
#define MAXBTN 42
int RECV_PIN = 12; //вход ИК приемника
IRrecv irrecv(RECV_PIN);
decode_results results;

//eventTime, для паузы,  вместо delay,будем использовать функцию millis. 
unsigned long eventTime=0;
//индикация таймера
int timer = 13;
int timerFlag = 0;
int counter[MAXBTN]={}; // для всех кнопок кроме тех, которые нужны для последовательных команд,например UP,DOWN,LEFT,RIGHT, VOL-, VOL+, CH-, CH+
String tempCmd;

long hexCodeArray[MAXBTN]= { 0xE0E020DF,0xE0E0A05F,0xE0E0609F,0xE0E010EF,0xE0E0906F,0xE0E050AF,0xE0E030CF,0xE0E0B04F,0xE0E0708F,0xE0E0C43B,
                             0xE0E08877,0xE0E0D32C,0xE0E0E01F,0xE0E0D02F,0xE0E0C837,0xE0E0F00F,0xE0E048B7,0xE0E008F7,0xE0E058A7,0xE0E013EC,
                             0xE0E0F30C,0xE0E006F9,0xE0E08679,0xE0E0A659,0xE0E046B9,0xE0E016E9,0xE0E0738C,0xE0E0F807,0xE0E08F70,0xE0E036C9,
                             0xE0E028D7,0xE0E0A857,0xE0E06897,0xE0E05EA1,0xE0E01FE0,0xE0E053AC,0xE0E0C23D,0xE0E034CB,0xE0E0807F,0xE0E0B34C,
                             0xE0E0B44B,0xE0E040BF
                            };
void setup() {
  
  irrecv.enableIRIn(); // включить приемник
  pinMode(timer, OUTPUT);
  Serial.begin(115200);
  delay(10);
 
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP()); 
}

void loop() {
      ir_recv();
}

void ir_recv() {
  
  
  if (digitalRead(RECV_PIN) == LOW) {
    //  Если обнаружен орицательный сигнал запускаем таймер,и включаем таймерПИН //(timer, HIGH);
     eventTime=micros();
     digitalWrite(timer, HIGH);
     timerFlag = 1;
  }
  
  //  Продолжительность работы таймера >100 миллисекунд. И ТаймерПИН выключаем //(timer, LOW)
  if (micros()-eventTime > 100000)
  {
    // индикация и флаг
    digitalWrite(timer, LOW);
    timerFlag = 0;

    for (int i=0;i<MAXBTN;i++){
      // определение долгого/короткого удержания кнопок
      
      if (counter[i] > 0){      
        tempCmd = "BTN" + String(i) + "=" + String(timerFlag);
        //sendCmd(tempCmd);
         client.connect(host, Port);
          client.println(tempCmd);
          Serial.println();
          Serial.println("disconnecting.");
          client.stop();
      }
      counter[i] = 0;
    }
  
  }
  
  //прием ИК команд
    if (irrecv.decode(&results)) {
      for (int k=0;k<MAXBTN;k++){
        if (results.value == hexCodeArray[k] && timerFlag == 1){  
            counter[k]++; //счетчик присланных команд от кнопки
        }
        if (timerFlag && counter[k] == 1){
          tempCmd = "BTN" + String(k) + "=" + String(timerFlag);
          //sendCmd(tempCmd);
          client.connect(host, Port);
          client.println(tempCmd);
          Serial.println();
          Serial.println("disconnecting.");
          client.stop();
          
         }
      }
    irrecv.resume();  
    }    
}

 

 

 

lilik
Offline
Зарегистрирован: 19.10.2017

jeka_tm пишет:

тоже ломал голову. дело в том что когда я делал управление танком ик пультом и через терминал смотрел коды пульта от телека и не только все пульты первую команду выдают свою а при дальшейшем нажатии FFFFFF. может конечно библиотека не очень была, незнаю. попытался сделать условие удрежания последней команды если идет команда FFFFFF. не получилось. не держит. может на самом деле там не чисто FFFFFF а сплошной поток F был. незнаю. ну или больше символов и изза этого не отрабатывала. в итоге забил. сделал триггер и кнопку сброса всех кнопок

Конечно чтобы включить-выключить нужна одна кнопка, а не две. Сделал пример для светодиода - светит пока удерживаем кнопку, гаснет после отпускания с задержкой 200 мс.

//Тест-скетч - работа кнопок ик пульта с выполнением команды пока кнопка нажата и отключением после отпускания
//////////
#include <IRremote.h>

int RECV_PIN = 11;               // Pin, an den der Empf�nger angeschlossen ist
IRrecv irrecv(RECV_PIN);         // Instanz der Receiver-Klasse
decode_results results;          // Zur Aufnahme des ermittelsten Codes
/////////
long Y=0;//переменная хранения моментов времени


void setup()
{
 pinMode(13,OUTPUT);
 digitalWrite(13,LOW); 
  irrecv.enableIRIn(); // Startet den Receiver
 }
/////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
 CheckSerial();
 if(millis()-Y>200){digitalWrite(13,LOW);}//если кнопка не удерживается, то через 200 мс отключить команду 
}
 /////////////////////////////////////////////////////////////////////////////////////////////////
//ФУНКЦИЯ ПРИЁМА И ОБРАБОТКИ ДАННЫХ
void CheckSerial()
{
 if (irrecv.decode(&results))   //Если произошло событие/кнопка была нажата
  {
    switch ( results.value )
    {
    case 0x8C837://исполнить команду
      digitalWrite(13,HIGH);
      Y=millis();  
        break;
     case 0xFFFFFFFF:// если кнопку удерживают, то не отключать команду ещё 200 мс
      Y=millis();
        break;
    }
    irrecv.resume();//Считываем следующую значение/кнопку
  
   }    
     
   
}
////////////////////////////////////////////////////////////////////////////////