www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frequenz messen, Korrelationsfolge?


Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Aufgabe mit einem AVR bei mehreren Kanälen jeweils 3 
Zustände (High,Low, Toggle) zu unterscheiden. Das Toggeln kann sich in 
der Frequenz unterscheiden, wobei nur eine bestimmte Frequenz als 
wirkliches toggeln, die jeweils anderen als AN und AUS-Schalten 
interpretiert werden. Flankeninterrupts an den Pins kann ich dazu nicht 
verwenden.
Ich habe mir folgendes gedacht:
Mit TimerX Kanäle abtasten und jeweils Zustände per shiften in eine 
Variable schreiben. Nach 8 Abtastwerten wird dieser ausgewertet. Dies 
entspricht 2 Perioden. Ich brauche also ein char. Nach den 8 Werten 
müsste in diesem char etwa sowas stehen, wenn es sich um das erwähnte 
toggelnhandelt:

11001100 oder
10011001 oder
00110011 ...

Kann man sich ja denken..!? Um nun festzustellen, ob der Kanal nun mit 
er Frequenz getoggelt wurd, muss in dieser Variablen der code 
"...110011..." oder "...001100..." auftauchen. Dabei nehme ich an, dass 
3 Halbperioden (an, aus, an oder aus,an,aus) ausreichen um das Toggeln 
zu identifizieren. 2 würden ja zB. nicht ausreichen, da es sich auch um 
ein normales AN, AUS-Schalten handeln könnte.

Ich habe mir nun diesen Algorithmus ausgedacht um diesen Code zu 
identifizieren.
char shifter=0;
char maske=0x3F;
char code = 0x33;
char invcode = ~code&0x0F;

while ( !(found_code) || (shifter<3) )
{
  if ( (buffer&(maske<<shifter)) == ((code<<shifter) || (invcode<<shifter)) ) found_code=1;
  shifter++;
}
Kurz zur Erklärung: Es wird solange die char Variable buffer (in der 
sich vielleicht der Code 0011 0011versteckt), mit der Maske 0011 1111 
geodert bis entweder der Code herauskommt oder das Shiftmaximum erreicht 
ist. In diesem Fall darf nur 2 mal links geshiftet werden, da dann die 
8Bit erreicht sind. Da auch der invertierte Code 00 00 11 00 auftauchen 
kann, wird nochmal geodert.
Wichtig ist hierbei, dass lediglich 3 Halbperioden als Code 
interpretiert werden. Deshalb wird auch nicht mit dem ~code sondern nur 
mit dessen ersten 6Bit gearbeitet.

Ich hoffe das war soweit verständlich. Ist der Algorithmus irgendwie 
nachvollziehbar/richtig? Habe nur bedingte Debugmöglichkeiten. Gibt es 
vielleicht bereits fertige Lösungen für das Problem?
Im Endeffekt, will ich eine bestimmte Frequenz messen und von einfachem 
AN, AUS mit anderen Frequenz zuverlässig unterscheiden. Die Abtastwerte 
liegen im Abstand von 70ms. Die Periode die hier detektiert werden soll 
liegt also bei 4x70ms.
Vielleicht könnr ihr mal was zum Code bzw. Problematik sagen


Gruß

Maddin

