Hallo !
Mein Ziel : ich möchte den Abstand zwischen einem Ultraschallsender und
einem Ultraschallempfänger ausmessen.Die beiden stehen sich direkt
gegenüber.
Es handelt sich dabei um "einfache" Piezokristalle, UST-40(T/R).( beim
Reichelt erhältlich).
Dieses "Problem" möchte ich mit einem Atmega8 lösen.
Den Ultraschallsender steuere ich mit einem NE555 an. Den Reset-Pin des
NE555 steuere ich mit dem Pin PB3 an.
Der Pin für das Input caputure ist PB0.
Ich schalte den Ultraschallsender für 600µs an, und mache ihn wieder
aus.
Beim einschalten setze ich den Timer auf 0. ( /und genau hier klappt es
bei mir nicht, die Geschichte mit der Zeitmessung. Glaube ich zumidest/
)
Die Schaltung für den Ultraschallempfänger habe ich so aufgebaut, dass
ich beim empfangen von Ultraschall eine steigende Flanke erhalte.
Diese steigende Flanke detektiere ich am ICP, und lese den Wert des
Timers zu diesem Zeitpukt aus.
dann berechne ich die zeit, die der Schall gebraucht hat:
dabei ist f die Frequenz, mit der sich das Register TCNT1 erhöht:
wobei A für die Anzahl der Erhöhungen pro sekunde ist.
und die Anzahl der erhöhungen pro Sekunde ist :
wenn ich die zeit in [ms] haben will, dann muss ich die "Anzahl der
Erhöhungen pro sekunde durch 1000 teilen.
( /oder es scheitert bei mir an der Mathematik, was aber nicht der fall
sein sollte/ )
Und jetzt der Quellcode:
1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include "defines.h"
|
4 | #include "onewireLCD.h"
|
5 | #include <avr/interrupt.h>
|
6 | #define F_CPU 8000000
|
7 |
|
8 | #define ticks 125
|
9 | // "ticks" ist die Anzahl der erhöhungen des Registers
|
10 | // TCNT1 in der sekunde( ticks = FCPU / Prescaler)
|
11 | // da ich aber in [ms] und [cm] rechne,
|
12 | // muss ich ticks durch 1000 teilen, und komme,
|
13 | // bei einem prescaler von 64 auf dem wert von 125
|
14 |
|
15 | volatile double ic;
|
16 | volatile double strecke;
|
17 | volatile double time;
|
18 |
|
19 | inline void stop()
|
20 | {
|
21 | PORTB &= ~(1<<PB3);
|
22 | }
|
23 |
|
24 | inline void start()
|
25 | {
|
26 | PORTB = 1<<PB3;
|
27 | TCNT1 = 0; // setze den Timer auf 0
|
28 | }
|
29 |
|
30 | inline void ICP_init()
|
31 | {
|
32 | TCCR1B |= (1<<ICNC1)|(1<<ICES1)|(0<<CS12)|(1<<CS11)|(1<<CS10);
|
33 | // Prescaler = 64,
|
34 | //Input capture enable, noise canceler enable
|
35 | TIMSK |= (1<<TICIE1); // Input capture Interrupt
|
36 | DDRB &= ~(1<<PB0); // PB0 ( ICP1) als eingang
|
37 | }
|
38 |
|
39 | ISR(TIMER1_CAPT_vect)
|
40 | {
|
41 | ic = ICR1; // Wert des ICR auslesen
|
42 | time = (ic/ticks);
|
43 | // Zeit im ms berechnen,
|
44 | // (t[s] = ICR * 1/Ticks )
|
45 | // (t[ms] = ICR * 1/(Ticks/1000))
|
46 | strecke = 34.4 * time;
|
47 | // strecke in cm berechnen ( s[cm] = v[cm/ms] * t[ms])
|
48 | }
|
49 |
|
50 |
|
51 | int main()
|
52 | {
|
53 | uint16_t i;
|
54 |
|
55 | onewire_init();
|
56 | clear_lcd();
|
57 | DDRB = (1<<PB3); // Ansteuerung des NE555 Reset_pin.
|
58 | ICP_init();
|
59 | stop();
|
60 |
|
61 | sei();
|
62 |
|
63 | while(1)
|
64 | {
|
65 | start();
|
66 | _delay_us(600);
|
67 | stop();
|
68 | string_lcd("ICR: ");
|
69 | digits_lcd(ic);
|
70 | // zeigt den wert der variable "ic" am display
|
71 | cursor_set(0,2);
|
72 | string_lcd("Zeit: ");
|
73 | double_lcd(time);
|
74 | // zeigt den wert der variable "time" am display
|
75 | cursor_set(0,3);
|
76 | string_lcd("Strecke: ");
|
77 | digits_lcd(strecke);
|
78 | // zeigt den wert der variable "strecke" am display
|
79 | _delay_ms(300);
|
80 | clear_lcd();
|
81 | }
|
82 | return(0);
|
83 | }
|
( /mit höchster wahrscheinlichkeit verbirgt sich im quellcode ein
kleiner fieser fehler/ )
Und jetz noch ein paar Zahlen, die weiterhelfen könnten:
wenn ich den Ultraschallsender 7cm weit vom empfänger platziere,
dann habe ich für ICP den Wert von 216
für die Zeit zeigt er mir dem wert von 1,8ms
und für die strecke 41cm ( /oder sind es überhaupt nicht cm ??/)
und wenn ich die Sensoren bewege, dann verändern sich die Werte
willkürlich.
Ich denke es leigt daran, dass ich die Zeit falsch messe, und dadurch
falsche werte rausbekomme >.<
Danke im Voraus !
Jakov