Source file: /~heha/mb-iwp/Bergwerk/Bergwerk.zip/us2.cpp

/* 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-80