LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using the Pic16F877 as an I/O Board via RS-232 with Labview

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
}


 

 

 

 

0 Kudos
Message 1 of 8
(4,981 Views)

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. 

Message 2 of 8
(4,973 Views)
Another way you could do it is to add a "frame start" and "frame end" to your dataset. Right now the PIC is continuously spitting out values. When LabVIEW gets in to read the serial port you don't know which one it's going to get. If you had a special byte value (or 2) to indicate the frame start then you could read the serial port until you see the frame start. Any bytes seen prior to this would be thrown away. Thus, you wouldn't catch part of the sequence.
0 Kudos
Message 3 of 8
(4,959 Views)

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

0 Kudos
Message 4 of 8
(4,907 Views)

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.

0 Kudos
Message 5 of 8
(4,898 Views)

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);

    an1 = ADC_Read(1) >> 2; 

    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
}

 

0 Kudos
Message 6 of 8
(4,882 Views)
Does USART_Data_Ready actually wait until data is ready, or is it just checking the bit for the register to indicate there's data available and then return a 0/1? If it's the latter then it's a simple timing issue. The way the PIC code is set up right now is that it will send out the flag byte, followed by 8 bytes, and then immediately check to see if there's a byte to read. If the first if statement shows no bytes, it immediately goes to the next one, which does the same thing. As well as the next. Thus, your PIC may skip past one or more of those if statements before data actually shows up for it to read. 
0 Kudos
Message 7 of 8
(4,875 Views)

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?

0 Kudos
Message 8 of 8
(4,865 Views)