Remote IR controller for Dimplex Fan Heater

PhilHornby

Senior Member
The Dimplex Opti-myst range of Electric Stoves, such as this Oakhurst model, are a combination of a Fan Heater and a device that uses water vapour to simulate smoke & flames. The smoke simulation is very realistic, but the in-built 'thermostat' that controls the Fan Heater, is somewhat less impressive. It is effectively little more than a variable power setting, with a lot of hysteresis and needs frequent adjustment. The heater cannot be controlled by switching its Mains input, as it enters a Standby mode when first powered up, which prevents an off-the-shelf Remote Thermostat being used.

However, the heater is supplied with an IR Remote Control, that can be used to control it (after a fashion!). The Remote Control uses NEC codes and has three buttons :-
  1. 'Flame-only' - Switches on just the Flame effect, if pressed when the heater is in Standby mode. No effect if pressed in 'Heat' mode.
  2. 'Standby' - switches off the Fan Heater and the Flame effect.
  3. 'Heat' - will switch from Standby or Flame-only to Flame AND heat. Subsequent presses toggle between 1KW and 2KW heat settings.
By decoding the Remote Control, it is possible to send IR commands to the Heater to toggle the heater 'on' and 'off', while retaining the Flame effect while 'off'. When heat is required, the 'Heat' command is sent (twice, for full power). To return to flame effect, the 'Standby' command is sent, followed by 'Flame-only'. The heater contains 4x50W incandescent bulbs which are part of the Flame effect - these go off when the 'Standby' button is received, and come back on when 'Flame-only' is sent. The gap between the two commands is kept short, to avoid shortening the lives of these bulbs.

The strange IR implementation means that the commands should only be sent by an external temperature sensing device when a change of state is detected. They cannot sensibly be repeated at intervals, to counter them being missed or obstructed. In the case of the 'OFF' commands, such a strategy would be likely to shorten the life of the bulbs and the 'smoke' generator. Also, the heater emits a series of loud beeps to indicate which mode it is in, which could quickly become annoying, if repeated frequently.

A variety of temperature-sensing devices could be used, but for maximum "W.A.F.", I modified a commercial 'Horstmann' wall-mounted thermostat (which cost £2.50 in a sale bin!). The normally voltage-free Relay contacts were rewired internally, to provide either 3V or 0V depending on the State of the thermostat. The thermostat's 3V supply proved sufficient to drive the Picaxe 08M2, which simply senses the state of the relay and sends the appropriate IR commands when a change of state occurs.

The circuit was built on a Rev Ed. 08M2 prototyping board, which was cut down slightly to fit inside the thermostat case. The IR section (LED, transistor and two resistors), was sourced from an old IR Remote Control. When power is first applied to the heater, it needs to be manually set to a state that matches the controlling thermostat.

Modified commercial thermostat. (needs some Red film over the LED to complete it) IMG_4571.jpg Schematic =>Dimplex.jpg

Code follows in next post.
 
Last edited:

PhilHornby

Senior Member
RemoteControl.basinc

RemoteControl.basinc

Rich (BB code):
;     All timings assume 32MHz operation.
;
; Macros used in generating an NEC IR signal; these are common to all Remotes. They generate the component
; parts of the NEC protocol, as used by the Dimplex Optimyst Electric 'stove'.
;     
      #macro StartCarrier                                   ;Turn on the PWM function
            ;
            ; The carrier is generated using the inbuilt PWM function.
            ;
            pwmout Data_Pin, 210, 278                       ;Start PWM output @ 38000Hz at 33% @ 32MHz (from wizard)
      #endm
      #macro SendAGC
            ;
            ; Sends 9mS worth of pulses of 8uS +16uS gap. Then pause 4.5mS.
            ; (Apparently, was used to set AGC originally.)
            ;
            StartCarrier                                    ;start 38KHz carrier o/p
            pauseus 7100                                    ;wait 8.875mS (7100 /8 = 887.5 * 10 = 8.875mS)
            pwmout Data_Pin,off                             ;then shut it off - it will have been active for 9mS in total.
            
            pauseus 3400                                    ;Pause further 4.25mS (3400 /8 = 425 * 10 = 4.25mS)
                                                            ;to bring total gap to 4.5mS (including delay in starting first 'bit' o/p,
                                                            ;which follows this preamble)
      #endm

      #macro Send38KHzBurst
            ;
            ; Sends 21 pulses of 8uS +16uS gap.
            ;
            StartCarrier                                    ;start 38KHz carrier o/p
            pauseus 325                                     ;wait 406uS (325 /8 = 40.625 * 10 = 406uS)
            pwmout Data_Pin,off                             ;then shut it off - it will have been active for 560uS in total.
      #endm
      #macro SendZero
            ;
            ; "0" bit
            ;
            Send38KHzBurst                                  ;250~270uS overhead, starting & stopping pulse train
            pauseus 226                                     ;226/8 = 28.25 * 10 (283) makes total gap = 560uS 
      #endm
      
      #macro SendOne
            ;
            ; "1" bit
            ;
            Send38KHzBurst                                  ;250~270uS overhead, starting & stopping pulse train
            pauseus 1148                                    ;1148/8 = 143.5 * 10 (1435) takes gap to 1.69mS
      #endm
      
      #macro SendEndPacket
            ;
            ; Mark the end with an extra bit and a long gap.
            ;
            Send38KHzBurst                                  ;21 pulses of 38KHz carrier
            Pause 320                                       ;then gap of 40mS (* 8 for 32MHz operation)
      #endm
