2

リモコンのIRコードをデコードし、スケッチで実行したときに機能するようにしました。IRコードを参照してください。

私のRFID猫フィーダースケッチも正常に動作します。RFIDコードを参照してください。

しかし、他のブロッキング機能、特にこのRFIDリーダースケッチでIRリモコンを使用するのに問題があります...各スケッチは、信号の準備をするために常に待機する必要があるようです。私がやりたいのは、RFIDリーダーを正常に実行しているが、IRリモコンを介して手動モードにできるようにすることです。ヘルプやポインタをいただければ幸いです。2つを統合しようとしたコードがありますが、正しく機能しませんでした。それが役立つかどうかをお知らせください。ありがとうございます。

IRコード

#include <IRremote.h>

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

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

// Compare two tick values, returning 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
  if (newval < oldval * .8) {
    return 0;
  } 
  else if (oldval < newval * .8) {
    return 2;
  } 
  else {
    return 1;
  }
}

// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261

/* Converts the raw code values into a 32-bit hash code.
 * Hopefully this code is unique for each button.
 */
unsigned long decodeHash(decode_results *results) {
  unsigned long hash = FNV_BASIS_32;
  for (int i = 1; i+2 < results->rawlen; i++) {
    int value =  compare(results->rawbuf[i], results->rawbuf[i+2]);
    // Add value into the hash
    hash = (hash * FNV_PRIME_32) ^ value;
  }
  return hash;
}

void loop() {
  if (irrecv.decode(&results)) {
    unsigned long hash = decodeHash(&results);
    switch (hash) {
      case 0x4AB0F7B6: // any button held down
        Serial.println("Button Repeat");
        break;
      case 0x2D4AFCCE: // Power
        Serial.println("Power");
        break;
      case 0xE8187BAA: // EQ
        Serial.println("EQ");
        break;
      case 0x95D01E65: // CD/Tuner
        Serial.println("CD/Tuner");
        break;
      case 0xE20BA29: // Mute
        Serial.println("Mute");
        break;
      default:
        Serial.print("Unknown ");
        Serial.println(hash, HEX);    
    }
    irrecv.resume(); // Resume decoding (necessary!)
  }
}

RFIDコード

/*** Cord Slatton
* date 12-13-2012 **/

#include <IRremote.h>
#define RFID_ENABLE 2   //to RFID ENABLE
#define CODE_LEN 10      //Max length of RFID tag
#define START_BYTE 0x0A 
#define STOP_BYTE 0x0D
#define MOTOR_RUN_LENGTH 1000 //time, in ms, to run door motor

char tag[CODE_LEN];
int pwm_b = 11;  //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_b = 13;  //direction control for motor outputs 3 and 4 is on digital pin 13
int door_status = 1; // 1 == closed, 0 == open
//PIR sensor
const int sensorPIR = A0;

unsigned long rfidHitTime = 0; //when did we get last rfid hit?
unsigned long pirHitTime = 0; //when did we get last PIR hit?
unsigned int pirClose = 0;
unsigned int rfidClose = 0;

void setup() {
  Serial.begin(2400); //parallax rfid reader seems to only like serial 2400  
  Serial.println("RoboFeeder Online");
  //rfid
  pinMode(RFID_ENABLE,OUTPUT);
  //motor
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_b, OUTPUT);
  //PIR
  pinMode(sensorPIR, INPUT);
  digitalWrite(sensorPIR, LOW);
  Serial.println("Warming up PIR...");
  delay(10000);
  Serial.println("PIR ready");

  Serial.println("RoboFeeder startup test: Door");
  openDoor();
  delay(2500);
  closeDoor();
  Serial.println("RoboFeeder door test complete");
}

void loop() {
  delay(1500);
  enableRFID(); 
  getRFIDTag(); //waiting function, till gets any tag

  disableRFID();
  openDoor();
  sendCode();

  Serial.flush();
  clearCode();
}

/*** Clears out the memory space for the tag to 0s. */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}

/*** Sends the tag to the computer. */
void sendCode() {
    Serial.print("TAG:");
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    }
    Serial.println("\r"); 
}

/**************************************************************/
/********************   RFID Functions  ***********************/
/**************************************************************/

void enableRFID() {
   digitalWrite(RFID_ENABLE, LOW);    
}

void disableRFID() {
   digitalWrite(RFID_ENABLE, HIGH);  
}

