News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

RC5 Infrared Transmitter

Started by top204, Jul 28, 2022, 02:17 PM

Previous topic - Next topic

top204

For RC5 Infrared transmissions, the code listing below can be used:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' RC5 Infrared Transmitter
' The program uses the CCP1 peripheral to produce the 38 KHz modulation
'
' Written for the Positron8 compiler by Les Johnson
'
    Device = 18F25K20                               ' Tell the compiler what device to compile for
    Declare Xtal = 16                               ' Tell the compiler what frequency the device will be operating at

    Declare CCP1_Pin = PORTC.2                      ' Tell the compiler what pin is used for the CCP1 peripheral

    Symbol TX_Pin = PORTC.2                         ' The CCP1 peripheral's pin to use for the IR LED
'
' Create some variables
'
    Dim RC5_bSystem  As Byte                        ' Holds the system value
    Dim RC5_bCommand As Byte                        ' Holds the command value
    Dim RC5_tToggle  As Bit                         ' Holds the toggle bit

'-------------------------------------------------------------------------------------------------------
' The main program starts here
' Transmit the system and command values using the RC5 infrared protocol
'
Main:
    Setup()                                         ' Setup the program

    RC5_bSystem = 0b00001111                        ' Load the system value to send
    RC5_bCommand = 0b00000001                       ' Load the command value to send
    Do                                              ' Create a loop
        RC5_TX(RC5_bSystem, RC5_bCommand)           ' Send the values from the TX_Pin, via an IR LED
        Inc RC5_bCommand                            ' Increment the command value
        DelayMS 500                                 ' Create a delay between transmissions
    Loop                                            ' Do it forever

'------------------------------------------------------------------------------
' Transmit the Toggle, System, and Command values as RC5 code
' Input     : pSystem (RC5_bSystem) holds the system value
'           : pCommand (RC5_bCommand) holds the command value
' Output    : None
' Notes     : None
'
Proc RC5_TX(pSystem As RC5_bSystem, pCommand As RC5_bCommand)
    Dim bBitIndex As Byte
       
    RC5_tToggle = ~RC5_tToggle                  ' Load the Toggle bit
    RC5_SendOne()                               ' Send the first Start bit
    RC5_SendOne()                               ' Send the second Start bit
'
' Send the toggle bit
'
    If RC5_tToggle = 0 Then                     ' Is the toggle bit clear?
        RC5_SendZero()                          ' Yes. So send a logic zero pulse
    Else                                        ' Otherwise... The bit is set   
        RC5_SendOne()                           ' So. Send a logic one pulse
    EndIf
'
' Send the 5-bit System value, MSB first
'
    For bBitIndex = 4 DownTo 0                  ' Create a loop for the 5 system bits 
        If GetBit(pSystem, bBitIndex) = 0 Then  ' Is the bit to send clear?
            RC5_SendZero()                      ' Yes. So send a logic zero pulse
        Else                                    ' Otherwise... The bit is set
            RC5_SendOne()                       ' So. Send a logic one pulse
        EndIf
    Next
'
' Send the 6-bit Command value, MSB first
'
    For bBitIndex = 5 DownTo 0                  ' Create a loop for the 6 command bits   
        If GetBit(pCommand, bBitIndex) = 0 Then ' Is the bit to send clear?
            RC5_SendZero()                      ' Yes. So send a logic zero pulse
        Else                                    ' Otherwise... The bit is set
            RC5_SendOne()                       ' So. Send a logic one pulse
        EndIf
    Next
    PinInput TX_Pin                             ' Make sure the 38 KHz modulation is disabled
    DelayUS 87                                  ' Frame gap delay
EndProc

'------------------------------------------------------------------------------
' Send a two-phase pulse for a logic 0
' Input     : None
' Output    : None
' Notes     : The logic sequence is High to Low
'
Proc RC5_SendZero()
    PinOutput TX_Pin                            ' Enable the 38 KHz modulation
    DelayUS 887                                 ' Delay for the required time
    PinInput TX_Pin                             ' Disable the 38 KHz modulation
    DelayUS 884                                 ' Delay for the required time
EndProc

