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.

Committer:
humlet
Date:
Sat Mar 23 21:51:13 2013 +0000
Revision:
4:c1517188f6ec
Parent:
3:038f86bac6cc
Child:
5:7ce37fae13ff
*made ISR user space communication vars volatile; *added tweaked Timeout; *optimized ISR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
humlet 0:a3a07eb0c1dd 1 #ifndef FTCONTROLSETRECEIVER_H
humlet 0:a3a07eb0c1dd 2 #define FTCONTROLSETRECEIVER_H
humlet 0:a3a07eb0c1dd 3
humlet 1:3904ef8c606e 4 #include "FtControlSetMessage.h"
humlet 0:a3a07eb0c1dd 5 #include "InterruptIn.h"
humlet 0:a3a07eb0c1dd 6 #include "FunctionPointer.h"
humlet 0:a3a07eb0c1dd 7 #include "Timeout.h"
humlet 0:a3a07eb0c1dd 8
humlet 0:a3a07eb0c1dd 9 using namespace mbed;
humlet 0:a3a07eb0c1dd 10
humlet 4:c1517188f6ec 11 /// Tweaked Timeout class, that publishes the protected TimerEvent methods
humlet 4:c1517188f6ec 12 /// remove and insert, which are a bit faster than detach and attach.
humlet 4:c1517188f6ec 13 struct TimeoutTweaked : public Timeout {
humlet 4:c1517188f6ec 14 /// calls protected TimerEvent::remove()that
humlet 4:c1517188f6ec 15 /// just removes the timer event from the schedule but keeps the handler attached before
humlet 4:c1517188f6ec 16 inline void remove() {
humlet 4:c1517188f6ec 17 TimerEvent::remove();
humlet 4:c1517188f6ec 18 }
humlet 4:c1517188f6ec 19 /// calls proteccted TimerEvent::insert() that inserts a new timeout event to the schedule at the given timestamp
humlet 4:c1517188f6ec 20 inline void insert(unsigned int timestamp) {
humlet 4:c1517188f6ec 21 TimerEvent::insert(timestamp);
humlet 4:c1517188f6ec 22 }
humlet 4:c1517188f6ec 23 };
humlet 4:c1517188f6ec 24
humlet 0:a3a07eb0c1dd 25 /// Receiver interface for the fischertechnik IR control set
humlet 0:a3a07eb0c1dd 26 ///
humlet 0:a3a07eb0c1dd 27 /// 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>
humlet 0:a3a07eb0c1dd 28 /// The ft IR remote control uses some kind of <A HREF="http://www.sbprojects.com/knowledge/ir/rcmm.php"> RC-MM Protocol </A>.
humlet 3:038f86bac6cc 29 /// 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.
humlet 1:3904ef8c606e 30 /// Each message delivers the complete remote control status encoded into 30 bits.
humlet 3:038f86bac6cc 31 /// The structure of the message can be seen in FtControlSetMessage.h.
humlet 3:038f86bac6cc 32 /// The protocol uses Pulse Distance Modulation (PDM) with two bits (di-bit) per pulse, hence four different
humlet 0:a3a07eb0c1dd 33 /// distances. A transmission consists of 16 pulses (15 distances) for a total of 30 bits.
humlet 1:3904ef8c606e 34 ///
humlet 1:3904ef8c606e 35 /// I assume that the ft control set works fine with standard 38kHz IR detectors. I have used a CHQ0038 from a broken DVD Player.
humlet 1:3904ef8c606e 36 /// It can be onnected directly to the mebed: GND, VCC->3.3V and the signal line to any of the numbered mbed gpios.
humlet 3:038f86bac6cc 37 ///
humlet 3:038f86bac6cc 38 /// 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
humlet 4:c1517188f6ec 39 /// 3% and 5%. This driver "ignores" up to 3 consecutive receive errors, i.e. it just indicates an error but still provides
humlet 4:c1517188f6ec 40 /// the last correctly received message, before it resets the message to zero after the fourth error.
humlet 4:c1517188f6ec 41 ///
humlet 4:c1517188f6ec 42 /// Some fluorescent energy saving lamp might disturb the transmision quite heavily.
humlet 3:038f86bac6cc 43
humlet 3:038f86bac6cc 44
humlet 0:a3a07eb0c1dd 45 class FtControlSetReceiver
humlet 0:a3a07eb0c1dd 46 {
humlet 0:a3a07eb0c1dd 47 InterruptIn m_pulseIRQ;
humlet 1:3904ef8c606e 48
humlet 3:038f86bac6cc 49 uint32_t m_rxBuffer; /// receive message buffer
humlet 4:c1517188f6ec 50 uint32_t m_nPulses; /// receive pulse counter (15 pulses per message)
humlet 4:c1517188f6ec 51 uint32_t m_timeOfLastEdge; /// signal edge time stamp memory
humlet 3:038f86bac6cc 52 uint8_t m_nOnes; /// number of received high bits for parity calculation
humlet 4:c1517188f6ec 53
humlet 4:c1517188f6ec 54 volatile uint32_t m_errorCount; /// counter of observed receive errors
humlet 4:c1517188f6ec 55 uint8_t m_nGracefullyIgnoredErrors; /// error counter that reset on successful message reception
humlet 1:3904ef8c606e 56
humlet 4:c1517188f6ec 57 volatile uint32_t m_lastMessage; /// last message received correctly
humlet 1:3904ef8c606e 58
humlet 4:c1517188f6ec 59 FunctionPointer m_callback; ///callback for user code that is called afetr successful message reception
humlet 1:3904ef8c606e 60
humlet 4:c1517188f6ec 61 TimeoutTweaked m_messageTimeout; /// Timeout for message reset when sender is inactive
humlet 4:c1517188f6ec 62 TimeoutTweaked m_receiveTimeout; /// receive timeout
humlet 4:c1517188f6ec 63 TimeoutTweaked m_recoverTimeout; /// error recovery timeout
humlet 4:c1517188f6ec 64
humlet 4:c1517188f6ec 65 static const uint32_t c_pulseWidthLimits[5]; /// di-bit discrimination times
humlet 3:038f86bac6cc 66 static const uint32_t c_pulseWidthDelta = 100;//101; /// di-bit discrimination pulse width delta
humlet 3:038f86bac6cc 67 static const uint32_t c_pulseWidthOffset = 795;//793; /// di-bit common pulse width base
humlet 3:038f86bac6cc 68 static const uint32_t c_maxPulseTime = c_pulseWidthOffset+7*c_pulseWidthDelta/2; /// reveive timeout
humlet 3:038f86bac6cc 69 static const uint32_t c_messageTimeout[2]; /// message timeout depends on selected sender frequency
humlet 4:c1517188f6ec 70 static const uint8_t c_errorsToBeGracefullyIgnored = 3; /// number of consecutive errors after which the message is reset
humlet 4:c1517188f6ec 71 static const uint32_t c_recoverTimeout = c_maxPulseTime; /// receiver is deactivated for this time after a receive error (IRQ burst suppression)
humlet 4:c1517188f6ec 72
humlet 3:038f86bac6cc 73 void pulseISR(); /// pulse handler
humlet 3:038f86bac6cc 74 void messageTimeoutISR(); /// message time out handler
humlet 3:038f86bac6cc 75 void recoverISR(); /// reactivates the pulse handler after recover timeout
humlet 1:3904ef8c606e 76
humlet 4:c1517188f6ec 77 void handleReceiveError();
humlet 4:c1517188f6ec 78
humlet 0:a3a07eb0c1dd 79 public:
humlet 4:c1517188f6ec 80
humlet 0:a3a07eb0c1dd 81 /// Create a receiver
humlet 1:3904ef8c606e 82 /// @parameter in: The pin the IR detector's message line is connected to
humlet 1:3904ef8c606e 83 FtControlSetReceiver(PinName in);
humlet 0:a3a07eb0c1dd 84
humlet 1:3904ef8c606e 85 /// get the last received message
humlet 3:038f86bac6cc 86 FtControlSetMessage getMessage()const {
humlet 4:c1517188f6ec 87 return FtControlSetMessage(m_lastMessage);
humlet 1:3904ef8c606e 88 };
humlet 1:3904ef8c606e 89
humlet 1:3904ef8c606e 90 /// get number of receive errors
humlet 1:3904ef8c606e 91 uint32_t getErrorCount()const {
humlet 1:3904ef8c606e 92 return m_errorCount;
humlet 1:3904ef8c606e 93 }
humlet 1:3904ef8c606e 94
humlet 1:3904ef8c606e 95 /// hook a call back into the receiver ISR e.g. for sending a RTOS message.
humlet 0:a3a07eb0c1dd 96 /// called on each update or receive error
humlet 4:c1517188f6ec 97 void setCallback(const FunctionPointer& callback) {
humlet 4:c1517188f6ec 98 m_callback=callback;
humlet 0:a3a07eb0c1dd 99 };
humlet 0:a3a07eb0c1dd 100 };
humlet 0:a3a07eb0c1dd 101
humlet 0:a3a07eb0c1dd 102
humlet 0:a3a07eb0c1dd 103 #endif
humlet 0:a3a07eb0c1dd 104
humlet 0:a3a07eb0c1dd 105
humlet 0:a3a07eb0c1dd 106
humlet 0:a3a07eb0c1dd 107
humlet 0:a3a07eb0c1dd 108
humlet 0:a3a07eb0c1dd 109
humlet 0:a3a07eb0c1dd 110