LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Issues reading ascii values

Hi,

 

Im currently trying to read data off of an analog to digital converter and use that data to change the levels on a gui display. I have the program reading in ASCII data and displaying the appropriate levels on the gui using this data but it seems that after the program reaches the 128th ascii value it no longer changes the gui. I have a seperate gui displaying the ASCII values produced by the analog to digital converter and it is displaying ascii data but this data doesnt seem to follow the traditional ASCII II table and wont change the gui level.

 

Here is the function in question which is being used inside a timer function which samples data every one second

 

 int CVICALLBACK timer_function(int panel, int control, int event,
                void *callbackData, int eventData1, int eventData2)
{
    switch(event)
    {
            double tank_lev=0;
            double i=0;
            read_data[0] = '\0';
        
            FlushInQ(1);
            FlushOutQ(1);

            
            case EVENT_TIMER_TICK:
                 OpenComConfig (1, "", 9600, 0, 8, 1, 512, 512);
                read_cnt=1;        
                bytes_read =  ComRd(1, read_data, read_cnt);
                CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
                SetCtrlVal (serial, SERIAL_TBOX_READ, tbox_read_data);
                
                for(i=0; i<=1024; i++)
                {
                    if(tbox_read_data[0]==i)
                    {
                        SetCtrlVal(panel_handle,PANEL_Tank, i);
                        SetCtrlVal(panel_handle, PANEL_Chart1, i, 1,0,0, VAL_DOUBLE);
                    }
                }
                                         
                break;                                                        
            case EVENT_RIGHT_CLICK :
                break;
    }
    return 0;
}

 

Any assistance would be appreciated,

thanks

0 Kudos
Message 1 of 5
(3,677 Views)

I can't figure out now the reason for your 128 byte problem, but there are a couple of suggestions that may help you to simplify the code and maybe obtain better results.

 

First of all, you are opening the com port every second, but you are never closing it! Even supposing you close the port before exiting the timer, you are flushing the queues before opening the port! In every case, opening and closing serial ports so often is not a clean policy: you should open the port at the beginning of your program and close it at the end, leaving only the flushing and reading tasks inside the timer callback.

 

Second hint: in the timer callback you are simply reading from the queue; in case no message is present at the port you gat he full timeout, which I seem to remember defaults to 10 seconds. Such a long time interferes with regular timer scheduling and is not a good practice for a timer callback which should be as short as possible. In this case you could use SetComTime immediately after opening the port to set a shorter timeout, and in the timer callback use GetInQLen (1) to detect how many characters are present to read.

 

Last item, what a complicated mechanism have you set to display your data! Here you must consider that a single byte can only hav value between 0 and 255 (or -127 to 125 if signed) so it's perfectly useless to test it up to 1024. Next, a numeric indicator can directly display your data if set to display integers and using SetCtrlVal (panelHandle, PANEL_CONTROL, (int)tbox_read_data[0]); similar methods can be use on the chart to avoid scanning for single byte values.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 5
(3,665 Views)

can you  confirm what you are expecting the analogue to digital converter to send.

 

is it  a single byte that represents the a to d value   ie -128 to +127 

or is it a stream of ASCII characters that represent the a to d value. ??

 

your program is currentally looking at the first character read from the serial interface

and will only match valules between -128 and +127  (if tbox_read_data is declared as a char) or (0 to 256 if tbox_read_data is declared as an unsigned char)  (you also will need to change defination of the read_data array to match  that of the tbox_read_data)

 

 (again i am assuming you are useing a windows machine  on sun machines the 8th bit on the serial port is undefined)

 

Colin

 

 

 

 

 

 

 

 

 

Message 3 of 5
(3,649 Views)
Hey, appreciate the help the unsigned char did do the trick. But as for the improvements that were mentioned, I agree I would like to remove that OpenComConfig statment from the loop but everytime i do i get the error Port not open when its not in there. Was wondering how to fix that
0 Kudos
Message 4 of 5
(3,611 Views)

One possible option is to place it in the main ( ) before the RunUserInterface. You could additionally set the timer in disabled state in the UIR editor and use SetCtrlAttribute (panelHandle, timerID, ATTR_ENABLED, 1); after successfully opening the port.

Another option is that you have a button that starts the acquisition progress: within its callback you can place both the port opening and the timer enable (which in this case is mandatory to prevent getting errors).

Remember to close the port at program end.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 5
(3,603 Views)