Go Down

Topic: Decoding two IR sensors separately (Read 1 time) previous topic - next topic

dkbex

Hello all,

I'm working on a demo for which I need to decode the output of two VISHAY TSOP34156 IR detectors. Essentially, I have a "wireless" IR beacon pulsing at 56khz and wish to track which IR module the beacon is in front of at any given time. I piggybacked on Ladyada's code (http://learn.adafruit.com/ir-sensor/using-an-ir-sensor) and have been successful in deciding whether or not the beacon is in front of one of my receivers at a time. However, I can't think of a way to modify my code to work dynamically for both detectors. My goal is to rapidly blink one LED when the beacon is in the field of view of the left VISHAY, and a different LED when in the FOV of my right one. I would truly appreciate any guidance or tips for how to accomplish this.

Thanks! Here's my code for "one at a time" detection. 

Code: [Select]

// Modification of Ladyada's code (http://learn.adafruit.com/ir-sensor/using-an-ir-sensor)
#include <Average.h>

#define IRpin_PIN PIND
#define IRpin 2

#define leftIRpin_PIN PIND // ...
#define leftIRpin 4 // This is the output of my second IR detector which I've been struggling to incorporate

#define RESOLUTION 30


uint16_t pulses[100][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
int counter = 0;
int pulsetrain[100];

void setup(void) {
  Serial.begin(38400);
  Serial.println("Ready to decode IR!");
  pinMode(13,OUTPUT); //Right LED, corresponds to right IR detector
  pinMode(12,OUTPUT); //Left LED, corresponds to left IR detector
}

void loop(void) {
  uint16_t highpulse, lowpulse; // temporary storage timing
  highpulse = lowpulse = 0; // start out with no pulse length

    while (IRpin_PIN & (1 << IRpin)) {

     // count off another few microseconds
     highpulse++;
     delayMicroseconds(RESOLUTION);
  }
  // we didn't time out so lets stash the reading
  pulses[currentpulse][0] = highpulse;
 
  while (! (IRpin_PIN & _BV(IRpin))) {
     // pin is still LOW
     lowpulse++;
     counter++;
     if (counter == 100) {
       printpulses();
       counter = 0;
       currentpulse=0;
       return;
     }
     delayMicroseconds(RESOLUTION);
}
  pulses[currentpulse][1] = lowpulse;

  // we read one high-low pulse successfully, continue!
  currentpulse++;
}

void printpulses(void) {
  for (uint8_t i = 0; i < currentpulse; i++) {
    pulsetrain[i] = pulses[i][0] * RESOLUTION;
  }
  int hundredmode = mode(pulsetrain,currentpulse);
  if (hundredmode == 960 || hundredmode == 990) {
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
  }
}




RIDDICK

#1
Jan 06, 2013, 08:26 am Last Edit: Jan 06, 2013, 01:27 pm by RIDDICK Reason: 1
u cant store so many pulses for 2 sensors, i think...
the atmega168 has just 1KiB of SRAM... :)
but u just store them for building an average over 100 samples, which u can do easier... or did i miss something?

is the blinking really necessary? :)

u mean something like this?

Code: [Select]

void setup() {...}

void loop() {
 lookAtSensorAtPin(2,12);
 lookAtSensorAtPin(4,13);
}

void lookAtSensorAtPin(const uint8_t pinSensor, const uint8_t pinLED) { // all IR sensors must be on port D (PIND)
 #define IRpin_PIN PIND
 const uint32_t ts0 = micros();
 const uint8_t C = 100;
 const uint8_t msk = _BV(pinSensor);
 for (uint8_t i=0; i<C; i++) {
   while ((IRpin_PIN&msk) && micros()-ts0<2UL*1000UL*1000UL);
   while (!(IRpin_PIN&msk) && micros()-ts0<2UL*1000UL*1000UL);
 }
 const uint32_t ts1 = micros();
 const uint32_t avg = (ts1-ts0)/C;
 Serial.print("Sensor "); Serial.print(pinSensor);
 Serial.print(" average cycle length "); Serial.print(avg); Serial.println("usec.");
 digitalWrite(pinLED,avg>960);
}
-Arne

Go Up