/*** Blocking function, waits for and gets the RFID tag. */
void getRFIDTag() {
  byte next_byte; 
  while(Serial.available() <= 0) {
    if(door_status == 0){ //open
      pirDetection(); 
      rfidClose = millis() - rfidHitTime;
      pirClose =  millis() - pirHitTime;
      Serial.print("RFID Close: ");
      Serial.print(rfidClose);
      Serial.print(" - PIR Close: ");
      Serial.println(pirClose);
      //if door has been open for more than a certain amount of time with no rfid hit and PIR no hit for certain time
      if( (rfidClose > 30000) && (pirClose > 10000) ){
        closeDoor();     
      }
    }        
  }
  pirHitTime = 0;
  if((next_byte = Serial.read()) == START_BYTE) {      
    byte bytesread = 0; 
    while(bytesread < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;       
          tag[bytesread++] = next_byte;         
      }
    }
    rfidHitTime = millis(); //keep track of when last rfid hit was    
  }
}

/********************   Motor Functions  ***********************/

void openDoor() {
  if(door_status == 1){      
    motorRun(150);
    digitalWrite(dir_b, HIGH);  //Set motor direction, 1 low, 2 high
    Serial.println("Door opening");
    delay(MOTOR_RUN_LENGTH);
    motorStop();
    door_status = 1 - door_status;
  }
}

void closeDoor() {
  if(door_status == 0){    
    motorRun(150);
    digitalWrite(dir_b, LOW);  //Reverse motor direction, 1 high, 2 low
    Serial.println("Door closing");
    delay(MOTOR_RUN_LENGTH);
    motorStop();
    door_status = 1 - door_status; 
  }     
}

void motorRun(int speed) {
  analogWrite(pwm_b, speed);  //set motor to run at speed variable value
}
void motorStop() {
  analogWrite(pwm_b, 0);  //set motor to run at 0
}

/********************   PIR Functions  ***********************/

boolean pirDetection() {
  //returns true if PIR analog reading has been rising for more than 10 cycles, false if has been falling
  int counter = 0;
  int pirSensorReading[10];
  int avgReading = 0;
  while(counter < 10){
    pirSensorReading[counter] = analogRead(sensorPIR);
    avgReading += pirSensorReading[counter];  
    counter++;
    delay(300);
  }
  avgReading = avgReading/10;
  Serial.print("Avg. PIR: ");
  Serial.print(avgReading);
  Serial.print(" - Last PIR: ");
  Serial.println( pirSensorReading[9] );

  if( (pirSensorReading[9] > avgReading+1) || (analogRead(sensorPIR) > 700) ){
    pirHitTime = millis(); //keep track of when last PIR hit was
    return true;
  }
  else if(pirSensorReading[9] <= avgReading){
    return false;
  }
}
4

1 に答える 1

2

AttachInterrupt()を使用することで、この問題を正常に解決することができました。

具体的には、以前使用しようとしていたポーリングベースではなく割り込みベースのIRリモート用のライブラリを見つけました。

誰かが興味を持っている場合、完成したRFIDIRリモートコントロール猫フィーダーコードは次のとおりです。

/*** Cord Slatton
 * date 12-28-2012 **/

//IR includes
//info: http://www.zbotic.com/index.php/download/
//download: http://www.zbotic.com/index.php/download_file/view/12/118/
#include "PCInterrupt.h"
#include "Device.h"
#include "irController.h"

#define RFID_ENABLE 8 //to RFID ENABLE
#define CODE_LEN 10 //Max length of RFID tag
#define START_BYTE 0x0A
#define STOP_BYTE 0x0D
#define MOTOR_RUN_LENGTH 1000 //time, in ms, to run door motor

char tag[CODE_LEN];
int pwm_b = 11; //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_b = 13; //direction control for motor outputs 3 and 4 is on digital pin 13
int door_status = 1; // 1 == closed, 0 == open
int manual_mode = 1; // 1 == auto, 0 == manual
//PIR sensor
const int sensorPIR = A0;
//IR init
int manualModePin = 10; //led pin for indication of manual mode
IRController irController;

unsigned long rfidHitTime = 0; //when did we get last rfid hit?
unsigned long pirHitTime = 0; //when did we get last PIR hit?
unsigned long pirClose = 0;
unsigned long rfidClose = 0;

void setup() {
  Serial.begin(2400); //parallax rfid reader seems to only like serial 2400  
  Serial.println("RoboFeeder Online");
  //rfid
  pinMode(RFID_ENABLE,OUTPUT);
  //motor
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_b, OUTPUT);
  //PIR
  pinMode(sensorPIR, INPUT);
  digitalWrite(sensorPIR, LOW);
  Serial.println("Warming up PIR...");
  delay(10000);
  Serial.println("PIR ready");
  //IR remote
  pinMode(manualModePin, OUTPUT);
  digitalWrite(manualModePin, LOW);
  int res = irController.begin(IR_PIN, OTHER_DEVICE);
  if (res != SUCCESS) {
    Serial.println("error=");
    Serial.println(res);
  }
  Serial.println("IR Remote enabled");

  Serial.println("RoboFeeder startup test: Door");
  openDoor();
  delay(2500);
  closeDoor();
  Serial.println("RoboFeeder door test complete");
}