Autor: Joachim K. (minifloat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass doch einen Timer frei rennen. Dann mach an den Input-Pin ein 
Pinchange Interrupt. Dann kannst du High- und Low-Zeiten messen, deren 
maximale Länge nur durch mehrmaliges(einmal ist ok) überlaufen des 
Timers begrenzt sind(darum kann man sich aber auch kümmern).

Jedesmal bei Pinchange speicherst du den Timerwert in einer Variable 
Timer_old. Das muss am Ende der PCINT-ISR geschehen.
Es ergibt immer Timer_jetzt - Timer_old die Zeit eines High bzw. 
Low-Pegels.

Die kannst du in ein Array schreiben(Ringpuffer oder Liste) und 
auswerten, ob deine Frequenz dabei ist. Dazu reicht eigentlich schon ein 
einziger Wert.
mehrmalige Timerüberläufe kann man detektieren und ein Flag setzen, dass 
der nächste Pinchange nicht gewertet wird(Wert wird nicht ins array 
übernommen).

Du kannst jetzt sogar obere und untere Schwellen für die halbe 
Periodenzeit deiner zu suchenden Frequenz setzen und bestimmen, wieviele 
halbe Periodenzeiten dir genügend Genauigkeit zum sicheren Detektieren 
bieten.

mfg mf

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt mir rechlich kompliziert vor.
Warum zählst du nicht einfach für jeden Kanal mit, wieoft hintereinander 
du ihn im selben Zustand vorgefunden hast. Bei 2-mal oder weniger 
toggelt er, bei mehr ist er konstant auf an oder aus.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mini Float schrieb:
> Dann mach an den Input-Pin ein
> Pinchange Interrupt.

Dazu müsste der entsprechende Kanal sich an einen INT Pin befinden. Tut 
er aber nicht. Ich habe 16 Kanäle die alle ausgewertet werden müssen.

Über den Rest den zu schriebst, muss ich jez erstmal nachdenken.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann ein Pinchange durchaus auch ohne Interrupt auswerten.
Benutz einfach ein Statusregister um den aktuellen Zustand zu sichern, 
dann kannst du alle Pins der Reihenfolge nach mit dem Statusregister 
vergleichen. Bei Änderung wird dann der jeweilige Timerwert abgelegt und 
die Bitposition im Statusregister angepasst. Dazu kannst du am besten 
ein Xor Verknüpfung nehmen.

Beispiel:

Pin5 von 0 auf 1
Statusregister: --0-----
Pinposition: 00100000
-> Xor ergibt: --1-----

Wichtig wäre noch die Frequenz die du als Toggeln ermitteln willst bzw. 
das Verhältnis zum Timer. Bei der Ermittlung der jeweiligen Zeit ist 
natürlich auf einen Timerüberlauf zu achten.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Warum zählst du nicht einfach für jeden Kanal mit, wieoft hintereinander
> du ihn im selben Zustand vorgefunden hast. Bei 2-mal oder weniger
> toggelt er, bei mehr ist er konstant auf an oder aus.

Ich glaube das ist nicht ganz eindeutig. Kommt zum Beispiel für 2 
Abtastwerte also eine Halbperriode (bzw. ein kurzes AN) eine 1, dann 
handelt es sich nicht zwangsläufig um das zu detektierende Toggeln mit 
entsprechender Frequenz.

Auch wenn sich dein Vorschlag schonmal interessan und einfach anhört. 
Das muss ja eine Art Ringzähler sein oder so. Nehmen wir an ich 
inkremtentiere immer dann, wenn der vorherige Zustand dem aktuellen 
entspricht. Dann muss ich das ja irgendwannn auswerten. Dann steht 
irgendwann in der Variablen eine 1. Ich habe also den Toggeln Zustand 
erkannt. Nun bleibt das Signal weiterhin auf dem Zustand und die Zahl 
wird größer. Es liegt also doch garkein Toggeln vor.
Oder ich muss die Variable erst nach eine längeren zeit auswerten. Aber 
dann sagt zum Beispiel eine 2 in de Variablen nichts darüber aus wie 
groß die Lücke zwischen 2 gleichen Zuständen ist.

Hhmmmm

Gruß

Maddin

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes schrieb:
> Man kann ein Pinchange durchaus auch ohne Interrupt auswerten.

Das Verstehe ich nicht. Wann bekommte ich mit wann eine Pinchange 
vollzogen wurde? Wer teilt mir das mit? Soll ich wie blöd 16 Kanäle 
pollen?

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Soll ich wie blöd 16 Kanäle pollen?

Nie wie blöde, sondern schlau! 5-10kHz bei 16MHz Takt sind kein Problem.
Auch ein AVR hat ein Recht auf Vollbeschäftigung :-)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Frequenzen sind den drei Zuständen zugeordnet?

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um das nochmal genauer zu erklären ^^
Du liest einfach zu einem bestimmten Zeitpunkt deine Ports aus und gehst 
Pin für Pin durch und vergleichst mit dem Vorzustand (Statusregister). 
Wenn sich etwas geändert hat wird es wie oben beschrieben im 
Statusregister übernommen.

