/* 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.
220808 Leitungen zu den SR04 mit Abschlusswiderständen garniert
220808 „Quelltext“ zugeworfen
220809 Umbau auf Unterprogramm, Arduino-Code zurückgedrängt, ~heha
220811 Vorsehung eines WS8212-Lichtbands
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 ╟─ Gemeinsamer Triggerausgang
─╢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 ╟─ WS8212-Lichtband
Trigger 5 ─╢A4/PC4 D1/PD1/TxD╟─ Arduino-Debuginterface
─╢A5/PC5 D0/PD0/RxD╟─ Arduino-Debuginterface
╚════════════════════════╝
*/
#include <avr/io.h>
#include <util/delay.h>
//#define DEBUG
#ifdef DEBUG
# include <stdio.h>
# include <avr/pgmspace.h>
#endif
typedef unsigned char byte;
constexpr float maximumRange = 0.4; // 40 cm
constexpr float minimumRange = 0.02; // 2 cm
constexpr unsigned RTICKS = 7;
constexpr unsigned RDIST(float dist) { // rechnet Distanz in Meter in Zählrunden um
return dist/343.2*F_CPU/RTICKS;
}
static void messen(byte mask) {
// Abstandsmessung wird mittels des 10us langen Triggersignals gestartet
byte tmask=mask;
PORTB|= 0x01;
PORTC|= tmask;
_delay_us(10);
PORTB&=~0x01;
PORTC&=~tmask;
// Nun wird am Echo-Eingang gewartet, bis das Signal aktiviert wurde
// und danach die Zeit gemessen, wie lang es aktiviert bleibt
byte emask=mask<<2;
unsigned rounds=0;
while (!(PIND&emask)) // warte bis high
if (!--rounds) return; // maximal 28 ms
rounds=0;
while (PIND&emask) // warte bis low
if (!--rounds) break; // Eine Runde dauert laut Disassembler 7 Takte, maximal 65536 Runden = 28 ms entsprechend 10 m
rounds=-rounds;
#ifdef DEBUG
printf_P(PSTR("Sensor %u: %u mm\n"),mask,unsigned(rounds*RTICKS*343200L/F_CPU));
#endif
byte omask=mask<<1;
if (RDIST(minimumRange)<=rounds && rounds<=RDIST(maximumRange)) {
PORTB&=~omask;
}else{
PORTB|= omask;
}
}
#ifdef DEBUG
static int uart_putc(char c, FILE*stream) {
while (!(UCSR0A&0x20)); // Warte bis Sendehalteregister frei
UDR0 = c;
return 0;
}
#endif
int main() {
asm("clr r1");
DDRB = 0x3F;
DDRC = 0x3F;
DDRD = 0x02; // TxD aktivieren
PORTD = 0xFF; // alles Eingänge mit Pullups
#ifdef DEBUG
UBRR0 = F_CPU/16/9600-1;
UCSR0B= 0x18; // RxD und TxD aktivieren
static FILE uart = {0,0,_FDEV_SETUP_RW,0,0,uart_putc,0,0};
stdout=&uart;
#endif
for(;;) {
for (byte mask=1; mask&0x1F; mask<<=1) messen(mask);
#ifdef DEBUG
printf_P(PSTR("--------\n"));
#endif
// _delay_ms(50); // Pause zwischen den einzelnen Messungen (wozu??)
}
}
Detected encoding: UTF-8 | 0
|