|
|
View previous topic :: View next topic |
Author |
Message |
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
Need help for IR communication |
Posted: Sat Apr 21, 2012 4:42 pm |
|
|
Hi everyone!
I really need your help on this. I'd like to transmit temperature between two 16f877a pics. I am using rs 232 and pwm. I used 74HCT00 to combine data and the PWM frequency but at the receiver i am absolutely not getting anything. The oscillator I am using is 12MHZ and the baud of 2400.
Looking at the oscilloscope I am receiving the same signal as one I transmitted but I am not getting anything.
Is there anyone with a better idea on this? Help plz
Thx |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sat Apr 21, 2012 8:38 pm |
|
|
So you are chopping a 2400 baud serial signal with a PWM signal? What is the PWM frequency and duty cycle? What do you do to this signal on the receiving end? What exactly do you mean by "i am not getting anything"?
I think we need a lot more explanation. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Sun Apr 22, 2012 5:19 am |
|
|
You should go back one step....
Have you sucessfully built the 2 PICs and run code to allow RS232 communications flawlessly ? By this I mean 2 separate modules only connected by 2 wires (data and ground).
There can be hundreds of reasons why 'it doesn't work', however if you've got the project to the stage above, it eliminates a LOT of possible reasons! |
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Sun Apr 22, 2012 3:58 pm |
|
|
Hello again,
Here is clear explanations of my problem:
I successfully displayed the temperature using PIC 16F877A and i want to transmit it to another PIC16F877A using infrared.For transmission i generated the PWM frequency of 38 KHz as the carrier with the duty of 50%.The output data and the carrier are combined using 74HCT00.Looking at the scope this is working well even if the PWM is causing some disturbances on the displays.
The biggest problem is at the receiving side.The output of the photo transistor i am using seems to produce the same signal as the one i transmitted but when i put to pin RC7 of the MCU nothing is displayed on the seven segments displays.
Here i put my code for the receiver and transmitter so you can help me from this.
Thank you
code for the receiver:
Code: |
#include<16f877a.h>
#fuses HS,NOWDT
#use delay(clock=12000000)
#use rs 232(baud=2400, rcv=PIN_C7)
byte const digit[]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//representation of digits from 0 to 9
char display[2];//for displaying;
byte c;
int main()
{
set_tris_B(0x00);//port B defined as output
output_high(PIN_B7);
while(true)
{
c=getc();
delay_ms(10);
output_d(0x01);
display[0]=c%10;
output_B(digit[display[0]]);
delay_ms(10);
output_d(0x02);
display[1]=c/10;
output_B(digit[display[1]]);
}
}
|
code for the transmitter:
Code: |
#include <16F877A.h>
#device *= 16
#device adc=10
#fuses HS, NOWDT
#use delay(clock=12MHz)
#use rs232(baud=1200, xmit=PIN_C6, bits=8, parity=N)
byte const digit[]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//representation of digits from 0 to 9
char display[2]; //for displaying;
float value; //variable to store the returned value of conversion
float value2; //variable to store the conversion result
float new_value; //variable to store conversion equivalent voltage
long int temp; //variable to store the temperature;
byte c;
void main()
{
set_tris_A(0xFF); //port A defined as input
set_tris_B(0x00); //port B defined as output
set_tris_D(0x00); //port D defined as output
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCk_INTERNAL);
set_ADC_channel(0);
setup_ccp1(ccp_PWM);
setup_timer_2(T2_DIV_BY_1,78,1); //PR2 value=78 for 38 KHz
set_pwm1_duty(39); //50%duty
output_high(PIN_B7);
output_d(0x00);
while(true)
{
delay_ms(10);
value=read_adc(ADC_START_ONLY);
value2=read_adc(ADC_READ_ONLY);
new_value=(value2*5)/1023;
temp=new_value*100;
output_d(0x01); //equivalent to:output_high(PIN_D0)and output_low(PIN_D1);
//PIN D0 is connected to Vcc of the tens display using PNP transistor
display[0]=temp%10;
output_B(digit[display[0]]);
delay_ms(10);
output_d(0x02); //equivalent to output_low(PIN_D0);and output_high(PIN_D1);
//PIN D1 is connected to Vcc of the units display using PNP transistor
display[1]=temp/10;
output_B(digit[display[1]]);
if(temp>=32)
{
output_high(PIN_C4);
}
else
{
output_low(PIN_C4);
}
c=temp;
putc(c); //send data to pin RC6
}
} |
|
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Sun Apr 22, 2012 4:04 pm |
|
|
There is a small change on the transmitter:
#use rs232(baud=2400, xmit=PIN_C6)
instead of the one above
Thx and i still waiting wating for you |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Sun Apr 22, 2012 5:47 pm |
|
|
Hi,
There are a lot of problems with your strategy, and your code.
The biggest issue is your overall strategy to use the serial comms. to transfer your data. You are taking a serial data stream at the transmitter, and using it to modulate a 38 KHz pulse train, and then expecting the receiver PIC to decode this signal with (in this case) a software UART. That's not going to work! For serial comms. to work, the incoming signal must adhere to some very specific parameters, and your input signal is no where near compatible. You say that you are getting the "same signal that you are transmitting", and that is well and good, but you must receive the same signal that comes out of the Tx pin in order for this to work, not the modulated signal. IOW, you need to de-modulate the signal prior to decoding it. For a lot of reasons this is not a practical way to proceed.
Some of the other things wrong in your code:
1. You only define a Tx or an Rx pin in your #Use RS232 statements. This will cause the compiler to generate a software UART even though you are connecting to the hardware UART pins. Define both Tx and Rx pins even though only one will be used in each implementation.
2. Always add 'Errors' to the #Use RS232 statement. This will prevent the hardware UART from locking up if it overflows.
3. Never try to set the TRIS registers unless you have a good reason to do so. The compiler will do this automatically for you.
4. Putc(c) is going to transmit a single byte of data. Is that what you want?
There are probably other issues as well, but that's a good start!
There are a lot of posts on the forum about IR communications, and I think you'll find that none rely on the UART to transmit and receive data, but rather use a single digital input, and a tight piece of code to decode the incoming data stream using a protocol intended for the purpose (ie. RC5). Search the forum, there are examples out there.
John |
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Sun Apr 22, 2012 6:36 pm |
|
|
Thank you very much John, actually I've never searched anything about RC5 but i am going to try. Now when i said that i was receiving the same signal as the one i transmitted, i was meaning the signal output from the transmitting pic (PIN_C6) comparing it with the signal from the output of the IR receiver(phototransistor). I thought that most of the IR receivers automatically demodulate the 38 KHz and maybe that's why i think i am receiving the same signal. Can anyone tell me whether this thought is wrong or not ?
Thx |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Sun Apr 22, 2012 7:38 pm |
|
|
Hi,
You didn't say, so I assumed an IR phototransistor as your receiver. Post a link to the actual part you are using, don't make us guess!
John |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun Apr 22, 2012 9:02 pm |
|
|
If you really are using a phototransistor it does not do any demodulation. Most IR receiver modules do demodulation but not all of them use 38kHz. We really need to know more about the specific receiver you are using. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Mon Apr 23, 2012 2:54 pm |
|
|
Hi there, thank you everyone for your time. To be honest, the IR receiver I am using I got it from an old TV set and on it, is written 106-057A but I didn't find anything related to it. As I said it before transmitting at 38KHz the receiver's output is perfect and today I changed a little bit my code and used putchar()-getchar() instead of putc()-getc() and now the displays are now flashing but very fast that it is not possible to see the number they are displaying. At the first time I thought it is a matter of delays and when I changed them the problem was not solved. Is my code wrong or the hardware?
Waiting for your suggestions.
Thx |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon Apr 23, 2012 3:07 pm |
|
|
Hi,
Without any documentation, there is not a whole lot we are going to be able to help you with. Having said that, your debugging strategy is really flawed. How do you know that your displays are even working correctly? You may be trying to troubleshoot with a tool that itself may be flawed. I recommend that you reduce the problem to it's simplest form, and then build on that. For example, send a single character from the transmitter, and then see if you can receive that single character with your receiver. Until you do that, you are really fooling yourself with the other complexity of what you are trying to do. On the receiver, instead of your digits (which should be tested separately!), I would define a unique serial stream for debugging purposes. You'll need a spare I/O pin and a MAX232 IC (or similar), and then you can send diagnostic info to the PC.
So, on the transmitter side do something like this:
Code: |
while (1){
putc('A');
delay_ms(1000);
}
|
and on the receive side, do something like this:
Code: |
while(1){
fputc(fgetc(Receiver), Debug);
}
|
You should get the idea here. Search the forum for any other info on this.
John |
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Mon Apr 30, 2012 6:15 am |
|
|
Hi everybody,
I finally found the IR receiver which is HS 0038 A2.It's datasheet is on this link:
http://pdf1.alldatasheet.com/datasheet-pdf/view/215919/VISHAY/HS0038A2.html
I saw it operates at 38 KHz carrier and a continuous bits(800bits/s) and with it, the problem still the same.That is the displays at the receiver tend to be the same as the one at the transmitter but the problem is how to make them stable so they can be readable.
I'm waiting your help.
Thx |
|
|
Diogene_Niyigena
Joined: 21 Apr 2012 Posts: 12
|
|
Posted: Fri May 04, 2012 4:14 am |
|
|
Using the IR receiver HS 0038 A2 with the baud of 1200 i am now able to see numbers on segments of the receiver but they are not stable at all.They only take a few seconds and alternate with zero.When i try to increase the baud and delays on the receiver code,the display seems to be clear but still not stable.Can any one help me please!
I changed the codes as follows:
Transmitter code:
#include <16F877A.h>
#device adc=10
#fuses HS, NOWDT
#use delay(clock=12000000)
#use rs 232(baud=1200, xmit=PIN_C6,rcv=PIN_C7,ERRORS,bits=8,PARITY=N)
byte const digit[]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//representation of digits from 0 to 9
byte display[2]; //for displaying;
float value; //variable to store the returned value of conversion
float value2; //variable to store the conversion result
float new_value; //variable to store conversion equivalent voltage
byte temp; //variable to store the temperature;
byte c;
void main()
{
set_tris_A(0xFF); //port A defined as input
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCk_INTERNAL);
set_ADC_channel(0);
setup_ccp1(ccp_PWM);
setup_timer_2(T2_DIV_BY_1,78,1); //PR2 value=78 for 38 KHz
set_pwm1_duty(39); //50%duty
output_high(PIN_B7);
output_d(0x00);
while(true)
{
delay_ms(10);
value=read_adc(ADC_START_ONLY);
value2=read_adc(ADC_READ_ONLY);
new_value=(value2*5)/1023;
temp=new_value*100;
output_d(0x01); //equivalent to:output_high(PIN_D0)and output_low(PIN_D1);
//PIN D0 is connected to Vcc of the tens display using PNP transistor
display[0]=temp%10;
output_B(digit[display[0]]);
delay_ms(10);
output_d(0x02); //equivalent to output_low(PIN_D0);and output_high(PIN_D1);
//PIN D1 is connected to Vcc of the units display using PNP transistor
display[1]=temp/10;
output_B(digit[display[1]]);
c=temp;
putc(c);
if(temp>=32)
{
output_high(PIN_C4);
}
else
{
output_low(PIN_C4);
}
}
}
Receiver code:
#include <16f877a.h>
#fuses HS,NOWDT
#use delay(clock=12000000)
#use rs 232(baud=1200,xmit=PIN_C6,rcv=PIN_C7,ERRORS,bits=8,PARITY=N)
byte const digit[]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//representation of digits from 0 to 9
byte display[2];//for displaying;
byte c;
void main()
{
output_high(PIN_B7);
while(true)
{
c=getc();
output_d(0x01);
display[0]=c%10;
output_B(digit[display[0]]);
delay_ms(20);
display[1]=c/10;
output_d(0x02);
output_B(digit[display[1]]);
delay_ms(20);
}
} |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Fri May 04, 2012 5:34 am |
|
|
It appears from the code you're using a three of 7 segment displays to show the data and are using software timers to 'mux' the displays.
If this is so, then the serial baudrate will not alter the problem you're seeing.
The multiplex rate( time delays) has to be altered to something less than 100Hz(maybe 50-60 Hz).
For a test, just hardcode say '123' into the 'data' of the receive PIC instead of getting data from the transmitter PIC. That way you can change code to get a stable display. You could have a simple loop of say '123', '012','010' as test numbers and show each one for say 1/2 second , again to test your timings. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|