'------------------------------------------------------------------------------
' Send a two-phase pulse for a logic 1
' Input     : None
' Output    : None
' Notes     : The logic sequence is Low to High
'
Proc RC5_SendOne()
    PinInput TX_Pin                             ' Disable the 38 KHz modulation
    DelayUS 887                                 ' Delay for the required time
    PinOutput TX_Pin                            ' Enable the 38 KHz modulation
    DelayUS 884                                 ' Delay for the required time
EndProc

'-------------------------------------------------------------------------------------------------------
' Setup the program
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    HPWM 1, 127, 38000                          ' Start CCP1 transmitting at 38KHz
    PinInput TX_Pin                             ' Make its pin an input to stop the waveform
    RC5_tToggle = 0                             ' Reset the toggle state
EndProc

The program turns on and off the Infrared LED's 38 KHz modulation by setting the PWM's pin as a input for off and an output for on. This is a very efficient method of turning on and off a PWM waveform without having to go through the motions of enabling and disabling the CCP peripheral.

Frizie

Nice code Les.
One little point of criticism: as far as I know is RC5 standard 36kHz.
Should you adjust this?
Ohm sweet Ohm | www.picbasic.nl

Yasin

Quote from: Frizie on Jul 28, 2022, 03:31 PMNice code Les.
One little point of criticism: as far as I know is RC5 standard 36kHz.
Should you adjust this?

I made an IR-controlled led driver control to help a friend. Previously, I also set out with 36khz, this misled me. But when I examined the led with the scope, it was understood that the frequency was 38khz. As far as I understand, many manufacturers in the Far East did not follow the standards very strictly. Perhaps the main factor that determines the carrier frequency is the demodulated frequency of the IR receiver. So it is necessary to comply with whatever the IR receiver wants. Manufacturers prefer whichever they can find easily or cheaply. This is my opinion. Maybe it was 2017. I did a study imitating the remote for Meanwell brand IR controlled led drivers. The work had been successful. Although it is not as nice as Les's codes, I want to share it in case someone wants to use it.

'****************************************************************
'*  Name    : REMOTE_LED_DRIVER.BAS                            *
'*  Author  : Yasin APatay                                      *
'*  Date    : 12.08.2017                                        *
'*  Version : 1.0                                              *
'*  Notes  :                                                  *
'*          :                                                  *
'****************************************************************
' RC5 Remote Control Transmitter
Device 18F2520
On_Hardware_Interrupt GoTo SUB_INT_CTRL
Declare Xtal 8
Declare Hserial_Baud 115200
Declare All_Digital True

Config_Start
    OSC = INTIO67
    IESO = On
    PWRT = OFF
    BOREN = OFF
    BORV = 2
    WDT = On
    WDTPS = 1024
    STVREN = OFF
    LVP = OFF
    Debug = OFF
    Cp0 = On
    CP1 = On
    CP2 = On
    CP3 = On
Config_End
'------------------------------------------------------------------------------
'-------------------- DEĞİŞKENLER ---------------------------------------------
'------------------------------------------------------------------------------
Dim I          As Byte                                                        'Genel kullanım amaçlı değişken
Dim RUN_MODE    As Byte                                                        'Çalışma modu değişken
Dim GRUP_MODE  As Byte                                                        'Ürün grup modu değişkeni
Dim TICK        As Byte
Dim IR_TICK    As Byte
Dim MAX_DRV    As Byte
Dim RUN_DRV[4]  As Byte
Dim COUNT1      As Word
'------------------------------------------------------------------------------
'-------------------- KÜTÜPHANELER --------------------------------------------
'------------------------------------------------------------------------------
Include "NEC_IR_V01.inc"                                                      'MOSO marka güç kaynaklarının kontrolü için IRDA kütüphanesi
'------------------------------------------------------------------------------
'-------------------- TANIMLAMALAR --------------------------------------------
'------------------------------------------------------------------------------
Symbol ANGIN        = PORTA.0
Symbol RUN          = PORTA.1
Symbol DEDECT      = PORTB.0
Symbol SW_A        = PORTB.4
Symbol SW_B        = PORTB.5
Symbol SW_C        = PORTB.6
Symbol SW_D        = PORTB.7
Symbol RS_EN        = PORTC.0
Symbol PWM2        = PORTC.1
Symbol IRTX        = PORTC.2
Symbol DS_SCK      = PORTC.3
Symbol DS_SDI      = PORTC.4
Symbol DS_RST      = PORTC.5
Symbol UTX          = PORTC.6
Symbol URX          = PORTC.7

