Engduino  3.1.0
A fun device for learning coding
Files | Classes | Macros | Functions | Variables
Driver for Engduino IR

Files

file  EngduinoIR.cpp
 
file  EngduinoIR.h
 

Classes

class  EngduinoIRClass
 

Macros

#define DEBUGG   0
 
#define IRBUFSZ   12
 
#define RAWBUFSZ   100
 
#define STATE_BLOCKED   1
 
#define STATE_IDLE   2
 
#define STATE_READING   3
 
#define STATE_STOP   4
 
#define STATE_TIMEOUT   5
 
#define GAP   5000
 
#define DELAYOFFSET   9
 
#define BITTIME   (600-DELAYOFFSET)
 
#define MARKSPACESPLIT   1500
 
#define E_TIMEOUT   -1
 
#define E_SYSERR   -2
 
#define MARK   true
 
#define SPACE   false
 

Functions

 ISR (PCINT0_vect)
 ISR2 interrupt service routine, called when a falling edge is seen on the RX line. More...
 
 ISR (TIMER3_COMPB_vect)
 ISR3 interrupt service routine, called when the timer has expired. More...
 
void TIMER3_COMPB_vect (void) __attribute__((signal))
 
void INT2_vect (void) __attribute__((signal))
 
void PCINT0_vect (void) __attribute__((signal))
 
 EngduinoIRClass::EngduinoIRClass ()
 Constructor. More...
 
void EngduinoIRClass::begin ()
 begin function - must be called before using other functions More...
 
void EngduinoIRClass::end ()
 end function - switch off the IR More...
 
void EngduinoIRClass::sendBit (bool b)
 Send a single bit. More...
 
void EngduinoIRClass::send (uint8_t b, bool startstop=true)
 Send a byte. More...
 
void EngduinoIRClass::send (uint8_t *buf, unsigned int len, bool startstop=true)
 Send a buffer of bytes. More...
 
void EngduinoIRClass::send (char *buf, unsigned int len, bool startstop=true)
 Send a buffer of bytes. More...
 
void EngduinoIRClass::sendRaw (unsigned int *buf, int len)
 Raw send function. Provide timings for mark and space pairs. More...
 
int EngduinoIRClass::recv (uint8_t *buf, uint16_t timeout=0, bool startstop=true)
 Blocking receive of an IR transmission, with optional timeout. More...
 
int EngduinoIRClass::recvRaw (uint16_t *buf, uint16_t timeout=0)
 Raw receive function - returns timings for inter-mark gaps. More...
 

Variables

EngduinoIRClass EngduinoIR = EngduinoIRClass()
 
EngduinoIRClass EngduinoIR
 

Detailed Description

This is the driver code for IR on the Engduino On v1.0 this is the Vishay TFBS4711 chip. This driver makes use of a timer to measure the length of inter-mark gaps, and an edge-triggered ISR to know where the marks are.

Because the ISR for the LEDs occupies considerable time, this can run slowly and somewhat erratically, meaning that only a rather low data rate is possible. The code distinguishes between marks and spaces based on the relative timings of them, and the threshold is hardwired in the header file.

This code makes use of timer 3, which cannot then be used for other purposes.

Function Documentation

void EngduinoIRClass::begin ( )

begin function - must be called before using other functions

This function enables the IR, sets up the receive state machine, initialises timer 3 to run at 1MHz, to give high resolution timings, and sets the interrupts for the TFBS4711 IR device. The TFBS4711 chip will drive the IR_RX line low briefly when receiving a mark, and will not generate any event whilst receiving a space. Consequently, we can only tell the difference between them by looking at the gaps between two marks; longer gaps mean more spaces.

void EngduinoIRClass::end ( )

end function - switch off the IR

Switch off both the IR chip and the ISRs.

EngduinoIRClass::EngduinoIRClass ( )

Constructor.

C++ constructor for this class. Empty.

ISR ( PCINT0_vect  )

ISR2 interrupt service routine, called when a falling edge is seen on the RX line.

