03-09-2010 11:42 AM
Hello all,
I need help regarding some problems arising from connecting a pic 16f877 to labview.. I do have everything working for the most part. I have all 8 ADC on port A and E working and they are all collecting data and sending it to Labview via RS232. The problem i'm having is syncing which ADC belongs to which guage in Labview. . They all display data fine but when I start and stop the information from the ADC's might switch guages. So I need a way to address each guage to make sure the right info is displayed on the correct guage. This is my only input problem. The other problem is output. I want to send info to 4 seperate ports, from labview to the pic. I do have two ports working great but for some reason the pic will only read two bytes and display them on port B and D. I also want to send info to two PWM outs. . . I know (or think) the problem is with the pic reciving the 3rd and 4th byte because i can get the pwm's working if i assign the port B and D data to the PWM. Or One to a port and one pwm. .But not all 4 at once. Any help would be greatly appreciated..
Thanks
Steve
Hears my C for my pic. and I will attatch my Labview VI.
unsigned int an0, an1 ,an2, an3, an4, an5, an6, an7, dig, dig1, pwm1, pwm2;
void InitMain() {
USART_Init(19200);
ADCON1 = 0;
TRISA = 0xFF;
PORTB = 255;
TRISB = 0;
TRISC = 240;
PORTD = 128;
TRISD = 0;
PWM1_Init(5000);
PWM2_Init(5000);
}
void main() {
initMain();
PWM1_Start();
PWM2_Start();
do {
an0 = ADC_Read(0) >> 2;
USART_Write(an0);
an1 = ADC_Read(1) >> 2;
USART_Write(an1);
an2 = ADC_Read(2) >> 2;
USART_Write(an2);
an3 = ADC_Read(3) >> 2;
USART_Write(an3);
an4 = ADC_Read(4) >> 2;
USART_Write(an4);
an5 = ADC_Read(5) >> 2;
USART_Write(an5);
an6 = ADC_Read(6) >> 2;
USART_Write(an6);
an7 = ADC_Read(7) >> 2;
USART_Write(an7);
if (USART_Data_Ready()) {
dig = USART_Read();
}
if (USART_Data_Ready()) {
dig1 = USART_Read();
}
if (USART_Data_Ready()) {
pwm1 = USART_Read();
}
if (USART_Data_Ready()) {
pwm2 = USART_Read();
}
PORTB = (dig);
PORTD = (dig1);
Pwm1_Change_Duty(pwm1);
Pwm2_Change_Duty(pwm2);
Delay_ms(100);
}
while (1); // endless loop
}
03-09-2010 12:48 PM
to have discriminated what value corresponds to a particular converter why dont you transmit a letter and the value: for example AN0 is a, and AN1 y b and so on. So the value you should send is for AN0 is "a###" where ### are the values you are transmiting from pic to the pc.
in transmiting from pc to pic you could do the same trick.
i couldn't open your vi's because my version is older.
03-09-2010 05:43 PM
03-16-2010 02:53 PM
Yes I see what your saying, i could use 255 for the start bit and take 1 away from all the ADC data before sending it. So data could be a max of 254 and 255 would be the start bit. . I was wondering how the pic sent it's info using the data_write function and if it used start and stop bits after every write command. If it doesen't then i should be able to sync it by using the start and stop bits. After labview detects a start bit recieve the full 8 bytes. It may be doing this now because it seems to work correctly for reading ADC 95% of the time. But my major problem The one that is driving me insane is why can i only recieve (on the pic) two bytes at a time and assign them to only two variables. Do I need to clear my recieve buffer after recieving two bytes? If someone could look at me C-code and my labview VI it would be great.
Thanks
Steve
03-16-2010 03:12 PM
You misunderstood what I was saying. I was talking about writing bytes, not bits. You cannot write bits on a serial port - you must write a full byte. The serial port protocol handles the start/stop bits for the transmission, not your data. Likewise, when you read data you read bytes.
I did look at your C code. Right now you're doing a USART_Write(an0) for example. You did not show USART_Write, but my assumption is that it's writing the value rea, which is a single byte. What I'm talking about is instead of doing a single write you would do either
USART_Write(START_BYTE)
USART_Write(an0)
USART_Write(an1)
USART_Write(an2)
...
or
USART_Write(START_BYTE)
USART_Write(an0)
USART_Write(an1)
USART_Write(an2)
...
USART_Write(STOP_BYTE)
or something similar, so the receiving end knows when the set of data arrives.
03-16-2010 07:48 PM
Hey smercurio_fc.
Haha I accually think we're talking about the exact same thing. I mistakinly said 255 as a start bit when I ment byte, as there would be no way for one bit to equal 255. I ment byte. Sorry for the mistake . as I was saying i'd have to take away 1 from the ADC data so the data could only go from 0 - 254 so when the usart sent a 255 it could only be the start byte. Then I could have labview keep serching for a 255. When this condition is true read next 8 bytes of data and display them on guages . . I think thats what we both ment??? Correct me if i'm wrong.
So yeah, as you were saying I could do is something like this? It looks like it should work and makes sense. Any Ideas on my recieve problem and why I can only recieve 2 bytes on the PIC?
Thanks
Steve
unsigned int an0, an1 ,an2, an3, an4, an5, an6, an7, dig, dig1, pwm1, pwm2;
void InitMain() {
USART_Init(19200);
ADCON1 = 0;
TRISA = 0xFF;
PORTB = 255;
TRISB = 0;
TRISC = 240;
PORTD = 128;
TRISD = 0;
PWM1_Init(5000);
PWM2_Init(5000);
}
void main() {
initMain();
PWM1_Start();
PWM2_Start();
do {
USART_Write(255);
an0 = ADC_Read(0) >> 2;
an0 = (an0 - 1); / 1 is taken away from the value of ADC read, because if Voltage In is 5 volts ADC value
USART_Write(an0); / will be 255 and labview will mistake the data as the start byte. Data can read from 0 - 254.
an1 = (an1 - 1);
USART_Write(an1);
an2 = ADC_Read(2) >> 2;
an2 = (an2 - 1);
USART_Write(an2);
an3 = ADC_Read(3) >> 2;
an3 = (an3 - 1);
USART_Write(an3);
an4 = ADC_Read(4) >> 2;
an4 = (an4 - 1);
USART_Write(an4);
an5 = ADC_Read(5) >> 2;
an5 = (an5 - 1);
USART_Write(an5);
an6 = ADC_Read(6) >> 2;
an6 = (an6 - 1);
USART_Write(an6);
an7 = ADC_Read(7) >> 2;
an7 = (an7 - 1);
USART_Write(an7);
if (USART_Data_Ready()) {
dig = USART_Read();
}
if (USART_Data_Ready()) {
dig1 = USART_Read();
}
if (USART_Data_Ready()) {
pwm1 = USART_Read();
}
if (USART_Data_Ready()) {
pwm2 = USART_Read();
}
PORTB = (dig);
PORTD = (dig1);
Pwm1_Change_Duty(pwm1);
Pwm2_Change_Duty(pwm2);
Delay_ms(100);
}
while (1); // endless loop
}
03-16-2010 10:40 PM
03-17-2010 09:00 AM
One thing I wanted to point out in your C code that I forgot to mention in my last reply is that you can't just blindly subtract one for all values. You have unsigned integers as the datatype for your variables. If the reading you have is 0, then subtracting one may create a rollover. You should check the documentation for your PIC and/or compiler, or better yet, don't subtract if the value is zero. You may also want to consider only doing so if the value you get is 255. Otherwise, you'd be incurring a reading error for all values, rather than having a 1-bit error on just the max value, which is probably OK.
Of course, the more obvious issue you have is that you are not correctly reading the ADC. That PIC has 10-bit ADCs. Yet you are taking the reading and right-shifting by 2 positions, effectively throwing away the lower 2 bits. Is there a reason why you are doing this?