void loop() {
  delay(1500);
  enableRFID(); 
  getRFIDTag(); //waiting function, till gets any tag

  disableRFID();
  openDoor();
  sendCode();

  Serial.flush();
  clearCode();
}

/*** Clears out the memory space for the tag to 0s. */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}

/*** Sends the tag to the computer. */
void sendCode() {
    Serial.print("TAG:");
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    }
    Serial.println("\r"); 
}

/**************************************************************/
/********************   RFID Functions  ***********************/
/**************************************************************/

void enableRFID() {
   digitalWrite(RFID_ENABLE, LOW);    
}

void disableRFID() {
   digitalWrite(RFID_ENABLE, HIGH);  
}

/*** Blocking function, waits for and gets the RFID tag. */
void getRFIDTag() {
  byte next_byte; 
  while(Serial.available() <= 0) {
    if(door_status == 0){ //open
      pirDetection(); 
      rfidClose = millis() - rfidHitTime;
      pirClose =  millis() - pirHitTime;
      Serial.print("RFID Close: ");
      Serial.print(rfidClose);
      Serial.print(" - PIR Close: ");
      Serial.println(pirClose);
      //if door has been open for more than a certain amount of time with no rfid hit and PIR no hit for certain time
      if( (rfidClose > 40000) && (pirClose > 15000) ){
        closeDoor();     
      }
    }    
    IRRemote(); 
    if(manual_mode == 0)
      manualMode();   
  }
  //PIR set to current loop time to keep it from freaking out
  pirHitTime = millis();

  if((next_byte = Serial.read()) == START_BYTE) {      
    byte bytesread = 0; 
    while(bytesread < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;       
          tag[bytesread++] = next_byte;         
      }
    }
    rfidHitTime = millis(); //keep track of when last rfid hit was    
  }
}

/**************************************************************/
/********************   Motor Functions  ***********************/
/**************************************************************/

void openDoor() {
  if(door_status == 1){      
    motorRun(150);
    digitalWrite(dir_b, HIGH);  //Set motor direction, 1 low, 2 high
    Serial.println("Door opening");
    delay(MOTOR_RUN_LENGTH);
    motorStop();
    door_status = 1 - door_status;
  }
}

void closeDoor() {
  if(door_status == 0){    
    motorRun(150);
    digitalWrite(dir_b, LOW);  //Reverse motor direction, 1 high, 2 low
    Serial.println("Door closing");
    delay(MOTOR_RUN_LENGTH);
    motorStop();
    door_status = 1 - door_status; 
  }     
}

void motorRun(int speed) {
  analogWrite(pwm_b, speed);  //set motor to run at speed variable value
}
void motorStop() {
  analogWrite(pwm_b, 0);  //set motor to run at 0
}

/**************************************************************/
/********************   PIR Functions  ***********************/
/**************************************************************/

boolean pirDetection() {
  //returns true if PIR analog reading has been rising for more than 10 cycles, 
  //false if has been falling
  int counter = 0;
  int pirSensorReading[10];
  int avgReading = 0;
  while(counter < 10){
    pirSensorReading[counter] = analogRead(sensorPIR);
    avgReading += pirSensorReading[counter];  
    counter++;
    delay(300);
  }
  avgReading = avgReading/10;
  Serial.print("Avg. PIR: ");
  Serial.print(avgReading);
  Serial.print(" - Last PIR: ");
  Serial.println( pirSensorReading[9] );

  if( (pirSensorReading[9] > avgReading+1) || (analogRead(sensorPIR) > 700) ){
    pirHitTime = millis(); //keep track of when last PIR hit was
    return true;
  }
  else if(pirSensorReading[9] <= avgReading){
    return false;
  }
}

/**************************************************************/
/********************   IR Remote Functions  ***********************/
/**************************************************************/

void IRRemote(){ 
  int val = irController.read(); // Returns negative value if no new command rcvd  
  if (val >=0){
    Serial.print("Key: ");
    Serial.println(val);
    if(val == 100){
      manual_mode = 1 - manual_mode;
    }    
    else if( (val >= 0) && (manual_mode == 0) ){
      if(door_status == 1)
        openDoor();
      else
        closeDoor();
    }
  }
  delay(500); 
}

//blocking function that won't let you leave till you turn off manual mode
void manualMode(){
  disableRFID();
  Serial.println("Manual Mode on");
  digitalWrite(manualModePin, HIGH);
  while(manual_mode == 0){
    IRRemote();
  }
  Serial.println("Manual Mode exiting");
  digitalWrite(manualModePin, LOW);
  //set sensors to count from now, esentially zero them out
  pirHitTime = millis();
  rfidHitTime = millis();
  enableRFID();
}    
于 2012-12-29T03:24:03.530 に答える