LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

serial

Hallo mvr,JR
 
Thank you very much I moved the definitions to outside the switch() and compiled and run the project,
all ok ,I can see the buffer plotted on the graph ,
However I have to sort out the byte order in the buffer as the data is not correct ,
this is now great that the port is reading I am Very thankful to you ,
 
Best Regards
Peter Erasmus
Switzerland 
0 Kudos
Message 11 of 20
(2,377 Views)

At the end of this link is the code to do byte swapping for 16 bit values [htons()] and 32 bit values [htonl()].  These are standard definitions used to handle the byte swapping requirements of a network interface, but they will also work any place you need to deal with "endianness".

http://www.netrino.com/Publications/Glossary/Endianness.html

0 Kudos
Message 12 of 20
(2,364 Views)

Hallo mvr.

Thank you for the link, I will do the data side now and when it is running will report my progress.

Thank you very much for you valueable knowledge,

Best regards Peter.

 

0 Kudos
Message 13 of 20
(2,360 Views)

Hallo,

I have changed the data format send to te serial port to 8 bits and reading an AD/value from a potensiometer and then send the data as Hex 0 to FF (0 -255),I can see the data in the array buffer of labwindows and in the Microcontroller debugger windows.In the controller debugger i see consistant numers and logic,in labwindows I see in 1 element the correct value and in the next element a minus number,If i set the potensiometer to read say decimal 150 the 1 element reads 150 and the next read - 50,I am not sure but could this be a syncronization problem as the controller send continuosly and when I activate the ok button the port reads ,How do I  synchronize  the port read and the controller sending to each other. Is it possible also in labwindows to do a continious read by pressing a button once and then only stop when the button is pressed again,

I apologise for asking so much help ,I really like the looks of labwindows and would like to work with it however by reading the referance manuals and user manual for a beginner is quit difficult to understand,I also apologise for my english I am a German speaker.

Best regards

Peter

0 Kudos
Message 14 of 20
(2,355 Views)

This sounds like it is being caused by using char as the data type for your buffer, which by default in CVI is signed. So any char value "above" 127 will actually be regarded as negative. Try changing the definition of your buffer to unsigned char instead.

JR

0 Kudos
Message 15 of 20
(2,338 Views)
No apologies are required, we have all been in a position where we needed to ask questions, and your english is excelent. 
 
Unfortunately I can not determine the cause of your alternating data values from the information provided.  If you could post a larger data set, and the values that you expected to see it may help.  There are a lot of possible causes for this kind of behavior. As JR has pointed out that, one possible cause is the use of signed or unsigned char values either on the hardware side or in CVI. 
Another thing to try is to send a block of data from the CPU like 0xAA, 0x55, 0x00, 0xFF, 0xFF, 0xFF and see if you can acquire it in the right order from the CVI application.  Then to try sending 16 bit values like 0xAA55, 0x00FF, 0xFFFF, This will give you some idea if you are transfering the data from the hardware to CVI correctly or if the problem lies somewhere else.
 
If I understand your continuous read question correctly you would like to have your CVI application continuously poll your hardware for data.  You can do this by using a timer control.  A timer control executes a callback, just like a command button has been pushed, but on the time interval you specify. 
To set this up add a Timer control on your user interface and set it so that it is disabled by default.  Setup the callback function of the timer control to be the one you use to read the data value.
In the callback of the control (like a button) you use to start the read process enable the timer by calling SetCtrlAttribute(YourPanel, YourTimerControl, ATTR_ENABLED, 1);  This will make the timer active.    When the timer event is fired, the timer callback receives a TIMER_TICK event (not event commit like a button), you use this event to execute your read process just as if a button had been pushed. 
You can call SetCtrlAttribute(YourPanel, YourTimerControl, ATTR_ENABLED, 0); to turn the timer back off when you want to stop reading data.
 
There are some good examples of how to use timers that ship in the CVI examples.  One thing to watch out for is not to poll the hardware too quickly by setting the timer to a very small value like 1mS, or to set the timer to fire faster than you can get the data over the serial port.  If you do then your applications user interface will be very slow to respond.  Just start slow with a value around 500mS until you get everything working.  You can turn the speed up when you are comfortable that everything is the way you want it.

Message Edited by mvr on 08-17-2006 11:17 AM

0 Kudos
Message 16 of 20
(2,327 Views)

Hallo mvr ,JRAlign Center

Thank you for the advice:

Mvr ,

I will preload the buffer in the controller with the data you sugested and send that to CVI ,this is easly done in the microcontroller and then varify the reception in CVI,I also confirmed with microchip today that all their USARTs send little endian as you suspected in an earlier post,therefore using you pointer suggestion in totally valid,and easier for me to start with.  I will try all first and work with the data to get myself more clear and then inform about my progress.

Thank you once again for the help .