Wichtig wäre für die Auswertung noch ob du nur eine bestimmte Frequenz 
detektieren willst, oder alle Impulse die unter einer bestimmten Dauer 
liegen.

Prinzipiell gibt es zwei Möglichkeiten. Entweder nutzt du einen frei 
laufenden Timer und ermittelst die genaue Länge über die Differenz der 
beiden Timerwerte oder du nutzt ein Timerinterupt welches auf die 
Frequenz des Toggelns abgestimmt ist. Letzteres erscheint mir die 
einfachere Variante, allerdings kann es dann zu Ungenauigkeiten kommen 
wenn du einen ganz bestimmten Frequenzbereich isolieren willst.

Hoffe ich konnt erstmal bissl helfen :D

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Das Verstehe ich nicht. Wann bekommte ich mit wann eine Pinchange
>vollzogen wurde? Wer teilt mir das mit? Soll ich wie blöd 16 Kanäle
>pollen?

Die Pin-Change-Interrupt-Flags werden auch ohne Interrupt gesetzt. Also 
beschränkt sich das Ganze auf die Abfrage einiger Bits in einem 
IO-Register.
Du darfst nur das Rücksetzen der Flags nicht vergessen.

MfG Spess

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Die Pin-Change-Interrupt-Flags werden auch ohne Interrupt gesetzt. Also
> beschränkt sich das Ganze auf die Abfrage einiger Bits in einem
> IO-Register

Ich weiß nich ob ich es schon verstehe. Ich soll jeweils das PINx 
Register auslesen? So mache ich es ja im Moment. Mich verwirrt der 
Ausdruck Pin-Change-Interrupt ohne den Zusammenhang mit den INT-pins. 
Das heißt für mich einfach das Register PIN auslesen.

Bis jetzt läuft es so: Der Timer liest im 70ms Takt Kanäle ein und 
shiftet den Status in die Variable bufferx.

Wenn ich das richtig verstehe, wäre es sinnvoller einfach für jeden 
Kanal ein Bit bereitzuhalten, dass den jeweils vorherigen Status 
beinhaltet. Diesen bekommt man in dem man PINx an der richtigen 
Bitstelle ausliest.

Das mit der Zeitmessung wäre auch eine Möglichkeit.

Im Prinzip ist das alles nicht zeitkritisch, es muss nur zuvelässig 
klappen. Das betreffende Toggeln geschieht im ca. 140ms Takt. Also 140ms 
An und wieder 140ms Aus. In der Regel setzt sich dies dann für einen 
längeren Zeitraum fort. Irgendwann kann der Kanal dann eben auf Low oder 
High bleiben. Und dies muss unterschieden werden vom Toggeln. Natürlich 
kann der Kanal sich auch im 300ms Takt toggeln, was jedoch einfach als 
AN und AUS detektiert werden muss. Änderungen unter 140ms brauchen nicht 
detektiert werden, solange die folgenden Kanalzustände richtig 
interpretiert werden. Da darf also nichts durcheinander kommen, nur weil 
mal kurz schnell AN,AUS und wieder AN geschalten wurde.

Ich bleib dran. Schonmal ein Dank an euch


Gruß

Maddin

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mein Vorschlag zur Auswertung wäre noch für jeden Pin ein Register 
anlegen. Dieses wird immer um 1 erhöht wenn der ausgelesen wurde und 
sich nix verändert hat. In gewisser Weise die Dauer des jeweiligen 
Pegels. Dazu kannst du die Ausleserate erhöhen und hast mehr 
Genauigkeit.
Zwei dinge sind zu beachten:

1. bei Überlauf eines Registers
   -> Lösung: wenn Flag gesetzt, zb. 128 in Register schreiben und Flag 
löschen
   (Dadurch bewegen sich die dauer-an/aus Ports immer zwischen 128 und 
255)

