Hallo liebe Forumsgemeinde, ich bin ein ziemlicher Anfänger was AVR Programmierung anbelangt und stehe gerade vor einem Problem, bei dem ich eure Hilfe erhoffe. Ich verwende eine Atmega88-PU als Slave für einen Rasenroboter, dieser soll 6 verschiedene HC-SR04 Ultraschallsensoren nacheinander auswerten und danach außerdem die Drehzhal der beiden Antriebsmotoren erfassen und beide Infos an den Master (auch ein Atmega88-PU) via UART schicken, wenn dieser danach fragt. Kernproblem ist hier aber die Sensorauswertung. Der restliche Code muss erst noch geschrieben werden. jetzt wollte ich diesen so verwenden, das jeder Triggereingang einen PIN vom Atmega geschenkt bekommt, die Echo Leitungen aber über Dioden und Pull Down Widerstände zusammengefasst werden. ( Da es ja nur 3 wirkliche externe Interrupts gibt, Pin Change wollte ich Zwecks des "was ist nun für ein Zustand?" nicht verwenden ) Randbedingung ist außerdem, dass INT0 und INT1 nicht verfügbar sind, da an diesen die Drehzahl über Inkrementalgeber für die Motoren ermittelt werden sollen. Nun allgemein die Frage ob der Code so funktionieren könnte? Und eher zwei speziellere die das alles schon scheitern lassen könnten: 1) Was passiert, wenn der Timer 1 bereits schon läuft ( um die Messung für Sensor x nach ca 35ms zu unterbrechen und den nächsten Sensor x+1 zu triggern ), nun aber durch den Analogkomparator ein weiterer Start des Timer 1 ausgelöst wird? ( dieser soll die steigende Flanke und fallende Flanke des Echos erfassen ) Beginnt dieser einfach erneut bei 0 zu zählen oder zählt er gemütlich weiter? Oder geht das an sich nicht? 2) Kann man, so wie ich es momentan versuche, während der Ausführung der ISR für den Analogkomparator durch Triggerung und auftreten einer steigenden Flanke an AIN0 den Komparator während der ISR die Triggerung auf eine fallende Flanke umstellen, sodass damit eine Zeitenmessung möglich ist? Entschuldigung für die doofe Darstellung, ich weiß nur leider nicht wie ich den Code hier schöner einbinden könnte. Ich hoffe die Pfiffigen unter euch können und wollen mir Amateur helfen. :D Schon einmal vielen Dank an euch! Grüße Kevin
Hi, es war nicht leicht deinen Ausführungen zu folgen, aber ich versuche mal mein bestes. Deinen Code so anzusehen ist mir nicht wirklich gelungen. Warum hast du statt den ganzen png Dateien nicht einfach die Quellcode Datei angehängt? 1) Interrupts sind im laufenden Interrupt gesperrt es sei denn du gibst sie explizit frei. Tritt während eines laufenden Interrupts ein weiterer erfasst, wird dieser sofort bearbeitet, sobald der 1. abgearbeitet ist. 2) Hab ich nicht ganz verstanden, aber ich sag mal was. Du kannst doch wenn AIN0 auf eine steigende Flanke ausgelöst wurde einfach im Interrupt direkt umkonfigurieren, dass nun auf fallende Flanke regiert werden soll. Falls du den Flankenwechsel schneller erwartest, als ihn der der 16MHz getaktete AVR verarbeiten kann musst du den Controller wechseln. Halte ich aber für unwahrscheinlich.
Erstmal danke dir Dennis! Wie binde ich das denn als Quellcode ein? Ich probiere mal etwas:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
Ich hoffe das hat so funktioniert! Schneller erwarte ich den Flankenwechsel keinesfalls. Ich möchte ja die Sensoren auf 8cm Entfernung Triggern, selbst mit Prescaler von 256 käme ich da auf eine so kurze Entfernung, die der HC SR04 schon gar nicht mehr erfassen kann. Zu 1) Also söllte es wohl so funktionieren oder? Zu 2)Sorry für die blöde Umschreibung. Also folgendes Szenario: Echo kommt an, da der Komparator auf steigende Flanke gestellt ist und der Timer 1 bereits läuft ( wird direkt nach der Triggerung des jeweiligen Sensors gestartet, um nach spätestens 35ms die Messung abzubrechen ( da kein Objekt in der Nähe ) und zum nächsten Sensor überzugehen) würde dieser den Timer 1 erneut starten, da ja das ACIC Bit gesetzt ist. Jetzt die Frage: startet der Timer einfach erneut von 0 an zu zählen oder macht dieser einfach ganz normal weiter oooder will der µC am Liebsten gar nichts von beiden tun und verweigert seine Arbeit? Nun weiter: Da jetzt eine Flanke kam wird die ISR für den Analog Komparator gestartet. Dieser schaut mit if(ACIS0==1), ob dieser noch auf die steigende Flanke eingestellt ist und wenn ja, soll dieser während der ISR auf die fallende Flanke umgestellt werden und den Timer mit TCNT1=0 von 0 an neu zählen lassen. Jetzt geht das ECHO auf LOW wodurch die ISR des Analog Komparators erneut ausgeführt wird, diesmal springt er aber in den else Zweig und übergibt den aktuellen Wert des Timers und setzt zusätzlich Hindernis=1, da sich etwas vor dem Sensor befindet. Danach wird alles dem Hauptprogramm übergeben, welches die Entfernung ausrechnet und bei einer Entfernung <= 8cm diese Information + die Richtung des Objektes, also Vorn oder Hinten, via UART an den Master schickt, welcher nun einen Bremsvorgang einleitet. Ich hoffe diese Beschreibung war etwas ausführlicher und hilft dir das ganze besser zu verstehen. Die Farge besteht nur noch, ob das ganze so funktioniert, wie ich es mir denke bzw geschrieben habe. Für weitere Hilfe würde ich mich weiter bedanken! :) Grüße Kevin
Zu 1)
Ja das mit den Interrupts kann so funktionieren.
Zu 2)
Eine weitere Frage. Wenn du den Analog Comparator nutzt musst du ja
beide Pins beschalten (AIN0 und AIN1). Ich denke es wäre einfacher über
PCINT irgendeinen PIN zu nehmen und über EICRA (DB Seite 73) auf
Interrupt bei "any logical change" zu konfigurieren.
ACIC zählt ja nur hoch wenn auch Ereignisse am Analog Comparator
auftreten. Wenn also die Flanke auf High wechelt zählt er einmal und das
nächste mal wenn du ihn umkonfiguriert hast und er die fallende Flanke
zählt. dein Ergebnis ist immer 2. Egal wie lange das dauert.
Ich würde es so machen:
Messung starten an SR04 - 1
Timer starten
mit einem PCINT erfassen (kann auf steigend, fallend und any gesetzt
werden)
Wert aus Timer holen
Wert speichern
Timer stoppen
Messung starten an SR04 - 2
...
...
...
Ich benutze den PCINT eigentlich sehr gerne:
ISR(PCINT0_vect)
// PC0 -> PCINT8
{
char x=0,y=0;
temp_old = temp;
test();
x = temp;
x &= 4;
y = temp_old;
y &= 4;
if (!(x == y)) {
if (x)
{
start0 = TCNT1;
}
if (!x)
{
stop0 = TCNT1;
steer = stop0 - start0;
}
}
}
char test (void) {
int_mask = PCMSK0;
temp = PINB;
temp &= int_mask;
return temp;
}
Ein kleiner Code Ausschnitt um am PCINT festzustellen welcher Pin
betätigt wurde macht die Funktion test().
Im Interrupt werte erfasse ich den Zählerstand des Timers und
subtrahiere den Startwert vom Endwert (fallende - steigende Flanke).
Ich finde das recht simpel.
Kannst du dir ja mal überlegen.
Hallo Bastelgemeinde, Jetzt versuche ich gerade mehrere ( 6 Stück ) parallel laufen zu lassen. Die Auswertung eines Sensors über UART mit dem Atmega88p läuft 1A ( ohne Interrupts, nur über Pinzustände ). Nun frage ich mich aber, ob es einen "Pinsparenden" Weg gibt die Sensoren zusammen zu schalten? Getriggert werden muss einzeln ( oder vielleicht mit Schieberegister möglich ), jetzt habe ich aber versucht die ECHO Ausgänge zusammen zu schalten. Direkt zusammen kommt nur 0 cm raus, mit Dioden kommen wiederum nur schwankende und sehr hohe Werte heraus ( ca. doppelt so viel ). Anzumerken sei hierbei, dass beim anstecken des zweiten Sensors bei beiden Varianten immer noch nur Sensor 1 getriggert und ausgewertet wurde. Also nur das physische Anschließen des zweiten Sensors hat die Werte schon so sehr verändert. Kennt jemand einen einfachen Weg, wodurch ich die ECHO Ausgänge zusammenschalten kann? LG, Kevin
Hi Zur Not per Spannungsfolger, Inverter, OR-Gatter, Opto-Koppler, ... to be continue ... und per Dioden entkoppelt. MfG
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.



