Hieronder mijn programma-code. In Arduino terminologie de Sketch.
Code: Selecteer alles
// Infrared Blockdetection for six IR detectors
const int Debug = 1; // 0 = No Debug-information
// For testing, compile with Debug = 1
// For run-time, compile with Debug = 0
const int BaudRate = 19200; // do not change
unsigned long CurTime;
float CurTimeDec;
unsigned long ShowTime;
const int ShowDelay = 1000; // time between show Debug-lines
const int DetectorCount = 6; // number of detectors to monitor
// Status-led = LED_BUILTIN = pin 13
// External Status-led = pin 2
const int Out_Pin[6] = {3, 4, 5, 6, 7, 8}; // To DCC Ground-detector Unit
const int Led_Pin[6] = {9, 10, 11, 12, A0, A1}; // IR Led near IR receiver
const int IR_Pin[6] = {A2, A3, A4, A5, A6, A7}; // IR transistor for input
const String IR_PinName[6] = {"A2", "A3", "A4", "A5", "A6", "A7"}; // IR transistors
// A2..A7 Should best be connected to +5V with a 5k resistor. Internal Pullup is not always sufficient.
// Pins A6 and A7 do NOT have internal Pullup.
// Pins A6 and A7 can NOT be used as output
String IR_Result[6][3] = {{"?", "?", "?"},
{"?", "?", "?"},
{"?", "?", "?"},
{"?", "?", "?"},
{"?", "?", "?"},
{"?", "?", "?"}}; // for three measurements per Led
int Out_State[6] = {0, 0, 0, 0, 0, 0}; // 0 = Off; 1 = On
int Out_StatePrev[6] = {0, 0, 0, 0, 0, 0};
String StateText[6] = {"", "", "", "", "", ""};
String StateTextPrev[6] = {"", "", "", "", "", ""};
// Max Allowed Difference-percentage for NOT Active
// If the difference for consecutive measurements is higher
// the detector is active.
// THE OPTIMAL VALUES ARE DEPENDENT ON THE ACTUAL SITUATION.
// So, try and test
const int LimitFactor[6] = {15, 30, 30, 30, 15, 10};
const int Led_React_Time = 3; // ms to turn Led On or Off
int IR_ValueWhenOn[6]; // Current Value When Led is On
int IR_ValueWhenOff[6]; // Current Value When Led is Off
int IR_ValueDifferenceFactor[6];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void setup() {
if (Debug == 1) {
Serial.begin(BaudRate);
};
if (Debug == 1) {
Serial.println("");
};
for (int i=0; i < DetectorCount; i++) {
if (Debug == 1) {
Serial.print(i);
Serial.print(": ");
Serial.print(IR_PinName[i]);
Serial.print(" = IR_Pin: ");
Serial.print(IR_Pin[i]);
Serial.print("; Out_Pin ");
Serial.print(Out_Pin[i]);
Serial.print("; Led_Pin ");
Serial.println(Led_Pin[i]);
};
digitalWrite(Led_Pin[i], LOW); // Led Off
delay(Led_React_Time);
digitalWrite(Out_Pin[i], HIGH); // not active
delay(Led_React_Time);
pinMode(Led_Pin[i], OUTPUT); // IR Led
pinMode(Out_Pin[i], OUTPUT); // To S88-Ground-module
if (i <= 4) {
pinMode(IR_Pin[i], INPUT_PULLUP); // Analog Pin
// Not all modules have external pull-up resistors
}
else {
pinMode(IR_Pin[i], INPUT); // Analog Pin
};
};
pinMode(LED_BUILTIN, OUTPUT); // show countdown to start loop
// This allows an interrupt to send updates
for (int i=0; i<4; i++) { //countdown four seconds
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(2, HIGH); // turn the external status LED on (HIGH is the voltage level)
delay(300); // wait for 3/10 second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
digitalWrite(2, LOW); // turn the external status LED off by making the voltage LOW
delay(700); // wait for 7/10 second
} // countdown
}; // setup
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void loop() {
// Shift previous measurement
for (int i=0; i<DetectorCount; i++) {
IR_Result[i][2] = IR_Result[i][1];
IR_Result[i][1] = IR_Result[i][0];
IR_Result[i][0] = "?"; // current measurement not yet known
}; // All Detectors
CurTime = millis();
// First perform all measurements on all detectors
for (int i=0; i<DetectorCount; i++) {
digitalWrite(Led_Pin[i], LOW); // IR Led Off
};
delay(Led_React_Time); // wait until IR-transistors are stable
for (int i=0; i<DetectorCount; i++) {
IR_ValueWhenOff[i] = analogRead(IR_Pin[i]);
};
for (int i=0; i<DetectorCount; i++) {
digitalWrite(Led_Pin[i], HIGH); // IR Led On
};
delay(Led_React_Time); // wait until IR-transistor are stable
for (int i=0; i<DetectorCount; i++) {
IR_ValueWhenOn[i] = analogRead(IR_Pin[i]);
};
for (int i=0; i<DetectorCount; i++) {
digitalWrite(Led_Pin[i], LOW); // IR Led Off
};
for (int i=0; i<DetectorCount; i++) {
// A relevant difference (> x %) means that reflection is detected
IR_ValueDifferenceFactor[i] = (100.0 * (IR_ValueWhenOff[i] - IR_ValueWhenOn[i]) / IR_ValueWhenOff[i]);
if (IR_ValueDifferenceFactor[i] < LimitFactor[i]) {
IR_Result[i][0] = "-"; // Negative
} // No reflection
else {
IR_Result[i][0] = "+"; // Positive
}; // Detection active
// Now interpret last three results of this detectors
StateText[i] = IR_Result[i][0] + " " + IR_Result[i][1] + " " + IR_Result[i][2];
if (StateText[i] == "- - -") {
Out_State[i] = 0;
if (Out_State[i] != Out_StatePrev[i]) {
StateText[i] = "On --> Off";
digitalWrite(Out_Pin[i], HIGH); // HIGH = Detection Not Active
};
}
else if (StateText[i] == "+ + +") {
Out_State[i] = 1;
if (Out_State[i] != Out_StatePrev[i]) {
StateText[i] = "Off --> On";
digitalWrite(Out_Pin[i], LOW); // LOW = Detection Active
};
};
if (StateText[i] != StateTextPrev[i]) {
// Status changed, so show it immediately
ShowTime = 0;
};
if (Debug == 1) {
if (CurTime > ShowTime) {
Serial.print((CurTime / 1000.0), 3);
Serial.print(" s ");
Serial.print(i);
Serial.print(": ");
Serial.print(IR_PinName[i]);
Serial.print(" Off: ");
Serial.print(IR_ValueWhenOff[i]);
Serial.print(", On: ");
Serial.print(IR_ValueWhenOn[i]);
Serial.print(", \t delta: ");
Serial.print(IR_ValueWhenOff[i] - IR_ValueWhenOn[i]);
Serial.print(" \t");
Serial.print(IR_ValueDifferenceFactor[i]);
Serial.print("/");
Serial.print(LimitFactor[i]);
Serial.print(" \t");
Serial.println(StateText[i]);
}; // if ShowTime
}; // if Debug
Out_StatePrev[i] = Out_State[i];
StateTextPrev[i] = StateText[i];
}; // For All Detectors
if (CurTime > ShowTime) {
Serial.println();
ShowTime = CurTime + ShowDelay;
};
// Show Heartbeat to see the system is working
CurTimeDec = (CurTime/1000.0 - int(CurTime/1000.0));
if (CurTimeDec < 0.7) {
digitalWrite(LED_BUILTIN, LOW); // turn the led OFF
}
else if (CurTimeDec < 0.8) {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
}
else if (CurTimeDec < 0.9) {
digitalWrite(LED_BUILTIN, LOW);
}
else {
digitalWrite(LED_BUILTIN, HIGH);
};
}; // Loop
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -