/* Konverter: Fragt 5 Ultraschall-Abstandssensoren „HC-SR04“ zyklisch ab
und liefert an 5 TTL-Ausgängen, wenn sich Objekte im Sensorbereich befinden.
In der ursprünglichen Version wurde ein gemeinsamer Triggerausgang benutzt.
Das führt zu gegenseitigem Übersprechen durch fehlenden Raummultiplex.
Nunmehr werden 3×5 = 15 I/Os für die Aufgabe verwendet.
Dass die Ausgänge eine Relaiskarte steuern ist der nächste Murks.
Zudem sind die Ausgänge invertiert: Sie melden „frei“ wenn High.
TODO: Schaltausgänge versetzen und Onboard-LED freihalten;
Relaiskarte durch (nur noch) Optokoppler ersetzen
220808 Leitungen zu den SR04 mit Abschlusswiderständen garniert
220808 „Quelltext“ von ~noman zugeworfen
220809 ~heha: Umbau auf Unterprogramm, Arduino-Code zurückgedrängt
220811 Vorsehung eines WS2812-Lichtbands
220816 Zugeworfener Quelltext entsprach /nicht/ dem Flash-Image auf dem Board!
220916 Kosmetische Änderungen, Zugrabetragen des gemeinsamen Triggers
Hardware:
╔════════════════════════╗
║ ║
║ SCL/PC5 ╟─
║ SDA/PC4 ╟─
║ AREF╟─
║ 00╟─
─╢- D13/PB5 ╟─ Schaltausgang 5 = Onboard-LED
─╢5P D12/PB4 ╟─ Schaltausgang 4
─╢RES ~D11/PB3 ╟─ Schaltausgang 3
─╢3P3 ~D10/PB2 ╟─ Schaltausgang 2
zu den SR04 ─╢5P ~D9/PB1 ╟─ Schaltausgang 1
zu den SR04 ─╢00 D8/PB0 ╟─ (Schraubklemme)
─╢00 ║
─╢Uin D7/PD7 ╟─ Echo 5
║ ~D6/PD6 ╟─ Echo 4
Trigger 1 ─╢A0/PC0 ~D5/PD5 ╟─ Echo 3
Trigger 2 ─╢A1/PC1 D4/PD4 ╟─ Echo 2
Trigger 3 ─╢A2/PC2 ~D3/PD3 ╟─ Echo 1
Trigger 4 ─╢A3/PC3 D2/PD2 ╟─ WS2812-Lichtband
Trigger 5 ─╢A4/PC4 D1/PD1/TxD╟─ Arduino-Debuginterface
─╢A5/PC5 D0/PD0/RxD╟─ Arduino-Debuginterface
╚════════════════════════╝
*/
#include <Adafruit_NeoPixel.h>
// Konstanten (Arduinos gcc kann kein constexpr)
enum{
maxTime = 40 /*cm*/ * 58 /*µs/cm*/,
minTime = 2 /*cm*/ * 58 /*µs/cm*/,
ledPin = 2, // am Arduino-Pin 2 = PD2
ledCount = 30, // max. 30 LEDs
ledColor = 0xFF2808, // RGB-Wert
// Farbe für jeden der 3 Schaltschränke anders!
// Siemens: Türkis: 0x00FFFF
// Beckhoff: Rot: 0xFF0000
// B&R: Orange: 0xFF3000
};
static Adafruit_NeoPixel pixels(ledCount,ledPin,NEO_GRB|NEO_KHZ800);
void setup() {
DDRB = 0x3E; // 5 Ausgänge
DDRC = 0x3F;
DDRD = 0x02; // TxD aktivieren (macht Serial.begin hoffentlich auch)
PORTB = 0x01; // Freie Schraubklemme als Eingang mit Pullup
PORTD = 0xFF; // Pullups aktivieren
Serial.begin(115200); // für Debugausgabe
pixels.begin();
pixels.fill(ledColor); // NeoPixel konvertiert selber in WS2812-GRB-Reihenfolge
pixels.show(); // ausgeben; die WS2812 behalten sich diesen Wert
}
static void mess(byte idx) {
// Abstandsmessung wird mittels des 10 µs langen Triggersignals gestartet.
// Nun wird am Echo-Eingang gewartet, bis das Signal High wurde
// und danach die Zeit gemessen, wie lange es High bleibt
byte mask=1<<idx;
PORTC|= mask; // Einzelner Trigger
delayMicroseconds(10);
PORTC&=~mask;
unsigned Dauer = pulseIn(3+idx,HIGH,60000); // max. 60 ms messen (warten)
Serial.print(Dauer); // µs ausgeben
mask<<=1;
// Überprüfung ob gemessener Wert innerhalb der gewünschten Entfernung liegt
if (minTime<=Dauer && Dauer<=maxTime) {
PORTB&=~mask; // Low ausgeben
Serial.print('.'); // besetzt
}else{
PORTB|= mask; // High ausgeben
Serial.print('?'); // frei: Kein Echo
}
}
static byte zeile;
void loop() {
if (!zeile) { // Alle 10 Zeilen eine Kopfzeile ausspucken
for (byte idx=0; idx<5; idx++) {
Serial.print(F("Sens "));
Serial.print(1+idx);
Serial.print(idx==4?'\n':'\t');
}
zeile=10;
}
for (byte idx=0; idx<5; idx++) {
mess(idx);
Serial.print(idx==4?'\n':'\t');
}
--zeile;
}
Vorgefundene Kodierung: UTF-8 | 0
|