TRISA = %11111001
TRISB = %11111111
TRISC = %10000000
Clear INTCON2.7                                                                'PortB pullup aktif edildi
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
OSCCON = 118                                                                  'Internal Osilatör 8 MHZ olarak ayarlandı
GoTo Main1
'------------------------------------------------------------------------------
'-------------------- İNTERRUPT RUTİN -----------------------------------------
'------------------------------------------------------------------------------
SUB_INT_CTRL:
Context Save                                                                  'Statusu sakla
    INTCON.1 = 0
    INTCON = %01010000
    COUNT1 = 0
   
    While DEDECT = 1            '
        Inc COUNT1
        DelayUS 10
        If COUNT1 > 500 Then
            COUNT1 = 0
            Inc RUN_MODE
            If RUN_MODE > 3 Then RUN_MODE = 0 '3
            For I =0 To 10
                DelayMS 20
                Toggle RUN
            Next
            While DEDECT = 0            '
            Wend
            NEC_IR_TX(IR_ADD, DRIVE_ON)
            DelayMS 100
            NEC_IR_TX(IR_ADD, RUN_DRV[RUN_MODE])
            GoTo PASS
        EndIf
    Wend
PASS:   
    Inc TICK
    If TICK > 100 Then TICK = 0
    INTCON.1 = 0
    INTCON = %11010000
    Context Restore
Resume
'------------------------------------------------------------------------------
'-------------------- ANA PROGRAM KOD RUTİNİ ----------------------------------
'------------------------------------------------------------------------------
Main1:
    DelayMS 2000                                                                'Güç kaynağının stabil olmasını bekle
    NEC_IR_INIT                                                                'IR gönderme için taşıyıcı frekansını ve pini konfigüre et
    RUN_MODE = 0
    GoSub GRUP_MODE_LOAD
    For I = 1 To 5                                                              'IR haberleşmenin kaçırma ihtimaline karşı 5 defa tekrar et
        NEC_IR_TX(IR_ADD, DRIVE_ON)                                            'IR haberleşmeyi uyandır
        DelayMS 100                                                            'Bekle
        NEC_IR_TX(IR_ADD, RUN_DRV[RUN_MODE])                                    'Açılış değerini güç kaynağına yükle
    Next I
    TICK = 0   
MAIN2:   
    If TICK = 5 Then
        Clrwdt
        Toggle RUN
        Inc TICK
    EndIf
    INTCON = %11010000                                                      '
    INTCON2.6 = 1
GoTo MAIN2
'------------------------------------------------------------------------------
'-------------------- GRUP MOD İŞLETME KOD RUTİNİ -----------------------------
'------------------------------------------------------------------------------
GRUP_MODE_LOAD:
    GRUP_MODE = PORTB >> 4
    Select GRUP_MODE
        Case %1111                                                                'Switchler 1=OFF , 2=OFF , 3=OFF , 4=OFF    KONTAKTÖR PALS
            RUN_DRV[0] = DRIVE_100
            RUN_DRV[1] = DRIVE_70
            RUN_DRV[2] = DRIVE_40
            RUN_DRV[3] = DRIVE_10
        Case %0111                                                                  'Switchler 1=OFF  , 2=OFF , 3=OFF , 4=ON    150W ARMATÜR
            RUN_DRV[0] = DRIVE_90
            RUN_DRV[1] = DRIVE_70
            RUN_DRV[2] = DRIVE_50
            RUN_DRV[3] = DRIVE_30
        Case %1011                                                                  'Switchler 1=OFF , 2=OFF  , 3=ON , 4=OFF    100W ARMATÜR
            RUN_DRV[0] = DRIVE_90
            RUN_DRV[1] = DRIVE_60
            RUN_DRV[2] = DRIVE_40
            RUN_DRV[3] = DRIVE_20
        Case %1101                                                                  'Switchler 1=OFF , 2=ON , 3=OFF  , 4=OFF    60W ARMATÜR
            RUN_DRV[0] = DRIVE_80
            RUN_DRV[1] = DRIVE_50
            RUN_DRV[2] = DRIVE_30
            RUN_DRV[3] = DRIVE_10
        Case %1110                                                                  'Switchler 1=ON , 2=OFF , 3=OFF , 4=OFF    PROJEKTÖR
            RUN_DRV[0] = DRIVE_100
            RUN_DRV[1] = DRIVE_70
            RUN_DRV[2] = DRIVE_40
            RUN_DRV[3] = DRIVE_40
        Case 0                                                                  'Switchler 1=ON , 2=ON , 3=ON , 4=ON
            RUN_DRV[0] = DRIVE_100
            RUN_DRV[1] = DRIVE_100
            RUN_DRV[2] = DRIVE_100
            RUN_DRV[3] = DRIVE_100
        Case Else
            RUN_DRV[0] = DRIVE_100
            RUN_DRV[1] = DRIVE_100
            RUN_DRV[2] = DRIVE_100
            RUN_DRV[3] = DRIVE_100
    EndSelect
