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:
Mon Mar 25 21:50:27 2013 +0000
Revision:
6:3cce31050c90
Parent:
5:7ce37fae13ff
just added NeedfulThings lib dependency; (hopefully)

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 5:7ce37fae13ff 7 #include "TimeoutTweaked.h"
humlet 0:a3a07eb0c1dd 8
humlet 0:a3a07eb0c1dd 9 using namespace mbed;
humlet 0:a3a07eb0c1dd 10
humlet 0:a3a07eb0c1dd 11 /// Receiver interface for the fischertechnik IR control set
humlet 0:a3a07eb0c1dd 12 ///
humlet 0:a3a07eb0c1dd 13 /// 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 14 /// 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 15 /// 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 16 /// Each message delivers the complete remote control status encoded into 30 bits.
humlet 3:038f86bac6cc 17 /// The structure of the message can be seen in FtControlSetMessage.h.
humlet 3:038f86bac6cc 18 /// The protocol uses Pulse Distance Modulation (PDM) with two bits (di-bit) per pulse, hence four different
humlet 0:a3a07eb0c1dd 19 /// distances. A transmission consists of 16 pulses (15 distances) for a total of 30 bits.
humlet 1:3904ef8c606e 20 ///
humlet 1:3904ef8c606e 21 /// 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 22 /// 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 23 ///
humlet 3:038f86bac6cc 24 /// 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 25 /// 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 26 /// the last correctly received message, before it resets the message to zero after the fourth error.
humlet 4:c1517188f6ec 27 ///
humlet 4:c1517188f6ec 28 /// Some fluorescent energy saving lamp might disturb the transmision quite heavily.
humlet 3:038f86bac6cc 29
humlet 3:038f86bac6cc 30
humlet 0:a3a07eb0c1dd 31 class FtControlSetReceiver
humlet 0:a3a07eb0c1dd 32 {
humlet 0:a3a07eb0c1dd 33 InterruptIn m_pulseIRQ;
humlet 1:3904ef8c606e 34
humlet 3:038f86bac6cc 35 uint32_t m_rxBuffer; /// receive message buffer
humlet 4:c1517188f6ec 36 uint32_t m_nPulses; /// receive pulse counter (15 pulses per message)
humlet 4:c1517188f6ec 37 uint32_t m_timeOfLastEdge; /// signal edge time stamp memory
humlet 3:038f86bac6cc 38 uint8_t m_nOnes; /// number of received high bits for parity calculation
humlet 4:c1517188f6ec 39
humlet 4:c1517188f6ec 40 volatile uint32_t m_errorCount; /// counter of observed receive errors
humlet 4:c1517188f6ec 41 uint8_t m_nGracefullyIgnoredErrors; /// error counter that reset on successful message reception
humlet 1:3904ef8c606e 42
humlet 4:c1517188f6ec 43 volatile uint32_t m_lastMessage; /// last message received correctly
humlet 1:3904ef8c606e 44
humlet 4:c1517188f6ec 45 FunctionPointer m_callback; ///callback for user code that is called afetr successful message reception
humlet 1:3904ef8c606e 46
humlet 4:c1517188f6ec 47 TimeoutTweaked m_messageTimeout; /// Timeout for message reset when sender is inactive
humlet 4:c1517188f6ec 48 TimeoutTweaked m_receiveTimeout; /// receive timeout
humlet 4:c1517188f6ec 49 TimeoutTweaked m_recoverTimeout; /// error recovery timeout
humlet 4:c1517188f6ec 50
humlet 4:c1517188f6ec 51 static const uint32_t c_pulseWidthLimits[5]; /// di-bit discrimination times
humlet 3:038f86bac6cc 52 static const uint32_t c_pulseWidthDelta = 100;//101; /// di-bit discrimination pulse width delta
humlet 3:038f86bac6cc 53 static const uint32_t c_pulseWidthOffset = 795;//793; /// di-bit common pulse width base
humlet 3:038f86bac6cc 54 static const uint32_t c_maxPulseTime = c_pulseWidthOffset+7*c_pulseWidthDelta/2; /// reveive timeout
humlet 3:038f86bac6cc 55 static const uint32_t c_messageTimeout[2]; /// message timeout depends on selected sender frequency
humlet 4:c1517188f6ec 56 static const uint8_t c_errorsToBeGracefullyIgnored = 3; /// number of consecutive errors after which the message is reset
humlet 4:c1517188f6ec 57 static const uint32_t c_recoverTimeout = c_maxPulseTime; /// receiver is deactivated for this time after a receive error (IRQ burst suppression)
humlet 4:c1517188f6ec 58
humlet 3:038f86bac6cc 59 void pulseISR(); /// pulse handler
humlet 3:038f86bac6cc 60 void messageTimeoutISR(); /// message time out handler
humlet 3:038f86bac6cc 61 void recoverISR(); /// reactivates the pulse handler after recover timeout
humlet 1:3904ef8c606e 62
humlet 4:c1517188f6ec 63 void handleReceiveError();
humlet 4:c1517188f6ec 64
humlet 0:a3a07eb0c1dd 65 public:
humlet 4:c1517188f6ec 66
humlet 0:a3a07eb0c1dd 67 /// Create a receiver
humlet 1:3904ef8c606e 68 /// @parameter in: The pin the IR detector's message line is connected to
humlet 1:3904ef8c606e 69 FtControlSetReceiver(PinName in);
humlet 0:a3a07eb0c1dd 70
humlet 1:3904ef8c606e 71 /// get the last received message
humlet 3:038f86bac6cc 72 FtControlSetMessage getMessage()const {
humlet 4:c1517188f6ec 73 return FtControlSetMessage(m_lastMessage);
humlet 1:3904ef8c606e 74 };
humlet 1:3904ef8c606e 75
humlet 1:3904ef8c606e 76 /// get number of receive errors
humlet 1:3904ef8c606e 77 uint32_t getErrorCount()const {
humlet 1:3904ef8c606e 78 return m_errorCount;
humlet 1:3904ef8c606e 79 }
humlet 1:3904ef8c606e 80
humlet 1:3904ef8c606e 81 /// hook a call back into the receiver ISR e.g. for sending a RTOS message.
humlet 0:a3a07eb0c1dd 82 /// called on each update or receive error
humlet 4:c1517188f6ec 83 void setCallback(const FunctionPointer& callback) {
humlet 4:c1517188f6ec 84 m_callback=callback;
humlet 0:a3a07eb0c1dd 85 };
humlet 0:a3a07eb0c1dd 86 };
humlet 0:a3a07eb0c1dd 87
humlet 0:a3a07eb0c1dd 88
humlet 0:a3a07eb0c1dd 89 #endif
humlet 0:a3a07eb0c1dd 90
humlet 0:a3a07eb0c1dd 91
humlet 0:a3a07eb0c1dd 92
humlet 0:a3a07eb0c1dd 93
humlet 0:a3a07eb0c1dd 94
humlet 0:a3a07eb0c1dd 95
humlet 0:a3a07eb0c1dd 96