2. Auswertung bei Toggeln
   -> Prüfen ob die Dauer im gewünschten Bereich liegt
   (sprich über 128 ist oder unter zb. 100; obere und untere Grenze)

Ich gebe zu es ist etwas aufwändig, aber dadurch kannst du mit einer 
guten Timereinstellung sehr genau bestimmte Toggellängen filtern.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich weiß nich ob ich es schon verstehe.

Nicht so richtig. Wenn dein AVR Pin-Change besitzt dann hat er auch 
folgende Register:

Pin Change Interrupt Control Register - PCICR
Pin Change Interrupt Flag Register - PCIFR

und ein oder mehrere

Pin Change Mask Register x – PCMSKx

in den PCMSKx-Registern legst du fest, welche Pins der zugehörigen 
Gruppe einen Interrupt auslösen kann.

Im PCICR wird festgelegt welche Pin-Gruppe einen Interrupt auslösen 
darf.

Die PCIFx-Bits im PCIFR zeigen an, in welcher Pin-Gruppe ein sich Pin 
verändert hat. Das passiert aber auch, wenn in PCICR kein Interrupt
freigegeben wurde. Um also eine Änderung an deinen Pins festzustellen 
brauchst du nur die PCIF-Bits im PCIF-Register überprüfen. Wenn eins 
oder mehrere 1 sind, haben Pins gewackelt. Die PCIF-Bits musst du danach 
durch Schreiben einer 1 wieder zurücksetzen.

MfG Spess

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achja, und bei Pegeländerung natürlich auch auf 0 setzen :D

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei Verwendung von PCINT würde ich aber vorher klären, woher die Impulse 
kommen. Falls es ein Relaisausgang sein sollte, wäre PCINT tödlich. Bei 
140ms Pulsdauer würde ich es per Pollen machen. Allerdings nicht mit 
70ms sondern feiner aufgelöst.

