Jim has used a pair of LaunchPads, LEDs and optical detectors to detect the trains in his five-turn helix. Here's Jim's description:
Quintet
Optical Sensor
This
project is to sense movement of a train through my helix. The single
track helix has a 33” radius and has approximately 5 ½ turns – HO scale 95 feet
of track – so I have decided 10 detectors are required each having an output which
stays on for around 10-12 seconds so that progression of a single railcar can
be seen on a “row of LED’s” display.
In
this project two LaunchPads will control the 10 LED display. Each
LaunchPad reads five of the optical sensors providing track occupancy and then illuminates
respective LED’s for a predetermined time. Please note that the “Block
Occupied” indication comes from a “Block Watcher” detector to be used for
signal logic.
Proposed Indicator
Panel
Bill of Materials:
(1) 2 x LaunchPad with MSP430G2553IN20 processor.
(2)
10 x Optical sensor modules from a Chinese vendor IR Reflective Sensor (this link
was valid at the time of publication) .
(3)
6 LED’s per LaunchPad.
(4)
5V regulated power supply to supply the optical sensors.
Optical
Sensor - component side of board
Optical
Sensor - emitter/detector
side of board
Theory
of Operation:
Reflective optical sensors are placed adjacent to the track at predetermined locations on the helix.
Each set of five sensors are connected to pins [Board
(IC)] P1.0 (2), P1.3 (5), P1.4 (6), P1.5 (7), P1.6 (14) and the respective indicator LED’s are
connected to pins P2.0 (8), P2.1 (9), P2.2 (10), P2.3 (11), P2.4 (12) of the
LaunchPad.
When a train is detected, the software in the LaunchPad causes the respective output to go high (turn on) and stay illuminated for a predetermined time.
This is achieved by using a simple counter for
each Input/Output pair e.g. Input #1 P2.0 (input) and P1.0 (output) [Output_1_Timer]. The other pairs are P2.1/P1.3 [Output_2_Timer], P2.2/P1.4 [Output_3_Timer], P2.3/P1.5 [Output_4_Timer] and P2.4/P1.6 [Output_5_Timer]. When an input is detected
the respective counter is indexed by 1. If a long train is used it would be
possible that all detectors are indexed at the same time. If the value of a
counter is equal to 1 then the respective output is switched on. The program then
checks to see if the counter exceeds the value of the variable max_time. When the value of max_time is exceeded then the respective output in turned off and
the respective counter reset to zero.
The final check is to index the respective counter for the next
iteration of the while loop then the program keeps cycling at the chip
operating frequency which depends on supply voltage as described on page 21 of the
manual.
The
Power on LED is connected to pin P2.5 (13) and illuminates when the LaunchPad
is running the program.
Notes on setting the sensitivity
of the detectors
- Turning
the adjustment screw continuously clockwise increases the sensitivity
eventually it detects nothing but activates (output goes low) make sure
that the adjustment screw is backed off at least one turn or spurious
activation results.
- The
surface the “reflection” is sought from does matter good results where
found with white, grey, orange, with varied results from dark brown &
black.
- Direct
sunlight will activate (output goes low) the sensor.
Circuit
Diagram:
Remember two of these circuits are required to illuminate the 10 LED’s. While the diagram looks complicated, hookup is actually reasonably simple using wire wrap techniques.
The
only complication comes in the fact that the relays and optical sensors require
5 VDC. Remember that the LaunchPad runs on 3.3 VDC, so it cannot supply 5
VDC for the other modules. An external 5VDC source is wired to the relay module
and to the optical sensors. For the circuit to work with the LaunchPad
running from (potentially) a different power
supply, a common ground connection must be made between the 5 VDC supply and
the LaunchPad and it's 3.3 VDC supply. Run a wire from the GND pin on the
LaunchPad to make a connection with the GND (-) wire from the 5 VDC
supply. The LaunchPad may be powered via it's USB port (as I did) or from
an external 3.3 VDC supply.
Demonstration of the Prototype
Link to Optical sensor
testing – note detector 4 fails….
Link to testing with
minimal time delay.
Link to see final
configuration.
The
Code
The
code can be found here.
The
code listing follows below.
/*
*
Quintet Optical Sensor Version 1.1
*
COPYRIGHT © 2013 Jim Gifford
*
http://halletcovesouthern.blogspot.com.au
*
Provided under a Creative Commons Attribution, Non-Commercial Share Alike,3.0
Unported License
*
*
I wish to acknowledge code snippets initially written by:
*
“Steve Hoffy Hofmeister”
*
“Terry Terrance”
*
that were adapted for use.
*
*
Also thanks to Toni Ryan for his clarity advice
*
*
TARGETED TO MSP430 LANUCHPAD W/MSP430G2553 PROCESSOR
*
*
Design Notes:
*
*
This code is designed to receive inputs from 5 Optical Sensors and light 5
independent indicator LEDS, hold them on for a predefined period of time
(currently set to about 12 seconds), to signal that an object as been detected.
*
*This
Project has been designed to be powered by the USB connection. Consult other
available instructions on how to connect your MSP430 to external power sources
before attempting.
*
*
*
Circuit Pinout:
*
PIN 1.0 = Anode of Indicator LED #1 \
*
PIN 1.1 = UNASSIGNED - UART
*
PIN 1.2 = UNASSIGNED - UART
*
PIN 1.3 = Anode of Indicator LED #2 \
*
PIN 1.4 = Anode of Indicator LED #3 \ Cathodes to ground
*
PIN 1.5 = Anode of Indicator LED #4 /
*
PIN 1.6 = Anode of Indicator LED #5 /
*
PIN 1.7 = UNASSIGNED
*
PIN 2.0 = Input for optical sensor 1
*
PIN 2.1 = Input for optical sensor 2
*
PIN 2.2 = Input for optical sensor 3
*
PIN 2.3 = Input for optical sensor 4
*
PIN 2.4 = Input for optical sensor 5
*
PIN 2.5 = Circuit Power Indicator
*
PINS 1.1, 1.2, 1.7 are left unused for integration into other projects.
*/
#include
<msp430g2553.h>
/////////////////////////////////////////////
// Define variables
////////////////////////////////////////////
volatile long Output_1_Timer
=0; //Define Output_1_Timer &
set to 0
volatile long Output_2_Timer
=0; //Define Output_2_Timer &
set to 0
volatile long Output_3_Timer
=0; //Define Output_3_Timer &
set to 0
volatile long Output_4_Timer
=0; //Define Output_4_Timer &
set to 0
volatile long Output_5_Timer
=0; //Define Output_5_Timer &
set to 0
volatile long
max_time=100000; //Define time for
outputs to stay on
void
main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P2DIR |= BIT5; //
Circuit Power Indicator
P2OUT |= BIT5; //
Used to Trouble Shooting
//Configure
Optical Sensors
P2DIR &= ~BIT0; // sets Port 2, bit 0 to input for optical detector1
P2DIR &= ~BIT1; // sets Port 2, bit 1 to input for optical detector2
P2DIR &= ~BIT2; // sets Port 2, bit 2 to input for optical detector3
P2DIR &= ~BIT3; // sets Port 2, bit 3 to input for optical detector4
P2DIR &= ~BIT4; // sets Port 2, bit 4 to input for optical detector5
P2REN |= BIT0; // sets pull-up resistor on Port 2, bit 0 input pin
P2REN |= BIT1; // sets pull-up resistor on Port 2, bit 1 input pin
P2REN |= BIT2; // sets pull-up resistor on Port 2, bit 2 input pin
P2REN |= BIT3; // sets pull-up resistor on Port 2, bit 3 input pin
P2REN |= BIT4; // sets pull-up resistor on Port 2, bit 4 input pin
P2OUT |= BIT0; // sets pull-up resistor on Port 2, bit 0 to pull-up
P2OUT |= BIT1; // sets pull-up resistor on Port 2, bit 1 to pull-up
P2OUT |= BIT2; // sets pull-up resistor on Port 2, bit 2 to pull-up
P2OUT |= BIT3; // sets pull-up resistor on Port 2, bit 3 to pull-up
P2OUT |= BIT4; // sets pull-up resistor on Port 2, bit 4 to pull-up
//Configure
Outputs
P1DIR |= BIT0; // Port 1 P1.0 (Indicator #1) as output
P1OUT &= ~BIT0; // Port 1 P1.0 (Indicator #1) Set to off State
P1DIR |= BIT3; // Port 1 P1.3 (Indicator #2) as output
P1OUT &= ~BIT3; // Port 1 P1.3 (Indicator #2) Set to off State
P1DIR |= BIT4; // Port 1 P1.4 (Indicator #3) as output
P1OUT &= ~BIT4; // Port 1 P1.4 (Indicator #3) Set to off State
P1DIR |= BIT5; // Port 1 P1.5 (Indicator #4) as output
P1OUT &= ~BIT5; // Port 1 P1.5 (Indicator #4) Set to off State
P1DIR |= BIT6; // Port 1 P1.6 (Indicator #5) as output
P1OUT &= ~BIT6; // Port 1 P1.6 (Indicator #5) Set to off State
//
Let's Get Down to Business
while( 1 ) //
begin infinite loop
{
//Detector #1
if( (P2IN & BIT0) == 0) //
When IR Detector #1 activates by going low
Output_1_Timer
++; //Index
the counter
if (Output_1_Timer ==1) // First
iteration when Detector #1 active
P1OUT |=
BIT0; //
Set LED Indicator #1 to ON
if (Output_1_Timer >
max_time) // Time up?
{
Output_1_Timer
=0; //
Reset the counter
P1OUT &=
~BIT0; //
Set LED Indicator #1 to OFF
}
if (Output_1_Timer !=0) //
Output_1_Timer is active
Output_1_Timer
++; //
Index the counter
//END of Detector #1
//Detector #2
if( (P2IN & BIT1) == 0) //
When IR Detector #2 activates by going low
Output_2_Timer
++; //
Index the counter
if (Output_2_Timer ==1) // First
iteration when Detector #2 active
P1OUT |= BIT3; //
Set LED Indicator #2 to ON
if (Output_2_Timer >
max_time) // Time up?
{
Output_2_Timer
=0; //
Reset the counter
P1OUT &=
~BIT3 ; //
Set LED Indicator #2 to OFF
}
if (Output_2_Timer !=0) //
Output_2_Timer is active
Output_2_Timer
++; //
Index the counter
//END of Detector #2
//Detector #3
if( (P2IN & BIT2) == 0) //
When IR Detector #3 activates by going low
Output_3_Timer
++; //
Index the counter
if (Output_3_Timer ==1) // First
iteration when Detector #3 active
P1OUT |=
BIT4; //
Set LED Indicator #3 to ON
if (Output_3_Timer >
max_time) // Time up?
{
Output_3_Timer
=0; //
Reset the counter
P1OUT &=
~BIT4; //
Set LED Indicator #3 to OFF
}
if (Output_3_Timer !=0) //
Output_3_Timer is active
Output_3_Timer
++; //
Index the counter
//END of Detector #3
//Detector #4
if( (P2IN & BIT3) == 0) //
When IR Detector #4 activates by going low
Output_4_Timer
++; //
Index the counter
if (Output_4_Timer ==1) // First
iteration when Detector #4 active
P1OUT |=
BIT5; //
Set LED Indicator #4 to ON
if (Output_4_Timer >
max_time) // Time up?
{
Output_4_Timer
=0; //
Reset the counter
P1OUT &=
~BIT5; //
Set LED Indicator #4 to OFF
}
if (Output_4_Timer !=0) //
Output_4_Timer is active
Output_4_Timer
++; //
Index the counter
//END of Detector #4
//Detector #5
if( (P2IN & BIT4) == 0) //
When IR Detector #5 activates by going low
Output_5_Timer
++; //
Index the counter
if (Output_5_Timer ==1) // First
iteration when Detector #5 active
P1OUT |=
BIT6; //
Set LED Indicator #5 to ON
if (Output_5_Timer >
max_time) // Time up?
{
Output_5_Timer
=0; //
Reset the counter
P1OUT &=
~BIT6; //
Set LED Indicator #5 to OFF
}
if (Output_5_Timer !=0) //
Output_5_Timer is active
Output_5_Timer
++; //
Index the counter
//END of Detector #5
} //End
of While
} // END OF MAIN
Good stuff! Wonder if it will work with low level infrared lighting? ;)
ReplyDeleteMichael I have a infrared camera in the same area and the system still seems to work ok.
ReplyDeleteHere is a link to it operating in place: https://www.youtube.com/watch?v=bkBk-bmS4M4
Cheers, Jim
Very Nice
ReplyDelete