Hallo Hans,
per Ultraschall ist das Laufzeitverfahren das einzig Mögliche. Das hast Du schon richtig gewählt.
@Alle Anderen
Doppler ist quatsch, denn es wird ja kein Schall vom Partikel zum einleitenden Transceiver zurück reflektiert. Doppler geht nur, wenn Sender und Empfänger am selben Ort lokalisiert ist und das zu messende Partikel sich (idealen Fall) im Längsabstand dazu bewegt. Im Laufzeitdifferenzverfahren, mit in Strömungsrichtung versetzten Transceivern, tritt der Dopplereffekt natürlich auch ein. Dummerweise aber spiegelbildlich. Denn die Frequenzverschiebung bei Schalleinleitung des Senders hebt sich spiegelbildlich bei der Ausleitung in den Empfänger wieder auf.
Und jetzt konstruktiv weiter...
Die Frequenzerzeugung sollte mit einem Arduino gut gehen. Der normale UNO, oder Nano mit 16MHz Takt hat 3 Timer, wobei Timer0 für einfaches Timing mittels millis() usw. verwendet wird. Timer1 (16Bit) und 2 (8Bit) stehen zur freien Verfügung. Und ein MHz steht im geradzahligen Verhältnis zu 16MHz. Ich würde Timer1 im CTC Verfahren verwenden, weil Timer1 zusätzlich über ein Input Capture Register verfügt. Grundsätzlich, während ein Timer hochzählt, zählt er von BOTTOM (=0) entweder bis zu MAX (0xFF bei 8Bit und 0xFFFF bei 16Bit), läuft über und beginnt von vorne. Es sei denn, es gibt einen Vergleich mit einem Registerwert kleiner als TOP. Dieser Wert nennt sich dann MAX. Bei Timer1 eignen sich dazu 3 Register: OCR1A, OCR1B und ICR1. Wobei OCR1A und OCR1B jeweils den Ausgangspins OC1A = D9 und OC1B = D10 zugeordnet sind. In den Registern TCCR1A und TCCR1B (Datsheet) befinden sich mehrer WGM- und COM-Bits .
- Interrupts ausschalten: cli();
- Register zurücksetzen: TCCR1A = 0;m TCCR1B = 0; TIMSK1 = 0;
- Prescaler mittels CS10 Bit auf 1 setzen, damit im 16MHz (62,5ns) Takt gezählt wird. 8 x 62,5ns = 500ns = 1 eine Halbwelle von 1MHz.
TCCR1B |= (1<<CS10); - Mit den WGMs bestimmst Du den Timermode (Hier 4 oder 12) und welches Register für TOP herangezogen wird (Hier OCR1A, oder ICR1).
TCCR1B |= (1 << WGM12); // Mode 4 = CTC => OCR1A sets TOP - Verhalten des Ausgangspins auf toggle setzen
TCCR1A |= (1 << COM1A0); //Toggle OC1A - Counter Zählregister auf 0 setzen.
TCNT1 = 0; - OCR1A auf TOP setzen
OCR1A = 7; //0-7 = 8 Takte => 1MHz - Interrupts scharf schalten
sei()
Anschließend kommt aus Pin D9 des Arduino 1MHz, egal was in Deinem Hauptprogramm läuft. Gehe mal auf die Webseiten von Nick Gammon. Da gibts viele gute Beispiele.
Hab den Code getestet.
---
Eine Frage, was kostet der Ultraschalltransceiver? Und welche Bezugsquelle und Lieferzeit?
Und vlt noch, hast Du ein Datenblatt mit der Sendeschalleistung und welche Spannung (VSS) er sehen will?
Es gibt diese Bridge-Motor-Driver ICs ULN...irgendwas. Die können größere Spannungen bis über 100kHz treiben. Ob 1MHz geht, weiß ich nicht.
Viel Grüße und Erfolg bei der Umsetzung, Rainer
Code:
//############ Code Begin ##############
//Timer1. Variable Square-Wave-Generator
//Objective: Use CTC Mode. OCR1A sets TOP
uint16_t TOP = 7;
void setup() {
Serial.begin(115200);
pinMode(9, OUTPUT);//Signal output
//pinMode(10, OUTPUT);
cli();
TCCR1A = 0; //Reset the register
TCCR1A |= (1 << COM1A0); //Toggle OC1A
TCCR1B = 0; //Reset the register
TCCR1B |= (1 << CS10); // Prescaler = 1
TCCR1B |= (1 << WGM12); // Mode 4 = CTC => OCR1A sets TOP
TCNT1 = 0;
OCR1A = TOP;//Set output Compare Register. OCR1A defines TOP;
sei();
Serial.println("1MHz Beep running...");
}
void loop() {
}
//############ Code End ##############
Lesezeichen