-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: IR-sender und empfänger, probleme mit dem empfang

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    70
    Beiträge
    1.344

    IR-sender und empfänger, probleme mit dem empfang

    Anzeige

    hallo allerseits,

    ich bastle immer noch an meiner IR-bake 2.0...

    im netz habe ich zwei interessante sketche gefunden.
    sender:

    den code habe ich wegen einer zusätzlichen grünen LED (die nur mitblinkt) ein bischen modifiziert:

    Code:
    // Damit die Pins schnell geschaltet werden können
    #include <digitalWriteFast.h>
    
    // Hier ist der Verstärker mit der IR-LED angeschlossen
    #define IRLED 8
    #define LEDpin 9
    
    // Globale Variablen für den Timer-Interrupt
    volatile uint8_t pinZustand = HIGH;
    volatile uint8_t sendenAn = false;
    
    
    
    /*************************************************************
     * 
     * void setup()
     *
     * Wird einmal beim Programmstart ausgeführt
     *
     *************************************************************/
    void setup() 
    {
    
      pinMode(8, OUTPUT);
      // IRLED ist ein Ausgabe-Pin
      pinModeFast(IRLED, OUTPUT);
    
      pinMode(9, OUTPUT);
    
      noInterrupts(); // Jetzt keine Interrupts
      TIMSK1 |= (1<<OCIE1A);  // Timer 1 Output Compare A Match Interrupt Enable
    
      TCCR1A = 0; // "Normaler" Modus
    
      // WGM12: CTC-Modus einschalten (Clear Timer on Compare match) 
      //        Stimmen OCR1A und Timer überein, wird der Interrupt
      //        ausgelöst
      // Bit CS12 und CS10 setzen = Vorteiler: 8
      TCCR1B = (1<<WGM12) | (1<<CS11);
    
      // Frequenz = 16000000 / 8 / 28 = rd. 71,428kHz, da jeweils an- und aus-
      // geschaltet wird, ergeben sich rund 36kHz Blinkfrequenz
      OCR1A = 28; 
    
      interrupts(); // Interrupts wieder erlauben
    }
    
    
    
    /*************************************************************
     *
     * Interrupt Service Routine
     *
     * Wird aufgerufen, wenn der entsprechende Interrupt
     * ausgelöst wird
     *
     *************************************************************/
    ISR(TIMER1_COMPA_vect) 
    {
      noInterrupts();
      if(! sendenAn) 
      {
        // IR-LED ausschalten
        digitalWriteFast(IRLED, LOW);
        // Zustand der IR-LED merken
        pinZustand = LOW;
        interrupts();
        return;
      } 
      else 
      {
        // IR-LED-Pin auf pinZustand schalten
        digitalWriteFast(IRLED, pinZustand);
        // pinZustand invertieren
        pinZustand = (pinZustand == HIGH) ? LOW : HIGH;
      }
      interrupts();
    }
    
    
    
    /*************************************************************
     *
     * void loop()
     *
     * Wird immer wieder durchlaufen
     *
     *************************************************************/
    void loop() 
    {
    
      // Sender für 5ms ausschalten  
      sendenAn = false;
      delay(5);
      //digitalWrite(9, LOW);
    
      // Das komplette Alphabet in Großbuchstaben senden
      //for(int i='A'; i<='Z'; i++) 
      for(int i=1; i<=9; i++) 
      {
        sendIR(i);
        digitalWrite(8, LOW);
        digitalWrite(9, LOW);
        delay(250); // Kann entfallen, hier nur, damit man auf
        // dem Empfänger Zeit hat, die Buchstaben
        // zu verfolgen
        digitalWrite(8, HIGH);
        digitalWrite(9, HIGH);
      }
      //digitalWrite(9, HIGH);
    }
    
    
    
    /*************************************************************
     *
     * void sendIR(uint8_t dataByte)
     *
     * Sendet ein Byte seriell mit 1200bps über die IR-LED
     *
     * dataByte = Das Byte, das gesendet wird
     *
     *************************************************************/
    void sendIR(uint8_t dataByte) 
    {
    
      // Start-Bit
      sendenAn = false;
      delayMicroseconds(550);
      sendenAn = true;
      delayMicroseconds(230);
    
      // 8 Datenbits
      for(int i=0; i<8; i++) 
      {
        // Falls LSB gesetzt...
        if(dataByte & B00000001 == 1) 
        {
          // ... 36kHz-Signal aus (Seriell = Invertierte Logik)...
          sendenAn = false;
          delayMicroseconds(550);
        } 
        else 
        { // ... andernfalls 36kHz-Signal an
          sendenAn = true;
          delayMicroseconds(230);
        }
        // Das nächste Bit bitte 
        dataByte >>= 1;
      }
    
      // Stopp-Bit
      sendenAn = true;
      delayMicroseconds(550);
      sendenAn = false;
    
      // kurze Pause
      delay(2);
    }

    der sender funktioniert was die signalübertragung betrifft, das konnte ich mit dem RP6 verifizieren, es wird dort aber nur mit einer blinkenden LED signalisiert signal ja oder nein...

    empfänger
    :
    der OUT-pin des TSOP 34836 ist am pin RX0 eines mega 2560 angeschlossen, die ansteuerung der LCD anzeige habe ich so modifiziert, wie sie in anderen sketches schon mal funktioniert hat. Am LCD erscheint nach dem einschalten "TSOP-Empfang" , sonst passiert aber nichts...

    Code:
    // Includes für das Display
    #include <Wire.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h> 
    
    // 7-Bit Adresse des Displays
    // #define I2C_ADDR    0x27 >> 1 // I2C-Addresse
    
    // Die Pin-Belegung des Displays
    #define BACKLIGHT_PIN  7
    #define En_pin  6
    #define Rw_pin  5
    #define Rs_pin  4
    #define D4_pin  0
    #define D5_pin  1
    #define D6_pin  2
    #define D7_pin  3
    
    #define  LED_OFF  1
    #define  LED_ON  0
    
    // Prototypen
    //LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
    
    
    
    //#define BACKLIGHT_PIN  7
    //#define  LED_OFF  1
    //#define  LED_ON  0
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
    
    
    /********************************************************************
     *
     * Nötige Initialisierungen
     *
     ********************************************************************/
    void setup()
    {
      lcd.begin (16,2);  // Display initialisieren
    
      // Hintergrundbeleuchtung einschalten
      lcd.setBacklightPin(BACKLIGHT_PIN,NEGATIVE);
      lcd.setBacklight(LED_ON);  
    
      // Display bereit machen
      lcd.clear();
      lcd.home();  
      lcd.backlight();    // Beleuchtung einschalten
      lcd.setCursor(0,0); // Zeichen 1, Zeile 1
      lcd.print("TSOP-Empfang");   
      lcd.setCursor(0,1); // Zeichen 1, Zeile 2
    
      Serial.begin(1200);
    }
    
    
    
    /********************************************************************
     *
     * Hauptschleife, wird immer wieder durchlaufen
     *
     ********************************************************************/
    void loop()
    {
      int counter = 0;
      char dataEin = 0;
    
    
      while(true) 
      {
        if(Serial.available() > 0) 
        {
          dataEin = Serial.read();
          lcd.print(dataEin);
    
          // Nach 16 Zeichen Cursor wieder nach vorne
          counter++;
          if(counter >= 16) 
          {
          //  lcd.clear();
            counter = 0;
            lcd.setCursor(0,1);
          }
        }
      }
    }

    der empfang am RP6 ist schon mal ein zeichen dafür, dass der sender funktioniert, ich weiss aber nicht, wo ich im code des empfängers was verändern könnte damit sich auf dem LCD auch was tut

    Könnte bitte jemand drüberschauen und mir einen schubs geben - von wegen der suchrichtung?
    gruß inka

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    49
    Beiträge
    1.245
    Hm. Find da so auf die Schnelle keinen Fehler aber: hast du mal ne andere Schnittstelle versucht?
    Wenn der MEGA am Rechner hängt, belegt der die serielle 0, wenn ich mich recht entsinne!
    Da du nen MEGA hast, kannst du ja easy mal ne andere benutzen.
    Einfach mal auf die Serial1 umstöpseln und serial1.begin(1200);

    Auch kannst du mal, bei deinem jetztigen Aufbau, versuchen, irgendein Zeichen über die serielle Konsole zu schicken, würd mich jetzt nicht wundern, wenn das direkt auf dem Display erscheinen würd...falls das passiert, weisst du Bescheid.
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    70
    Beiträge
    1.344
    hi Rabenauge,
    danke für den tipp mit der seriellen schnittstelle, jetzt kommen am empfänger auch zeichen an, statt des (gedacht) gesendeten alphabets allerdings solche:

    Klicke auf die Grafik für eine größere Ansicht

