Diorama: Infra-red Control In progress

The infra-red control sub-system enables all the diorama‘s features to be controlled using an infra-red handset.

The sub-system does not implement those features, it simply interprets the input from an infra-red handset and passes valid commands on the diorama's main microcontroller to perform the required actions.

Requirements

  1. An infra-red receiver should be placed on the front of the diorama as unobtrusively as possible.
  2. A simple infra-red handset should be used, with as few key presses as possible being used to enter the commands.
  3. The IR sub-system should interpret and encode the commands for onward transmission to the diorama's main microcontroller.
  4. There should be some visible feedback given to the user as commands are entered. The following states need to be reported:
    1. Waiting for a command
    2. Valid command entered
    3. Further input required
    4. Erroneous command entered

Design

The infra-red control sub-system has its own microcontroller that communicates with the diorama's main microcontroller. The sub-system receives inputs from an infra-red handset, interprets those inputs as commands and forwards valid commands to the main microcontroller over I²C.

The decision to use I²C for communication with the main microcontroller was arrived at after testing both serial and I²C communications.

Commands from the handset comprise one or two keypresses. Valid commands have three parts: a command ID, a sub-command ID and some data, the meaning of which is command dependent. Commands are encoded into a pair of bytes before being transmitted to the main microcontroller. The first byte stores the command ID in its high nybble and the sub-command in its low nybble. The second byte contains the data.

Command Key(s) Command codes
1st key 2nd key Command ID Sub-command ID Data byte
Toggle given light in given section on & off 1 … 9
(Section code)
1 … 9
(Normal light code) or
#
(Flicker light code)
1 1 High nybble: 0..8 (Normal light ID) or 0xF (Flicker light ID)
Low nybble: 0..8 (Section ID)
Toggle all lights in given section on & off 1 … 9
(Section code)
0 1 2 0..8 (Section ID)
Toggle all normal lights on & off 0 * 1 3 1
Toggle all flicker lights on & off 0 # 1 3 2
Toggle all lights on & off 0 OK or 0 1 3 3
Toggle the state of a given dual state feature or activate a given single state feature * 1 … 9
(Feature code)
2 1 0..8 (Feature ID)
Reset all dual state features * 0 2 2 N/a
Switch ambient lighting on to full brightness RIGHT-ARROW 3 1 0xFF
Switch ambient lighting off LEFT-ARROW 3 1 0
Brighten ambient lighting a little UP-ARROW 3 2 1
Dim ambient lighting a little DOWN-ARROW 3 2 0xFF
Run a given program # 1 … 9
(Program code)
4 1 0..8 (Program ID)
Stop current program # 0 4 2 N/a
Master reset OK 5 N/a N/a

Notes:

  1. Section, normal light, feature and program codes that use handset keys 1 to 9 map onto an ID that is one less than the numeral on the handset key, e.g key 4 represents ID 3.
  2. Even though there are 9 available codes for the the various sections, normal lights, features and programs, the highest permitted code may be < 9, depending on the number of sections, lights, features and programs that are available. For example, there may be 6 model light sections and each section may enforce it's own limit on the number of normal lights it supports.
  3. The data byte of the command to turn all lights off is calculated by ORing together the parameters of the commands to turn off normal lights and to turn off flicker lights. I.e. 0b01 | 0b10 = 0b11 = (1 | 2) = 3.
  4. The data byte of the command to dim ambient lighting was chosen to be 0xFF because that value is -1 if the byte is signed, which implies a reduction in value.
  5. Where "N/a" appears for a sub-command ID or data byte it means that the value is not used. It is ignored and can be anything. Zero is usually used, but garbage values are equally acceptable. For example the "Master reset" command, which has neither a sub-command nor a data byte, could be encoded as, for example, 0x50 0x00 or 0x5F 0xFF.

Notice that commands fall into one of the following groups, numbered by command ID:

  1. Model Lighting Commands – 1st key press is a digit
  2. Feature Commands – 1st key press is *
  3. Ambient Lighting Commands – activated by the arrow keys
  4. Program Commands – 1st key press is #
  5. Reset Command – uses the OK key

Visual feedback to the user will be by means of an RGB LED that displays as follows:

LED Meaning
Colour State
Blue Steady System initialising. Not ready for commands.
N/a Off Awaiting the next command.
Yellow Steady Awaiting a further key press to complete the current command.
Yellow Four quick blinks Timed out waiting for a key press to complete the current command.
Green Single long blink A command was entered correctly.
Red Four quick blinks Erroneous command.
Blue Single short blink Input acknowledgement. The input is well formed, but may or may not be valid.