Return
'------------------------------------------------------------------------------
'-------------------- ÇALIŞMA MOD İŞLETME KOD RUTİNİ ------------------
'------------------------------------------------------------------------------
End


'****************************************************************
'*  Name    : NEC_IR_V01.INC                                    *
'*  Author  : Yasin APatay                                      *
'*  Date    : 20.08.2017                                        *
'*  Version : 1.0                                              *
'*  Notes  : Bu kütüphane NEC IR protokolünün transmit        *
'*          : rutinlerini içermektedir                          *
'****************************************************************

$ifndef _NEC_IR_V01_INC_
$define _NEC_IR_V01_INC_

'#ifMacro- _NEC_IR_INIT, _NEC_IR_TX

'#endIfMacro

$define IR_ADD      $80      ' INFRARED REMOTE ADDRESS
$define DRIVE_OFF  $12      ' IR OFF COMMAND KEY NO = 18
$define DRIVE_SET  $1A      ' IR SET COMMAND KEY NO = 26
$define DRIVE_ON    $1E      ' IR ON COMMAND KEY NO = 30
$define DRIVE_DOWN  $02      ' IR - COMMAND KEY NO = 2
$define DRIVE_UP    $03      ' IR + COMMAND KEY NO = 3
$define DRIVE_10    $04      ' IR %10 COMMAND KEY NO = 4
$define DRIVE_20    $05      ' IR %20 COMMAND KEY NO = 5
$define DRIVE_30    $06      ' IR %30 COMMAND KEY NO = 6
$define DRIVE_40    $07      ' IR %40 COMMAND KEY NO = 7
$define DRIVE_50    $08      ' IR %50 COMMAND KEY NO = 8
$define DRIVE_60    $09      ' IR %60 COMMAND KEY NO = 9
$define DRIVE_70    $0A      ' IR %70 COMMAND KEY NO = 10
$define DRIVE_80    $1B      ' IR %80 COMMAND KEY NO = 27
$define DRIVE_90    $1F      ' IR %90 COMMAND KEY NO = 31
$define DRIVE_100  $01      ' IR %100 COMMAND KEY NO = 1

'$define T          550      ' IR Transmit bit  period

Symbol T = 550

Dim NEC_ADDRESS As Byte
Dim NEC_COMMAND As Byte
Dim NEC_TX_FREQ As Byte
Dim Bit_Nr As Byte



GoTo NEC_IR_Main                    ' Jump over any subroutine   
'---------------------------------------------------------------------------------
'---------------------------------------------------------------------------------
'---------------------------------------------------------------------------------
' Macro Name    : NEC_IR_INIT
' Return Value  : None
' Parameters    :
' Notes        :
'              :
'
NEC_IR_INIT Macro
    GoSub _NEC_IR_INIT
    Endm
'-------------------------------------------------------------------------------
#ifdef NEC_IR_INIT#Req
_NEC_IR_INIT:
    TRISC.2 = 0                    ' CCP1 pin (PORTC.2) To Output
    PR2 = 52'131                      ' Set PWM Period For approximately 38KHz
    CCPR1L = 26'66                    ' Set PWM Duty-Cycle To 50%
    T2CON = 4
    Return
