Receiver interface for the fischertechnik IR control set

Dependencies:   NeedfulThings

Receiver interface for the fischertechnik IR control set.

An mbed port of the code found on this ft community WIKI page The ft IR remote control uses some kind of RC-MM Protocol . When any of the controls is applied the remote control sends updates at a rate of at 1/120ms or 1/90ms depending on the senders frequency setting. Each message delivers the complete remote control status encoded into 30 bits. The structure of the message can be seen in FtControlSetMessage.h.

I assume that the ft control set works fine with standard 38kHz IR detectors. I have used a CHQ0038 from a broken DVD Player. It can be connected directly to the mbed: GND, VCC->3.3V and the signal line to any of the numbered mbed gpios.

The PDM timing of the ft IR control set isn't that exact. Thus receive errors occur quite frequently. I am observing an error rate somewhere between 3% and 5%. This driver "ignores" up to 3 consecutive receive errors, i.e. it just indicates an error but still provides the last correctly received message, before it resets the message to zero after the fourth error.

Revision:
1:3904ef8c606e
Parent:
0:a3a07eb0c1dd
Child:
2:1ae8bb468515
--- a/FtControlSetReceiver.h	Sat Mar 16 23:48:57 2013 +0000
+++ b/FtControlSetReceiver.h	Sun Mar 17 22:15:41 2013 +0000
@@ -1,7 +1,7 @@
 #ifndef FTCONTROLSETRECEIVER_H
 #define FTCONTROLSETRECEIVER_H
 
-#include "FtControlSetSignal.h"
+#include "FtControlSetMessage.h"
 #include "InterruptIn.h"
 #include "FunctionPointer.h"
 #include "Timeout.h"
@@ -13,62 +13,76 @@
 /// An mbed port of the code found on this <A HREF="http://www.ftcommunity.de/wiki.php?action=show&topic_id=36">ft community WIKI page</a>
 /// The ft IR remote control uses some kind of <A HREF="http://www.sbprojects.com/knowledge/ir/rcmm.php"> RC-MM Protocol </A>.
 /// When any of the controls is applied the remote control sends updates at a rate of 1/90ms~12Hz.
-/// Each signal delivers the complete remote control status encoded into 30 bits. 
-/// The structure of the signal is can be seen in FtControlSetSignal.h.
+/// Each message delivers the complete remote control status encoded into 30 bits.
+/// The structure of the message is can be seen in FtControlSetMessage.h.
 /// The protocol uses Pulse Distance Modulation (PDM) with two bits (dibit) per pulse, hence four different
 /// distances. A transmission consists of 16 pulses (15 distances) for a total of 30 bits.
-/// 
-/// The control set works fine with standard 38kHz IR detectors. I have used a CHQ0038 from  broken DVD Player.
-/// It can be onnected directly to the mebed: GND, VCC->3.3V and the signal line to any of the numbered mbed gpios. 
+///
+/// I assume that the ft control set works fine with standard 38kHz IR detectors. I have used a CHQ0038 from a broken DVD Player.
+/// It can be onnected directly to the mebed: GND, VCC->3.3V and the signal line to any of the numbered mbed gpios.
 class FtControlSetReceiver
 {
     InterruptIn m_pulseIRQ;
-    Timeout m_timeOutTimer;
-    
-    uint32_t m_timeOut;
+
     uint32_t m_rxBuffer;
-    FtControlSetSignal m_lastSignal;
     uint32_t m_nPulses;
     uint32_t m_timeOfLastEdge;
-    uint8_t m_nOnes;
+    uint8_t  m_nOnes;
+    uint32_t m_errorCount;
+
+    FtControlSetMessage m_lastMessage;
+
+    FunctionPointer m_callBack;
+
+    Timeout m_messageTimeout;
+    Timeout m_receiveTimeout;
     
-    FunctionPointer m_callBack;
-    
+    static const uint32_t c_pulseLengthLimits[5];
+    static const uint32_t c_pulseLengthDelta = 99;//101;
+    static const uint32_t c_pulseLengthOffset = 797;//793;
+    static const uint32_t c_maxPulseTime = c_pulseLengthOffset+7*c_pulseLengthDelta/2;
+    static const uint32_t c_messageTimeout[2];
+
     void pulseISR();
-    void timeOutISR();
-    inline void reset();
+    void messageTimeoutISR();
+    void recoverISR();
+
+    void messageReceived();
+    void handleReceiveError();
     
-    static const uint32_t c_pulseLeghthDelta = 100;
-    static const uint32_t c_pulseLengthOffset = 795-c_pulseLeghthDelta/2;
-   
+    void DBGrising();
+
 public:
-    
+
     uint32_t dbg1;
     uint32_t dbg2;
     uint32_t dbg3;
     uint32_t dbg4;
-    
-    
+    uint16_t DBGhist[800];
+    uint16_t DBGhist2[800];
+    uint32_t DBGtime;
+
     /// Create a receiver
-    /// @parameter in: The pin the IR detector's signal line is connected to
-    /// @parameter tmOut: After this time [µs] of inactivity the data is reset. A value of zero deactivates the timeout.
-    FtControlSetReceiver(PinName in, uint32_t timeOut=120000);
-    
-    /// get the last received signal 
-    FtControlSetSignal getLastSignal()const{return m_lastSignal;};
+    /// @parameter in: The pin the IR detector's message line is connected to
+    FtControlSetReceiver(PinName in);
 
-    /// hook a call back into the receiver ISR e.g. for sending a RTOS signal.
+    /// get the last received message
+    FtControlSetMessage getLastMessage()const {
+        return m_lastMessage;
+    };
+
+    /// get number of receive errors
+    uint32_t getErrorCount()const {
+        return m_errorCount;
+    }
+
+    /// hook a call back into the receiver ISR e.g. for sending a RTOS message.
     /// called on each update or receive error
     void setCallBack(const FunctionPointer& callBack) {
         m_callBack=callBack;
     };
 };
 
-void FtControlSetReceiver::reset(){
-    m_nPulses=0;
-    m_rxBuffer=0;
-    m_nOnes=0;
-}
 
 #endif