View Full Version : Infrared HPWM setup
astanapane
- 31st May 2023, 22:14
Dear all,
just a quick question. I didnt want to open a new thread but most of the Infrared threads are closed.
I would like to set up the PIC18F26k22 in order to use HPWM for the 38khz IR.
First of all i would like to ask if i can use 64Mhz as the main PIC frequency.
i tried to use mister e's pic multi-calc and set 64Mhz. The following are the results i got.
9436
but from the calculations i made:
(64Mhz / (4*TMR2 prescale value * 38Khz))-1 = PR2
(64Mhz / (4*1*38Khz)) - 1 = PR2
(64Mhz / (152000)) - 1 = PR2 <=>
64,000,000
<=> PR2 = ------------ -1 <=>
152,000
<=> PR2 = 420
Also calculating the bits:
log(FOSC / FPWM)
Resolution = ------------------- bits
Log(2)
log(64,000,000 / 38,000) = 3.226
log(2) = 0.301
so we have:
3.226
------- = 10.17 ~ 10 bits
0.301
and calculating the CCPRL1:
(PR2 + 1) * TMR2 prescale * 50% Duty Cycle = value for CCPRL1, or
(420 + 1) * 1 * 0.50 = 421 * 0.50 = 210
So i set in the code the following:
TRISC.2 = 0 ' CCP1 (PortC.2 = Output)
PR2 = 420 ' Set PWM Period for approximately 38KHz
CCPR1L = 210 ' Set PWM Duty-Cycle to 50%
T2CON = %00000100 ' Timer2 ON + 1:1 prescale --> i know this might not be right as at 64Mhz there is no 1:1 scale based on mister's e multi-calc.
CCP1CON = %00001100 ' Mode select = PWM
could you please help me to clear things up?
I dont mind using 16Mhz as a base frequency, but still the calculations i get are not match with mister's e multi-calc.
Thanks for your help in advance.
richard
- 31st May 2023, 23:16
prescaler is 4 , 16 is also a possibility
(64Mhz / (4*TMR2 prescale value * 38Khz))-1 = PR2
(64Mhz / (4*4*38Khz)) - 1 = PR2
(64Mhz / (152000*4)) - 1 = PR2 <=>
Code:
64,000,000
<=> PR2 = ------------ -1 <=>
152,000*4
<=> PR2 = 104
(PR2 + 1) * TMR2 prescale * 50% Duty Cycle = value for CCPRL1, or
(104+ 1) * 4 * 0.50 = 421 * 0.50 = 210
T2CON = %00000101
PR2 = 104 ' Set PWM Period for approximately 38KHz
CCPR1L = 210>>2 ' Set PWM Duty-Cycle to 50%
note
PR2 is a 8bit reg it cannot ever be 420 or anything larger than 255
CCPR1L are the upper 8 bits of the duty cycle word value
CCP1CON bit 4 and 5 are the lower two bits
astanapane
- 1st June 2023, 06:37
Hi Richard,
thanks for the clarification and answer.
I found in the manual what you said regarding the Resolution bits.
9440
richard
- 1st June 2023, 07:10
the duty cycle is a 10 bit value at best for that chip, not all frequencies can have the full 10bit range available
it totally depends on choices made with regard to prescaler and period.
no matter what bit resolution is possible the CPRxL value is the upper 8 bits of the duty cycle word valueCCP1CON bit 4 and 5 are the lower two bits
astanapane
- 1st June 2023, 07:45
i've also noticed you've shifted 2 bits on the right the CCPR1L
CCPR1L = 210>>2 ' Set PWM Duty-Cycle to 50%
So the CCPR1L value will be 52.
(11010010) 210>>2 = 00110100 = 52
why have we shifted?
richard
- 1st June 2023, 08:03
why have we shifted?
CPRxL value is the upper 8 bits of the duty cycle word valueCCP1CON bit 4 and 5 are the lower two bits
(011010010) 210>>2 = 00110100 = 52 ;high 8bits
(011010010) 210 & 3 = 00000010 = 2 ;low 2 bits
00000010<<4 = 00100000
CCP1CON = 00100000 |12 to set low bits in pwmmode
C version from microchip
void PWM1_LoadDutyValue(uint16_t dutyValue)
{
// Writing to 8 MSBs of pwm duty cycle in CCPRL register
CCPR1L = ((dutyValue & 0x03FC)>>2);
// Writing to 2 LSBs of pwm duty cycle in CCPCON register
CCP1CON = ((uint8_t)(CCP1CON & 0xCF) | ((dutyValue & 0x0003)<<4));
}
astanapane
- 1st June 2023, 08:12
thanks Richard. now is clear.
i will get back once i have a working code and establish an IR communication.
astanapane
- 1st June 2023, 14:20
with the following configuration i got this on the scope. So i guess we are in a good path.
To mention that the main OSC is at 64Mhz using HPWM on the PIC18f26K22 on portc.2
TRISC.2 = 0 ' CCP1 (PortC.2 = Output)
PR2 = 104 ' Set PWM Period for approximately 38KHz
CCPR1L = 52 ' Set PWM Duty-Cycle to 50% (011010010) 210>>2 = 00110100 = 52
T2CON = %00000101 ' Timer2 ON + 4 prescale
CCP1CON = %00001100 ' Mode select %00001100 = PWM
9443
all thanks to Richard.
now im going on the next step.
richard
- 2nd June 2023, 02:52
very good.
you could set the lower two bits of the Duty-Cycle word [CCP1CON bits 4:5] to get the duty cycle
even closer to exactly 50%, if you wanted to
CCP1CON = %00101100
astanapane
- 2nd June 2023, 06:23
I will do that thanks a lot.
Yesterday i tried till late at night to set a code for the TX and RX, a very simple one but didnt work.
tx:
'*-----------------------------------------------------------------------------|
'* | --------------------- | |
'*----------------------- | EUART 1 Configuration | --------------------------|
'* | --------------------- | |
'*-----------------------------------------------------------------------------| |
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 130 ' 9600 Baud @ 64MHz, -0.02%
SPBRGH = 6
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
'------------------------------------------------------------------------------|
ID VAR BYTE
button1 var porta.0 ' we configure this button 1 at porta.0
button2 var porta.1 ' we configure this button 2 at porta.1
RED var latc.3 ' a RED LED indicates the PIC working condition
Blue var lata.2 ' a Blue LED indicates the push button everytime
high red
pause 100
low red
pause 50
high red
'------------------------------------------------------------------------------|
BEGIN:
ID = 10
if button1 = 0 then
gosub button1_pressed
endif
low blue
GOTO BEGIN
'------------------------------------------------------------------------------|
button1_pressed:
high blue
hSEROUT [ID] ' we send at portc.6 which is connected the IR module at the 74LS00 in pin No2
PAUSE 100
return
button2_pressed:
high blue
hSEROUT [ID] ' we send at portc.6 which is connected the IR module at the 74LS00 in pin No3
PAUSE 100
return
end
RX:
'*-----------------------------------------------------------------------------|
'* | --------------------- | |
'*----------------------- | EUART 2 Configuration | --------------------------|
'* | --------------------- | |
'*-----------------------------------------------------------------------------| |
DEFINE HSER2_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER2_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER2_CLROERR 1 ' Clear overflow automatically
DEFINE HSER2_SPBRG 130 ' 9600 Baud @ 64MHz, -0.02%
SPBRGH2 = 6
BAUDCON2.3 = 1 ' Enable 16 bit baudrate generator
'-------------------------------------------------------------------------------|
ID con 10
Green var lata.1 ' a Green LED which indicates the 1st output of the IR input code
Blue var lata.0 ' a Blue LED indicates the 2nd output of the IR input code
Red var lata.2 ' a Red LED indicates the PIC working condition
'------------------------------------------------------------------------------|
' RED LED indicates that PIC is up and running |
'------------------------------------------------------------------------------|
high red
pause 100
low red
'------------------------------------------------------------------------------|
Begin:
hSERin2 [wait(ID)]
high red
'pause 100
gosub FIRST_SIGNAL
' endif
'------------------------------------------------------------------------------|
FIRST_SIGNAL:
high green
pause 500
low green
return
end
richard
- 2nd June 2023, 07:09
any Alias that refers to a LATx reg cannot be safely used with HIGH,LOW,TOGGLE or any other pbp high level command
the sort of bugs it can introduce vary from chip to chip and can be difficult to understand , don't do it
Blue var lata.2 '; an alias to a lata
high blue ; will not work safely
blue = 1 ; will work
low blue ; will not work safely
blue = 0 ; will work
toggle blue ; will not work safely
blue = !blue ; will work
etc...
Yesterday i tried till late at night to set a code for the TX and RX, a very simple one but didnt work.
how are the chips connected , show a schematic
astanapane
- 2nd June 2023, 10:22
I will make the schematic on paper later today and will upload it here.
thanks :)
Ioannis
- 2nd June 2023, 10:27
any Alias that refers to a LATx reg cannot be safely used with HIGH,LOW,TOGGLE or any other pbp high level command the sort of bugs it can introduce vary from chip to chip and can be difficult to understand , don't do it
Blue var lata.2 '; an alias to a lata
high blue ; will not work safely
Though this is the recommended way to control output pins. I suppose this was before LAT registers showed up?
Ioannis
astanapane
- 2nd June 2023, 21:44
Please find the schematic as follows.
I hope i didnt forget anything. In any case is very simple.
9445
richard
- 2nd June 2023, 23:54
if you look at the data sheet for a tsop4838 you will see that you have a numbers of issues to contend with
9446
1. @9600baud the bit time is 100uS or approx 4 cycles of 38khz , about 2 to three times faster than the tsop4838 can cope with
2. the max burst rate is 800/sec a 9600baud stream can exceed that
3. after a 70 cycle transmission a 12 cycle min tx gap must be made [some devices can lock up if u don't and need a pwr cycle to recover]
4. the device will do its very best to reject a continuous transmission and go mute till a min tx gap in tx is observed, which is what you are doing.
overall tsop4838 is not particularly suitable for serial tx from a uart, you could try a much lower baud rate and you will need to
invert the transmission logic so that there no transmission at idle
i would also wire tx to rx directly to verify code works before trying ir link, also have a look at Manchester encoding and check out ir tx protocols like RC5/6 NEC etc
astanapane
- 5th June 2023, 07:30
Hi Richard,
you are right, i have decreased the speed and manage to play a lit bit with the delay in useconds.
I worked somehow but not always reliable.
I think i will try the RC5 method.
richard
- 5th June 2023, 11:20
I worked somehow but not always reliable.
the series resistor for the led is wat too big, it will make range / reliability pretty low. it could go as low as 39 ohms safely [probably lower even] in a non continuously on configuration otherwise 100 ohm would be better
astanapane
- 5th June 2023, 12:16
I will try to change that as well before i go for the RC5.
The following 15 days i will be in a business trip in Abu Dhabi so i will get back as soon as i have time to check this out.
Many thanks.
tumbleweed
- 5th June 2023, 18:13
You can get rid of the transistor and associated resistors and just connect the OUT directly to RB7.
If you need to, you can invert the RX sign with the DTRXP bit in the baudcon register.
mpgmike
- 6th June 2023, 01:50
the series resistor for the led is wat too big, it will make range / reliability pretty low. it could go as low as 39 ohms safely [probably lower even] in a non continuously on configuration otherwise 100 ohm would be better
For most LEDs or SSRs, I found 470 ohms offers a good compromise between response time and effectiveness.
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.