#endif
'---------------------------------------------------------------------------------
'---------------------------------------------------------------------------------
'---------------------------------------------------------------------------------
' Macro Name    : NEC_IR_TX
' Return Value  : None
' Parameters    : AD1, CM1
' Notes        :
'              :
'$define NEC_IR_TX(NEC_ADDRESS, NEC_COMMAND) _NEC_IR_TX NEC_ADDRESS, NEC_COMMAND
'
$define NEC_IR_TX(NEC_ADDRESS1, NEC_COMMAND1) '
NEC_ADDRESS = NEC_ADDRESS1 '
NEC_COMMAND = NEC_COMMAND1 '
GoSub __NEC_IR_TX

'---------------------------------------------------------------------------------
__NEC_IR_TX:
    GoSub Logic_Header                              ' Protokolün Lojik header frame gönder
    For Bit_Nr = 0 To 7                            ' 
        If GetBit NEC_ADDRESS, Bit_Nr = 0 Then      ' Adres datasının ilgili biti 0 ise
            GoSub Logic_0                          ' Lojik 0 ı gönder
        Else                                        ' Adres datasının ilgili biti 1 ise
            GoSub Logic_1                          ' Lojik 1 i gönder
        EndIf                                      '
    Next Bit_Nr                                    '
    NEC_ADDRESS = ~NEC_ADDRESS                      ' Adres datasını tersle   
    For Bit_Nr = 0 To 7                            '
        If GetBit NEC_ADDRESS, Bit_Nr = 0 Then      ' ADRES datasının ilgili biti 0 ise
            GoSub Logic_0                          ' Lojik 0 ı gönder
        Else                                        ' ADRES datasının ilgili biti 1 ise
            GoSub Logic_1                          ' Lojik 1 i gönder
        EndIf                                      '
    Next Bit_Nr                                    '
    For Bit_Nr = 0 To 7                            '
        If GetBit NEC_COMMAND, Bit_Nr = 0 Then      ' Command datasının ilgili biti 0 ise
            GoSub Logic_0                          ' Lojik 0 ı gönder
        Else                                        ' COMMAND datasının ilgili biti 1 ise
            GoSub Logic_1                          ' Lojik 1 i gönder
        EndIf                                      '
    Next Bit_Nr                                    '
    NEC_COMMAND = ~NEC_COMMAND                      ' Command datasını tersle
    For Bit_Nr = 0 To 7                            '
        If GetBit NEC_COMMAND, Bit_Nr = 0 Then      ' Command datasının ilgili biti 0 ise
            GoSub Logic_0                          ' Lojik 0 ı gönder
        Else                                        ' COMMAND datasının ilgili biti 1 ise
            GoSub Logic_1                          ' Lojik 1 i gönder
        EndIf                                      '
    Next Bit_Nr                                    '
    GoSub Logic_End                                ' Protokolün Lojik end frame gönder
    Return

'---------------------------------------------------------------------------------
' Rutine Name  : Logic_Header
' Return Value  : None
' Parameters    : None
' Notes        : 9 ms göndermede, 4,5 ms beklemede kalarak NEC protokolün
'              : header frame i oluşturulur.
'
Logic_Header:
    CCP1CON = $0C
    DelayUS 9000
    CCP1CON = $00
    PORTC.2 = 0
    DelayUS 4500
    Return
'---------------------------------------------------------------------------------
' Rutine Name  : Logic_0
' Return Value  : None
' Parameters    : None
' Notes        : 550 us göndermede, 550 us beklemede kalarak NEC protokolün
'              : Lojik0 frame i oluşturulur.
'
Logic_0:
    CCP1CON = $0C
    DelayUS T
    CCP1CON = $00
    PORTC.2 = 0
    DelayUS T
    Return
'---------------------------------------------------------------------------------
' Rutine Name  : Logic_1
' Return Value  : None
' Parameters    : None
' Notes        : 550 us göndermede, 1650 us beklemede kalarak NEC protokolün
'              : Lojik1 frame i oluşturulur.
'
Logic_1:
    CCP1CON = $0C
    DelayUS T
    CCP1CON = $00
    PORTC.2 = 0
    DelayUS (T * 3)
    Return