Name:	2015_06_28_display_wirre_zeichen_gesendet-1.jpg
Hits:	14
Größe:	58,6 KB
ID:	30372
    empfänger oder senderproblem?
    gruß inka

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    13.01.2014
    Beiträge
    398
    Blog-Einträge
    3
    Serial.begin(1200); -ungewöhnlich niedriger Wert...
    Hast du im Arduino-Monitor den Wert auf 1200 Baud geändert, bevor du Zeichen sendest?

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    49
    Beiträge
    1.245
    Er sendet nicht auf den "Monitor", sondern direkt zum Display.

    Hm, kann mehrere Ursachen haben nun: falscher Zeichensatz? Eventuell (die billgen Displays haben nen fest verbauten Zeichensatz, da kann man gewöhnlich nur acht eigene definieren) brauchst du ne Art Übersetzungstabelle.
    Auch denkbar: einfach das falsche Format, also binär/hex oder sowas....
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.555
    Zitat Zitat von inka Beitrag anzeigen
    ... jetzt kommen am empfänger auch zeichen an, statt des (gedacht) gesendeten alphabets allerdings solche ...
    Hmm, ich verwende HD44780 und KS0066 kompatible LCDs. Beide haben diese Zeichen nicht fest eingebaut. Ich jedenfalls müsste mir für meine Displays die Zeichen ± und den senkrechten Doppelstrich selbst basteln und =>>> erstmal in den lokalen Speicher laden ! !

    Schau doch mal ins Datenblatt von Deinem LCD und vergleiche den Code der gesendeten Zeichen mit dem der angezeigten Zeichen. Vielleicht sieht man darin einen Unterschied, mit dem man näher an den Fehler kommt . . .
    Ciao sagt der JoeamBerg

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hi inka,
    noch ne Idee:
    Der Sender Code geht ja von einer nicht invertierendenTreiberschaltung mit NPN Transistor aus.
    Was hast du als Treiber für die Sende-LED?
    Gruß
    Dirk

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    70
    Beiträge
    1.344
    @Dirk,
    Zitat Zitat von Dirk Beitrag anzeigen
    Was hast du als Treiber für die Sende-LED?
    den 2N2222...

    ich habe jetzt diesbezüglich noch einen test gemacht. Nach diesem schaltplan (im bild selbst links)
    Klicke auf die Grafik für eine größere Ansicht

