Arduino/ C++ Programm zum Samplen von IR-Signalen

Der Jockel

Ensign
Registriert
Nov. 2016
Beiträge
150
Hallo zusammen,

ich bastel gerade an einem Arduino Projekt, welches IR Signale von Fernbedienungen aufnehmen soll um diese später mit dem Arduino zu senden. Die Schaltung funktioniert schon (siehe im Bild unten). Es hängt nurnoch am Programm. Meine Idee, wie es Funktionieren soll sieht man oben im Bild und hier ist mein Programm welches leider nicht funktioniert. Schonmal Danke für Tipps und Anregungen!

C++:
#define MAXPULSE 65000
#define SAMPLERATE 26 //kehrwert der Trägerfrequenz in Microsekunden hier 38kHZ
#define DIODEPIN 8

unsigned int pulses[100][2];
unsigned short currentpulse = 0;
bool running = true;

bool lastVal = 1;
bool currentVal = 0;
bool inPulse = true;

void setup() {
  pinMode(DIODEPIN, INPUT);
  digitalWrite(DIODEPIN, HIGH);
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

void loop() {

  if( !(PINB & 1) && running){
  unsigned long previousMicros = micros();
  ++pulses[currentpulse][inPulse];
  while(running){
    unsigned long currentMicros = micros();
    if( currentMicros - previousMicros >= SAMPLERATE ){
      currentVal = !(PINB & 1);
      if(currentVal == lastVal){
        ++pulses[currentpulse][inPulse];
        if(pulses[currentpulse][inPulse] > MAXPULSE){
          printpulses();
        }
      }
      else{
        ++currentpulse;
        inPulse = !inPulse;
        ++pulses[currentpulse][inPulse];
      }
      
      previousMicros = currentMicros;
      lastVal = currentVal; 
    }
  }
 
 }
 
}

void printpulses() {
  running = false;
  for(short i = 0; i < currentpulse-1; i++){
    Serial.print(pulses[i][0] * SAMPLERATE, DEC);
    Serial.print(", ");
    Serial.print(pulses[i][1] * SAMPLERATE, DEC);
    Serial.print(", ");
  }
}
Ergänzung ()

807445
 
  • Gefällt mir
Reaktionen: new Account()
bereits während ich mir das mal ansehe stelle ich einmal die standardfragen:
was heißt denn funktioniert nicht? was produziert das programm und was hättest du stattdessen erwartet?
zweitens, die schaltung funktioniert? heißt? du hast sie ausgemessen und wenn du eine taste drückst, liegt am pin 8 GND an und ansonsten 5V?
 
  • Gefällt mir
Reaktionen: Der Jockel
Es kommt im seriellen Monitor nur die ausgabe ready to decode IR!
Eigentlich sollte das Programm ja noch die Puls Zeiten ausgeben.
Damit, dass die Schaltung
Funktioniert mein ich, das mit einem simpleren Program zu erwartende Werte im Serial Monitor angezeigt werden. Der Sensor ist sogar so empfindlich, dass er aufs IR im Tageslicht anschlägt.
 
was im code erst mal auffällt, ist, dass er wenn dann nur einmal etwas ausgeben würde, denn running wird nie wieder auf true gesetzt. aber dazu kommt es ja offenbar schon mal gar nicht..
ich muss jetzt zugeben, dass mein letztes arduino programmieren schon wieder 2 jahre her ist. aber rein analytisch stellt sich mir logischerweise nun die frage, ob die bedingung if( !(PINB & 1)) im loop denn überhaupt erfüllt wird?
kannst du das mal darauf runterbrechen? oder hast du das in dem simpleren programm schon so gehabt?
 
Ich würde das nicht sampeln, sondern mit pin change interrupts arbeiten. Sampling ist immer viel schwerer, weil du nicht driften darfst, sonst sampelst du an der falschen Stelle.

Gruß
BlackMark
 
  • Gefällt mir
Reaktionen: Der Jockel und Kanibal
Woher bekommt PINB seinen Wert? Was macht das Ding überhaupt?

807532


und bau paar Serial.print() mehr ein. Nach jedem if() um zu sehen wo du überhaupt alles reinkommst.
Weil sobald printpulses() 1x ausgeführt wird, kommst nie wieder in die while Schleife rein.
 
  • Gefällt mir
Reaktionen: Der Jockel
Hier ist noch das simple Programm:

807593



@BlackMark über Interrupts habe ich auch schon nachgedacht ist vermutlich die bessere Lösung aber sind die auch schnell genug? (Ich werde es mal testen)

Ich könnte mir auch vorstellen das der Arduino für die schleife länger als 26us braucht und dadurch das ganze Konzept hinfällig ist.
Ergänzung ()

@Simple Man Das (PINB & 1) kannst du dir wie ein schnelleres digitalRead(8) vorstellen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: new Account()
Das ist das Programm mit Interrupts, das ich mir überlegt hab. So ganz funktioniert es auch noch nicht
aber immerhin zeigt der Serial Monitor nach mehrmaligem Drücken der Fernbedienung folgendes an:

Ready to decode IR!
readi⸮Ready to decode IR!
rea⸮Ready to decode IR!
readingReady to decode IR!
rea⸮Ready to decode IR!
Ready to decode IR!
reading taken:
0, 5167, 26, 2759, 26, 187, 26, 1783, 26, 1207, 26, 1787, 26, 1783, 26, 1207, 26, 1783, 26, 1219, 26, 1211, 26, 1783, 26, 1211, 26, 1783, 26, 1783, 26, 1783, 26, 1211, 26, 1219, 26, 1207, 26, 1783, 26, 1787, 26, 1783, 26, 13039, 26, 2955, 26, 1783, 26, 1207, 26, 1783, 26, 1783, 26, 1211, 26, 1779, 26, 1219, 26, 1211, 26, 1783, 26, 1207, 26, 1783, 26, 1783, 26, 1783, 26, 1207, 26, 1219, 26, 1211, 26, 1783, 26, 1779,

C++:
#define MAXPULSE 100000
#define PERIOD 26

int diodePin = 2;

unsigned long currentMicros = 0;
volatile unsigned long previousMicros = 0;
unsigned long timing = 0;

unsigned int pulses[100][2];
unsigned short currentpulse = 0;
int highpulse = 0;

void setup() {
  pinMode(diodePin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(diodePin), counter, FALLING);
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");

}

void loop() {
  if( (micros() - previousMicros) > MAXPULSE && currentpulse != 0 ){
    printpulses();
    currentpulse = 0;
  }

  delay(1);
}

void counter() {
  currentMicros = micros();
  timing = currentMicros - previousMicros;
  previousMicros = currentMicros;

  if( timing < 30 ){
    ++highpulse;
  }

  else{
    pulses[currentpulse][0] = highpulse;
    pulses[currentpulse][1] = timing - 13;
    highpulse = 1;
    ++currentpulse;
  }

}

void printpulses() {
  Serial.println("reading taken:");
  for(short i = 0; i < currentpulse-1; i++){
    Serial.print(pulses[i][0] * PERIOD, DEC);
    Serial.print(", ");
    Serial.print(pulses[i][1], DEC);
    Serial.print(", ");
  }
}
 
Zurück
Oben