pcdshub / lcls-twincat-general

A PLC code toolkit for LCLS TwinCAT PLC projects
https://pcdshub.github.io/lcls-twincat-general/
Other
16 stars 20 forks source link

Fix FB_AnalogOutput and FB_AnalogInput for negative numbers #54

Open slactjohnson opened 3 years ago

slactjohnson commented 3 years ago

While attempting to use these function blocks for an experiment setup in RIX I found that these function blocks don't appear to work properly for negative values. I had to make some quick hacks (as these needed to be functional in ~30 minutes at the time), resulting in pcdshub/lcls-plc-crixs-motion#7. For example, the analog output terminal I was using needed to operate from -10 to 10 Volts. The analog output conversion does the following:

fScale := (EXPT(2, iTermBits) - 1) / (fTermMax - fTermMin);
iRaw := LREAL_TO_INT((fReal - fTermMin) * fScale);

However, if fReal is negative, and fTermMin is negative (as it would be for a bipolar output card) then a requested value of e.g. -9.0 V would result in:

(-9.0V - (-10 V)) * (2^16 - 1) / (10 V - (-10 V)) = 3277 (a 1 V positive output)

For the analog input, setting the iTermBits to 16, fTermMax to 10 and fTermMin to -10, an input value of e.g. -30000 ADC, or about -9V, would result in the following:

fReal = (-30000) / [(2^16 - 1)/(10 V - (-10 V))] + (-10 V) = -19.1 V

ZLLentz commented 4 months ago

This caused the same problem again during https://github.com/pcdshub/lcls-plc-kfe-rix-motion/pull/66 when the terminal needed a negative value