我正在与一个福禄克8588工作,并与它通信使用Ivi.Visa.Interop
,我试图使用数字化功能,以获得一个5V,1k赫兹正弦波的大量样本。为了改善数据的传输时间,手册提到了使用二进制打包数据格式的设置。它提供了2字节和4字节的打包。
这是我能举出的最小的例子:
using System;
using System.Threading;
using Ivi.Visa.Interop;
namespace Example
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Initiallizing Equipment");
int timeOut = 3000;
string resourceName = "GPIB0::1::INSTR";
ResourceManager rm = new ResourceManager();
FormattedIO488 fluke8588 = new FormattedIO488
{
IO = (IMessage)rm.Open(resourceName, AccessMode.NO_LOCK, timeOut)
};
Console.WriteLine("Starting Setup");
fluke8588.WriteString("FORMAT:DATA PACKED,4");
fluke8588.WriteString("TRIGGER:COUNT 100000");
Console.WriteLine("Initiate Readings");
fluke8588.WriteString("INITIATE:IMMEDIATE");
Thread.Sleep(3000);
Console.WriteLine("Readings Complete");
Console.WriteLine("Fetching Reading");
fluke8588.WriteString("FETCH?");
string response = fluke8588.ReadString();
Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(response);
fluke8588.WriteString("FORMAT:DATA:SCALE?");
double scale = Convert.ToDouble(fluke8588.ReadString());
int parityMask = 0x8;
for (int i = 0; i < 100000; i += 4)
{
int raw = (int)((bytes[i] << 24) | (bytes[i + 1] << 16) | (bytes[i + 2] << 8) | (bytes[i + 3]));
int parity = (parityMask & bytes[i]) == parityMask ? -1 : 1;
int number = raw;
if (parity == -1)
{
number = ~raw * parity;
}
Console.WriteLine(number * scale);
}
Console.Read();
}
}
}
生成的数据如下所示:
我使用一个名为NI Max的工具“手动”预编好了这些步骤。我得到一个标题,后面跟着104个字节整数,并以一个新的行字符结尾。负整数是2s补码,没有在手册中指定,但我能够确定在我有足够的样本。
在拍摄此图像时,TRIGGER:COUNT
只设置为10。
如何在c#?中得到这个结果?
发布于 2021-08-26 22:21:04
我发现我使用了错误的编码,从System.Text.Encoding.ASCII.GetBytes(response)
更改为
System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(1252);
Byte[] bytes = encoding.GetBytes(response);
得到了想要的结果。
尽管如此,我还了解到,对于二进制数据,还有一种替代的FormattedIO488.ReadString
选项,使用FormattedIO488.ReadIEEEBlock(IEEEBinaryType.BinaryType_I4)
,这将返回一个整数数组,并且不需要对旋转位进行额外的工作,这是我建议的解决方案。
using System;
using System.Linq;
using Ivi.Visa.Interop;
using System.Threading;
using System.Collections.Generic;
namespace Example
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Initiallizing Equipment");
int timeOut = 3000;
string resourceName = "GPIB0::1::INSTR";
ResourceManager rm = new ResourceManager();
FormattedIO488 fluke8588 = new FormattedIO488
{
IO = (IMessage)rm.Open(resourceName, AccessMode.NO_LOCK, timeOut)
};
Console.WriteLine("Starting Setup");
fluke8588.WriteString("FORMAT:DATA PACKED,4");
fluke8588.WriteString("TRIGGER:COUNT 100000");
Console.WriteLine("Initiate Readings");
fluke8588.WriteString("INITIATE:IMMEDIATE");
Thread.Sleep(3000);
Console.WriteLine("Readings Complete");
Console.WriteLine("Fetching Reading");
fluke8588.WriteString("FETCH?");
List<int> response = new List<int>(fluke8588.ReadIEEEBlock(IEEEBinaryType.BinaryType_I4));
fluke8588.WriteString("FORMAT:DATA:SCALE?");
double scale = Convert.ToDouble(fluke8588.ReadString());
foreach (var value in response.Select(i => i * scale).ToList())
{
Console.WriteLine(value);
}
Console.Read();
}
}
}
结果数据如下:
https://stackoverflow.com/questions/68945950
复制相似问题