0
\$\begingroup\$

So I've been working on this project for some time now and I've hit a wall since I'm new to using pickit3 and using C language is not my strong. Basically what I'm trying to do is use two micro-controllers to communicate to each other using an infrared I've manage to program the first PIC which creates different pulses using various input combination using 4 switches. For example (0000 = 200 us pulse,0001 =250 us pulse). now for the receiver i need to capture the pulses and display them using 4 LED's (200us = 0000, 250us = 0001). the code below is the code i did for the First micro-controller. MY question is how would I do the receiver part of the code. i know i should use Timer1 or Timer0 from reading the data sheets. but i havent been able to work something out even from using other examples where people make use of these timers/counters.

main(){ ANSEL =0b000000; TRISC=0b110111; PORTC=0b000000; OSCCAL=0b11111; while(1){ if (RC0==0 && RC1==0 && RC2==0 && RC4==0){ RC3=1; __delay_us(183); RC3=0; __delay_us(166);} else if (RC0==0 && RC1==0 && RC2==0 && RC4==1){ RC3=1; __delay_us(229); RC3=0; __delay_us(196);} else if (RC0==0 && RC1==0 && RC2==1 && RC4==0){ RC3=1; __delay_us(276); RC3=0; __delay_us(234);} else if (RC0==0 && RC1==0 && RC2==1 && RC4==1){ RC3=1; __delay_us(322); RC3=0; __delay_us(264);} else if (RC0==0 && RC1==1 && RC2==0 && RC4==0){ RC3=1; __delay_us(368); RC3=0; __delay_us(318);} else if (RC0==0 && RC1==1 && RC2==0 && RC4==1){ RC3=1; __delay_us(415); RC3=0; __delay_us(348);} else if (RC0==0 && RC1==1 && RC2==1 && RC4==0){ //500us RC3=1; __delay_us(460); RC3=0; __delay_us(385);} else if (RC0==0 && RC1==1 && RC2==1 && RC4==1){ //550us RC3=1; __delay_us(508); RC3=0; __delay_us(415);} else if (RC0==1 && RC1==0 && RC2==0 && RC4==0){ //600us RC3=1; __delay_us(555); RC3=0; __delay_us(500);} else if (RC0==1 && RC1==0 && RC2==0 && RC4==1){ //650us RC3=1; __delay_us(600); RC3=0; __delay_us(530);} else if (RC0==1 && RC1==0 && RC2==1 && RC4==0){ //700us RC3=1; __delay_us(646); RC3=0; __delay_us(568);} else if (RC0==1 && RC1==0 && RC2==1 && RC4==1){ //750us RC3=1; __delay_us(694); RC3=0; __delay_us(600);} else if (RC0==1 && RC1==1 && RC2==0 && RC4==0){ //800us RC3=1; __delay_us(738); RC3=0; __delay_us(650);} else if (RC0==1 && RC1==1 && RC2==0 && RC4==1){ //850us RC3=1; __delay_us(785); RC3=0; __delay_us(680);} else if (RC0==1 && RC1==1 && RC2==1 && RC4==0){ //900us RC3=1; __delay_us(828); RC3=0; __delay_us(718);} else if (RC0==1 && RC1==1 && RC2==1 && RC4==1){ //950us RC3=1; __delay_us(880); RC3=0; __delay_us(750);} }} 
\$\endgroup\$
3
  • \$\begingroup\$ Wait for the signal; Start the timer; Wait for the signal to turn off; Read the timer; Calculate the time interval (or use trial and error); This will take all the time the PIC has, so start studying how to start and stop the timer using interrupts. \$\endgroup\$ Commented Dec 4, 2017 at 15:22
  • 1
    \$\begingroup\$ Why don't you use the USART? to communicate between PICs. How far is the link? Use like a TV remote IR Tx/Rx with parity for some error detection. You only need to use 4 of 8 bits. \$\endgroup\$ Commented Dec 4, 2017 at 15:58
  • \$\begingroup\$ e.g. ~38kHz IR carrier then OOK with negative logic. Low speed, long range \$\endgroup\$ Commented Dec 4, 2017 at 16:09

2 Answers 2

0
\$\begingroup\$

You don't need to use a hardware timer, but it can improve measurement resolution and accuracy. The 16F676 has a 16 bit timer (TMR1) with 'Gate Control' (/T1G) which can provide higher resolution than a typical software timing loop.

To work reliably the timing resolution has to be high enough to handle sampling jitter, clock speed variation between MCUs, and noise in the received signal. TMR1 can be clocked at Fosc/4 which gives 1us resolution when using the internal 4MHz oscillator, and its maximum count of 65535 is enough to directly measure pulse widths up to ~65ms. /T1G accepts active low pulses, which your IR detector circuit must be configured to match.

How to use the TMR1 Gate feature to measure the width of a pulse

After measuring the pulse width you compare it to values that bracket the pulse widths you want to detect. For example to discriminate between a 200us and 250us pulse the comparison values might be 175us, 225us, and 275us. 175us-225us would be detected as 200us, 225us-275us would be 250us, and anything else would be invalid.

\$\endgroup\$
-1
\$\begingroup\$

Take a look at the CCP (capture, compare, pulse-width modulation) module. In capture mode it can grab the free running 16-bit timer 1. You can use successive captures to compute the time between the captures in firmware.

\$\endgroup\$
3
  • \$\begingroup\$ i don't think this specific pic has ccp \$\endgroup\$ Commented Dec 4, 2017 at 15:44
  • \$\begingroup\$ You don't think it has one!? You obviously need to read the datasheet. If it doesn't have a CCP module, then use a PIC that does, or wire the event into the INT pin or use interrupt on change. In both those methods you'd do the capture of timer 1 in firmware, then the rest is the same regardless of timer 1 was captured. \$\endgroup\$ Commented Dec 4, 2017 at 15:55
  • \$\begingroup\$ i did read the data sheet and yes it doesn't have a ccp. I've done my research on timers and i understand how the work. all im asking is for some help on how to start the code with the timers. i cant use another PIC \$\endgroup\$ Commented Dec 4, 2017 at 17:30

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.