Pages: [1]   Go Down
Author Topic: IR break beam sketch language issues  (Read 1370 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys,

I am making a break beam people counter which uses an infrared beam (made with a Vishay TSTS7100 IR LED) and an infrared sensor (Vishay TSOP341 IR receiver module). When a person walks through the beam a count is recorded by my arduino and is then sent with a GSM modem to a web server.
The infrared LED pulses at 38kHz and my IR receiver module only responds to 38kHz infrared.

I am using an arduino to do the following:
1. make the LED pulse at 38kHz for 6 cycles (ie HIGH to LOW 6 times) then pause for 60 microseconds
2. power the IR receiver module
3. receive an input from that IR receiver when the IR beam is broken by a person
4. output a short (0.1s maybe) HIGH/LOW to the GSM modem's data logger.

I need help with the code to do this.

The code I have written so far consists of modified example sketches. I have gotten as far as making, what I think (I haven't been able to test it) is, a sketch which will: make the LED pulse CONSTANTLY (remember I need it to pause for 60 microseconds) at 38kHz, power the IR receiver, pause the IR LED for 60 microseconds, and receive an input for that IR receiver. I still need help with outputing a short HIGH/LOW.

It is important to realise that the input to the Arduino from the IR receiver module is going to be 1,0,1,0,1.... (going from HIGH to LOW every 60 microseconds) so I can't simply say in my sketch that whenever there is a 1 or a 0 the Arduino should output to the GSM modem. I need a way to say that when there is a LOW (yes a LOW not a HIGH. The ir receiver outputs a LOW) for, let's say 0.05s (or the time it takes a person to walk through a beam of IR light), then the Arduino should output HIGH/LOW. How do I do this?


Here is my sketch thus far:

  
Code:

/*

People Counter sketch.
 
 */

#include <TimedAction.h>

TimedAction pulsefunction = TimedAction (0.6, pulse);

int irLED =  13;      // the number of the irLED pin
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 0.02631579;           // interval at which to blink (milliseconds)

void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards
  pinMode(13, OUTPUT);
  pinMode (12, OUTPUT);  //assign pin 12 as output to power the irRec
  digitalWrite (12, HIGH); //give irREC power
  Serial.begin(9600);  //just in there so I can watch what's happening on the serial monitor
  pinMode(2, INPUT); //assign pin 2 as input for the irRec
 
}

void loop()
{
  {
  pulsefunction.check(); //check pulsefunction to see if the interval is complete
  int irRec = digitalRead(2); //arduino will read the value at pin 2 and assign a number (1 or 0) to it
  Serial.println(irRec, DEC);} //value IR rec. will be printed on serial monitor

}   

 
 void pulse() {
    digitalWrite(13, HIGH);   // set the IR LED on #1
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, HIGH);   // set the IR LED on #2
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, HIGH);   // set the IR LED on #3
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, HIGH);   // set the IR LED on #4
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, HIGH);   // set the IR LED on #5
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, HIGH);   // set the IR LED on #6
    delayMicroseconds(26);              // wait for 1/38 of a milisecond
    digitalWrite(13, LOW);    // set the IR LED off
  }
   

Thanks heaps to anyone who can help smiley)))
« Last Edit: October 16, 2011, 01:47:11 am by LiamLambChop » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
Uno R2! and a bunch of random LEDS and a lcd!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please "edit" your post and select the code and hit the button that is displaying a # sign and it will shorten the page and make the code a little bit easier to see
Logged

GO TECH!

Offline Offline
Faraday Member
**
Karma: 65
Posts: 2500
Now, More Than Ever
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here I am doing essentially what you have in mind --

Code:
/*
  OS_checking_04
  repeat
 
  works pretty good, but NOT with USB_volts
  demo not right till 5V lab supply
  [ USB is marginal, typ IRrcvr module Vmin = 4V7
 
 */
 
int passes = 0;
byte x = 0;
byte dets = 0;

void setup()

  // 38kc bursts xmit on D3 for 38kc IR rcvr
  // LO means IR is present (active state)
  // initialize the digital pin as an output.
  // D3 has an IRED connected
  pinMode(3, OUTPUT);          // IRED aka XMTR
  pinMode(4, INPUT);           // 38kc DET
  pinMode(5, OUTPUT);          // EVENT! annunciator (no beam!)
  delay(1000);   
}

void loop()
{   
   while (passes < 25)          // est. beam, overcome det
                                // latency: it's slow to det
                                // (slow to release, too, but
                                // that's not a concern)
                                // Doesn't need to be this
                                // long, but that's where
                                // it is.
   {
      digitalWrite(3, HIGH);   // set the LED on
      delayMicroseconds(13);   // wait for 13usec
      digitalWrite(3, LOW);    // set the LED off
      delayMicroseconds(2);
      x = digitalRead(4);      //
     
      if (passes > 15 && x == 1)  //
        {
          dets ++;
        }
       
      passes ++;               // 
   }   

   if (dets == 0)             // beam was not broken
     {
        delayMicroseconds(120);
     }
   if (dets > 0)             //  beam was broken
     {
        digitalWrite(5, HIGH);
        delay(2500);
        digitalWrite(5, LOW);
     }
   passes = 0;
   dets = 0;
}   

It's running at about 33 kHz, but it's still effective - it's within the usable bandwidth.  Changing the delayMicroseconds(13) to delayMicroseconds(11) will bring it closer to 38 kHz. 
I've tested this on the bench with the IRED and "rcvr" a few inches apart.  Try that first and if it doesn't do as well over distance then tweak that number till it comes closer (optimise it.)
Logged

"Hello, I must be going..."
"You gotta fight -- for your right -- to party!"
Don't react - Read.
"Who is like unto the beast? who is able to make war with him?"

Essex, UK
Offline Offline
Full Member
***
Karma: 4
Posts: 150
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bit-banging a 38khz signal is completely un-necessary when you have an onboard timer that can generate that for you. See Ken Shirriff's IRemote library for the code.

I assume that you're using a pulsed and modulated signal to drive the IR LED? It looks like that LED can be pulsed at up to 1A if you get the pulse timing right. If you're just driving it with a constant supply your range will be very limited. I've had more than 15 meters reliable outdoor range by pulsing at 600mA  smiley-eek
Logged

Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Pages: [1]   Go Up
Jump to: