Close

Adafruit IR Break Beam

A project log for The Smart Letterbox

Attach a device to an existing letterbox that will send a push notification when a letter or package is inserted

Tony KambourakisTony Kambourakis 02/15/2016 at 01:192 Comments

The Adafruit IR Break Beam sensor comprises two components; an emitter that generates an IR beam and a receiver that is sensitive to the IR beam. When the beam from the emitter is broken the receiver pulls its digital output low. The receiver's digital output is open collector therefore the input mode for D4 and D6 were set to INPUT_PULLUP to keep them normally high.

There are two IR break beam sensors, one for the top slot and one for the bottom slot of the letterbox. The scope shot below shows both sensors being triggered at the same time.

Both sensors normally hovered around 3.3V. They exhibited a little bounce which is taken care of using software debouncing.

An interrupt was attached to each input triggered on the falling edge.

void init_letter_sensor() {
  Serial.println("Initialising letter sensor");
  pinMode(D6, INPUT_PULLUP);
  pinMode(D7, OUTPUT);
  pinMode(D4, INPUT_PULLUP);
  pinMode(BUILTIN_LED, OUTPUT);
  attachInterrupt(D6, letterBottomSensorActivated, FALLING);
  attachInterrupt(D4, letterTopSensorActivated, FALLING);
  digitalWrite(D7, LOW);
}

As you can't pass a parameter to an interrupt handler two interrupts were created, one for top and bottom. An LED was driven from D7 to indicate when either IR beam's were broken.

The interrupt handlers simply update a global state variable that, when changed, is handled within the main loop() routine.

void letterBottomSensorActivated() {
  state = LETTER_SENSOR_DETECTED;
  letterSensorDetected = LETTER_BOTTOM_SENSOR;
}

void letterTopSensorActivated() {
  state = LETTER_SENSOR_DETECTED;
  letterSensorDetected = LETTER_TOP_SENSOR;
}

When a letter sensor is activated it will publish an event with a payload indicating top or bottom sensor. Separate topics were created to separate temperature readings and letter sensor events.

// temperature sensor event topic

char tempsensortopic[] = "int-2/evt/tempsensor/fmt/json";

// letter sensor event topic

char lettersensortopic[] = "int-2/evt/lettersensor/fmt/json";

The NodeRED flow was changed to accommodate the different topics. A second IBM IoT node was added and the original IBM IoT node was changed to only take in temperature sensor events.

The Temp Sensor node only listens for tempsensor events.

The Letter Sensor node only listens for lettersensor events.

A timer was also introduced to trigger reading the DHT22 temperature and humidity sensor. The os_timer_t was set to complete at 15 seconds and repeat.

os_timer_t myTimer;
bool timerCompleted;
void setup() {

  // ...other setup code

  os_timer_setfn(&myTimer, timerCallback, NULL);
  os_timer_arm(&myTimer, 15000, true);
}
Again the timer handler routine simply sets a global state that is handled within the main loop() routine.
void timerCallback(void *pArg) {
  
  timerCompleted = true;
}
The current consumption with these components was as follows:
StateMin Current (mA)Average Current (mA)Max Current (mA)Power Supply (V)
Idle53.565.2104.93.3
Top Sensor Active107.5
Bottom Sensor Active107.5
Both Sensors Active108.0

Chopsticks came in handy to hold up the emitter and receiver units. This was also the first time OTA firmware update was used.

Refer to the IR Break Beam branch for the code

Discussions

c835722 wrote 02/15/2016 at 23:00 point

Good post. Perhaps a table comparing the sensors is in order. I also observe that the MCU loop() stlye program with flags being set within subroutines the observed and reset within main could be the source of a good post. Let me see if I can find the pattern for that. Also could be time to expose a linter/parser to validate the pattern doesnt get broken along the way.

  Are you sure? yes | no

c835722 wrote 02/15/2016 at 23:00 point

Good post. Perhaps a table comparing the sensors is in order. I also observe that the MCU loop() stlye program with flags being set within subroutines the observed and reset within main could be the source of a good post. Let me see if I can find the pattern for that. Also could be time to expose a linter/parser to validate the pattern doesnt get broken along the way.

  Are you sure? yes | no