A regulated 5V supply and ground connection will be required from the diorama’s power supply.

Progress

Circuit

The following circuit was designed:

IR control sub-system circuit design

The circuit is sub-divided into two modules – the Sensor Module and the Control Module. Each is discussed in its own section below.

Sensor Module

This module contains the infra-red sensor and the RGB feedback LED.

The values of the current limiting resistors for the RGB LED were chosen to get the best colour balance from the LED. The resistances were arrived at by experiment. The LED is powered directly from the Nano's digital pins because the LED's power consumption is within the Nano's tolerances.

An infra red sensor and remote controller were obtained, packaged together. The handset uses the common NEC protocol.

A small plastic case, recovered from a defunct power supply, was adapted to house the module. The front of the diorama was modified to accomodate the housing such that it can been removed for repair if necessary.

The following is a photo of two parts of the sensor module as built on perfboard, almost ready for adding to the housing. The upper component is the IR receiver itself and the lower component is the RGB feedback LED, with attached resistors. The six wires on the left of the picture were threaded through a hole in the back of the case. The black wire attached to the IR receiver board, which is a ground connection, was later soldered to the LED board.

IR control receiver module circuit as built

This second photo shows the housing with the components installed and held in place with hot glue. The runners on the case were made from coffee stirrers. They slide into a slot on the front of the diorama baseboard.

IR control receiver module in case

The wires emerging from the back of the housing were connected to choc blocks mounted under the diorama baseboard:

IR control receiver module connections under the diorama baseboard

Control Module

This module contains the microcontroller and some supporting circuitry for I²C.

An Arduino Nano R3 clone is being used as the microcontroller.

Note: it was originally hoped to use an ATtiny85 microcontroller, but problems getting a suitable IR receiver library to work meant that this plan was abandoned. No such problems were found when using the Nano.

The module was constructed on a piece of perfboard. Both sides of the board, as built, can be seen in the following photo montage:

IR control module as built on perfboard

A pair of 90° header pins were used to receive 5V and GND from the diorama power supply. Three blue two pin screw connectors were used for connections to the sensor module, one connector to supply 5V and ground and the other two for connections to the RGB LED and the infra-red sensor. Wires from these connectors will be run to the choc block under the baseboard described in the previous section. An additional two pin screw connector was provided for the I²C connection to the main microcontroller.

Software

A program to run on the microcontroller has been designed and implemented. This program is available from the cahamo/diorama project on GitHub. It can be found in the /src/ir-control/src directory. The main file is ir-control.cpp.

The IRRemote library was chosen to interpret commands from the handset.

The program interprets the commands from the remote handset and maps valid input into the 2 byte data packets that are sent out over I²C to the main microcontroller. The required user feedback is provided by manipulating the RGB LED.

The interpretation of the handset commands, the conversion to data packets and the operation of the RGB LED are all as described in the Design section above. The software also has knowledge of the number of sections, lights per section, features and programs that are available and rejects any otherwise valid inputs that fall outside those parameters.

The program was developed in VSCode using the PlatformIO extension. Compiling from within VSCode will resolve all library dependencies automatically.

Testing

Sensor Module

The sensor module was tested by being connected to an Arduino Nano clone that was running an early version of the Nano's software:

IR sensor module being tested

This version of the software had I²C output disabled, but could be used to test the input from the infra-red sensor and could control the RGB LED. The software was modified until the non-I²C part was working satisfactorily. A version of the software used for testing the sensor module can be viewed in ir-control.cpp as it was at commit e62f361 of the software.

Control Module

The control module part of the circuit was tested on a breadboard prior to being constructed. The already completed sensor module was connected to the breadboard via a choc block. An Arduino Uno clone was connected to the Nano via I²C. The following photo shows the lash-up.

IR control receiver module being tested on a breadboard

The Uno was running a test program that interpreted the data being sent from the Nano over I²C and outputting a description of the received data to its serial port. The test program is available from the cahamo/diorama project on GitHub. It can be found in the /research/ir-control-tests/mock-i2c-command-receiver/src directory. The source file is mock-i2c-command-receiver.cpp as it was at commit 7e801f6.

Once the circuit had been validated it was constructed as described above.

The completed control unit circuit board was then connected to the sensor unit and the I²C output was connected once again to the Uno, now running an updated version of mock-i2c-command-receiver.cpp. This lash up (see photo below) was used to further develop the Nano software, until the controller was working according to specifications. The result was the software described above.

IR subsystem software test rig

Back to diorama home page