| Products > Test Equipment |
| Some old school instruments showing how it's done (HP 3325A and Fluke 8506a) |
| << < (60/91) > >> |
| joeqsmith:
--- Quote from: SilverSolder on February 17, 2021, 06:44:17 am ---The new software has apparently dropped any mention of the high voltage chips (since they can't be programmed anyway). I don't think the old software will work on the new programmer, at least not without downgrading the firmware in the programmer. --- End quote --- That's too bad as my intent would have been to improve the hardware. ** Both the Programmer and printer port were damaged. It looks like they still offer a printer port using the same chipset. That board was nice as it would actually work even with DOS. You could install a loopback connector that allows the software to self test the hardware. I have ordered up a couple of ports like before to see if I can find another one that actually works. I also noticed that VirtualBox now has some undocumented, limited support for printer ports. If I can get the port to work, I will see about another old programmer. |
| garrettm:
Turns out that converting the 32bit and 40bit fixed-point binary data from normal and average modes was as simple as the 22bit fixed-point data from HS mode. The exponent bytes are used to check for error's reported by the meter, but are otherwise ignored since fluke uses fixed exponents for all measurements except ohms. The following C++ code can take 12 and 13-byte ASCII data as well as 3, 5 and 6-byte binary from a 8505/6A and convert it to a 64bit floating point number. The binary data isn't range or calibration corrected yet. I also still need to work out triggering for the binary data. But I should have those figured out shortly and then I can start testing with my meter. I downloaded the community edition of NI LabVIEW so I might try using it to make a program to control 8505/6As. If anyone has suggestions I'd be happy to hear them. --- Code: ---#include <iostream> #include <inttypes.h> // TYPE DEFINITIONS // fixed point data from average mode typedef union { struct { uint32_t f; // fraction bits uint8_t i :7; // integer bits bool s :1; // sign bit }; uint64_t w :40; // 40bit fixed point word uint8_t b[5]; } fxp40_t; // 40-bit fixed point data bit fields // fixed point data from normal operation typedef union { struct { uint32_t f :24; // fraction bits uint8_t i :7; // integer bits bool s :1; // sign bit }; uint32_t w; // 32bit fixed point word uint8_t b[4]; } fxp32_t; // 32-bit fixed point data bit fields // fixed point data from high speed mode typedef union { struct { uint32_t f :20; // fraction bits bool i :1; // integer bit bool e :1; // error bit bool s :1; // sign bit }; uint32_t w :22; // 22bit fixed point word uint8_t b[3]; } fxp22_t; // 22bit fixed point data bit fields typedef union { struct { uint64_t f :63; // mantissa and exponent bool s :1; // sign }; double r = 1; // set mantissa bits to 0 } fp64_t; // 64bit floating point bit fields // GLOBAL VARIABLES constexpr char LF = 10; // line feed constexpr char CR = 13; // carriage return bool meas_err = 0; // flag for DMM reading error bool data_type = 1; // data type flag: 0 => binary, 1 => ASCII // FUNCTIONS // convert fixed point types to 64bit floating point double fxp_to_fp64(uint64_t f, uint8_t i, bool s) { fp64_t val; val.f |= f; // fraction bits val.r += i - 1; // integer bit / FP exp val.s = s; // sign bit return val.r; // unscaled floating point value } double binary_to_double(uint8_t b[], const uint8_t& length) { // high speed mode, 3-byte binary if (b[length - 1] == 3) { fxp22_t fxp; std::copy(&b[length - 1 - b[length - 1]], &b[length - 1], &fxp.b[0]); if (!fxp.s == fxp.e) // check error bit for measurement error meas_err = true; if (fxp.s) // perform two's complement if value is negative fxp.w = ~fxp.w + 1; // convert fixed point data to floating point return fxp_to_fp64(static_cast<uint64_t>(fxp.f) << 32, fxp.i, fxp.s); } //normal mode, 5-byte binary else if (b[length - 1] == 5) { fxp32_t fxp; std::copy(&b[length - b[length - 1]], &b[length - 1], &fxp.b[0]); if (b[length - 6] == 0) // check exponent for measurement error meas_err = true; if (fxp.s) { // perform two's complement if value is negative fxp.w = ~fxp.w + 1; fxp.s = 1; // retain sign information } // convert fixed point data to floating point return fxp_to_fp64(static_cast<uint64_t>(fxp.f) << 28, fxp.i, fxp.s); } // average mode, 6-byte binary else if (b[length - 1] == 6) { fxp40_t fxp; std::copy(&b[length - b[length - 1]], &b[length - 1], &fxp.b[0]); if (b[length - 7] == 0) // check exponent for measurement error meas_err = true; if (fxp.s) { // perform two's complement if value is negative fxp.w = ~fxp.w + 1; fxp.s = 1; // retain sign information } // convert fixed point data to floating point return fxp_to_fp64(static_cast<uint64_t>(fxp.f) << 20, fxp.i, fxp.s); } // handle mangled binary data else { meas_err = true; return 0; } } double ascii_to_double(uint8_t b[], const uint8_t& length) { // normal mode 5.5/6.5 digit measurement if (b[length - 1] == 12) { char s[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0}; std::copy(&b[0], &b[12], &s[0]); return std::stod(s); } // average mode 6.5/7.5 digit measurement else if (b[length - 1] == 13) { char s[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; std::copy(&b[0], &b[13], &s[0]); return std::stod(s); } // handle CR LF terminations and mangled ASCII data else { meas_err = true; return 0; } } //dummy data for testing uint8_t b_data[] = /* 3-byte binary data {0b11110111, // 1st byte 0b10111111, // 2nd byte 0b11111111}; // 3rd byte //*/ /* 5-byte binary data {0b00000011, // 1st byte 0b10000000, // 2nd byte 0b00000000, // 3rd byte 0b00000000, // 4th byte 0b00000001}; // 5th byte //*/ /* 6-byte binary data {0b00000011, // 1st byte 0b10000000, // 2nd byte 0b00000000, // 3rd byte 0b00000000, // 4th byte 0b00000000, // 5th byte 0b00000001}; // 6th byte //*/ //* 12-byte ASCII data {'+','0','1','0','.','0','0','0','1','E','-','3',CR,LF}; //*/ /* 13-byte ASCII data {'-','1','0','.','0','0','0','3','3','3','E','+','0',CR,LF}; //*/ /* test terminations for ASCII data {CR,LF}; //*/ /* mangled ASCII data test {'-','1','0','.','0',CR,LF}; //*/ double get_reading(void) { // character buffer, last index stores number of bytes read from DMM uint8_t b[14]; // read binary data from DMM if (data_type == 0) { // store bytes in reverse order, b[sizeof b - 1] counts # of bytes for (uint8_t &i = b[sizeof b - 1]; i <= sizeof b_data - 1; i++) b[sizeof b - 2 - i] = b_data[i]; std::cout << (int)b[sizeof b -1] << "-byte binary" << std::endl; return binary_to_double(b, sizeof b); } // read ASCII character data from DMM else { // store valid characters in buffer, b[sizeof b - 1] counts # of bytes for (uint8_t &i = b[sizeof b - 1]; b_data[i]!=CR && b_data[i]!=LF; i++) b[i] = b_data[i]; std::cout << (int)b[sizeof b -1] << "-byte ASCII" << std::endl; return ascii_to_double(b, sizeof b); } } int main() { // set data type: 0 == binary, 1 == ASCII data_type = 1; // get reading and convert to 64bit FP double r = get_reading(); std::cout << "reading error? " << meas_err << std::endl; printf("FP value: %4.7f \n", r); } --- End code --- |
| joeqsmith:
There may be software already for the Fluke meter. I would check that first. If you have never used LabView, the first thing I would suggest is you spend a day going through the getting started manual. Work all the examples and get a basic idea how it works. It's not magic and like any language takes time to learn. You may also want to join their forums. The 5-byte data is what the LED displays. No need to correct it like the 3-byte. Also, no 2's comp. So a little easier. I've not seen any problems using the technique I mentioned to sync up with the data. Then again, that serial data is very slow. But the PCs are so fast... I guess you just need to try it. |
| SilverSolder:
I noticed in AN25 there is a sample program (in Tektronix Basic no less) that does the 3-byte correction in the typically terse way of that era! Not sure I even understand what this code is doing, but it is compact... |
| garrettm:
--- Quote from: joeqsmith on February 17, 2021, 04:39:34 pm ---There may be software already for the Fluke meter. I would check that first. If you have never used LabView, the first thing I would suggest is you spend a day going through the getting started manual. Work all the examples and get a basic idea how it works. It's not magic and like any language takes time to learn. You may also want to join their forums. The 5-byte data is what the LED displays. No need to correct it like the 3-byte. Also, no 2's comp. So a little easier. I've not seen any problems using the technique I mentioned to sync up with the data. Then again, that serial data is very slow. But the PCs are so fast... I guess you just need to try it. --- End quote --- I'm sure there is software used by the military, but I haven't seen any open source software that supports the Fluke 8505/6A. I'll try looking on NI's site in case someone has uploaded something for one of the paid LabVIEW editions. All fixed-point binary data (except the exponent byte) require two's complementing as an entire word before conversion to floating point. This is done to make the value positive before merging the fraction bits into the floating point mantissa and letting the processor figure out the bit fields for the integer portion (using FP addition). Otherwise, all single byte binary data is in signed char format (i.e., "two's complement"). So no work to do there. That said, there are free fixed-point libraries for C++ available which would eliminate the need for conversion, but I haven't tried using them yet. https://github.com/johnmcfarlane/cnl https://github.com/eteran/cpp-utilities I'm hoping to get at least 360 readings/s using the HS mode. I can do it with the external trigger input but I've yet to get it to work using bus triggering with my current setup. I plan on making an AR488 Arduino GPIB interface here soon which should solve my inability to directly control the talk/listen operation of the DMM. https://www.eevblog.com/forum/projects/ar488-arduino-based-gpib-adapter/ If I can't figure out LabVIEW I may write a program in Visual Studio 2017 or Matlab to control the instrument, generate CSV files and plot the data--as I have a little more experience with them. Though, from what I can tell, LabVIEW is supposed to make doing this pretty simple. There is also a program on the forum for reading from multiple instruments but it appears to only work with SCPI instruments. I need to look through the documentation and see if I could make it work with these older meters. https://www.eevblog.com/forum/testgear/program-that-can-log-from-many-multimeters/ |
| Navigation |
| Message Index |
| Next page |
| Previous page |