I wish you all a nice weekend.

Peter

0 Kudos
Message 17 of 20
(2,311 Views)

Hallo mvr,

Thank you very much my Serial port is running now I included the timer and poll every 0.5 sec for data at the serial port,I am sending chars and they are correct and my controls show the correct data aswell.However by defining the buffer as unsigned char ,the compiler give a warning that an char is expected, by looking at the function prototype for the ComRd() it shows char buff, you can see it as I posted the code and warning below.Now I will start to work on the intergers in buffer and use the integers as the data values ,

I am so happy thank you for your help with out it i would still be in the dark. 

 

#include <cvirte.h>  
#include <userint.h>
#include "USART.h"
//*****************************************************************************************************************
static int panelHandle;

int main (int argc, char *argv[])
{
 if (InitCVIRTE (0, argv, 0) == 0)
  return -1; /* out of memory */
 if ((panelHandle = LoadPanel (0, "USART.uir", PANEL)) < 0)
  return -1;
 DisplayPanel (panelHandle);
 OpenComConfig (4, "COM4", 9600, 0, 8, 1, 512, 512);
 RunUserInterface ();
 DiscardPanel (panelHandle);
 return 0;
}
//******************************************************************************************************************

int CVICALLBACK ReadCallback (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 switch (event)
 {
  case EVENT_COMMIT:
   SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 1);

   break;
 }
 return 0;
}
 //---------------------------------------------------------------------------------------------------------------------

int CVICALLBACK QuitCallback (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
                  
{
 switch (event)
 {
  case EVENT_COMMIT:
   
   CloseCom (4);
   QuitUserInterface (0);
   break;
 }
 return 0;
}

//______________________________________________________________________________________________________________________

int CVICALLBACK EndreadCallBack (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 unsigned char Battery_V;
 
 switch (event)
 {
  case EVENT_COMMIT:
   
   Battery_V = 0;
   SetCtrlVal (panelHandle, PANEL_Battery, Battery_V);
   SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 0);
   

   break;
 }
 return 0;
}

//_____________________________________________________________________________________________________________________

int CVICALLBACK TimerCallback (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 int n;
 unsigned char Battery_V;
 unsigned char Rev;
 unsigned char Data[10];
 switch (event)
 {
  case EVENT_TIMER_TICK:
  FlushInQ (4);
  n = ComRd (4, Data, 10);
  Rev = (Data[4] * 30)/1000;
  Battery_V = (Data[5]*0.0196);
  SetCtrlVal (panelHandle, PANEL_NUMERICGAUGE, Rev);
  SetCtrlVal (panelHandle, PANEL_Battery, Battery_V);
  
  if (Rev > 4){
  DeleteGraphPlot (panelHandle, PANEL_GRAPH, -1, VAL_IMMEDIATE_DRAW);
   
     PlotY (panelHandle, PANEL_GRAPH, Data, 10, VAL_UNSIGNED_CHAR,
      VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
   
   } 
  
    break;
 }
 return 0;
}

//**********************************************************************************************************************

 

0 Kudos
Message 18 of 20
(2,276 Views)

Looks like you are well on your way.  Getting the data is usually the most frustrating part.

A couple of things to think about:
By "casting" your buffer pointer to a signed char you will eliminate the compiler complaint.  n = ComRd (4, (char *)Data, 10);  This does not change anything about how the data is handled, it simply tells the compiler to accept the Data array pointer as a signed char pointer.  Depending on how your data is used, another solution may be to redefine your Data buffer as a signed char.  I dont see a problem in mixing signed and unsigned values for your specific application at this point.

Your timer callback looks good.  Here is something to consider as you expand your use of them.  Timer callbacks are like hardware interrupts, you want to minimize execution time of the callback as much as possible.  The SetCtrlVal() function redraws the screen for each call, which is inefficient when using multiple calls to update controls.  An easy way to avoid this is to use SetCtrlAttribute().
SetCtrlVal (panelHandle, PANEL_NUMERICGAUGE, Rev); can be replaced by
SetCtrlAttrbute(panelHandle, PANEL_NUMERICGAUGE, ATTR_CTRL_VAL, Rev);
This updates the control value, but delays the draw event.

Update all your controls this way and at the end of the callback insert a ProcessDrawEvents() call and this will update the display in a single operation without the overhead of multiple draw operations. 


 

0 Kudos
Message 19 of 20
(2,233 Views)

Hallo mvr,

Thank you very much it is clear to me about the differences between SetCtrlVal(); and SetCtrlAttribute after your explenation, I have so much to learn ,I will change my code and also  now I am working on pointers and arrays in in my C study book I am really uncomfortable with the pointers but will give it a good go,

Wish you nice week ,

Peter

 

 

0 Kudos
Message 20 of 20
(2,226 Views)