Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
// amateur code - use at own risk - author accepts no responsibility for anything, anywhere, ever
// I have used direct-register programming, as it is what I am more familiar with - you may use BASIC style code if you wish
// tested on EasyPIC v7 development board with IR click inserted into mikroBUS 2 socket
Device = 18F43K22
Clock = 8 // adjust to suit your setup
// simple IR receiver test - PORTD LEDs reflect IR input status from RA2
// IR input is on RA3 - from 3-pin 38 KHz IR receiver module such as TSOP38338
// IR output is on RC1 - not used here
// LEDs on PORTD.0 and PORTD.1 where D0 mirrors input, D1 is inverted compared to IR input
ANSELA = 0 // all digital
TRISA = $ff // all input for IR and switches
LATA = 0 // all low
ANSELD = 0 // all digital
TRISD = 0 // all output for LEDs
LATD = 1 // LED pattern 0x01
Repeat
If PORTA.3 = 1 Then // test IR input on RA3
LATD = 1 // LED on D0 lit if IR input is high (normal state) , LED on D1 off
Else
LATD = 2 // LED on D1 lit, LED on D0 off
EndIf
Until false
// simple timer 0 16 bit counter running at 1MHz
// 8Mhz clock provides timer 0 with 2Mhz to prescaler, prescaler 1:2 causes timer 0 to count microseconds
Device = 18F43K22
Clock = 8
// initialise
ANSELC = 0 // all digital
TRISC = 0 // all output
ANSELD = 0 // all digital
TRISD = 0 // all output
T0CON = $80 // timer 0 on, 16 bit, fosc/4, prescaler 1:2 - count microseconds
While true // main program loop...
LATC = TMR0L // background display timer 0 on LEDs - TMR0H read during read of TMR0L
LATD = TMR0H // background display timer 0 on LEDs - expect 15.25Hz on RD7 for 1MHz counter
Wend
// read first header bit of IR remote control signal
// I will test using Sony TV IR remote
// simple timer 0 16 bit counter running at 1MHz
// 8Mhz clock provides timer 0 with 2Mhz to prescaler, prescaler 1:2 causes timer 0 to count microseconds
Device = 18F43K22
Clock = 8
// Sony protocol:
// 40kHz 7 bits command (LSB first) then 5 bits address
// this is 12 bit, there are also 15 bit and 20 bit versions of Sony protocol
// start bit = 2.4mS mark, .6mS space
// 1 = 1.2mS mark .6mS space, 0 = .6mS mark .6ms space
// repeat every 45mS if key is held down
// Sony device will not respond to a single message,
// - so remotes usually send 3 or more repeated messages
// initialise
ANSELA = 0 // all digital
ANSELB = 0 // all digital
TRISB = 0 // all output for diagnostic LEDs
ANSELC = 0 // all digital
TRISC = 0 // all output for diagnostic LEDs
ANSELD = 0 // all digital
TRISD = 0 // all output for diagnostic LEDs
T0CON = $80 // timer 0 on, 16 bit, fosc/4, prescaler 1:2 - count microseconds
While true // main program loop...
LATB = 0 // start of a new IR read
DelayMS(1000) // allow time for end of previous IR remote message
LATB = 1 // waiting for header
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
Wend
LATB = 2 // header started
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
While(PORTA.3) = 0 // wait for IR input to go high - end of first leader bit 2.4ms
Wend
LATB = 3 // header ended
LATC = TMR0L // background display timer 0 on LEDs - TMR0H read during read of TMR0L
LATD = TMR0H // background display timer 0 on LEDs - expect 15.25Hz on RD7 for 1MHz counter
Wend
// read IR remote control signal to PIC EEPROM
// I will test using Sony TV IR remote
// EEPROM will contain sets of 4 bytes in the order mark-low_byte, mark-high_byte, space_low_byte, space-high-byte
// combine high/low bytes to get number of microseconds mark or space
// number of bits stored as byte in EEPROM location 255
// status 28 December 2020 - seems to work, but this is a really dumb program that does not yet stop at end of message
// - press the button twice or set correct number of bits in code
// - will improve if and when I get bored enough
// simple timer 0 16 bit counter running at 1MHz
// 8Mhz clock provides timer 0 with 2Mhz to prescaler, prescaler 1:2 causes timer 0 to count microseconds
Device = 18F43K22
Clock = 8
// import EEPROM module
Include "EEPROM.bas"
// Sony protocol:
// 40kHz 7 bits command (LSB first) then 5 bits address
// this is 12 bit, there are also 15 bit and 20 bit versions of Sony protocol
// start bit = 2.4mS mark, .6mS space
// 1 = 1.2mS mark .6mS space, 0 = .6mS mark .6ms space
// repeat every 45mS if key is held down
// Sony device will not respond to a single message,
// - so remotes usually send 3 or more repeated messages
// There is a fundamental issue with measuring raw timing from IR receiver, as the received signal is a slightly distorted reproduction
// of the original waveform sent by IR remote. Space times are shortened a little and mark times are lengthened a little.
// If you are lucky, then the distortion will be small enough that you may acheive re-transmission that is good enough.
Const NumCycles = 35 // a cycle is considered to be a mark followed by a space
Dim mark_microseconds_h As String (NumCycles + 2)
Dim mark_microseconds_l As String (NumCycles + 2)
Dim space_microseconds_h As String (NumCycles + 2)
Dim space_microseconds_l As String (NumCycles + 2)
Dim bitcount As Byte // count bits
Dim int_microseconds As Word
Dim int_microseconds2 As Word
Dim gap_found As Byte // count bits up to inter-message gap
Dim junk As Byte // just a throw-away byte
// initialise
ANSELA = 0 // all digital
ANSELB = 0 // all digital
TRISB = 0 // all output for diagnostic LEDs
T0CON = $80 // timer 0 on, 16 bit, fosc/4, prescaler 1:2 - count microseconds
While true // main program loop...
LATB = 0 // diagnostic - start of a new IR read
DelayMS(1000) // allow time for end of previous IR remote message
LATB = 1 // waiting for header
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
Wend
LATB = 2 // diagnostic - header started
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
gap_found = 0 // initialise
For bitcount = 0 To (NumCycles -1) // adjust for the maximum number of bits wanted
While(PORTA.3) = 0 // wait for IR input to go high - end of next mark bit
Wend
mark_microseconds_l(bitcount) = TMR0L // background TMR0H read during read of TMR0L
mark_microseconds_h(bitcount) = TMR0H // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
junk = TMR0L // don't care about timer low byte, but need to populate TMR0H
If TMR0H > 200 Then // threshold for determining end of message - 0 is about 20ms
gap_found = bitcount // indicate that an inter-message gap found at bit gap-found
LATB = 2 // diagnostic - gap found
EndIf
Wend
space_microseconds_l(bitcount) = TMR0L // background TMR0H read during read of TMR0L
space_microseconds_h(bitcount) = TMR0H // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
Next
LATB = 3 // diagnostic - numcycles bits received
EE.WriteByte(255, gap_found) // write number of bits to EEPROM...
For bitcount = 0 To (NumCycles -1) // adjust for the maximum number of bits wanted
int_microseconds = mark_microseconds_l(bitcount)
int_microseconds2 = mark_microseconds_h(bitcount)
int_microseconds2 = int_microseconds2 * 256
int_microseconds = int_microseconds + int_microseconds2 // we now have mark time in int_milliseconds
EE.WriteWord(bitcount * 4, int_microseconds) // write mark data to EEPROM...
int_microseconds = space_microseconds_l(bitcount)
int_microseconds2 = space_microseconds_h(bitcount)
int_microseconds2 = int_microseconds2 * 256
int_microseconds = int_microseconds + int_microseconds2 // we now have space time in int_milliseconds
EE.WriteWord((bitcount * 4) + 2, int_microseconds) // write space data to EEPROM...
Next
Wend
// send IR remote control signal using PIC EEPROM raw timing information
// I tested using Sony TV IR remote button '7', but should work for many common remote controls
// IR input is on RA3 - not used here
// IR output is on RC1 - 38Khz PWM 2 output
// button on RA4 goes low when pressed - causes IR message to be sent
// EEPROM should contain sets of 4 bytes in the order mark-low_byte, mark-high_byte, space_low_byte, space-high-byte
// combine high/low bytes to get number of microseconds mark or space
// EEPROM address 255 contains a byte with number of original IR bits in message
// note that what I call an IR bit, is really just a mark/space pair. This may or may not correspond to a bit, depending on protocol
// status 28 December 2020 - seems to work, but not properly tested yet
// there are vast opportinities for improvement, but this examplee proves the concept
Device = 18F43K22
Clock = 8
Include "EEPROM.bas"
// Sony protocol:
// 40kHz 7 bits command (LSB first) then 5 bits address
// this is 12 bit, there are also 15 bit and 20 bit versions of Sony protocol
// start bit = 2.4mS mark, .6mS space
// 1 = 1.2mS mark .6mS space, 0 = .6mS mark .6ms space
// repeat every 45mS if key is held down
// Sony device will not respond to a single message,
// - so remotes usually send 3 or more repeated messages
// There is a fundamental issue with measuring raw timing from IR receiver, as the received signal is a slightly distorted reproduction
// of the original waveform sent by IR remote. Space times are shortened a little and mark times are lengthened a little.
// If you are lucky, then the distortion will be small enough that you may acheive re-transmission that is good enough.
Const NumCycles = 60 // a cycle is considered to be a mark followed by a space
Dim bitcount As Byte // count bits
Dim int_microseconds As Word
Dim num_bits As Byte // message bits found from EEPROM
Sub send_mark()
T2CON.2 = 1 // start PWM
DelayUS(int_microseconds)
T2CON.2 = 0 // stop PWM
End Sub
Sub send_space()
DelayUS(int_microseconds)
End Sub
// initialise
ANSELA = 0 // all digital
ANSELB = 0 // all digital
TRISB = 0 // all output for diagnostic LEDs
ANSELC = 0 // all digital
TRISC = 0 // all output for diagnostic LEDs and PWM out
CCPR2L = 20 // duty cycle approx 30%
CCP2CON = $0c // PWM mode
CCPTMRS0 = $0 // use timer 2
PR2 = $38 // adjust for $38=36kHz, $34=38kHz or $31=40kHz
T2CON = $04 // timer 2 off
While true // main program loop...
LATB = 0 // diagnostic - start of a new IR read
While(PORTA.4) = 1 // wait for button to go low - button press gives low
Wend
num_bits = EE.ReadByte(255) // read number of bits from EEPROM...
If num_bits > NumCycles Then // more bits than can be handled - probably due blank EEPROM
While true // flash PORTB LEDs forever
LATB = $ff // all diagnostic LEDs on
DelayMS(1000)
LATB = 0 // all diagnostic LEDs off
DelayMS(1000)
Wend
EndIf
For bitcount = 0 To (num_bits) // adjust for the maximum number of bits wanted
LATB = bitcount // diagnostic LEDs
int_microseconds = EE.ReadWord(bitcount * 4) // read mark data from EEPROM...
send_mark() // send mark of length in variable int_microseconds
int_microseconds = EE.ReadWord((bitcount * 4) + 2) // read space data from EEPROM...
send_space() // send space of length in variable int_microseconds
Next
DelayMS(1000) // limit send repeat rate
Wend
// read IR remote control signal to PIC EEPROM then re-send when wanted
// the strategy of blindly re-transmitting what is received from 3-pin IR receiver will always have limitations...
// ... most notably RC5 and similar will not give sensible toggle bit values
// I am using Swordfish SE, so RAM is limited to 256 bytes
// If you use full version, you may wish to increase NumCycles definition up to a maximum of 60
// It would be very nice to print out timing values on UART - but this is just too much for the SE compiler
// EEPROM will contain sets of 4 bytes in the order mark-low_byte, mark-high_byte, space_low_byte, space-high-byte
// combine high/low bytes to get number of microseconds mark or space
// number of bits stored as byte in EEPROM location 255
// Issues to fix
// IR read sometimes goes wrong - ultra-short messages - or something
// status 31 December 2020 at 01:30 UTC
// - seems to work, but this is a really dumb program that does not yet stop at end of message
// - press the button twice or set correct number of bits in code
// - will improve if and when I get bored enough
// amateur code - use at own risk - author accepts no responsibility for anything, anywhere, ever
// I have used direct-register programming, as it is what I am more familiar with - you may use BASIC style code if you wish
// tested on EasyPIC v7 development board with IR click inserted into mikroBUS 2 socket
// This is original code that author makes no claim to - anyone is free to use and change in any way they like
// tests so far:
// pass SIRC12 - Sony TV
// pass RC6 mode 0 - Philips TV
// pass Samsung TV
// pass NEC 32 bit - Logik TV
// pass NEC extended 32 bit
// pass JVC
// pass RC5 - Windows remote - NOTE THAT TOGGLE BIT WILL NEVER WORK CORRECTLY !!!
// seems OK RC6 mode 6 - seems OK, but cannot test with Swordfish SE - needs full version compiler with higher value of NumCycles
//
// fail - Sharp TV - don't know why this does not work, not sure I care
// simple timer 0 16 bit counter running at 1MHz
// 8Mhz clock provides timer 0 with 2Mhz to prescaler, prescaler 1:2 causes timer 0 to count microseconds
// IR input is on RA3 - from 3-pin 38kHz IR receiver module
// IR output is on RC1 - 38Khz PWM 2 output
// operating buttons - all button inputs must have pull-up resistor - take low when pressed
// button on RA0 goes low when pressed - select receive mode
// button on RA1 goes low when pressed - select transmit mode
// PORTB LED indications
// all off - nothing happening
// B0 on - receive mode - waiting for IR button press
// B1 on - transmit mode - sending IR
// all LEDs flashing - EEPROM is blank
// (PORTD LEDs are for diagnostics only and show number if IR cycles received)
Device = 18F43K22
Clock = 8
// configuration fuses... PIC18F43K22 External 8MHz 2-pin crystal (2 x 22pF caps), no PLL for 8MHz Fosc
Public Config
FOSC = HSMP, // [LP, XT, HSHP, HSMP, ECHP, ECHPIO6, RC, RCIO6, INTIO67, INTIO7, ECMP, ECMPIO6, ECLP, ECLPIO6]
PLLCFG = OFF, // [OFF, ON],
PRICLKEN = ON // [OFF, ON],
// default config settings
// FCMEN = OFF,
// IESO = OFF,
// BOREN = ON,
// WDTEN = OFF,
// WDTPS = 128,
// PBADEN = OFF,
// STVREN = ON,
// LVP = OFF,
// XINST = OFF,
// DEBUG = OFF
// import library modules
Include "EEPROM.bas"
// Sony protocol:
// 40kHz 7 bits command (LSB first) then 5 bits address
// this is 12 bit, there are also 15 bit and 20 bit versions of Sony protocol
// start bit = 2.4mS mark, .6mS space
// 1 = 1.2mS mark .6mS space, 0 = .6mS mark .6ms space
// repeat every 45mS if key is held down
// Sony device will not respond to a single message,
// - so remotes usually send 3 or more repeated messages
// There is a fundamental issue with measuring raw timing from IR receiver, as the received signal is a slightly distorted reproduction...
// ... of the original waveform sent by IR remote. Space times are shortened a little and mark times are lengthened a little.
// If you are lucky, then the distortion will be small enough that you may acheive re-transmission that is good enough.
Const NumCycles = 50 // maximum message length - a cycle is considered to be a mark followed by a space
Dim mark_usecs(NumCycles) As Word
Dim space_usecs(NumCycles) As Word
Dim bitcount As Byte // count bits
Dim int_microseconds As Word // general purpose store for timing values
Dim gap_found As Byte // count bits up to inter-message gap
Dim num_bits As Byte // message bits found from EEPROM
// stop PWM 2 and take RC1 low
Sub pwm_stop()
CCP2CON = 0 // stop PWM
LATC.1 = 0 // IR Tx off
End Sub
// start PWM 2
Sub pwm_start()
CCP2CON = $0c // start PWM
End Sub
// IR mark - send 38kHz to IR transmitter for number of us specified in int_microsends
Sub send_mark()
pwm_start()
DelayUS(int_microseconds)
pwm_stop()
End Sub
// IR space - send nothing to IR transmitter for number of us specified in int_microsends
Sub send_space()
pwm_stop()
DelayUS(int_microseconds)
End Sub
// initialise
ANSELA = 0 // all digital
ANSELB = 0 // all digital
TRISB = 0 // all output for diagnostic LEDs
ANSELC = 0 // all digital
TRISC = 0 // all output for diagnostic LEDs and PWM out
ANSELD = 0 // all digital
TRISD = 0 // all output for diagnostic LEDs
LATD = 0 // all LEDs off
CCPR2L = 20 // PWM duty cycle approx 30%
CCPTMRS0 = $0 // PWM use timer 2
PR2 = $38 // PWM adjust for $38=36kHz, $34=38kHz or $31=40kHz
T2CON = $04 // timer 2 on for PWM
T0CON = $80 // timer 0 on, 16 bit, fosc/4, prescaler 1:2 - count microseconds
pwm_stop() // make sure IR Tx output is low
While true // main program loop...
LATB = 0 // diagnostic - nothing happening
////// IR Receive (learning) routine //////
If PORTA.0 = 0 Then // button or switch on RA0 goes low to read IR message
DelayMS(1000) // allow time for end of previous IR remote message
LATB = 1 // waiting for header
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
Wend
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
gap_found = 0 // initialise
For bitcount = 0 To (NumCycles - 1) // adjust for the maximum number of bits wanted
While(PORTA.3) = 0 // wait for IR input to go high - end of next mark bit
Wend
int_microseconds.bytes(0) = TMR0L // background TMR0H latches during read of TMR0L
int_microseconds.bytes(1) = TMR0H
mark_usecs(bitcount) = int_microseconds // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
WREG = TMR0L // don't care about timer low byte, but need to update TMR0H (16-bit mode)
If TMR0H > 200 Then // threshold for determining end of message - 0 is about 20ms
gap_found = bitcount // indicate that an inter-message gap found at bit gap-found
EndIf
Wend
int_microseconds.bytes(0) = TMR0L // background TMR0H latches during read of TMR0L
int_microseconds.bytes(1) = TMR0H
space_usecs(bitcount) = int_microseconds // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
Next
EE.WriteByte(255, gap_found) // write number of bits to EEPROM...
For bitcount = 0 To (NumCycles - 1) // adjust for the maximum number of bits wanted
EE.WriteWord(bitcount * 4, mark_usecs(bitcount)) // write mark data to EEPROM...
EE.WriteWord((bitcount * 4) + 2, space_usecs(bitcount)) // write space data to EEPROM...
Next
LATB = 0 // diagnostic - IR read finished
EndIf
////// IR transmit routine //////
If PORTA.1 = 0 Then // loop while button/switch is low
LATB = 2 // diagnostic - sending IR
num_bits = EE.ReadByte(255) // read number of bits from EEPROM...
LATD = num_bits // LEDs on PORTD show bit count stored in EEPROM
If num_bits > NumCycles Then // more bits than can be handled - probably due blank EEPROM
For num_bits = 0 To 20 // flash PORTB LEDs to indicate error
LATB = $ff // all diagnostic LEDs on
DelayMS(200)
LATB = 0 // all diagnostic LEDs off
DelayMS(200)
Next
num_bits = 1 // send only 2 bits
EndIf
For bitcount = 0 To num_bits // adjust for the maximum number of bits wanted
int_microseconds = EE.ReadWord(bitcount * 4) // read mark data from EEPROM...
send_mark() // send mark of length in variable int_microseconds
int_microseconds = EE.ReadWord((bitcount * 4) + 2) // read space data from EEPROM...
send_space() // send space of length in variable int_microseconds
Next
pwm_stop()
DelayMS(1000) // limit send repeat rate
EndIf
Wend
Above code is original and free for anyone to ignore, fix, use, improve in any way they wish.
// from hexreader
// https://www.electro-tech-online.com/threads/a-remote-control-using-a-pic.160501/page-3 post #52
// v6 rev2 - replace strings with word arrays
//
// read IR remote control signal to PIC EEPROM then re-send when wanted
// I will test using Sony TV IR remote
// EEPROM will contain sets of 4 bytes in the order mark-low_byte, mark-high_byte, space_low_byte, space-high-byte
// combine high/low bytes to get number of microseconds mark or space
// number of bits stored as byte in EEPROM location 255
// Issues to fix
// IR read sometimes goes wrong - ultra-short messages - or something
// status 29 December 2020 at 02:00 UTC
// - seems to work, but this is a really dumb program that does not yet stop at end of message
// - press the button twice or set correct number of bits in code
// - will improve if and when I get bored enough
// amateur code - use at own risk - author accepts no responsibility for anything, anywhere, ever
// I have used direct-register programming, as it is what I am more familiar with - you may use BASIC style code if you wish
// tested on EasyPIC v7 development board with IR click inserted into mikroBUS 2 socket
// tests so far:
// pass Sony TV
// pass RC6 mode 0 - Philips TV
//
// todo RC6 mode 6
// todo RC6 mm
// todo RC5
// todo Samsung TV
// todo NEC 32 bit
// todo NEC extended 32 bit
// simple timer 0 16 bit counter running at 1MHz
// 8Mhz clock provides timer 0 with 2Mhz to prescaler, prescaler 1:2 causes timer 0 to count microseconds
// IR input is on RA3 - not used here
// IR output is on RC1 - 38Khz PWM 2 output
// operating buttons - all button inputs must have pull-up resistor - take low when pressed
// button on RA0 goes low when pressed - select receive mode
// button on RA1 goes low when pressed - select transmit mode
// PORTB LED indications
// all off - nothing happening
// B0 on - receive mode - waiting for IR button press
// B1 on - transmit mode - sending IR
// all LEDs flashing - EEPROM is blank
Device = 18F43K22
Clock = 8
// import EEPROM module
Include "EEPROM.bas"
// Sony protocol:
// 40kHz 7 bits command (LSB first) then 5 bits address
// this is 12 bit, there are also 15 bit and 20 bit versions of Sony protocol
// start bit = 2.4mS mark, .6mS space
// 1 = 1.2mS mark .6mS space, 0 = .6mS mark .6ms space
// repeat every 45mS if key is held down
// Sony device will not respond to a single message,
// - so remotes usually send 3 or more repeated messages
// There is a fundamental issue with measuring raw timing from IR receiver, as the received signal is a slightly distorted reproduction
// of the original waveform sent by IR remote. Space times are shortened a little and mark times are lengthened a little.
// If you are lucky, then the distortion will be small enough that you may acheive re-transmission that is good enough.
Const NumCycles = 50 // maximum message length - a cycle is considered to be a mark followed by a space
Dim mark_usecs(NumCycles) As Word
Dim space_usecs(NumCycles) As Word
Dim bitcount As Byte // count bits
Dim int_microseconds As Word
Dim gap_found As Byte // count bits up to inter-message gap
Dim num_bits As Byte // message bits found from EEPROM
// stop PWM 2 and take RC1 low
Sub pwm_stop()
CCP2CON = 0 // stop PWM
LATC.1 = 0 // IR Tx off
End Sub
// start PWM 2
Sub pwm_start()
CCP2CON = $0c // start PWM
End Sub
Sub send_mark()
pwm_start()
DelayUS(int_microseconds)
pwm_stop()
End Sub
Sub send_space()
pwm_stop()
DelayUS(int_microseconds)
End Sub
// initialise
ANSELA = 0 // all digital
ANSELB = 0 // all digital
TRISB = 0 // all output for diagnostic LEDs
ANSELC = 0 // all digital
TRISC = 0 // all output for diagnostic LEDs and PWM out
ANSELD = 0 // all digital
TRISD = 0 // all output for diagnostic LEDs
LATD = 0 // all LEDs off
CCPR2L = 20 // duty cycle approx 30%
CCPTMRS0 = $0 // use timer 2
PR2 = $38 // adjust for $38=36kHz, $34=38kHz or $31=40kHz
T2CON = $04 // timer 2 on
T0CON = $80 // timer 0 on, 16 bit, fosc/4, prescaler 1:2 - count microseconds
pwm_stop()
While true // main program loop...
LATB = 0 // diagnostic - nothing happening
If PORTA.0 = 0 Then // button or switch on RA0 goes low to read IR message
DelayMS(1000) // allow time for end of previous IR remote message
LATB = 1 // waiting for header
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
Wend
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
gap_found = 0 // initialise
For bitcount = 0 To (NumCycles -1) // adjust for the maximum number of bits wanted
While(PORTA.3) = 0 // wait for IR input to go high - end of next mark bit
Wend
int_microseconds.bytes(0) = TMR0L // background TMR0H latches during read of TMR0L
int_microseconds.bytes(1) = TMR0H
mark_usecs(bitcount) = int_microseconds // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
While(PORTA.3) = 1 // wait for IR input to go low - first leader bit 2.4ms (0x0960 microseconds hex)
WREG = TMR0L // don't care about timer low byte, but need to update TMR0H (16-bit mode)
If TMR0H > 200 Then // threshold for determining end of message - 0 is about 20ms
gap_found = bitcount // indicate that an inter-message gap found at bit gap-found
EndIf
Wend
int_microseconds.bytes(0) = TMR0L // background TMR0H latches during read of TMR0L
int_microseconds.bytes(1) = TMR0H
space_usecs(bitcount) = int_microseconds // expect a count of approximately 2400 for 2.4ms
TMR0H = 0 // gets written later, when TMR0L is written
TMR0L = 0 // clear count and prescaler
Next
EE.WriteByte(255, gap_found) // write number of bits to EEPROM...
For bitcount = 0 To (NumCycles -1) // adjust for the maximum number of bits wanted
EE.WriteWord(bitcount * 4, mark_usecs(bitcount)) // write mark data to EEPROM...
EE.WriteWord((bitcount * 4) + 2, space_usecs(bitcount)) // write space data to EEPROM...
Next
LATB = 0 // diagnostic - IR read finished
EndIf
If PORTA.1 = 0 Then // loop while button/switch is low
LATB = 2 // diagnostic - sending IR
num_bits = EE.ReadByte(255) // read number of bits from EEPROM...
LATD = num_bits // LEDs on PORTD show bit count stored in EEPROM
If num_bits > NumCycles Then // more bits than can be handled - probably due blank EEPROM
For num_bits = 0 To 20 // flash PORTB LEDs to indicate error
LATB = $ff // all diagnostic LEDs on
DelayMS(200)
LATB = 0 // all diagnostic LEDs off
DelayMS(200)
Next
num_bits = 1 // send only 2 bits
EndIf
For bitcount = 0 To num_bits // adjust for the maximum number of bits wanted
int_microseconds = EE.ReadWord(bitcount * 4) // read mark data from EEPROM...
send_mark() // send mark of length in variable int_microseconds
int_microseconds = EE.ReadWord((bitcount * 4) + 2) // read space data from EEPROM...
send_space() // send space of length in variable int_microseconds
Next
pwm_stop()
DelayMS(1000) // limit send repeat rate
EndIf
Wend
I took the liberty of changing your Project 6 code in post #52
I rarely program in BASIC and am very new to Swordfish, so I have a huge amount to learn. I suspect that I will gain more from this thread than Mr Deb will.
I suspect that's true too. VERY true.I rarely program in BASIC and am very new to Swordfish, so I have a huge amount to learn. I suspect that I will gain more from this thread than Mr Deb will.
// standard example of setting configuration fuses
config
OSC = HSPLL,
BOR = off,
BORV = 25