Комфликт между двумя библиотеками.

Dima85
Offline
Зарегистрирован: 07.01.2013

Подскажите что я делаю не так. Задача отследить нажатие на ТВ пульте и отправить 433mhz сигнал на выключатель. После нажатия на кнопку пульта я вижу надпись "ok" но лампочка не включается.

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

#include <livolo.h>
Livolo livolo(8); // transmitter connected to pin #8

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    
 if (results.value==16738455) {
      Serial.println("ok");
     livolo.sendButton(6400, 120);
    }
    irrecv.resume(); // Receive the next value
  }
 
}

В то же время вот такой код работает, он включает и выключает каждые 3-4 секунды лампочку.

#include <livolo.h>
Livolo livolo(8); // transmitter connected to pin #8
void setup() {
}
void loop() {
  livolo.sendButton(6400, 120); // blink button #3 every 3 seconds using remote with remoteID #6400
  delay(3000);
}

Что я делаю не так? Тесты провожу на Arduino Mega 2560.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

В первом коде есть дополнительная библиотека IRremote. Первый код не работает.
Во втором коде нет библиотеки IRremote. Второй код работает.
Библиотеку Livolo нам всем, у кого её нет, придется искать (обычно достаточно хотя бы ссылку дать, откуда можно скачать, иначе может так случиться, что таких библиотек несколько и мы не будем знать, какой пользуетесь Вы), устанавливать. А у Вас она уже установлена и нужно всего лишь посмотреть, например, какие таймеры, прерывания, используют эти библиотеки (IRremote & Livolo).

На вопрос "Что я делаю не так?", ответ такой: не смОтрите исходники библиотек на предмет пересечения использования общих ресурсов, например, таймеров, прерываний.

 

Dima85
Offline
Зарегистрирован: 07.01.2013

Выкладываю библиотеку:

livolo.cpp

/*
  Livolo.cpp - Library for Livolo wireless switches.
  Created by Sergey Chernov, October 25, 2013.
  Released into the public domain.
*/

#include "Arduino.h"
#include "Livolo.h"

Livolo::Livolo(byte pin)
{
  pinMode(pin, OUTPUT);
  txPin = pin;
}

// keycodes #1: 0, #2: 96, #3: 120, #4: 24, #5: 80, #6: 48, #7: 108, #8: 12, #9: 72; #10: 40, #OFF: 106
// real remote IDs: 6400; 19303
// tested "virtual" remote IDs: 10550; 8500; 7400
// other IDs could work too, as long as they do not exceed 16 bit
// known issue: not all 16 bit remote ID are valid
// have not tested other buttons, but as there is dimmer control, some keycodes could be strictly system
// use: sendButton(remoteID, keycode), see example blink.ino; 


void Livolo::sendButton(unsigned int remoteID, byte keycode) {

  for (pulse= 0; pulse <= 180; pulse = pulse+1) { // how many times to transmit a command
  sendPulse(1); // Start  
  high = true; // first pulse is always high

  for (i = 16; i>0; i--) { // transmit remoteID
    byte txPulse=bitRead(remoteID, i-1); // read bits from remote ID
    selectPulse(txPulse);    
    }

  for (i = 7; i>0; i--) { // transmit keycode
    byte txPulse=bitRead(keycode, i-1); // read bits from keycode
    selectPulse(txPulse);    
    }    
  }
   digitalWrite(txPin, LOW);
}

// build transmit sequence so that every high pulse is followed by low and vice versa

void Livolo::selectPulse(byte inBit) {
  
      switch (inBit) {
      case 0: 
       for (byte ii=1; ii<3; ii++) {
        if (high == true) {   // if current pulse should be high, send High Zero
          sendPulse(2); 
        } else {              // else send Low Zero
                sendPulse(4);
        }
        high=!high; // invert next pulse
       }
        break;
      case 1:                // if current pulse should be high, send High One
        if (high == true) {
          sendPulse(3);
        } else {             // else send Low One
                sendPulse(5);
        }
        high=!high; // invert next pulse
        break;        
      }
}

// transmit pulses
// slightly corrected pulse length, use old (commented out) values if these not working for you

void Livolo::sendPulse(byte txPulse) {

  switch(txPulse) { // transmit pulse
   case 1: // Start
   digitalWrite(txPin, HIGH);
   delayMicroseconds(500); // 550
   digitalWrite(txPin, LOW);
   break;
   case 2: // "High Zero"
   digitalWrite(txPin, LOW);
   delayMicroseconds(100); // 110
   digitalWrite(txPin, HIGH);
   break;   
   case 3: // "High One"
   digitalWrite(txPin, LOW);
   delayMicroseconds(300); // 303
   digitalWrite(txPin, HIGH);
   break;      
   case 4: // "Low Zero"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(100); // 110
   digitalWrite(txPin, LOW);
   break;      
   case 5: // "Low One"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(300); // 290
   digitalWrite(txPin, LOW);
   break;      
  } 
}

 

livolo.h

/*
  Morse.h - Library for Livolo wireless switches.
  Created by Sergey Chernov, October 25, 2013.
  Released into the public domain.
*/

#ifndef Livolo_h
#define Livolo_h

#include "Arduino.h"

class Livolo
{
  public:
    Livolo(byte pin);
    void sendButton(unsigned int remoteID, byte keycode);
  private:
    byte txPin;
	byte i; // just a counter
	byte pulse; // counter for command repeat
	boolean high; // pulse "sign"
	void selectPulse(byte inBit);
	void sendPulse(byte txPulse);
};

#endif

Нашел ее на хабре: http://habrahabr.ru/post/211594/

Прямая ссылка на библиотеку: https://drive.google.com/file/d/0B0DQ7La4EBHlU2ltTmlmeHhya3M/edit?usp=sharing

Dima85
Offline
Зарегистрирован: 07.01.2013

Точно такая же проблема с RC-Switch (https://code.google.com/p/rc-switch/)

После нажатия на кнопку пульта я вижу надпись "ok" но лампочка не включается.

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  mySwitch.enableTransmit(11);
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    
 if (results.value==16738455) {
      Serial.println("ok");
      mySwitch.send("110100100100011110000010");
    }
    irrecv.resume(); // Receive the next value
  }
 
}

В то же время такой код работает, включает лампочку и выключает каждые 3-4 секунды.:

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
  mySwitch.enableTransmit(11);
}
void loop() {
  mySwitch.send("110100100100011110000010");
  delay(3000);
}

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Пофантазирую.
Первое.
Для вывода кода в выключатель запрещаем прерывания, после вывода - разрешаем.
Пробуем.
Что получилось?

Dima85
Offline
Зарегистрирован: 07.01.2013

А как запретить это прерывание и снова потом разрешить?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Скажи НЕТ прерываниям :)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012
Dima85
Offline
Зарегистрирован: 07.01.2013

kisoft, помогло. Спасибо большое.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Не очень хорошо. Значит надо искать другой вариант реализации. Но если Вас устраивает этот вариант, тогда проще забить :)