Autor: John (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maddin schrieb:
> Bis jetzt läuft es so: Der Timer liest im 70ms Takt Kanäle ein und
> shiftet den Status in die Variable bufferx.

Was so, oder so ähnlich schon vorgeschlagen wurde:
Die eingelesenen, aktuellen Werte mit denen bei der letzten Abfrage 
eingelesenen (und gespeicherten) Werte XOR Verknüpfen. Das Ergebnis der 
XOR-Verknüpfung schiftest Du dann, für jeden Kanal, in je eine bufferx 
Variable. Die Anzahl der 1sen in der jeweiligen Variable gibt dann an, 
wie oft der dazugehörige Eingang während der letzten 8 Abfragen, 
getoggelt wurde.

Gruß
John

Autor: Joachim K. (minifloat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pin Change Interrupts kennst du nicht, ist schade.
Da mein Vorgehen noch nicht ganz verstanden wurde, muss Ich das wohl mal 
in Pseodocode gießen.

Hier mal nur für einen zu prüfenden Pin. Sonst muss eben ein 
mehrdimensionales Array hergenommen werden und in der Pinchange 
Interrupt Routine auf jeden geänderten Pin die Schiebung und das 
Speichern angewendet werden auch braucht man immer ein anderes Time_old 
wie auch eigene Flags. Ringpuffer statt schieben ist natürlich 
eleganter, aber hier zum Verständnis des Prinzips mal draußen gelassen.
Doch nun der Reihe nach:
Globales Int Array Zeiten(20 Elemente);
Globales Int Timer_old;

Main:
   Pinchange Interrupt init.
   Timer overflow init.
   Starte Timer.
   Mainloop:
      Tue dies.
      Tue das.
      Werte das Array aus.
      foobar.
   End Mainloop.
End Main


Timer Overflow Interrupt:
   Flagvariable++
End Timer Overflow Interrupt


Pinchange Interrupt:

   Wenn Flagvariable < 2 Dann
      schiebe_Arrayelemente_eins_nach_hinten(Zeiten)
      erstes Arrayelement(Zeiten) = Timer_count - Time_old
   End Wenn.

   Flagvariable = 0
   Time_old = Timer_count

End Pinchange Interrupt
mfg mf

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Nicht so richtig. Wenn dein AVR Pin-Change besitzt dann hat er auch
> folgende Register:
>
> Pin Change Interrupt Control Register - PCICR
> Pin Change Interrupt Flag Register - PCIFR
>
> und ein oder mehrere
>
> Pin Change Mask Register x – PCMSKx

Geht es also doch um die PCINTs!?  Habe es also doch verstanden. Bei mir 
heißen die EICRA, EICRB, EIMSK... mMan stellt ein, auf welche Flanke der 
Interrupt kommen soll und für welchen INTx Pin und dann springt das 
Programm in die ISR(INTx). Davon gibts aber nunmal nur 8. Ich könnte 
höhstens bei 8 von den 16 die Frequenz damit feststellen.
Nebenbei: Bei 8 von den 16 stelle ich den Kanalzustand eh schon über 
diese PCINTs fest. bei den anderen 8 überprüfe ich mit TimerAbfrage.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Bei mir heißen die EICRA, EICRB, EIMSK...

Nein. Die sind für INT0...INTn. Aber vielleicht solltest du mal 
verraten, welchen AVR du benutzt.

MfG Spess

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich merk schon, wir reden von verschiedenen Sachen. Das gesamte 
Datenblatt kennt kein PCI oder ähnliches. Nutze ATmega64

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ich merk schon, wir reden von verschiedenen Sachen. Das gesamte
>Datenblatt kennt kein PCI oder ähnliches.

Richtig.

>Nutze ATmega64

Der hat keinen Pin-Change-Interrupt. Das sind normale externe 
Interrupts.

MfG Spess

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes schrieb:
> mein Vorschlag zur Auswertung wäre noch für jeden Pin ein Register
> anlegen. Dieses wird immer um 1 erhöht wenn der ausgelesen wurde und
> sich nix verändert hat. In gewisser Weise die Dauer des jeweiligen
> Pegels. Dazu kannst du die Ausleserate erhöhen und hast mehr
> Genauigkeit.


Mit diesem erhöhen wird man meiner Meinung nach nicht die Frequenz genau 
bestimmen können. Woher soll man wissen ob der Kanal lange einen Zustand 
hatte und dann gleiche Zeit einen anderen oder ob zwischendurch immermal 
wieder umgeschaltet wurde. Das wird man später nicht mehr wissen wenn 
man nur eine Zahl hat.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du kannst das ganze auch über ein Timerinterupt steuern, dann ist auch 
egal was der Controller kann. Is sozusagen eine Softwarelösung :)

also ich würde das so machen:

Timerinterupt -> alle Pins werden eingelesen und mit dem vorherigen 
Zustand verglichen

Dann wird für jeden Pin ein Register geschrieben, bei gleichem Pegel um 
1 erhöhen und bei Änderung den Wert im Register auswerten und dann 
wieder 0 setzen.
Bei der Auswertung stellt sich die Zahl im jeweiligen Register ein 
Vielfaches des Timerinterupttaktes dar. Wichtig ist hier nur das alle 
Register die über 255 steigen, also überlaufen, wieder auf einen Wert 
gesetzt werden der nicht als Toggeln erkannt wird.
(wenn flag gesetzt -> 141 in Register schreiben -> flag löschen)
Damit bewegen sich alle Register der Pins die länger als 255 Durchläufe 
an sind zwischen 141 und 255. Das Toggeln kann dann im unteren 
Zahlenbereich detektiert werden. Also wenn eine Änderung vorliegt, dann 
wird der Wert in dem Register welches die Pegeldauer eines Pins enthält 
geprüft.
(alles was zb zwischen 70 und 140 liegt wird dann als Toggeln 
betrachtet)

Du kannst den Timerinterupt so einstellen, das du in den Registern die 
Millisekunden zählst. Dadurch können dann Mindestdauer und Höchstdauer 
genau gesetzt werden.

Einziger Nachteil könnte sein, das es durchaus passieren kann wenn alle 
Pins gleichzeitig wechseln, das der nächste Timerinterupt übersprungen 
wird.

Ich hoffe mal das war jetzt ausführlich genug und stiftet nich zu viel 
Verwirrung :D

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes schrieb:
> Ich hoffe mal das war jetzt ausführlich genug und stiftet nich zu viel
> Verwirrung :D

Das war sehr gut. Denke mal drüber nach und bastel rum. Danke vorerst.

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du musst allerdings wie schon erwähnt berücksichtigen, das wenn alle 
Pins wechseln und bearbeitet werden müssen die Summe der 
Programmschritte nicht über das nächste Timerinterupt führen darf.
Sonst wirds ungenau :P bzw. wird die Obergrenze für die Pegeldauer die 
noch als Toggeln erkannt wird erhöht.

Dann viel spaß beim basteln =)

