LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Serial / function declaration questions

Two questions, one quick, the other I have no idea.

1)  Returning an array from function call should be done by pointer reference, yes?  So how does one define the function return type as a pointer. E.g.:

int rates[NUM_CHANNELS];
rates = SPC_getallrates();

//////////////////////////////////////////////////////////

int SPC_getallrates (void)
{
    int intensities[NUM_CHANNELS];
    int i;
   
// Do something like record data for .1s and calculate intensities
    for (i=0;i<NUM_CHANNELS;i++)
    {
        intensities[i] = 0;
    }
   
    return intensities;
}



2)  I'm trying to connect to an RS485 stepper-motor controller via a standard COM port and a converter cable (supplied with controller).  Sending commands (12 character ASCII strings) to the controller works fine (movement and status changes occur exactly as expected), but when a status request is made (another ASCII string), either the answer is returned in the first 500 characters or not at all, meaning in order to get a correct response, one has to poll the controller with the same status request repeatedly.  This slows the response tremendously, as the correct response is only seen once per 5-10 requests.

I'm currently looping:
        FlushInQ(COM_channel);
        ComWrt (COM_channel, strQuery, 12);
        ComRdTerm (COM_channel, strRead, 500, 13);
        FlushInQ(COM_channel);
       // Check if certain pattern has been returned.

All ComConfig options (e.g. baud / parity etc. have been set correctly - or at least, as correctly as I can make out from the minimal information I have).
        OpenComConfig (COM_channel, "COM1", 9600, 0, 8, 1, 4096, 4096);
        SetComTime (COM_channel, 0.5);

Any help appreciated.
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 1 of 12
(4,656 Views)
1) I would declare:
void SPC_getallrates(int *intensities,int numberOfElements)
{
int i;

for (i=0; i < numberOfElements;i++)
{
*(intensities+i) = 0;
}
}
and then call SPC_getallrates(rate,NUM_CHANNEL);


2)
- OpenComConfig (COM_channel, "COM1", 9600, 0, 8, 1,512,512);
- Use
GetInQLen (int COMPort) to see if the expected number of bytes is there.
- Are you sure that the message from your device has a termination byte being CR (ASCII code 13). That's not a common RS485 stuff.

BR


0 Kudos
Message 2 of 12
(4,653 Views)
1) So pass the inputs by reference, and let the values be changed within the function without altering the initial pointer.  Gotcha.



2)  GetInQLen correctly responds with the number of bits in the queue, but that doesn't help if the answer hasn't been sent.
Apologies, this is probably a little to component specific (32 SmartDrive LC4E units) to be answered generically, I was just wondering whether anyone had asynchronous problems with a COM port (i.e. sends fine, recieves wrong).

And yes, the ASCII string returned is definitely supposed to terminate in CR.
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 3 of 12
(4,645 Views)
Pythonist:

I don't see any error checking in the serial communications code that you posted.  Did you strip it out for clarity?  You may be getting a timeout error or be getting out of sync with the device that you are communicating with.  What is the contents of strRead when you don't get the correct response?

You should check the return value of ComRdTerm.
----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 4 of 12
(4,642 Views)
        FlushInQ(COM_channel);
        ComWrt (COM_channel, strQuery, 12);
        ComRdTerm (COM_channel, strRead, 500, 13);
        FlushInQ(COM_channel);
       // Check if certain pattern has been returned.

I haven't stripped anything specific out of this - the error checking of the response is taken care of by the pattern recognition (checks to find 12 characters starting with a '$').

Oh - I've got SetComTime (COM_channel, 0.5) along with the previously mentioned ComConfig line

BTW if a correct answer is returned, it occurs early in the 500 bytes read, and well within the Com timeout.  If no answer is sent from the LC4E units, the whole string is empty, but again returns before the timeout is reached.
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 5 of 12
(4,639 Views)
So if ComRdTerm is returning an empty string, there are 3 things that can happen.
1) The termination character was received.  You're out of sync with the instrument or using the wrong termination character.
2) An error occured.  This will be indicated in the return value.  You should check this.  It will help with debugging.  It's absolutely necessary in production code.  Things fail, com ports die, bits rot.... 
3) A timeout occured.  This would be indicated in the return value.

Have you tried this sequence in HyperTerminal?  Do you get the same results?
----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 6 of 12
(4,635 Views)
Bascially tried all of those...

Hyperterminal sends correctly and receives exactly what the LabWindows code receives.  However, there are only ever two return values:
1) Correct response with termination character (usually as the first characters in the response)
2) 500 blank characters (no termination byte found) - NIDAQMX interprets this as a string of 500 '.'

Given that 1) is received occassionally, but always as the correct status, the send/receive is not out of sync (have also tried reading the buffer repeatedly - if 1) isn't recieved in the first 500 characters, it isn't ever received).

Here's the real problem - I would be happy to throw my hands up and state that there's a problem with the controller.  However, I have a piece of Delphi code that seems to work perfectly, but recreating exactly in LabWindows doesn't seem to work... Robot Indifferent

__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 7 of 12
(4,634 Views)
That is just bizarre.  I just want to see if I have this straight.  The problem appears in HyperTerminal.  The problem appears in LabWindows/CVI.  The problem does not appear in your Delphi code.

The LabWindows code is a straight port of the Delphi code.

In LabWindows and HyperTerminal you are setting up the port the same way as the Delphi code does.

When changing applications do you cycle power to the converter and the stepper motor controller?

Beyond that, all I can suggest is to get an RS-232 breakout box and start comparing the way the Delphi code controls the port to the way that LabWindows controls the port.
----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 8 of 12
(4,622 Views)
Yes, you have it absolutely right.

To be more specific:
I have a disc mounted on a stepper motor.  The disc has a small hole in it so that, when in an "initialisation position", a photodetector is illuminated through said hole by an LED.  Dependent on whether the photodetector is illuminated, the controller returns one of two responses when queried.  The stepper motor is commanded to increment its position, then queried as to its status, thus verifying the orientation of the disc (which has other features more specific to the rest of the instrument).

2 PCs: one 98 running Delphi, one XP running LabWindows.
An exact replica of the Delphi code, which sends the move command, delays 30ms, then queries the status and gets an immediate response, initialising a disc in a matter of seconds, seems to have this problem of null responses under LabWindows and hence takes up to 40 min (10 queries per position, then giving up and trying the next one, resulting in the entire disc being checked many times).  Playing with the structure / logic of the code (varing buffer sizes / delays / looping read-outs) has reduced the initialisation to roughly a minute, but that's still an order of magnitude difference.

As previously stated, I think that there is something simple I just don't know about the controller, but have no legacy information for it (and it's only as old as 1998!).  However, this "simple" difference is hidden somewhere in the way delphi and LabWindows treat a 232 port, at a lower level than is seen in any code.

Any suggestions as to a good break-out?

Thanks for the interest!
__________________________________________
The world is full of exciting challenges,
brilliantly disguised as insoluble problems.
0 Kudos
Message 9 of 12
(4,608 Views)
A-ha!  From which system did you try HyperTerminal?  WinXP or Win98?  Does it make a difference?

I tend to buy most of my cabling from L-Com.  A breakout box should be pretty common.
----
I am the founder of CnCSoftwareSolutions. When not cleaning up baby drool, I write about test data or work on Vision, a tool for understanding your test data. Visit me at www.cncsoftwaresolutions.com
0 Kudos
Message 10 of 12
(4,604 Views)