PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie viele Interrupts / Impulse/s verkraftet ein Atmega



damfino
25.02.2015, 11:57
Hallo,

bin gerade dabei den Rasenmäher und die Software umzubauen, etwa in verbesserte Drehzahlregelung.
Da stellt sich die Frage wie sehr Interrupts den Kontroller auslasten, so dass das eigentliche Programm vielleicht nicht mehr richtig ausgeführt werden kann.
An Interrupts gibt es:
Motordrehzahl 1: 180 Impulse/s nur zählen
Motordrehzahl 2: 180 Impulse/s nur zählen
Motordrehzahl 3: 200 Impulse/s nur zählen
USART mit 9600Baud, FiFo Buffer, Buffer wird erst gestartet wenn Startzeichen erkannt wird
Timer mit 10ms, im Timer Interrupt regelmäßig PID Berechnung Motordrehzahlen

Mit diesem Timer werden wie Tasks rechenintensive Funktionen getriggert, zB 8x in der Sekunde PID Motordrehzahl 1 und 2 berechnen, 4x in der Sekunde PID Motordrehzahl 3. Ein neuer Task wird mit mindestens 10ms Abstand vergeben, lt Simu benötigt die längste Funktion 0.7ms.
zB Tasks timen:


tasktimer++;

if (tasktimer>=TASKdauer_ms) {tasktimer=0;}
if (tasktimer==TASK250ms) {taskflag=task250msflag;}

if (tasktimer==TASKFunkdatenA) {taskflag=FunkdatentaskA;}
if (tasktimer==TASKFunkdatenB) {taskflag=FunkdatentaskB;}
if (tasktimer==TASKmessermotor)
{
drehtemp=(short)60*(short)odo_messer;
.
.
}




Kann das ein Atmega mit 16Mhz schaffen?
Momentan gibt es nur Motordrehzahl 3 und PID Regelung im Interrupt, Motor 1 und 2 max 4 Impulse/s und UART durch polling.
Wenn noch das Erfassen der Motordrehzahlen 1 und 2 sowie USART als Interrupts dazukommen, geht das noch, oder kommt er aus den Interrupts gar nicht mehr raus?

LG!

drew
25.02.2015, 12:32
Das schaut für mich von den Interrupts jetzt gar nicht so wild aus. Ich würde vermuten, dass das mit den 16MHz locker geht.
Ich kann nicht genau abschätzen, was die PID-Regelung frisst.

markusj
25.02.2015, 13:46
Wenn noch das Erfassen der Motordrehzahlen 1 und 2 sowie USART als Interrupts dazukommen, geht das noch, oder kommt er aus den Interrupts gar nicht mehr raus?
Das hängt im wesentlichen davon ab, wie viel Rechenzeit der AVR in den Interrupts verbringt. Wenn du die ISRs schlank programmierst, kommst du bei den Zähl-ISRs mit vielleicht 20-30 Instruktionen aus. Bei 16MHz und ~600 Pulsen/Sekunde in Summe ergibt das überschlagen etwas mehr als eine Millisekunde Rechenzeit. Da ist also noch viel Luft nach oben.

mfG
Markus

malthy
25.02.2015, 14:43
Hi,

wenn ich das Gefühl habe dass es irgendwo knapp werden könnte, messe ich die Ausführungzeiten von den Teilen die "parallel" laufen sollen. Ich setze am Beginn des entpsrechenden Programmteils irgendeinen Pin, den ich dann am Ende wieder lösche. Die high-Phase guck ich mir dann mit dem Oszi an. Auf diese Weise kann man auch die Aufenthaltsdauer in einer ISR in etwa bestimmen. Dabei muss man natürlich noch bedenken, dass da ggf noch Register gesichert werden, bevor der Pin gesetzt, bzw nachdem er wieder gelöscht wird.

Gruß
Malte

damfino
25.02.2015, 14:47
Die Zähl ISR sehen zB so aus:


ISR(INT6_vect) // Odo_li
{
odo_li++;
odo_speed_li++;
status_motor_li_count=0;
Motor_Fehler_Status_links= Motor_ok;
}


Einzig die Timer ISR ist länger da hier zum Teil die PID Regler berechnet werden. Muss am Abend das durch den Simu lassen, glaube es waren um die 700 Takte. Sind alles Festkomma Berechnungen.
3x das gleiche Schema, teilweise wird Anfangs von volatile auf lokale Variablen kopiert da damit der Ablauf schneller sein soll:


if (tasktimer==TASKmessermotor)
{
drehtemp=(short)60*(short)odo_messer;
drehzahl_ist=(unsigned short)drehtemp;
odo_messer=0;

if (drehzahl_soll>drehzahl_max) drehzahl_soll=drehzahl_max;
v = ((short)drehzahl_soll-drehtemp);
v=v/10;
i_summe = i_summe + v;

if (i_summe < 0) i_summe = 0;
if (i_summe > 1280) i_summe = 1280;
// PI Regler 0,3*(v/100+1/1,2*i_summe)

temp_mower=(10*i_summe)/12;
mowersp= (v+temp_mower)*3;
mowersp=mowersp/10;

if (mowersp < 100) mowersp = 100; //Begrenzung Stellgröße
if (mowersp >= 240) mowersp = 240;

mowerspeed=(unsigned char)(mowersp);
Mower=mowerspeed;
}




LG!

Bumbum
25.02.2015, 17:34
Hallo,

