View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 18, 2021 2:02 am |
|
|
I was able to make it work. First I ordered this very cheap IR remote
and sensor set from Amazon. It's even cheaper from China on EBAY
but I didn't want to wait:
https://www.amazon.com/dp/B07S67SFSF/
Then I connected one of the IR sensors to the Microchip Low Pin Count
board, running at +5 volts. I also connected Vcc and Gnd for the sensor.
1. I moved the IR sensor pin to pin A2 on the PIC. He originally had it
on pin A3. That's the MCLR pin, so he had to use the NOMCLR fuse.
I personally like to use the MCLR pin as MCLR. I have a 10K
pullup on it.
2. I did not use pin A0 or A1 for anything because those are the ICSP
pins for the Pickit3, and I don't want anything on them.
3. I got rid of #use fast_io(A). I don't like fast io. I let the compiler
handle the TRIS.
4. I added a software RS-232 transmit on pin A4. I like to see what I'm
doing, and print results on TeraTerm on my PC.
5. I got rid of the #fuses statement. For this little test program I went with
the default fuses that the compiler assigns. They can be reviewed at the
end of the .LST file.
6. I let the compiler handle setting up the clock by using:
#use delay(internal=32M)
I dropped all the zeros after the 32 because it's way easier to read this way.
7. Most important, I did not try to make his program work as is.
I cut out his if() statements for his codes. Instead I went diagnostic
and used printf to display the codes that I'm actually getting.
In short, I went for speed of editing the program and for reliability.
Also, after I made these changes, it worked immediately.
On the little remote, if I press a key, I get these codes:
Press 1: 00ff30cf
press 2: 00ff18e7
press CH: 00ff629d
These correspond exactly with the codes listed on this website in a table:
https://www.circuitbasics.com/arduino-ir-remote-receiver-tutorial/
Scroll down to the part where he shows a terminal window for:
Quote: | COM 7 (Arduino / Genuino Uno) |
Just below that image, he has a table of the codes. He's using the
same remote as sold on Amazon and EBAY. This remote is tiny.
It's 3.4 inches long by 1.6 inches wide (8.6cm x 4.0cm).
The original code (same as used by Denny) comes from the receiver
code on this webpage:
http://ccspicc.blogspot.com/2016/09/nec-ir-transmitter-receiver-circuit-pic-c-code.html
Here is the modified code I used to test the hardware (with CCS vs. 5.103):
Code: | // Extended NEC protocol IR remote control decoder using PIC12F1822 CCS PIC C code
// http://ccspicc.blogspot.com/
// [email protected]
// Use at your own risk
#include <12F1822.h>
#use delay(internal=32M)
#use rs232(baud=9600, xmit=PIN_A4)
//#use fast_io(A)
#define IR_Sensor PIN_A2
unsigned int32 ir_code;
short nec_remote_read()
{
unsigned int16 count = 0;
unsigned int8 i;
// Check 9ms pulse (remote control sends logic high)
SET_TIMER1(0);
while(!input(IR_Sensor) && (count < 9500))
count = GET_TIMER1();
if( (count > 9499) || (count < 8500))
return FALSE;
// Check 4.5ms space (remote control sends logic low)
SET_TIMER1(0);
count = 0;
while((input(IR_Sensor)) && (count < 5000))
count = GET_TIMER1();
if( (count > 4999) || (count < 4000))
return FALSE;
// Read message (32 bits)
for(i = 0; i < 32; i++){
SET_TIMER1(0);
count = 0;
while(!input(IR_Sensor) && (count < 650))
count = GET_TIMER1();
if( (count > 649) || (count < 500))
return FALSE;
count = 0;
SET_TIMER1(0);
while((input(IR_Sensor)) && (count < 1800))
count = GET_TIMER1();
if( (count > 1799) || (count < 400))
return FALSE;
if( count > 1000) // If space width > 1ms
bit_set(ir_code, (31 - i)); // Write 1 to bit (31 - i)
else // If space width < 1ms
bit_clear(ir_code, (31 - i)); // Write 0 to bit (31 - i)
}
return TRUE;
}
//===============================
void main()
{
// setup_oscillator(OSC_8MHZ | OSC_PLL_ON); // Set internal oscillator to 32MHz (8MHz and PLL)
// output_a(0);
// set_tris_a(8);
SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_8);
while(TRUE)
{
while(input(IR_Sensor)); // Wait until IR_Sensor pin falls
nec_remote_read();
printf("%lx\n\r", ir_code);
}
}
|
|
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Thu Mar 18, 2021 4:31 am |
|
|
Thanks PCM, I purchased the same remote package on Amazon, to originally test and it looks as if the codes are different than the one’s the original author had in Their source code. That would explain a lot, and appreciate the time and effort you’ve put into this, I’ve learned a lot!
It would really help if I build a decoder first, so that I know the exact hexadecimal codes to use. I have a 1602 LCD screen in my stash, so I may do that first. |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Thu Mar 18, 2021 6:07 am |
|
|
PCM, do you see a problem migrating this code to a 16F1823? I want to have access to a few more pins, because I like your idea of not using the MCLR pin for an I/O.
Last edited by Denny9167 on Thu Mar 18, 2021 8:08 am; edited 2 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Thu Mar 18, 2021 7:30 am |
|
|
I'd say 'no problem'. They are close relatives. However if I was doing that
I'd say go to the 1824. More ROM is always useful as well as the extra
pins. The 1829 is still from the same family, and has even more pins and
EEPROM etc.. |
|
|
dexta64
Joined: 19 Feb 2019 Posts: 11
|
Clock must be selected in the oscillator setting. |
Posted: Fri Mar 19, 2021 12:23 am |
|
|
in this row you must select the internal clock.
Code: |
setup_oscillator(OSC_8MHZ | OSC_PLL_ON | OSC_INTRC);
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 19, 2021 3:15 am |
|
|
With CCS vs. 5.103, you don't need that line. The compiler will set it up
to use the PLL and the correct #fuses for the 12F1822, based on this line:
Code: | #use delay(internal=32M) |
|
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Fri Mar 19, 2021 9:21 am |
|
|
I’m going to re-build the code with the new hexadecimal commands that PCM
Pointed out in a earlier post, and see if that doesn’t get this going. |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Fri Mar 19, 2021 3:41 pm |
|
|
Works great!! With the right command codes!
I have a question for the experts, i don’t want two of the LED’s to latch, but only remain high as long as the switch is pressed. A “while” instead of “if” statement on the specific output pins possibly? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 20, 2021 1:05 am |
|
|
Here's a quick way to do it, as shown in bold below. Anytime it receives
the IR code, it will turn on the LED for 200 ms. This delay can potentially
cause problems, because it blocks anything else from happening during
the delay time.
This delay could be done with a timer interrupt, but again, you'd have
interrupts potentially occurring when the PIC should be receiving data.
Try this, see if it solves your problem. You need to copy that code for
each LED.
Quote: | if(nec_remote_read())
{
if(ir_code == 0x40BF00FF)
{
output_high(PIN_A0);
delay_ms(200);
output_low(PIN_A0);
}
if(ir_code == 0x40BF807F)
output_toggle(PIN_A1);
if(ir_code == 0x40BF40BF)
output_toggle(PIN_A2);
if(ir_code == 0x40BF20DF)
output_toggle(PIN_A4);
if(ir_code == 0x40BFA05F)
output_toggle(PIN_A5);
} |
|
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Sat Mar 20, 2021 3:59 am |
|
|
PCM programmer wrote: | Here's a quick way to do it, as shown in bold below. Anytime it receives
the IR code, it will turn on the LED for 200 ms. This delay can potentially
cause problems, because it blocks anything else from happening during
the delay time.
This delay could be done with a timer interrupt, but again, you'd have
interrupts potentially occurring when the PIC should be receiving data.
Try this, see if it solves your problem. You need to copy that code for
each LED.
Quote: | if(nec_remote_read())
{
if(ir_code == 0x40BF00FF)
{
output_high(PIN_A0);
delay_ms(200);
output_low(PIN_A0);
}
if(ir_code == 0x40BF807F)
output_toggle(PIN_A1);
if(ir_code == 0x40BF40BF)
output_toggle(PIN_A2);
if(ir_code == 0x40BF20DF)
output_toggle(PIN_A4);
if(ir_code == 0x40BFA05F)
output_toggle(PIN_A5);
} |
|
I will try that, I won’t be able to use this Amazon remote because I
believe it transmits a different code when any button remains pressed, but I’m
Still working on the Transmitter that goes with this. I just need it for 2 pins the others will be used to initiate relays, and they will need to remain latched. |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Sat Mar 20, 2021 4:09 am |
|
|
I have another project that I’ve used where
one can change the action of the relays from latched to momentary.
But it’s written in assembly code, I’m sure something similar can be done
In C.
https://picprojects.org/projects/ir/sirc10f/index.htm |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Sat Mar 20, 2021 5:37 am |
|
|
PCM programmer wrote: | Here's a quick way to do it, as shown in bold below. Anytime it receives
the IR code, it will turn on the LED for 200 ms. This delay can potentially
cause problems, because it blocks anything else from happening during
the delay time.
This delay could be done with a timer interrupt, but again, you'd have
interrupts potentially occurring when the PIC should be receiving data.
Try this, see if it solves your problem. You need to copy that code for
each LED.
Quote: | if(nec_remote_read())
{
if(ir_code == 0x40BF00FF)
{
output_high(PIN_A0);
delay_ms(200);
output_low(PIN_A0);
}
if(ir_code == 0x40BF807F)
output_toggle(PIN_A1);
if(ir_code == 0x40BF40BF)
output_toggle(PIN_A2);
if(ir_code == 0x40BF20DF)
output_toggle(PIN_A4);
if(ir_code == 0x40BFA05F)
output_toggle(PIN_A5);
} |
|
It seems to be working, I did away with the “#use fast_io” directive also. |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Sat Mar 20, 2021 7:52 am |
|
|
One more question, is it possible to have only one PiN engaged at a time? Meaning each time a command is sent, it engages one PIN at a time, and whenever another command is sent, it engages another pin and turns off the others. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Sat Mar 20, 2021 8:49 am |
|
|
Of course it is.
If you just have the code for button 1 turn on it's pin, and turn the others
off, then button 2 does the same, 3 etc. etc..
Then if you push 1, this pin will go on, and all others off. Staying on
till another button is pressed. |
|
|
Denny9167
Joined: 15 Feb 2021 Posts: 49
|
|
Posted: Sat Mar 20, 2021 10:02 am |
|
|
PCM programmer wrote: | Here's a quick way to do it, as shown in bold below. Anytime it receives
the IR code, it will turn on the LED for 200 ms. This delay can potentially
cause problems, because it blocks anything else from happening during
the delay time.
This delay could be done with a timer interrupt, but again, you'd have
interrupts potentially occurring when the PIC should be receiving data.
Try this, see if it solves your problem. You need to copy that code for
each LED.
Quote: | if(nec_remote_read())
{
if(ir_code == 0x40BF00FF)
{
output_high(PIN_A0);
delay_ms(200);
output_low(PIN_A0);
}
if(ir_code == 0x40BF807F)
output_toggle(PIN_A1);
if(ir_code == 0x40BF40BF)
output_toggle(PIN_A2);
if(ir_code == 0x40BF20DF)
output_toggle(PIN_A4);
if(ir_code == 0x40BFA05F)
output_toggle(PIN_A5);
} |
|
Instead of the delay, which only works with the initial command, how would the statement be worded to keep the output high so long as the command is being received and then go low when it’s not(button release on transmitter). |
|
|
|