NEC format bit-banged IR output using Macros and Include files.

PhilHornby

Senior Member
#1
I've recently embarked on a project to implement a remote thermostat for a Dimplex Opti-myst Electric Stove, since the built-in one is hopeless.

As user pleitch discovered, when trying to do something similar with a Dimplex Air-conditioner, control via the IR remote is the only way to go - control via the mains input just toggles between 'OFF' and 'Standby'.

Here is my code to implement the three buttons on the Dimplex RC02-010 Remote Control, which uses the NEC protocol. I've used the #Macro and #Include functionality of the V6.x.x.x Picaxe Editor to try and improve readability.

I used InglewoodPete's Background Infrared Receiver to verify the output.


This is a demo program - that just sends the 'Centre' button repeatedly.

Code:
#picaxe 08M2
;+
; NEC.BAS - Demonstrate sending NEC format IR signals, using Macro and include file 
;        functionality of Picaxe Editor V6.x.x.x.
;
; Author: Phil Hornby: 
;
;-
Symbol Data_Pin    = C.2                            ;connect to IR LED, or driver transistor/mosfet
Symbol Debug_Pin    = C.4                            ;20uS pulse to sync oscilloscope - if req'd


#rem
 


This is the o/p of this program, as decoded by 'InglewoodPete's 20X2 program:-


See: http://www.picaxeforum.co.uk/showthread.php?16576-Background-Infrared-Receiver-for-32-bit-Codes




    Start >2h-TOut- 
    Start >2h
    <End 00000000111111111001000001101111>
    [42][25]%00000000.11111111 %10010000.01101111
    $00FF 906F


    which is identical to that produced by a physical Remote Control 
    (Dimplex model: RC02-010, "Centre" ON/OFF Button)


    Start >2h-TOut- 
    Start >2h
    <End 00000000111111111001000001101111>
    [42][25]%00000000.11111111 %10010000.01101111
    $00FF 906F


Dimplex Opti-myst (RC02-010) codes:-


LEFT (Flame)    => 0000 0000 | 1111 1111 | 0101 0000 | 1010 | 1111    (10)
CENTRE (ON/OFF)    => 0000 0000 | 1111 1111 | 1001 0000 | 0110 | 1111    (9)
RIGHT (HEAT)    => 0000 0000 | 1111 1111 | 1101 0000 | 0010 | 1111    (11)


(usually followed by one or more repeat codes - though the target hardware (a heater) ignores them.)


#endrem




#No_data
#No_end


#include "RemoteControl.basinc"


;
; Start execution
;
    setfreq M32                                ;warp factor 9


    ;dirs = %00010100                            ;Pin direction statements not needed - implied from usage




;    Loop forever, sending same code.


do
    pulsout Debug_Pin,15                        ;optional pulse to sync oscilloscope.
                                        ;15 * 1.25 = 18.75uS + 2uS overhead = 20 uS 
                                        
;    SendLeftButton                            ;Send code for Left Button ('Flame')
    SendCentreButton                            ;Send code for Centre Button (ON/OFF)
;    SendRightButton                            ;Send Code for Right Button ('Heater Power')
loop
and here is where the actual work is done:-

Code:
;+
; RemoteControl.basinc - macro definitions
;
;    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.
;    
    #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 880                        ;then gap of 110mS (* 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
Attached files - RemoteControl.basinc had to be renamed to RemoteControl.bas to keep the Uploader happy...
 

Attachments

Last edited:
Top