Hallo!
Ich habe vor dieses Projekt (Infrarot-Schalter und -Regler) zum Regeln der Lautstärke eines Audiosignals als Arduinoprojekt nachzubauen. Der Programmablauf ist unten erklärt und ich bin dabei, ihn mehr oder weniger auf die Processing Umgebung zu übertragen (soweit das eben von einer strukturierten auf eine objektorientierte Programmiersprache möglich ist). Zum Umsetzen der IR Signalanalyse wie im Assemblercode versuchte ich eben auch mit der Kombination aus Timer und PinChangeInterrupt zu arbeiten, wobei mir gleich ein Thread auffiel an dem ich mich stark orientierte, den ich jedoch nicht zu 100% durchschaute (http://arduino.cc/playground/Code/ReadReceiver). Diese Vorgehensweise erschien mir auch aufgrund der Interrupts exakter als Vorgehensweisen wie diese ->Reading IR Commands | IR Sensor | Adafruit Learning System auf die ich später stieß. Jetzt habe ich meinen Code zur Analyse der IR Signale endlich fertig und habe nötige Änderungen bei der Übertragung des Beispielthreads "ReadReceiver" auf mein Projekt angepasst (#include <PinChangeIntConfig.h> fällt in der neuen Version weg und mit ihm die defines, nur ein Receiverpin also auch keine for-Schleife im setup und statt pin eine Pinvariable und (zur besseren Verständlichkeit andere Namen der Interrupt-Methoden)).
Der Code konnte auch ohne Fehlermeldung des Compilers hochgeladen werden, jedoch kam beim Öffnen des Serial Monitors und der korrekten Initialisierung der Baudrate die Ernüchterung: Es wurden nicht wie erhofft die Timerzeiten von Low bis erneut Low ausgegeben, als ich mit meiner IR Fernbedienung auf den Receiver TSOP 1738 beim Drücken eines Knopfes zielte, sondern nur die Systemausgabe "PinChangeInt test am IR Pin 11". Der Funktionstest des Receivers war jedoch positiv und als ich sämtliche Instruktionen im Code nach jeder Zeile mit einer Systemausgabe versah, gingen die Systemausgaben erstaunlicherweise nur bis zur Instruktion Timer1.restart() also noch in der setup(). Jetzt verstehe ich überhaupt nicht, was nicht stimmt, obwohl mir gleich aufgefallen war, dass .restart im Gegensatz zu .stop nicht gehightlighted wurde.
Daher frage ich mich:
- Als Keyword findet sich .restart in der include Datei TimerOne.h, warum wird dann weder gehighlighted, noch fortgefahren?
- Warum stehen die Anweisungen Serial.print('f') bzw. Serial.print('r') als Kommentare, falls falsch, was nützen sie wenn in der loop() durch Serial.read nach 'p' gesucht wird?
- Muss der state beim case FALLING nicht schließlich 0 sein?
(- Ist i bei pin nicht ausschließlich eine Zählvariable für die for Schleife und im weiteren Code überhaupt verwendbar?) In meinem Fall egal, da ich ja nur einen relevanten Eingang habe..
```
*#include <PinChangeInt.h> //PinChangeInterrupt-Include Bibliothek
#include <TimerOne.h> //Timer1- Include Bibliothek
int pbIrIn = 11; //portbIRinput IR-Receiver am Digitaleingang 11
byte burp=0; //Zählvariable für die Anzahl der PinChangeInterrupts/PCInts/IR Signale ankommend + aufhörend
byte IRstate=0; //IR Status, RISING/ansteigend/Signal kommt an, oder FALLING/fallend/Signal hört auf
byte cmd=0; //Speicher für Serielle Daten
unsigned int time=0;
void setup()
{
//Pin-Modus Konfiguration
pinMode (pbIrIn, INPUT);
digitalWrite(pbIrIn, HIGH);
Serial.begin(115200); // Serielle Kommunikation bei Übertragungsgeschwindigkeit von 115200 Baud
Serial.print("PinChangeInt test am IR Pin "); // Funktionstest der PinChangeInt.h Include Datei
Serial.print(pbIrIn); // funktioniert, wenn Pin 3/11? ausgegeben wird wie im define initiiert
Serial.println(); // neue Zeile
Timer1.initialize(2200); // Längster PWM-Impuls ist normalerweise 2,1ms lang, mit etwas Spielraum gewählt
Serial.println("Timer1 initialisiert");
Timer1.stop(); // Timer stoppen..
Serial.println("Timer1 gestopppt");
Timer1.restart(); // ..und zurückksetzen, um direkt beim ersten Interrupt zu starten
Serial.println("Timer1 neu gestartet");
PCintPort::attachInterrupt(pbIrIn,IRSignalerkannt,RISING); //Interruptfunktion "IRSignalerkannt" wird bei steigender Spannung am PIN (3/11) ausgeführt
Serial.println("Interrupt attached");
}
void loop()
{
cmd=Serial.read();
if (cmd=='p')
{
Serial.print("time:\t");
Serial.print(pbIrIn);
Serial.print(": ");
Serial.print(time,DEC);
Serial.print("\t");
Serial.println(burp, DEC);
Serial.println();
}
cmd=0;
switch (IRstate)
{
case RISING:
PCintPort::detachInterrupt(pbIrIn);
PCintPort::attachInterrupt(pbIrIn, IRSignalstoppt, FALLING);
IRstate=255;
break;
case FALLING:
PCintPort::detachInterrupt(pbIrIn);
PCintPort::attachInterrupt(pbIrIn, IRSignalerkannt, RISING);
IRstate=255;
break;
}
}
void IRSignalerkannt() //Pin_change interrupt am IR-Eingang (11), startet Timer um Signaldauer zu identifizieren
{
Timer1.restart(); //Timer wird zurückgesetzt..
Timer1.start(); //.. und gestartet
IRstate=RISING;
Serial.print("Der erste Interrupt wurde ausgelöst");
// Serial.print('r'); - ?wird im Beispielsketch nur als Kommentar eingeschrieben ?
burp++;
}
void IRSignalstoppt ()
{
IRstate=FALLING;
time=readTimer1();
//Serial.print('f');
Timer1.stop();
}
unsigned long readTimer1() //gibt den Timerstand in Mikrosekunden aus
{
unsigned int tmp=TCNT1;
char scale=0;
switch (Timer1.clockSelectBits)
{
case 1:// no prescalse
scale=0;
break;
case 2:// x8 prescale
scale=3;
break;
case 3:// x64
scale=6;
break;
case 4:// x256
scale=8;
break;
case 5:// x1024
scale=10;
break;
}
while (TCNT1==tmp) //if the timer has not ticked yet
{
//do nothing -- max delay here is ~1023 cycles
}
tmp = ( (TCNT1>tmp) ? (tmp) : (ICR1-TCNT1)+ICR1 );//Wenn heruntergezählt wird, füge den obigen Wert hinzu
return ((tmp1000L)/(F_CPU /1000L))<<scale;
}
```
Schon im Vorraus vielen Dank für eure Hilfe! ![]()