die sehr kurze Zähl-ISR werden kein Problem. Sollte es trotzdem optimiert werden: Die AVR's habe doch spezielle Zähl-Eingänge, die die Timer/Counter automatisch zählen.

Viele Grüße
Andreas

WL
25.02.2015, 18:20
Hi,

wenn ich das Gefühl habe dass es irgendwo knapp werden könnte, messe ich die Ausführungzeiten von den Teilen die "parallel" laufen sollen. Ich setze am Beginn des entpsrechenden Programmteils irgendeinen Pin, den ich dann am Ende wieder lösche. Die high-Phase guck ich mir dann mit dem Oszi an. Auf diese Weise kann man auch die Aufenthaltsdauer in einer ISR in etwa bestimmen. Dabei muss man natürlich noch bedenken, dass da ggf noch Register gesichert werden, bevor der Pin gesetzt, bzw nachdem er wieder gelöscht wird.

Gruß
Malte

Noch komfortabler wird diese Taktik + Logik-Analyser.
Bei mehreren ISR kann sehr schön die Dauer und zeitliche Abfolge verfolgt werden.
Diese Teile sind machmal mehr als Gold wert............ :)

damfino
25.02.2015, 20:03
Oszi und Logik Analyzer wären toll, aber nicht vorhanden. Für die 3x im Jahr wo ich diese brauchen würde zahlt sich ein Kauf nicht aus. Ich behelfe mich mit dem Simu indem ich die notwendigen Takte für Funktionen überprüfe und so auf Geschwindigkeit optimiere. Der PI Regler oben benötigt 737 Takte (jetzt gemessen).

Das Projekt und die ISR haben sich laufend weiter entwickelt. Zuerst ein einfacher Zähler, dann ein PI Regler, dann 3 PI Regler, und die Odometriezähler so erweitert dass auf defekte (Wackelkontakt) Hallsensoren reagiert werden kann. Damit kann man schlecht auf Counter wechseln.

LG!

Besserwessi
25.02.2015, 21:16
Das sieht noch alles recht harmlos aus. Bei weniger 1 MHz Takt müsste man ggf. nochmal genau nachrechnen. Die Simulation ist schon ganz gut geeignet um die Laufzeiten je ISR raus zu bekommen. Damit kann man dann auch ganz gut ausrechnen wieviel Rechenzeit die ISRs verbrauchen, und wie lang die Reaktionszeit im ungünstigsten Fall wird.

drew
26.02.2015, 12:36
Hi,
Laufzeitmessungen mach ich auch so, dass ich im untersten Level eine Schleife mit NOPs durchlaufen lasse.
Dann messe ich die Zeit einmal ohne Interrupts und einmal mit Interrupts. (Die Zeit ohne Interrupts sollte schon mal ein paar Sekunden dauern...)

Die Differenz ist dann die Zeit, die die Interrupts schlucken.
Wenn ich dann die Differenz zur gesamt-Zeit mit Interrupts ins Verhältnis stelle habe ich eine prozentuale Auslastung des System.

Also:
To: Zeit ohne Interrupts
Tm: Zeit mit Interrupts
Td = Tm-To: Zeit der Interrupts
(Td/Tm)*100%: Prozentuale Auslastung des Systems durch die Interrupts.

Gruß,
Drew

damfino
26.02.2015, 16:04
Letztes Jahr musste ich wegen diverser Hardwareschäden den Takt von 16Mhz auf 8Mhz reduzieren, da ging dem Kontroller dann die Luft aus, zB funktionierte die Drehzahlregelung obwohl in ISR nicht mehr...
Deswegen gibt es neue Hardware, von 2 Kontrollern zurück auf 1, damit entfällt die langsame Datensynchronisation über TWI, aber gleicht sich aus dass eben alle Aufgaben von einem Kontroller erledigt werden müssen.
Daher wird die Software optimiert, eine Überlegung war eben den USART von Polling und damit verbundenen sinnlosen Wartezeiten auf Interrupt umzustellen, der Hoffnung dass der Interrupt Aufruf kürzer ist als die Wartezeiten zuvor.

Das mit der Laufzeitmessung werde ich mal testen.

LG!

damfino
26.02.2015, 20:18
Habe jetzt folgende Laufzeitmessung durchgeführt:
Zähler in der Hauptschleife, alle 0.25s am LCD anzeigen.
1.) normal das Programm mit LCD, nur mit Timer Interrupt.
danach mehr und mehr Code dazugenommen bis:
2.) Programm mit LCD, allen Interrupts und allen regelmäßigen Tasks, TWI das ins leere und damit Timeout geht, als Simulation der 3 Odometrie Zähler haben ich einen zweiten Timer mit 1khz gestartet und in dessen ISR 4 Werte hochgezählt.

Bei 1 gab es max 3580 Durchläufe in 0.25s, bei 2 gab es min 3410 Durchläufe.
Damit komme ich nach obiger Rechnung auf 5% Auslastung durch Interrupts und regelmäßgigen Tasks.
Somit bleibt ja jede Menge Rechenleistung übrig :)

Eines war schön zu sehen: Habe den Fifo Buffer des USART so programmiert dass er erst Werte aufnimmt wenn der gewünschte Startcode vom GPS NMEA Code zB: "$GPGGA" kommt. Auswertung startet im Hauptprogramm wenn Übertragung komplett ist. Da nur 1x pro Sekunde die Daten übertragen werden konnte man schön sehen das kurz die Durchläufe von 3580 auf 3560 einbrachen. Bei abgestecktem GPS blieb der Wert schön gleichmäßig bei 3579/3580.


LG!