... wenn ... IR-Led z.B. 1000us lang senden lasse ... der TSOP auch 1000us auf low gehen ...
Klar. MUSS ja so sein, sonst könnte ich nicht die verschieden(st)en Protokolle mit ihren unterschiedlichen high-low-Zyklen verarbeiten.
... aber in jede Richtung weiter experimentieren und wieder berichten ...
NEIN, um alles in der Welt nein. Es reicht wenn Du NUR die sinnvollen Richtungen weiter verfolgst. Die Wahrscheinlichkeit dass eine sinnlos erscheindende Richtung das Optiumum oder auch nur einigermassen sinnvoll wird, ist sehr gering, glaub mir.
... RC-Baggersteuerung ... wurde ... "ISR-Register-Speicher-Orgie" von
Bascom zum Hauptproblem ...
Mal nur so als kurzen Denkansatz: ICH dekodiere meine Codes, vorzugsweise RC-5, NICHT (ääähhhh nur zum Teil) mit einer eigenen ISR. Ich habe in meinen Controllern praktisch immer einen 50 µs-Heartbeat - und die Controller laufen praktisch immer mit 20 MHz (kann doch der 45er tiny auch: DAtenblatt: – ATtiny25/45/85: 0 - 10 MHz @ 2.7 - 5.5V, 0 - 20 MHz @ 4.5 - 5.5V); von dem abgeleitet zeigt mein 1-sek-LED-Toggle korrekt an, dass zumindest diese ISR noch läuft. Eine sehr praktische Funktionsanzeige. DANEBEN nutze ich diesen 20 kHz-Timer als Zeitmesser - - und hole mir IN dieser ISR manchen Pinzustand im Polling. Meine zugehörigen Zeitscheiben heissen tupsi - Timer Unit Per Sensor Interrupt, wurde irgendwann so eingeführt und seither beibehalten.
Auch der Zustand des RC-5-Pinns wird in der Timerroutine abgefragt - und die Zeit für eine "Zustandsperiode" festgehalten. Daneben wird in einer ISR zu einem externen Interrupt (im untenstehenden Code PCINT) der Pinzustand abgefragt, weil ich auf JEDE Zustandsänderung/Flanke triggere. Erfahrungsnachweis: immerhin starte ich mit dieser Routine z.B. in meiner Getränkedose MiniD0 und in meinem WALL R bestimmte Tasks - im WALL R auch eine Wegfahrsperre !!, in meinem ArchieKopf ebenfalls Tasks und auch einzelne Funktionsparameter (schneller, langsamer etc).
Langer Rede kurzer Sinn . . . steht im Codebeispiel. Vielleicht kannst Du etwas damit anfangen.
Code:
// ============================================================================== =
// === Nicht unterbrechbare ISR für timer2, Kanal B !! 20 kHz / 50 µs
ISR(TIMER2_COMPB_vect) // Vektor 11 Progr.addr. $0014
{ //
// SetBit (PORTD, 7);
// - - - - - - - - - - - - - - -
if (Izeit_b) Izeit_b --; //Interrupt-Timer = 1 ... 20 000 ... (1 sec blink)
else Izeit_b = Izthrznt; // in if (Izeit_1 <= Izthrznt)
// - - Ende der eigentlichen Timer2-ISR
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Zeiten für RC-5-Analyse setzen, RC-5-Analyse in ~mot~/(PCINT2_vect)
if (IsBitSet (RC5prt, RC5pin)) // WENN RC5-pinn high; Encoder empfängt nichts
{ // => zähle Vorstartcounter hoch
// Vorstartcounter wird in IRS(INT2_vect) genullt
RCvorsc ++; // RC-5-Vor-Sequenz-Counter bis 100 hochzählen
if (RCvorsc > 1000) RCvorsc = 1000; // RCvorsc max 1000 tupsi / 50 ms
} // Ende if (RC5prt & (1<<RC5pin))
// - - - - - - - - - - - - - - -
RCbit_zt ++; // Zeit für 1 Codebit 1,778ms, in tupsi 33 .. 38
RCzeit1 ++; // Tupsicounter uint16_t für RC-5-Decoding
RCges_zt ++;
if (RCges_zt >= 490 && RCDECO) // Endemarkierung RC-5-Deco 27Nov2012-15:22
{ // Endeerkennung: Zeitablauf und RCDECO != 0
RCBB = RCDECO; // Datum wird übernommen
RCDCO2 = RCDECO; // Datum sichern zum Dekodieren
RCTold = RCTGGB; // Toggelbit für nächses Lesen sichern
RCTGGB = IsBitSet (RCDECO, 1<<10); // Togglebit lesen + sichern
if ( RCTGGB == RCTold ) RCTums = 0;
else RCTums = 1;
RCDECO = 0; // RCDECOdierungsbyte leeren
} //
if ( RCzeit1 > 2000) // "Reset" Dekodierung bei einer zehntel Sekunde
{ //
// RC5roff = 1; // RC5-read-off, 0 <=> Lesen ist an, 1 <=> aus
RCzeit1 = 0; //
} //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return; //
} // Ende ISR(TIMER2_COMPB_vect)
// ============================================================================== =
// ============================================================================== =
// === INT20/Pin PC4 zum Dekodieren von RC-5 nach folgendem Arbeitsablauf
// - In ~tmr~/ISR(TIMER2.. wird der Vorstartcounter RCvorsc bis 100 hochgetickt
// - Hier wird zuerst das Startbit abgefragt
//
ISR (PCINT2_vect) // ISR für INT20 auf Pin PC4 zum Dekodieren von RC-5
{ //
// - - - - - - - - - - - - - - - -
// Start RC5-Decoding: Level (RC5prt & (1<<RC5pin)) ist low <=> IR-Empfang aktiv !!
// ===== RC-5-DECOding-Byte (RCDECO) ist Null
// RCvorsc >= 99 -- nur dann ist "vorher" länger high
if ((!(RC5prt & (1<<RC5pin))) && (!RCDECO) && (RCvorsc > 99)) //
{ //
RCvorsc = 0; // Vorstartcounter nullen 07. Nov. 2013 11h42
RCges_zt = 18; // ?? Gesamtzeit in tupsi f EINEN kplt CodeSATZ
// hier ein offset, weil ja 1/2 Bit vorbei ist
RCBptr = 13; // RC-5-Code: Bitpointer (0..13) f RC-5-Code-Word
// - - - - - - - - - - - - - - - -
// Hauptaufgabe: Schreibe Bit ins Target
RCDECO |= ((uint16_t)1<<13 ); // Hier wird nur Bit 13 {13..0} gesetzt
RCBptr = 12; // ... und pointer auf nächstes Bit
RCbit_zt = 0; // Zeit für 1 Codebit 1,778ms, in tupsi 33 .. 38
} //
// - - - - - - - - - - - - - - - -
if (RCBptr >= 0) // war : if ((32 < RCbit_zt) && (RCbit_zt < 39))
{ //
if ((RCbit_zt>26) && (RCbit_zt < 60)) // <<## gute Funktion, so bleibts
{ // Ist ein gültiges Bit erkannt worden ?
if (!(RC5prt & (1<<RC5pin))) // High oder low level ?
{ //
RCDECO |= ((uint16_t)1<<RCBptr ); // Bei LOW schreib "1" weg
} // Ende if (!(RC5prt & (1<<RC5pin))) : High oder low
RCBptr -- ; // ... und pointer auf nächstes Bit
RCbit_zt = 0; // Zeit für 1 Codebit 1,778ms, in tupsi 33 .. 38
} // Ende if ((RCbit_zt>26) && (RCbit_zt < 48))
} // Ende if (RCBptr >= 0)
// - - - - - - - - - - - - - - - -
// TESTWEISE Ausgabe Codewort und Zeitbedarf
if ((RCBptr < 0) && (RCges_zt < 1000))
{ //
RCBptr = 0; // doppelte Ausgabe verhindern
} // Ende if (RCBptr < 0)
// - - - - - - - - - - - - - - - -
} // Ende ISR (PCINT2_vect)
// ============================================================================== =
ABER - wie schon oben geschrieben - ich vermute dass Du mit der Abfrage der Pulslänge Deines DEKODIERTEN IR-Pulses alleine Deine Steuerung erfüllen könntest.
1x IR-LED
1x TSOP
1x RC Signal Gas (vom RC-Empfänger) rein
1x RC Signal Gas (zum Motorregler) raus
1x Optional RC Signal (feuern) rein
Jaaaaa - so eine Tabelle ist SEHR aussagekräftig. Danke. Dir reicht also eigentlich a) das Durchschleifen des RC-Gas-rein zum RC-Gas-raus UND die Analyse des RC-Signals (und ich denke für eine erste Funktion brauchst Du NUR die Existenz dieses Signals nachzuweisen, ohne Codecontrolle). Und wenn dieses Signal erreicht wird, dann wird eben das RC-Gas-raus für ne bestimmte Zeit auf "wenig Gas" gesetzt. Oder ?!
Lesezeichen