Set for a falling edge on the INT2 pin - i.e. on IR_RX. Such events occur in 2.2us periods when there is a mark on the IR. The width of the pulse is unrelated to the baud rate of transmission, so we simply time the space between marks using timer 3, setting (and resetting) a timeout which, when it expires, indicates that the code has ended.

ISR ( TIMER3_COMPB_vect  )

ISR3 interrupt service routine, called when the timer has expired.

TIMER3 interrupt code - timer 3 COMPB is used as a timeout to determine when a code we are receiving has ended, or when a call to the recv function has timed out.

int EngduinoIRClass::recv ( uint8_t *  buf,
uint16_t  timeout = 0,
bool  startstop = true 
)

Blocking receive of an IR transmission, with optional timeout.

Parameters
bufThe buffer in which to place the received data
timeoutThe time to wait before returning
startstopWhether to remove start/stop bits from transmission
Returns
The length of the buffer in bytes.

Receive a message if it's there to be received. Otherwise wait for a time that depends on the timeout value: if this is zero (as it is by default), then wait forever, else set a timer. If the timer expires return a negative number (-1), else return the length of the buffer received. The timeout is considered not to have expired if, by the time the period is passed, a message has started to arrive.

The first received bit is placed in the MSB, meaning that if there is not a complete byte's worth of data, the lowest bits will be zero.

Note: Differentiating between a mark and a space is based on a hardwired test of length.

int EngduinoIRClass::recvRaw ( uint16_t *  buf,
uint16_t  timeout = 0 
)

Raw receive function - returns timings for inter-mark gaps.

Parameters
bufThe buffer in which to place the inter-mark timings
timeoutThe time to wait before returning
Returns
The length of the buffer in bytes.

Receive a message if it's there to be received. Otherwise wait for a time that depends on the timeout value: if this is zero (as it is by default), then wait forever, else set a timer. If the timer expires return a negative number (-1), else return the length of the buffer received. The timeout is considered not to have expired if, by the time the period is passed, a message has started to arrive.

On return, the buffer contains the timings, in microseconds, between pairs of marks. Again, this allows a higher-level protocol to be written in a sketch.

void EngduinoIRClass::send ( uint8_t  b,
bool  startstop = true 
)

Send a byte.

Parameters
bThe byte to send
startstopWhether to send mark bits as start/stop markers

If startstop is true, send a mark at the beginning and end of data, but between the two, send the byte, LSB first.

void EngduinoIRClass::send ( uint8_t *  buf,
unsigned int  len,
bool  startstop = true 
)

Send a buffer of bytes.

Parameters
bufThe buffer of bytes to send as a (uint8_t *)
lenLength of the buffer
startstopWhether to send mark bits as start/stop markers

If startstop is true, send a mark at the beginning and end of data, but between the two, send the individual bytes, LSB first.

void EngduinoIRClass::send ( char *  buf,
unsigned int  len,
bool  startstop = true 
)

Send a buffer of bytes.

Parameters
bufThe buffer of bytes to send as a (char *)
lenLength of the buffer
startstopWhether to send mark bits as start/stop markers

If startstop is true, send a mark at the beginning and end of data, but between the two, send the individual bytes, LSB first.

void EngduinoIRClass::sendBit ( bool  b)

Send a single bit.

Parameters
bThe boolean representing the bit to be sent.

This sends a single bit. A mark is sent as a mark signal, and a space is sent as a space followed by a mark. This encoding works well because we do not have to concern ourselves about the relative timings of runs of spaces. Instead a mark - space transition should always be a constant length, and this should be considerably longer than a mark - mark transition.

void EngduinoIRClass::sendRaw ( unsigned int *  buf,
int  len 
)

Raw send function. Provide timings for mark and space pairs.

Parameters
bufBuffer containing alternate mark/space timings in microseconds
lenLength of the buffer

The argument to this function is a buffer containing alternate mark/space timings, given in milliseconds, allowing a higher-level protocol to be written in a sketch.