Autor: Maddin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
volatile char counter,flag,flag_for_toggle;
void main ()
{
  while(1)
  {
    sleep_mode();  //AVR in sleepmode
    while(flag)
    {
      flag=0;
      if ( (counter>10) && (counter<128) ) flag_for_toggle=1;
    }
  }
}

ISR(timer)
{
  static char last_status=0;
  ...
  if(pin_high)  //wenn Signal high am Pin
  {
    if (!(flag_for_toggle)) function_for_high();  //Funktion nur aufrufen, wenn Zustand "nicht toggeln" ist
    else function_for_toggel();
    if (last_status)
    {
      counter++;      //wenn letzter Signalzustand auch high dann Zähler++
      if(counter==0xFF) counter = 0x80;  //wenn Zähler überläuft, dann auf 128 setzen
    }
    else flag=1;            //wenn nicht, also Zustand sich geändert hat, dann Flag für main() setzen
    last_status = 1;          //speicher aktuellen Zustand für nächstes Abtasten
  }
  else if(pin_low)  //wenn Signal low am Pin
  {
    if (!(flag_for_toggle)) function_for_low();    //Funktion nur aufrufen, wenn Zustand "nicht toggeln" ist
    else function_for_toggel();
    if (!(last_status))
    {
      counter++;      //wenn letzter Signalzustand auch low dann Zähler++
      if(counter==0xFF) counter = 0x80;  //wenn Zähler überläuft, dann auf 128 setzen
    }
    else flag=1;            //wenn nicht, also Zustand sich geändert hat, dann Flag für main() setzen
    last_status = 0;          //speicher aktuellen Zustand für nächstes Abtasten
  }
  
  ...
}

Habe das nun mal ausprobiert für einen Kanal. Ob das nun die 
ressourcensparenste lösung ist, mag mal dahin gestellt sein. Was zählt 
ist vorher ein Ergebnis.
Fakt ist, dass function_for_toggle() nicht aufgerufen wird. Meiner 
Meinung nach bleiben nur die Möglichkeit der falschen werte für die 
if(..) in der Main oder eben ein von mir noch unentdeckter einfacher 
Fehler im Algorithmus. Vielleicht springt euch was ins Auge...?

Kurz zur Erklärung, es gibt eine Funktion für jeden Zustand 
(high,low,toggel). Die Funktionen für high und low werden gesetzt wenn 
der Signalzustand ensprechend ist und das Flag flag_for_toggle NICHT 
gesetzt ist. Ist es gesetzt wird die Funktion fürs toggeln aufgerufen.
Das Flag wird in der Main gesetzt in dem der Counter untersucht wird auf 
einen bestimmten Bereich. (Noch) in der ISR wird counter kurz vor dem 
überlauf auf 128 gesetzt. Counter läuft also wiederholt von 128 bis 255 
wenn der Zustand des Kanals lange einen Zustand hat.

Ein Manko gibt es noch, sollte jedoch nicht zum aktuellen Fehlverhalten 
führen: Startet das Programm und last_status ist 0 und wird ein high 
erkannt, dann wird auch schon das Flag für die main gesetzt auch wenn 
dies noch keiner wichtigen! Zustandsänderung entspricht.

Gruß

Maddin

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maddin schrieb:
> Die Funktionen für high und low werden gesetzt

Die Funktionen für high und low werden ausgeführt

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm will nun doch keiner mehr?

Gruß

Maddin

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.