1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 <2007> 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 <2007> 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Use of waveform records |
From: | [email protected] (Touchard Dominique) |
To: | Mark Rivers <[email protected]> |
Cc: | [email protected] |
Date: | Thu, 11 Oct 2007 10:45:36 +0200 |
Mark Rivers a écrit : You are totally right. Thanks. I'll take back my glasses. ;-)Hi Dominique,Perhaps I discovered a modbus driver "feature" ? I created one modbus number 4 read function which read 11 bytes. I tested three waveform input records. These three records read 3 different values on different offsets. These 3 records read the offset 0 ???!!!That is the documented behavior for asynInt32Array support. Look at http://cars9.uchicago.edu/software/epics/modbusDoc.html#EPICS%20device%20support in the section on asynInt32Array support. You will see that the "offset" field is NA (not applicable) for all Modbus functions for asynInt32Array. I broke the EPICS database to make a SNL code. I haven't got any example. I tried to use the 0x0000FFFF bit mask. I thought this value was converted in a float value and the bitwise operation didn't give the right result when it was converted back to an integer. The 0x0001000 bit mask worked. Perhaps I made a mistake.About ai/ao records, I will need to write and read float values with the Modbus driver. I saw integer examples. Ai/ao examples work with asyn32int type. Did you test asynFloat64 values ? Do I have to use waveform records (ie 32bits : sign:1bit exponent:8bits fraction:23bits) ?Float values are not a standard Modbus data type; they are not documented in the Modbus standard. Again, because they are more than 16 bits long, they require multiple Modbus words. I think you need to do the same thing you do for 32-bit integers, i.e. use a calc, Gensub or SNL code to convert to two 16-bit integers and then use two longout records or a waveform record.I have a beginner's question : does the bit left shift work like C code? Can I write something like A << 16 in the calc _expression_?Yes, that is documented under Bitwise Operators here: http://www.aps.anl.gov/epics/EpicsDocumentation/AppDevManuals/RecordRef/Recordref-13.html#HEADING13-0I tried to convert the 32 bit integer value into 2 16 bits values with a calc record. Because of float conversion troubles, I don't get through to get the right values.It seems to me like it should work, since I think any 32-bit integer can be represented exactly in a 64-bit double. Can you send an example that did not seem to work? I will tried again with two shifts (one 16 bits left shift to lose MS bits and and one right to give back the right bit position). Thanks again for your help. Dominique. Mark ________________________________ From: Touchard Dominique [mailto:[email protected]] Sent: Tue 10/9/2007 3:50 AM To: Mark Rivers Cc: [email protected] Subject: Re: Use of waveform records Hi Mark, Thanks for your answer. I agree with you. We mustn't modify the driver. The power supply could work with two longout records. In the future, I will need to know how to work with a waveform, an SNL or Gensub code. So I decided to try these tools. I have written an SNL code which does this conversion. I know this is not the best solution. I will try a gensub record soon. I tried to convert the 32 bit integer value into 2 16 bits values with a calc record. Because of float conversion troubles, I don't get through to get the right values. I have a beginner's question : does the bit left shift work like C code? Can I write something like A << 16 in the calc _expression_? Perhaps I discovered a modbus driver "feature" ? I created one modbus number 4 read function which read 11 bytes. I tested three waveform input records. These three records read 3 different values on different offsets. These 3 records read the offset 0 ???!!! So I decided to create only one input waveform which read the whole bytes. It works fine. At present, the SNL code converts the values. About ai/ao records, I will need to write and read float values with the Modbus driver. I saw integer examples. Ai/ao examples work with asyn32int type. Did you test asynFloat64 values ? Do I have to use waveform records (ie 32bits : sign:1bit exponent:8bits fraction:23bits) ? Thanks for your help. Dominique. Mark Rivers a écrit : One thought on this. Because you must do 2 Modbus operations to write a 32-bit value with Modbus, I suspect that the power supply only updates the value when you write one of the 16-bit words, i.e. either the most-significant or least-significant 16 bits. You should read the documentation to find out which one actually updates the power supply and make your database write that value last. Otherwise you will get a momentary garbage output if you do it in the wrong order. Mark -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Mark Rivers Sent: Friday, October 05, 2007 11:23 AM To: Touchard Dominique; [email protected] Subject: RE: Use of waveform records Hi Dominique, Sorry for the delay in replying to this, I was on vacation. I think an easier solution to this problem is to use 2 calc records to convert the 32-bit integer to 2 16-bit integers, and write those to the Modbus driver using function 6. Then you don't have to write any C code, just a simple database. PowerSupply (longout) -> calc1 (16 LSB) -> longout1 -> Modbus -> calc2 (16 MSB) -> longout2 -> Modbus I don't recommend modifying the driver, because a 32-bit integer is not a standard Modbus data type, and we could end up with all sorts of modifications for non-standard data types. Mark -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Touchard Dominique Sent: Wednesday, September 19, 2007 8:44 AM To: [email protected] Subject: Use of waveform records Hi, we are working on/with the Epics modbus tcp driver written by Mark Rivers. We need to write a 32 bits integer value in a power supply command control interface. First we thought to write an asyn32Int record with the number 6 modbus function. Immediatly, we saw that the driver uses the number 6 modbus function which works only on a 16 bits word. After reading the Modbus Driver Support documentation, we saw that we have to use a two value length waveform record. First question : is this correct ? Second question : do we have to use the gensub record to manipulate values inside a waveform record ? In this case, is there any example that shows how to do this ? Could somebody send us an example on this ? Third question : Is a bad idea to modify the modbus driver in the goal to write a asyn32Int 32 bits integer record with the number 16 modbus function ? Thanks for your help . Dominique Touchard. |