'---------------------------------------------------------------------------------
' Rutine Name  : Logic_End
' Return Value  : None
' Parameters    : None
' Notes        : 550 us göndermede kalarak NEC protokolün
'              : LojikEnd frame i oluşturulur.
'
Logic_End:
    CCP1CON = $0C
    DelayUS T
    CCP1CON = $00
    PORTC.2 = 0
    Return
'---------------------------------------------------------------------------------
' Rutine Name  : Logic_Repeat
' Return Value  : None
' Parameters    : None
' Notes        : 100 ms bekleyip, 9 ms göndermede, 2,25 ms beklemede kalarak NEC protokolün
'              : LojikTekrar frame i oluşturulur.
'
Logic_Repeat:
    DelayMS 100
    CCP1CON = $0C
    DelayUS 9000
    CCP1CON = $00
    PORTC.2 = 0
    DelayUS 2245
    Return

NEC_IR_Main:

$endif

Yasin

Since I couldn't edit my post above, I had to write a message again. There is an important detail that I forgot to mention. The codes I shared are valid for the NEC protocol.

Best regards.

keytapper

I also made a little effort for a SIR protocol. I've one project (incomplete) that would make all the best of a 12F675. Just make a selection of what is used for.
Ignorance comes with a cost

top204

I've found over the years, Frizie, that the IR remote manufacturers can never make their mind up as to the exact modulation frequency they will use. :-)

It ranges from 36 KHz to 38 KHz, and if the incorrect frequency is used, the receiver will still respond, but its range will be shorter, because the IR sensor units have quite a large bandwidth. So I always set it to 38 KHz, then test for range with differing frequencies.

Ivano

Quote from: top204 on Jul 28, 2022, 02:17 PMIl programma attiva e disattiva la modulazione a 38 KHz

Good morning,
on page 146 of positron compiler the declared maximum HPWM frequency is 32767 Hz, I see that instead it accepts a frequency up to 65535 Hz. Error in the manual?

top204

I have forgotten to update that particular piece of text in the manual, and have not fully tested the HPWM commands for higher frequencies. The HPWM library now uses 32-bit multiplications and divisions with 18F devices, so it should (in theory) work up to 65535.
 

Ivano

Yes, HPWM works up to 65535.
Tested on pic 18F25K83

top204

Thanks Ivano.

On a newer 18F device it "should" operate up to the maximum 16-bit value, but it may not on the original, old, 18F devices, and it will not on 14-bit core devices, because they do no have hardware multiply.

keytapper

In the manual, IIRC, the statement is for a maximum of 32678.
Ignorance comes with a cost

top204

#11
That's why the 32768 frequency is still in the compiler's manual, because it is guaranteed at that frequency.

To see what the HPWM command does to calculate a particular frequency and allow a duty cycle from 0 to 255, take a look at the "Proton_Hpwm_Macros" folder in the installed "Samples\New Samples\" folder. They are located here: "C:\Users\User Name\PDS\Samples\New Samples\".

The demo was created before I added procedures to the compiler and was created for the Amicus18 board that used a PIC18F25K20 device and the standard CCP peripherals for PWM, back in about 2011. It shows how the calculations are performed and how the timer's prescaler is chosen for a particular frequency.

It could easily be adapted for procedures and changed for devices that do not have the standard CCP peripherals for PWM anymore. Then you will have a true HPWM library that can evolve for different devices.

JonW

Quote from: top204 on Jul 28, 2022, 02:17 PMThis is a very efficient method of turning on and off a PWM waveform without having to go through the motions of enabling and disabling the CCP peripheral.

I use the same method for generating Diseqc via PWM and use the I/O to gate the output as writing to the duty register can cause glitches in the start and stop of the PWM waveform. Another really powerful peripheral is the DSM  and if your device has one (Data Signal Modulator) then you can create a hardware modulator pretty easily feeding the modulator from the TXUART and the carriers from 2 PWM sources or external pins.  I have driven the DSM externally with clock sources >> FOSC as the DSM logic is really fast!