;     Now, the Device-specific macros...
      
;
;     Macro to define the target device of a particular Remote Control.
;
      #macro SendAddress
            SendAGC                                         ;marks start of packet
            ;
            ; Address Byte, LSB first "00000000" (This is Dimplex's choice...for reasons known only to them!)
            ;
            SendZero
            SendZero
            SendZero
            SendZero
            SendZero    
            SendZero
            SendZero
            SendZero
            ;
            ; Inverse of Address byte "11111111"
            ;
            SendOne
            SendOne
            SendOne
            SendOne
            SendOne
            SendOne
            SendOne
            SendOne
      #endm
;
;     Macro(s) to define each button on the Remote Control.
;
      #macro SendLeftButton
            ;
            ; Send Dimplex Opti-myst Remote Control "Left Button" ('Flame' = code 10)
            ;
            SendAddress
            ;
            ; Command byte, LSB first "01010000" (10)
            ;
            SendZero
            SendOne
            SendZero
            SendOne
            SendZero
            SendZero
            SendZero
            SendZero
            ;
            ; Inverse of Command byte "10101111"
            ;
            SendOne
            SendZero
            SendOne
            SendZero
            SendOne
            SendOne
            SendOne
            SendOne
            ;
            ; End of packet marker (33rd 'bit' and 110mS gap)
            ;
            SendEndPacket                                               ;terminate the data
      #endm
      
      #macro SendCentreButton
            ;
            ; Send Dimplex Opti-myst Remote Control "Centre Button" (ON/OFF = code 9)
            ;
            SendAddress
            ;
            ; Command byte, LSB first "10010000" (09)
            ;
            SendOne
            SendZero
            SendZero
            SendOne
            SendZero
            SendZero
            SendZero
            SendZero
            ;
            ; Inverse of Command byte "01101111"
            ;
            SendZero
            SendOne
            SendOne
            SendZero
            SendOne
            SendOne
            SendOne
            SendOne
            ;
            ; End of packet marker (33rd 'bit' and 110mS gap)
            ;
            SendEndPacket                                               ;terminate the data
      #endm
      #macro SendRightButton
            ;
            ; Send Dimplex Opti-myst Remote Control "Right Button" ('Heater Power' = code 11)
            ;
            SendAddress
            ;
            ; Command byte, LSB first "11010000" (11)
            ;
            SendOne
            SendOne
            SendZero
            SendOne
            SendZero
            SendZero
            SendZero
            SendZero
            ;
            ; Inverse of Command byte "00101111"
            ;
            SendZero
            SendZero
            SendOne
            SendZero
            SendOne
            SendOne
            SendOne
            SendOne
            ;
            ; End of packet marker (33rd 'bit' and 110mS gap)
            ;
            SendEndPacket                                               ;terminate the data
      #endm
      
      goto START_OF_PROGRAM
      
_SendCentreButton:
      SendCentreButton
      return
      
_SendLeftButton:
      SendLeftButton
      return
      
_SendRightButton:
      SendRightButton
      return      
      
START_OF_PROGRAM:
      
 
Last edited:

PhilHornby

Senior Member
Optimyst.bas

Optimyst.bas

Rich (BB code):
;+
;
; Author: Phillip Hornby
; Date: 6th November 2016
;
;-
#picaxe 08M2
#No_data
#No_end
#Terminal 38400
Symbol Data_Pin   = C.2                                     ;connect to IR LED, or driver transistor/mosfet
Symbol InputPin   = PinC.3                                  ;Thermostat input (VCC=DEMAND, GND=SATISFIED)
;
; 'normal' RAM
;
Symbol LastState  = b6                                      ;Last thermostat state.
Symbol BatteryVoltage = w4                                  ;used to store battery voltage
; 28 - 127 via bptr or peek/poke
;
; Other stuff
;
Symbol Demand     = 0                                       ;Pin is connected...
Symbol Satisfied  = 1                                       ;...to thermostat relay
Symbol Unknown    = 2                           
Symbol DebounceTime= 2                                      ;2 nap units = 72mS
Symbol SleepTime  = 9                                       ;9 nap units = 8S
Symbol Tickover   = K31
Symbol FullSpeed  = M32
#Rem
 
Dimplex Opti-myst (RC02-010) codes:-
LEFT (FLAME ONLY) => 0000 0000 | 1111 1111 | 0101 0000 | 1010 | 1111    (10)        ;Only effective from STANDBY - NOT HEAT.
CENTRE (STANDBY)  => 0000 0000 | 1111 1111 | 1001 0000 | 0110 | 1111    (9)         ;switches off both Power and 'Flame'. (Annoyingly!)
RIGHT (HEAT LEVEL)=> 0000 0000 | 1111 1111 | 1101 0000 | 0010 | 1111    (11)        ;toggles between 1KW and 2KW
(usually followed by one or more repeat codes - though the target hardware (a heater) ignores them.)
#Endrem
;
; Start execution
;
#Include "RemoteControl.basinc"                             ;MUST BE FIRST EXECUTABLE STATEMENT       
      Disablebod                                            ;more appropriate for low voltage use
      dirs = %00010000                                      ;Pin direction statements (not needed - implied from first usage)
      Pullup %00000010                                      ;C.1 might be a switch to GND
;
;     Get initial battery voltage reading. Code taken from "Picaxe microcontroller projects for the evil genius".
;     
      Calibadc10 BatteryVoltage
      BatteryVoltage = 52378 / BatteryVoltage
      BatteryVoltage = BatteryVoltage * 2                   ;gives an answer like 300, meaning 3.00V
      Pause 2000                                            ;Wait for serial terminal to be ready
      Setfreq FullSpeed                                     ;Required for our comms setting
      Sertxd(Cr,Lf,"Version 2.0.0, 6/11/16")                ;Just proving we're alive.    
            
      Bintoascii BatteryVoltage,b4,b3,b2,b1,b0
      sertxd (" - VCC: ",b2,".",b1,b0,"V")                  ;Battery voltage debug
      setfreq Tickover                                      ;throttle right back to save power
      
      LastState = Unknown                                   ;invalidate thermostat state
                                                            ;to force initial setup
;
;     Loop forever
;
do
      if InputPin <> LastState then 
            ;
            ; Input from thermostat has changed since last time
            ;           
            Nap DebounceTime                                ;contacts may have just changed and be bouncing...
                  if InputPin <> LastState then                   
                  ;
                  ; Input from thermostat has definitley changed - Send IR command to switch the heater state
                  ;
                  setfreq FullSpeed                         ;required by IR routines
                  Select Case InputPin
                        
                        Case Demand
                              Gosub _SendRightButton        ;Power ON (or toggle between Full and Half Power, if already ON)
                              Nap 5                         ;pause 576mS
                              Gosub _SendRightButton        ;Go at throttle up.
                        
                        Case Satisfied
                              gosub _SendCentreButton       ;Power OFF
                              Nap 6                         ;pause 1 second (in low power mode)
                              gosub _SendLeftButton         ;'Flame' only ON
                              
                  end select
                        
                  LastState = InputPin                      ;remember last input signal state (from thermostat)
            endif
      endif
;     GO TO SLEEP

      setfreq Tickover                                      ;throttle right back
      nap SleepTime                                         ;zzzzzzzzzzzz.......
;     YAWN - Time to get up ;-)
End_Loop:
loop
 
Last edited:

newplumber

Senior Member
Thats neat philHornby
how far away will your remote work?
I built one (but sadly didn't read enough in these forms ) and mine only was remote for 6 to 10 inches away lol
should sell them for people in the US that have busting scale problems
I'm sure it took some brain work to fit in nicely in the box looks cool
 

PhilHornby

Senior Member
how far away will your remote work?
I built one (but sadly didn't read enough in these forms ) and mine only was remote for 6 to 10 inches away lol
should sell them for people in the US that have busting scale problems
I'm sure it took some brain work to fit in nicely in the box looks cool
My Dimplex heater is in a holiday home, so I had to guess at the range required - and the angle of the IR beam. I didn't measure the ultimate range - but it was still working at 5 or 6m, which is far more than required in my application. Maybe I got better range, because I cheated and stole the IR section from an old TV Remote?

The cut-down 08M2 'Proto-board' just fits in the thermostat case at a 45° angle, which fortuitously sets the IR beam angle correctly. As I mentioned, these came from the 'sale bin', so I bought two; it always helps to have one to practice on. Pity I didn't buy three :)
 
Top