Hallo, mein ATmega16 führt das draugeflashte Programm zunächst richtig aus. Dann stoppt er. Macht Quatsch. Danach geht es dann wieder Ordnungsgemäß. Dann stoppt er. Macht Quatsch. Danach geht es dann wieder Ordnungsgemäß. Dann stoppt er. Macht Quatsch. [...] Bis er schließlich ganz aufgibt. Es sind auch keine festen Zeitabstände dazwischen. Ordnungsgemäß heisst: PORTC verschieden setzen. (Ausgang) Entw-Board: easyAV6. Die ADC´s sind in Betrieb, ein LCD an PORT B und eine PWM an PD5. Ich hab den uC auch schon ausgetauscht. Da der Code länger ist wollte ich Ihn hier nicht direkt posten.
Marius S. schrieb: > Macht Quatsch. Was genau? > Da der Code länger ist wollte ich Ihn hier nicht direkt posten. Meine Glaskugel wird gerade repariert.
Marius S. schrieb: > Da der Code länger ist wollte ich Ihn hier nicht direkt posten. dann können wir aber auch nicht helfen. Vermutlich steckt der fehler im code. (speicherüberschreiber oder stackoverflow)
1 | |
2 | #define TASTERPORT PIND
|
3 | #define TASTERBIT1 PD2
|
4 | #define TASTERBIT2 PD3
|
5 | |
6 | #include <avr/io.h> |
7 | #include <stdlib.h> |
8 | #include <util/delay.h> |
9 | #include "lcd-routines.h" |
10 | #include "lcd_functions.c" |
11 | #include <avr/interrupt.h> |
12 | #include "entprellung.h" |
13 | |
14 | |
15 | volatile int gew_Diode = 4; |
16 | volatile int adcval_max = 0; |
17 | volatile int adcval_alt = 0; |
18 | volatile int adcval; //für das ADC-Ergebnis |
19 | volatile int adcval_neu; |
20 | volatile int an= 0x11; //linkslauf |
21 | volatile int andersrum = 0x22; //rechtslauf |
22 | |
23 | volatile int zaehler=0; //für ADC-ISR |
24 | |
25 | volatile int differenz; |
26 | volatile int differenz_alt = 0; |
27 | volatile int differenz_alt2 = 0; |
28 | |
29 | volatile double zeit; |
30 | volatile double altezeit; |
31 | |
32 | char Buffer2[20]; //für das ADC-Ergebnis |
33 | char Buffer3[20]; //für die gewählte Diode |
34 | |
35 | //-----------------------------------------
|
36 | // ADC-Funktionen
|
37 | //-----------------------------------------
|
38 | |
39 | /* ADC initialisieren */
|
40 | void ADC_Init(void) |
41 | {
|
42 | |
43 | uint16_t result; |
44 | |
45 | ADMUX = (0<<REFS1) | (0<<REFS0); // PIN AREF als Referenz nutzen |
46 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler : 8 |
47 | ADCSRA |= (1<<ADEN); // ADC aktivieren |
48 | ADCSRA |= (1<<ADIE); // ADC-Interrupt aktivieren |
49 | |
50 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
51 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
52 | |
53 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
54 | while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten |
55 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der naechsten
|
56 | Wandlung nicht uebernommen. */
|
57 | result = ADCW; |
58 | }
|
59 | |
60 | /* ADC Einzelmessung */
|
61 | uint16_t ADC_Read( uint8_t channel ) |
62 | {
|
63 | // Kanal waehlen, ohne andere Bits zu beeinflu?en
|
64 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); |
65 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" |
66 | while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten |
67 | ;
|
68 | return ADCW; // ADC auslesen und zurueckgeben |
69 | }
|
70 | |
71 | /* ADC Mehrfachmessung mit Mittelwertbbildung */
|
72 | uint16_t ADC_Read_Avg( uint8_t channel, uint8_t average ) |
73 | {
|
74 | uint32_t result = 0; |
75 | |
76 | for (uint8_t i = 0; i < average; ++i ) |
77 | {
|
78 | result += ADC_Read( channel ); |
79 | _delay_ms(20); |
80 | }
|
81 | return (uint16_t)( result / average ); |
82 | }
|
83 | |
84 | //-----------------------------------------
|
85 | // Motor-Drehrichtung
|
86 | //-----------------------------------------
|
87 | |
88 | void change_direction() |
89 | {
|
90 | if( (an & 0x11) == 0x11) |
91 | {
|
92 | an = 0x02; |
93 | andersrum = 0x11; |
94 | }
|
95 | else if ( (an & 0x22) == 0x02) |
96 | {
|
97 | an = 0x01; |
98 | andersrum = 0x22; |
99 | }
|
100 | }
|
101 | |
102 | //-----------------------------------------
|
103 | //Interrupt Service Routinen
|
104 | //-----------------------------------------
|
105 | |
106 | |
107 | ISR(INT0_vect) //PD2 gedrückt |
108 | {
|
109 | |
110 | int pgd = tasterhoch(); |
111 | |
112 | if( (pgd == 1 ) ^ (gew_Diode < 8) ) |
113 | {
|
114 | |
115 | if( gew_Diode == 2) |
116 | {
|
117 | gew_Diode +=2; |
118 | |
119 | }
|
120 | |
121 | else if ( gew_Diode == 5) |
122 | {
|
123 | gew_Diode +=2; |
124 | }
|
125 | |
126 | else
|
127 | {
|
128 | gew_Diode +=1; |
129 | }
|
130 | |
131 | }
|
132 | |
133 | else
|
134 | {
|
135 | |
136 | }
|
137 | |
138 | an = 0x22; //rechtslauf |
139 | andersrum = 0x11; //linkslauf |
140 | |
141 | adcval_max = 0; |
142 | zaehler = 0; |
143 | |
144 | //Erste Zeile löschen
|
145 | lcd_setcursor( 0, 1 ); |
146 | lcd_string(" "); |
147 | lcd_setcursor( 0, 1 ); |
148 | |
149 | //Ausgabe der gewählten Diode auf dem LCD
|
150 | itoa( gew_Diode, Buffer3, 10 ); |
151 | lcd_string("Diode "); |
152 | lcd_string(Buffer3); |
153 | |
154 | }
|
155 | |
156 | ISR(INT1_vect) //PD3 gedrückt |
157 | {
|
158 | int mgd = tastertief(); |
159 | |
160 | if ( (mgd == 1) ^ (gew_Diode > 1) ) |
161 | {
|
162 | |
163 | if( gew_Diode == 2) |
164 | {
|
165 | gew_Diode = gew_Diode; |
166 | }
|
167 | |
168 | else if ( gew_Diode == 4) |
169 | {
|
170 | gew_Diode -=2; |
171 | }
|
172 | |
173 | else if ( gew_Diode == 7) |
174 | {
|
175 | gew_Diode -=2; |
176 | }
|
177 | |
178 | else
|
179 | {
|
180 | gew_Diode -=1; |
181 | }
|
182 | |
183 | }
|
184 | |
185 | else
|
186 | {
|
187 | |
188 | }
|
189 | |
190 | an = 0x11; //linkslauf |
191 | andersrum = 0x22; //rechtslauf |
192 | |
193 | adcval_max = 0; |
194 | zaehler = 0; |
195 | |
196 | //Erste Zeile löschen
|
197 | lcd_setcursor( 0, 1 ); |
198 | lcd_string(" "); |
199 | lcd_setcursor( 0, 1 ); |
200 | |
201 | //Ausgabe der gewählten Diode auf dem LCD
|
202 | itoa( gew_Diode, Buffer3, 10 ); |
203 | lcd_string("Diode "); |
204 | lcd_string(Buffer3); |
205 | |
206 | }
|
207 | |
208 | |
209 | ISR(ADC_vect) //Interrupt nach Abschluss einer ADC Wandlung |
210 | {
|
211 | |
212 | if(adcval > 0) |
213 | {
|
214 | adcval_neu = ADC_Read_Avg( (gew_Diode - 1),100); //neuer ADC_Wert zum "Arbeiten" |
215 | |
216 | if(adcval_neu > adcval_max) |
217 | {
|
218 | adcval_max = adcval_neu; |
219 | }
|
220 | |
221 | if(adcval_neu < adcval_alt) |
222 | |
223 | {
|
224 | change_direction(); |
225 | }
|
226 | |
227 | /*
|
228 | |
229 | differenz = 300 - adcval_neu; //300 = Sollwert
|
230 | // q0 q1 q2
|
231 | zeit = 0.1*differenz + 0.2*differenz_alt + 0.3*differenz_alt2; //Reglergleichung
|
232 | |
233 | differenz_alt2 = differenz_alt;
|
234 | differenz_alt = differenz;
|
235 | altezeit = zeit;
|
236 | |
237 | int zeitganz = (int) zeit;
|
238 | |
239 | lcd_setcursor( 10, 1 );
|
240 | lcd_int(zeitganz);
|
241 | |
242 | if(zeit>80)
|
243 | {
|
244 | zeit = 80;
|
245 | }
|
246 | |
247 | PORTC = an;
|
248 | _delay_ms(zeitganz);
|
249 | PORTC = andersrum;
|
250 | _delay_ms(zeitganz/2);
|
251 | |
252 | */
|
253 | |
254 | zaehler += 1; |
255 | |
256 | if(zaehler == 1) |
257 | {
|
258 | PORTC = an; |
259 | _delay_ms(180); |
260 | PORTC = andersrum; |
261 | _delay_ms(50); |
262 | |
263 | PORTC = 0x00; //STOPP - Laserpointerstrahl ist prinzipiell auf der Diode |
264 | }
|
265 | |
266 | else if(( (zaehler >=31) & ((adcval_max - adcval_neu) < 50) )) |
267 | {
|
268 | PORTC = 0x00; |
269 | }
|
270 | |
271 | else // 1 < zaehler < 31 |
272 | {
|
273 | |
274 | PORTC = an; |
275 | _delay_ms(80); |
276 | PORTC = andersrum; |
277 | _delay_ms(50); |
278 | PORTC = 0x00; |
279 | |
280 | |
281 | |
282 | }
|
283 | }
|
284 | |
285 | else
|
286 | {
|
287 | PORTC = an; |
288 | _delay_ms(100); |
289 | |
290 | PORTC = andersrum; |
291 | _delay_ms(50); |
292 | |
293 | PORTC = 0x00; |
294 | |
295 | zaehler = 0; |
296 | }
|
297 | |
298 | adcval_alt = adcval_neu; |
299 | |
300 | }
|
301 | |
302 | //-----------------------------------------
|
303 | // Start Hauptprogramm
|
304 | //-----------------------------------------
|
305 | |
306 | int main(void) |
307 | {
|
308 | |
309 | //-----------------------------------------
|
310 | // Datenrichtung (Ein-/Ausgänge) setzen
|
311 | //-----------------------------------------
|
312 | |
313 | DDRC |= (1 << PD0 | 1 << PD1 | 1 << PD4 | 1 << PD5); |
314 | |
315 | DDRD |= (1 << PD4 | 1 << PD5); |
316 | |
317 | //-----------------------------------------
|
318 | // PWM-Einstellungen
|
319 | //-----------------------------------------
|
320 | |
321 | // COM: verhalten bei match WGM: Phase Correct Mode
|
322 | TCCR1A |= ( 1 <<COM1A1 | 0 << COM1A0| 1 << COM1B1| 0 << COM1B0| 1 << WGM11 | 0 << WGM10 ); |
323 | // WGM: Phase Correct Mode CS Prescaler
|
324 | TCCR1B |= ( 1 << WGM13 | 0 << WGM12 | 0 << CS12 | 0 << CS11 | 1 << CS10); |
325 | |
326 | |
327 | ICR1 = 8000; // Frequenz 500 Hz mit prescaler 1 |
328 | |
329 | OCR1A = 2000; |
330 | |
331 | //-----------------------------------------
|
332 | // ADC einstellen / aktivieren
|
333 | //-----------------------------------------
|
334 | |
335 | ADC_Init(); |
336 | |
337 | //-----------------------------------------
|
338 | // Interrupt-Register
|
339 | //-----------------------------------------
|
340 | |
341 | MCUCR = 0x0F; //auf steigende Flanken reagieren (Taster mit externem Pull-Down) |
342 | |
343 | GICR = 0xC0; //Interrupts INT0 + INT1 aktivieren |
344 | |
345 | //-----------------------------------------
|
346 | // für die Ausgabe auf dem LCD
|
347 | //-----------------------------------------
|
348 | |
349 | lcd_init(); // Initialisierung des LCD |
350 | |
351 | lcd_string(" Neustart"); |
352 | lcd_setcursor( 0, 2 ); // Die Ausgabemarke in die 2te Zeile setzen |
353 | lcd_string(" Neustart"); |
354 | |
355 | _delay_ms(1000); |
356 | |
357 | //Erste Zeile löschen
|
358 | lcd_setcursor( 0, 1 ); |
359 | lcd_string(" "); |
360 | lcd_setcursor( 0, 1 ); |
361 | |
362 | //Ausgabe der gewählten Diode auf dem LCD
|
363 | itoa( gew_Diode, Buffer3, 10 ); |
364 | lcd_string("Diode "); |
365 | lcd_string(Buffer3); |
366 | |
367 | sei(); //Interrupts anschalten |
368 | |
369 | //-----------------------------------------
|
370 | // Start Endlosschleife
|
371 | //-----------------------------------------
|
372 | |
373 | while(1) |
374 | {
|
375 | if( ((PORTC == 0x00) & (zaehler >=31)) ) |
376 | {
|
377 | //2. Zeile löschen
|
378 | lcd_setcursor( 0, 2 ); |
379 | lcd_string(" "); |
380 | lcd_setcursor( 0, 2 ); |
381 | |
382 | lcd_string("Ausgerichtet :-)"); |
383 | }
|
384 | |
385 | else
|
386 | {
|
387 | // Kanal x (gew_Diode - 1) wandeln
|
388 | adcval = ADC_Read(gew_Diode - 1); |
389 | |
390 | lcd_setcursor( 10, 1 ); |
391 | lcd_int(zaehler); |
392 | |
393 | //Umwandlung "Zahl" in einen "String"
|
394 | itoa( adcval_neu, Buffer2, 10 ); |
395 | |
396 | //2. Zeile löschen
|
397 | lcd_setcursor( 0, 2 ); |
398 | lcd_string(" "); |
399 | lcd_setcursor( 0, 2 ); |
400 | |
401 | //Vorbereitung Ausgabe des Wandlungsergebnisses der gew. Diode
|
402 | lcd_string("ADC_Diode"); |
403 | lcd_string( Buffer3 ); |
404 | lcd_string(": "); |
405 | |
406 | //Ausgabe Wandlungsergebnis
|
407 | lcd_string( Buffer2 ); |
408 | }
|
409 | |
410 | _delay_ms(500); |
411 | |
412 | }
|
413 | |
414 | return (0); |
415 | }
|
du machst zuviel im der ISR. das LCD sollte an dieser stelle nicht beschrieben werden weil das viel zu lange dauert. Das sollte aber nicht zu solchen Problemen führen. Warum hast du immer int verwendet? Das ganze ist damit langsam und eventuell fehlerhaft weil alles operrationen mit der Variable mit atomic sind.
Peter II schrieb: > Das sollte aber nicht zu solchen Problemen führen. Doch, weil das LCD sowohl aus der ISR als auch aus main angesprochen wird.
Ordnungsgemäß: PC0 setzen 0,1s halten PC0 rücksetzen PC1 setzen 0,05s halten PORTC ganz aus. 0,5sek Pause PC0 setzen 0,1s halten PC0 rücksetzen PC1 setzen 0,05s halten PORTC ganz aus. 0,5sek Pause [...] Quatsch: PORTC ganz aus. PC0 setzen. (halten < 0,1s) PC0 rücksetzen PC1 setzen halten < 0,1s PORTC ganz aus. kurze Pause (länger als 0,5s) dies 3-4 mal nahcdem PORTC ganz aus ist PC0 setzen. (extrem kurz) PC0 rücksetzen PC1 setzen (extrem kurz) PORTC ganz aus. danach geht es dann aber wieder ordnungsgemäß
Aeh. Ja. Fehler zu haben ist ueblich. Dann ist nun Debuggen angesagt. Debuggen ist keine Krankheit, sondern Teil des Entwicklungsprozesses. Der Programmaufbau sollte auch schon mit Debuggen geplant sein. Das bedeutet mit den kleinstmoeglichen Codeeinheiten gepruefte Bloecke aufzubauen. Dann lass das Ganze mal ohne Interrupts laufen. Dann mit einem, dann mit zweien. Bis der/die Fehler gefunden sind.
Verrätst du uns auch noch, was das Ganze sein soll? (In deinem Code findet sich ziemlich viel unübersichtliches und ich würde sogar nach einem ersten Drüberschauen sagen "unsinniges", dass es schwer ist, den Sinn hinter der ganzen Sache zu verstehen. Deine exzessive Verwendung von Hex-Konstanten macht die Sache dann auch nicht leichter.)
Bei PORTA werden Signale von Fotodioden digitalisiert. An PORTB hängt ein Display zur Ausgabe auf welche Diode sich ein Laserpointer ausrichten soll. Und zur Ausgabe des ADC-Wertes. PORTC ist für die Steuerung einer H-Brücke. Links- / Rechtslauf eines Motors. Auf PORTD(PD5) liegt eine PWM. (H-Brücke) In der ADC-ISR soll gesteuert werden. (wenn möglich später geregelt).
Das die Ursache ein aktiver Watchdog ist, oder ein reset wegen Brown-Out Detection bzw. wegen Unterspannungspulsen kann ausgeschlossen werden?
Geh bei der Fehlersuche systematisch vor. Behebe zuerst die Fehler, die aus dem Quelltext offensichtlich sind und wir dir schon genannt haben. Dann teste neu. Fang z.B. damit an, die LCD-Ausgabe in Ordnung zu bringen. Vielleicht läuft das Programm ja korrekt, nur die Ausgabe spinnt? Also: entweder alle LCD-Zugriffe aus den ISRs entfernen (gut), oder wenigstens während allen LCD-Zugriffen im main() die Interrupts sperren (quick&dirty). ( schnelle Lösung: das _delay_ms(500) im Main durch sei(); _delay_ms(500); cli(); ersetzen, das andere sei() weiter oben entfernen. ) Dann schauen wir weiter.
Brown-out kann ausgeschlossen werden. Ich hab mittlerweile herausgefunden das er mit dem ADC_interrupt so seine Schwierigkeiten hat.
1 | int main() |
2 | [...]
|
3 | sei(); |
4 | |
5 | while(1) |
6 | {
|
7 | //1. Zeile löschen
|
8 | lcd_setcursor( 0, 1 ); |
9 | lcd_string(" "); |
10 | lcd_setcursor( 0, 1 ); |
11 | |
12 | //Ausgabe der gewählten Diode auf dem LCD
|
13 | itoa( gew_Diode, Buffer3, 10 ); |
14 | lcd_string("Diode "); |
15 | lcd_string(Buffer3); |
16 | |
17 | if( ((PORTC == 0x00) & (zaehler >=31)) ) |
18 | {
|
19 | //2. Zeile löschen
|
20 | lcd_setcursor( 0, 2 ); |
21 | lcd_string(" "); |
22 | lcd_setcursor( 0, 2 ); |
23 | |
24 | lcd_string("Ausgerichtet :-)"); |
25 | }
|
26 | |
27 | else
|
28 | {
|
29 | // Kanal x (gew_Diode - 1) wandeln
|
30 | //ADC_Read(gew_Diode - 1);
|
31 | |
32 | lcd_setcursor( 10, 1 ); |
33 | lcd_int(zaehler); |
34 | |
35 | //Umwandlung "Zahl" in einen "String"
|
36 | itoa( adcval_neu, Buffer2, 10 ); |
37 | |
38 | //2. Zeile löschen
|
39 | lcd_setcursor( 0, 2 ); |
40 | lcd_string(" "); |
41 | lcd_setcursor( 0, 2 ); |
42 | |
43 | //Vorbereitung Ausgabe des Wandlungsergebnisses der gew. Diode
|
44 | lcd_string("ADC_Diode"); |
45 | lcd_string( Buffer3 ); |
46 | lcd_string(": "); |
47 | |
48 | //Ausgabe Wandlungsergebnis
|
49 | lcd_string( Buffer2 ); |
50 | }
|
51 | |
52 | PORTC = an; |
53 | _delay_ms(50); |
54 | PORTC = andersrum; |
55 | _delay_ms(50); |
56 | PORTC = 0x00; |
57 | |
58 | _delay_ms(500); |
59 | |
60 | }
|
61 | |
62 | return (0); |
Obwohl erst Interrupts vor der Endlosschliefe freigegeben werden. Und er auch eigentlich keinen werfen dürfte (ADC-Read ist auskommentiert). Springt er wenn er wenn im ADC-Register der ADC-Interrupt aktiviert wird in die ISR. Die LCD-Zugriffe sind auch aus allen ISR raus.
bzw. jetzt springt er überhaupt nicht mehr rein obwohl er sollte. // Also jetzt funktioniert es wieder richtig. (k.A. warum) mist zu früh gefreut. es kann aber nicht sein das es erst funktioniert und dann irgendwann nicht mehr.
Marius S. schrieb: > Obwohl erst Interrupts vor der Endlosschliefe freigegeben werden. Und er > auch eigentlich keinen werfen dürfte (ADC-Read ist auskommentiert). > Springt er wenn er wenn im ADC-Register der ADC-Interrupt aktiviert wird > in die ISR. Deine "ADC_init" schaltet zuerst den ADC Irq frei, und macht danach einen Dummy-Read. Dieser Dummy-Read löst natürlich auch einen IRQ aus. Also: ADCSRA |= (1<<ADIE); ans Funktionsende schieben. Bei Global deaktivierten IRQs sollte das jedoch wurscht sein. Sicher dass der noch vor dem "sei()" dort reinspringt? Eventuell enthält dein rest-Quelltext (lcd, enprellung, ..) ein sei() ?
Dein Programm ist nicht gerade "klein" (deine LCD-Routinen und entprellung kommen ja auch noch dazu) und du verwendest viele sehr große Variablen.. Gib mal folgendes auf deinem PC ein:
1 | avr-size --mcu=atmega16 -C foo.elf |
foo.elf ist die elf-Datei deines Programms, die wird beim Übersetzen in die .hex mit erzeugt. Jetzt wird dir angzeigt wie viel RAM du schon verbraucht hast, vielleicht isses ja wirklich schon so weit dass du nen größeren Controller brauchst (Atmega32)
-schumi- schrieb: > Jetzt wird dir angzeigt wie viel RAM du schon verbraucht hast, > vielleicht isses ja wirklich schon so weit dass du nen größeren > Controller brauchst (Atmega32) Soweit isses noch nicht... Mit wenig Aufwand könnte er z.B. alle String-Konstanten vom Ram in den Flash verbannen... PSTR(), lcd_string_P ()...
Ein delay ist sowieso Schrott. Besser ist ein konstrukt wie timer_isr { timer_came=1 rimerreload... } main .. if (timer_came==1) { .. timer_came=1; }
Εrnst B✶ schrieb: > -schumi- schrieb: >> Jetzt wird dir angzeigt wie viel RAM du schon verbraucht hast, >> vielleicht isses ja wirklich schon so weit dass du nen größeren >> Controller brauchst (Atmega32) > > Soweit isses noch nicht... Mit wenig Aufwand könnte er z.B. alle > String-Konstanten vom Ram in den Flash verbannen... PSTR(), lcd_string_P > ()... AVR Memory Usage ---------------- Device: atmega16 Program: 5670 bytes (34.6% Full) (.text + .data + .bootloader) Data: 426 bytes (41.6% Full) (.data + .bss + .noinit) Build succeeded with 0 Warnings...
Mittlerweile läuft es recht stabil. Nach einer langen Zeit hat er immer noch nen kurzen Aussetzer. -Ich mach jetzt direkt am Anfang der main erstmal ein cli(); -sei(); direkt vor der Endlosschleife. -Ich hab mich um die Datenrichtung bei allen Ports gekümmert. -Alle Interrupts schalte ich jetzt in der main, direkt vor dem sei(); , ein (externe (Taster), ADC). -in der ADC_ISR: zuerst adif & adie = 0; am ende adie = 1 -Displayzugriffe alle ausserhalb der ISRn. -Es läuft allerdings immer noch mit delays anstatt dem timer. Und auch wenn es nicht zum Beitrag passt: Habe ich ne Chance auf einen Regler wenn ich in dem Sinne keinen Sollwert habe außer das der entspr. Wert maximal sein soll? Ich meine nein. Da ich ja in dem Sinne keinen Wert habe mit dem ich den aktuellen Wert vergleichen kann. Zudem habe ich ja dann nie eine Abweichung wo dann der Stellwert/Stellgröße entspr. zurückgefahren/invertiert wird.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.