Name:	Schaltplan_2-stufiger-IR-sender_und_empfänger.jpg
Hits:	15
Größe:	33,1 KB
ID:	30400


    einen zweiten 2N2222 hinzugefügt. Nach dem was ich irgendwo gelesen habe sollte der zweiter transistor die invertierung wieder umkehren. Stimmt das?

    Der Q2 verändert nichts an den "wirren" zeichen auf dem arduino LCD, verringert die leistung und die reichweite der schaltung aber erheblich. Das könnte aber auch die nicht angepasste ansteuerung des Q2 verursacht haben...

    @rabenauge:
    an den anderen möglichkeiten bin ich dran. Die veränderung der loop-schleife des senders (habe das senden der zeichen auskommentiert)

    Code:
    void loop() 
    
    {
      sendenAn = false;
      delayMicroseconds(550);
      sendenAn = true;
      delayMicroseconds(2330);
      sendenAn = false;
      /*
       for(int i=1; i<=16; i++)
       {
      sendIR(i);
       }
       */
      //delay(500);
      digitalWrite(IRLED, LOW);
      digitalWrite(LEDpin, LOW);
      delay(500); // blinkfrequenz
      Serial1.print(1, DEC);
      digitalWrite(IRLED, HIGH);
      digitalWrite(LEDpin, HIGH);
    
    }
    bewirkt, das auf dem LCD nun beim jedem durchlauf der schleife zwei senkrechte striche "||" ausgegeben werden. Jetzt muss ich "nur noch" rausfinden warum das so ist...

    einerseits ist für das weitermachen das problem der reichweite gelöst, der kontakt zum RP6 funktioniert auch, alleine für die später geplante kommunikation zwischen den beiden per IR ist das bis jetzt erreichte nicht ausreichend...
    gruß inka

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hi inka,

    in dem Schaltplan erfolgt die Ansteuerung invertierend (Port HIGH, LED OFF). Der von dir verwendete Sender-Code geht von einem nicht invertierenden Treiber (Port HIGH, LED ON) aus.
    Optionen: Treiber ändern ODER Sender-Code ändern.

    Nebenbei: Die rechts abgebildete Empfängerschaltung (die du hoffentlich nicht verwendest!) dürfte einen dauerhaften LOW-Pegel ausgeben (Rx mit GND verbunden).
    Gruß
    Dirk

  10. #10
    Erfahrener Benutzer Roboter Genie Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    70
    Beiträge
    1.344
    Hi Dirk,
    Zitat Zitat von Dirk Beitrag anzeigen
    Nebenbei: Die rechts abgebildete Empfängerschaltung (die du hoffentlich nicht verwendest!) dürfte einen dauerhaften LOW-Pegel ausgeben (Rx mit GND verbunden).
    nein, den empfänger habe ich nicht verwendet, ich verwende den TSOP (angeschlossen an den drei anschlüssen) ohne zusätzliche bauteile...


    Zitat Zitat von Dirk Beitrag anzeigen
    in dem Schaltplan erfolgt die Ansteuerung invertierend (Port HIGH, LED OFF). Der von dir verwendete Sender-Code geht von einem nicht invertierenden Treiber (Port HIGH, LED ON) aus. Optionen: Treiber ändern ODER Sender-Code ändern.
    hier wäre noch die frage ob die invertierung des signals durch eine zweite transistorstufe wieder rückgängig gemacht werden kann, aber das großgeschriebene ODER suggeriert, dass die softwareänderun die einfachere lösung und daher vorzuziehen ist. Also habe ich mir viel zeit genommen und ausgiebig experimentiert , allerdings ohne den durchschlagenden erfolg:


    hier habe ich den anfangszustand der globalen variablen wahlweise geändert:
    Code:
    // Globale Variablen für den Timer-Interrupt
    volatile uint8_t pinZustand = HIGH;
    volatile uint8_t sendenAn = false;
    hier sehe ich keine möglichkeit für änderungen, es dreht sich alles mehr oder weniger nur um die einstellungen für die 36khz:
    (oder sollte der interrupt ausgelöst werden wenn " Stimmen OCR1A und Timer NICHT überein, wird der Interrupt ausgelöst"?)
    Code:
    void setup() 
    {
    
      pinMode(8, OUTPUT);
      // IRLED ist ein Ausgabe-Pin
      pinModeFast(IRLED, OUTPUT);
    
      pinMode(9, OUTPUT);
    
      noInterrupts(); // Jetzt keine Interrupts
      TIMSK1 |= (1<<OCIE1A);  // Timer 1 Output Compare A Match Interrupt Enable
    
      TCCR1A = 0; // "Normaler" Modus
    
      // WGM12: CTC-Modus einschalten (Clear Timer on Compare match) 
      //        Stimmen OCR1A und Timer überein, wird der Interrupt
      //        ausgelöst
      // Bit CS12 und CS10 setzen = Vorteiler: 8
      TCCR1B = (1<<WGM12) | (1<<CS11);
    
      // Frequenz = 16000000 / 8 / 28 = rd. 71,428kHz, da jeweils an- und aus-
      // geschaltet wird, ergeben sich rund 36kHz Blinkfrequenz
      OCR1A = 28; 
    
      interrupts(); // Interrupts wieder erlauben
    }
    hier habe ich die invertierung des pinzustandes wahlweise zwischen if und else geändert, bzw abgefragt ob gesendet wird "if(sendenAn)":
    Code:
    ISR(TIMER1_COMPA_vect) 
    {
      noInterrupts();
      if(! sendenAn) // = if(sendenAn==false)
      {
        // IR-LED ausschalten
        digitalWriteFast(IRLED, LOW);
        // Zustand der IR-LED merken
        pinZustand = LOW;
        interrupts();
        return;
      } 
      else 
      {
        // IR-LED-Pin auf pinZustand schalten
        digitalWriteFast(IRLED, pinZustand);
        // pinZustand invertieren
        pinZustand = (pinZustand == HIGH) ? LOW : HIGH;
      }
      interrupts();
    }
    hier in der hauptschleife sehe ich keine sinnvolle änderungsmöglichkeit:
    Code:
    void loop() 
    {
    
      // Sender für 5ms ausschalten  
      sendenAn = false;
      delay(5);
      //digitalWrite(9, LOW);
    
      // Das komplette Alphabet in Großbuchstaben senden
      for(int i='A'; i<='Z'; i++) 
      //for(int i=1; i<=9; i++) 
      {
        sendIR(i);
        digitalWrite(8, LOW);
        digitalWrite(9, LOW);
        delay(250); // Kann entfallen, hier nur, damit man auf
        // dem Empfänger Zeit hat, die Buchstaben
        // zu verfolgen
        digitalWrite(8, HIGH);
        digitalWrite(9, HIGH);
      }
      //digitalWrite(9, HIGH);
    }
    in dieser sendefunktion könnte man die an- bzw. abschaltung des 36khz signals umkehren zwischen der if und else abfrage:
    Code:
    void sendIR(uint8_t dataByte) 
    {
    
      // Start-Bit
      sendenAn = false;
      delayMicroseconds(550);
      sendenAn = true;
      delayMicroseconds(230);
    
      // 8 Datenbits
      for(int i=0; i<8; i++) 
      {
        // Falls LSB gesetzt...
        if(dataByte & B00000001 == 1) 
        {
          // ... 36kHz-Signal aus (Seriell = Invertierte Logik)...
          sendenAn = false;
          delayMicroseconds(550);
        } 
        else 
        { // ... andernfalls 36kHz-Signal an
          sendenAn = true;
          delayMicroseconds(230);
        }
        // Das nächste Bit bitte 
        dataByte >>= 1;
      }
    
      // Stopp-Bit
      sendenAn = true;
      delayMicroseconds(550);
      sendenAn = false;
    
      // kurze Pause
      delay(2);
    }
    ---------------------------------------

    wie bereits oben geschrieben habe ich die verschidensten änderungen (und ihre kombinationen) mit gar keinen bzw. negativen konsequenzen ausprobiert, die einzige "positive" verhaltensänderung war die, dass die IR-LED sendet, blinkt und die "||" zeichen sendet...

    bin also wieder mit meinem latein am ende...
    gruß inka

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. DB Pitch: Bahn modernisiert sich mit Sensor-, Lampen- und AR-Startups
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 25.06.2015, 11:10
  2. Suche Sender und Empfänger
    Von Daniong im Forum Kaufen, Verkaufen, Tauschen, Suchen
    Antworten: 0
    Letzter Beitrag: 16.10.2012, 20:48
  3. IR-Sender und Empfänger
    Von volvo im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 16.02.2010, 14:30
  4. RMF 01 und RMF 02 Sender + Empfänger
    Von baubau im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 27
    Letzter Beitrag: 08.04.2009, 14:00
  5. DMX-Empfänger/Sender
    Von guenter1604 im Forum Vorstellungen+Bilder von fertigen Projekten/Bots
    Antworten: 0
    Letzter Beitrag: 13.01.2009, 21:55

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •