信号采集问题??? 点击:975 | 回复:17



keepmoon

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-08-05 11:21:00
楼主
adlink pci-9118数据采集卡,选择单极编码时,电压范围0-10V,数据应该是0-65535(16位),0V电压对应于数据0,但是实际采集的结果是32767,不是0,请问其原因是什么?



GaryLin

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1186回
  • 年度积分:0
  • 历史总积分:1263
  • 注册:2003年4月15日
发表于:2003-07-24 12:17:00
1楼
有些采集卡在作 0~10v 的量测时, 实际上还是用 -10v ~ 10v 的方法量测, 然后取其 0 ~ 10v 的部份. 如此, 您就有可能看到 0v 不是 0x0000 的采样结果, 而是看到中间值.

gongkongedit

  • 精华:1099帖
  • 求助:0帖
  • 帖子:14392帖 | 54470回
  • 年度积分:0
  • 历史总积分:622
  • 注册:2008年9月08日
发表于:2003-07-24 13:09:00
2楼
有谁能够设计脉冲控制器线路板,并能够做出来,我将购买.具体要求邮件来取.   我Email:gaowenhai123@sohu.com

keepmoon

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-07-24 14:05:00
3楼
谢谢GaryLin的回答,但是我不知道如何取数据才是合理的。 不知道这样做行不行。 for(num=0;num<data_size;num++){ if(ai_buf[num]>32767) ai_buf[num] -= 32768; else ai_buf[num] += 32768; } 其中data_size 是采样点数,ai_buf是采集的数据。

GaryLin

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1186回
  • 年度积分:0
  • 历史总积分:1263
  • 注册:2003年4月15日
发表于:2003-07-24 14:34:00
4楼
上面讲的 0~10v 与 +/- 10v, 只是假设. 建议您向 ADLink 确认一下才好. 若是假设成立... 则小于 0v 的数据都将视为 0v. if ( ai_buf[num] < 32767 ) ai_buf[num] = 32767; 另外, 建议您查一下 hardware manual, 看看是否有 jumper 需要设定才能量测 0~10v.

GaryLin

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1186回
  • 年度积分:0
  • 历史总积分:1263
  • 注册:2003年4月15日
发表于:2003-07-24 14:43:00
5楼
另外一提的是, 泓格的 16 bits 采集卡, 其表示的方式较特别! dec: -32768 ........ -1, 0 ......... 32767 hex: 0x8000 .... 0xFFFF, 0x0000, ... 0x7FFF vol: -10v .... -0.0003v, 0v, ....... 9.9997v 所以, 每个厂家的 16 bits 表示法可能都不一样, 您得先确认过才好.

keepmoon

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-07-24 15:34:00
6楼
非常感谢GaryLin的回复。我采集到数据好像都是大于零的情况。比如空采的话,数据都是32767。我刚才作了一个试验。我采用手册中转化电压的函数,这个函数,需要采集后的数据作为其中的一个参数。得到的结果是对于32767的数据而言,电压差不多就是0。我采用的是Unipolar模式即电压范围是0到10伏(Bipolar是+-5伏)。这么看来32767就是相对于0伏了。虽然电压我已经得到了。但是对于数据仍旧有参考价值。我所用的卡是ADLink PCI-9118/HR.这是我大体上的编程代码。 #define CardNumber 0 #define LastADChan 1 #define ADChanCount 2 #define ScanCount 65536 #define SampleRate 16000.0000 //AI config constants definition #define ModeCtrl P9118_AI_UniPolar|P9118_AI_SingEnded #define FunCtrl P9118_AI_DtrgNegative|P9118_AI_EtrgNegative #define BurstNumber 0 #define PostCount 0 //variables definition I16 cardID = -1; I16 err=0; U32 AccessCnt = 0; U32 MemSize = 0; I16 InBuf[131072]; //AI data buffer F64 InVolBuf[131072]; // AI voltages buffer cardID = Register_Card(PCI_9118HR, CardNumber); if (cardID<0) { //Error occurs !! //ToDo : Handle error here } err = AI_InitialMemoryAllocated(cardID,&MemSize); if (err!=NoError) { //Error occurs !! //ToDo : Handle error here } if (MemSize*1024 < ScanCount*ADChanCount*sizeof(I16) ) { //available memory size for analog input in the device driver //is smaller than the data size specified!! //ToDo : do something here } err = AI_AsyncDblBufferMode(cardID, 0); if (err!=NoError) { //Error occurs !! //ToDo : Handle error here } err=AI_9118_Config(cardID, ModeCtrl, FunCtrl, BurstNumber, PostCount); if (err!=NoError) { //Error occurs !! //ToDo : Handle error here } //这里扫描通道 err=AI_ContScanChannels (cardID, LastADChan, AD_U_10_V, InBuf, ScanCount*ADChanCount, SampleRate, SYNCH_OP); if (err!=NoError) { //Error occurs !! //ToDo : Handle error here } //这里取得电压值,他需要上面所得到的InBuf作为一个参数输入 err=AI_ContVScale (cardID, AD_U_10_V, InBuf, InVolBuf, ScanCount*ADChanCount); if (err!=NoError) { //Error occurs !! //ToDo : Handle error here } Release_Card(cardID); 空采的话,所得到的数值是32767,电压是0。按照要求,如果是双极的话数据是-32768到+32767。而我所用是单极数据应该是0~65535。才对。

李侃

  • 精华:22帖
  • 求助:0帖
  • 帖子:30帖 | 813回
  • 年度积分:0
  • 历史总积分:1015
  • 注册:2002年2月27日
发表于:2003-07-24 18:55:00
7楼
PCI-9118HR的数据范围是-32768~32767,你的程序中用的是AD_U_10_V(0~10V),所以-32768对应0V,32767对应10V,如果A/D通道浮空,会采到最大电压值,是正常的。你可以试试采0V电压,看是否是0。

keepmoon

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-07-24 20:58:00
8楼
谢谢GaryLin和李侃老师的回复。果然,32767对应10伏。但是函数AI_ContScanChannels 中用来存储采样数据的参数是U16*,这样是就是16位的无符号整型数,就是0-65535,所以采样值得不到-32768到+32767,接受到数据都是正的,而且数据有大于32767的,而且数据值越大,电压值越小。比如取得的数据65056 对应于4.926833伏。7596 对应6.159152伏。32767对应10伏。按照这种情况,请您指点。怎么对数据进行处理。

李侃

  • 精华:22帖
  • 求助:0帖
  • 帖子:30帖 | 813回
  • 年度积分:0
  • 历史总积分:1015
  • 注册:2002年2月27日
发表于:2003-07-25 05:53:00
9楼
PCI-9118HR用的数据格式是2进制补码格式。获得实际电压值有两种途径: A:将AI_ContScanChannels 中的buffer定义为I16即可,或者将你程序中U16 的InBuf强制转换成I16 b:使用AI_ContVScale 将数据转换成电压值

keepmoon

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-07-25 08:11:00
10楼
谢谢李侃老师回复。我查了一下手册,问题是AI_ContScanChannels 和 AI_ContVScale 里面的参数都是U16。我直接采样。发觉得到的数据是不对的。其范围是0到65535之间。所以按照您所说的,数据应该是-32768到+32767之间。那么说明,里面大于32767的数据就是负值了。所以我就将大于32767的数据转换为负值。方法是-(32768-(x-32768))=x-65535.然后所有的数据加上32767量化到0~65536之间。所以现在数据转化方法就是。 for(num=0;num<data_size;num++){    if(ai_buf[num]>32767)    ai_buf[num] -= 32768;    else    ai_buf[num] += 32768; 然后将所得除以65535。然后乘以10。就得到电压了。而且我将这样算得的值与我采样得到的电压比较,发觉有的很相符。有的有偏差。我计算电压是直接按照 //这里扫描通道    err=AI_ContScanChannels (cardID, LastADChan, AD_U_10_V, InBuf, ScanCount*ADChanCount, SampleRate, SYNCH_OP);    if (err!=NoError) {    //Error occurs !!    //ToDo : Handle error here    }   //这里取得电压值,他需要上面所得到的InBuf作为一个参数输入    err=AI_ContVScale (cardID, AD_U_10_V, InBuf, InVolBuf, ScanCount*ADChanCount);    这里都是U16类型。AI_ContVScale 中值必须是U16,否则编译不通过。那么您所说的强制转换是不是将AI_ContVScale 中的InBuf强制转换为I16,然后代入到AI_ContVScale 中去了。AI_ContVScale 接受I16。虽然他要求是U16。还是您认为不需要作任何改动,至少电压是直接用上面两个函数就是正确的。事实上,我看到直接用上面两个函数,电压值到象是对的。所以很奇怪,采集卡是怎么工作的。采集到数据很不一致。比如 一通道数 二通道数 一通道电压 二通道电压 35915 29902 0.080720 10.000000 35757 28537 0.089570 10.000000 35631 27562 0.094301 10.000000 35503 25235 0.097963 10.000000 35426 24137 0.106203 10.000000 35360 24088 0.109712 10.000000 35341 24373 0.118105 10.000000 35288 23678 0.125734 10.000000 35297 25795 0.131533 10.000000 35089 26417 0.133059 10.000000 35123 26973 0.144961 10.000000 35155 28294 0.144656 10.000000 35058 29387 0.148775 10.000000 34959 30397 0.149386 10.000000 34905 30623 0.159304 10.000000 34885 29896 0.166018 10.000000 34888 29184 0.166018 10.000000 34868 27691 0.179446 10.000000 34891 25486 0.177005 10.000000 34900 25569 0.191958 10.000000 34905 24774 0.196078 10.000000 34985 23201 0.202029 10.000000 35094 23213 0.213931 10.000000 35071 22934 0.223087 9.916075 这是直接用上两个函数得到的。没有任何转换。上面数据是异常情况。有很多数据看上去还是很对的。就象李侃老师讲的32767对应10伏的情况。

GaryLin

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1186回
  • 年度积分:0
  • 历史总积分:1263
  • 注册:2003年4月15日
发表于:2003-07-25 09:31:00
11楼
Voltage = ((short)ai_buf[num]) / 32768 * 10.0;

keepmoon

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 5回
  • 年度积分:0
  • 历史总积分:8
  • 注册:2003年7月18日
发表于:2003-07-25 11:12:00
12楼
非常感谢GaryLin和李侃老师热情的帮助。现在问题差不多解决了。我的思路仍旧是采用 道      AI_ContScanChannels (cardID, LastADChan, AD_U_10_V, InBuf, ScanCount*ADChanCount, SampleRate, SYNCH_OP);      AI_ContVScale (cardID, AD_U_10_V, InBuf, InVolBuf, ScanCount*ADChanCount); 两个函数完成。由于他采用的是U16,所以采得的数据是不对的。所以加以转换。但是这样的“错误”数据得到的电压,看上去到是对的,是不是卡内部有个变换了。我不知道ADLink的卡是怎么作的。既然按照李侃老师所讲,数据输出范围是-32768~32767的话。应该是要用I16装才对。 现在有一点疑问就是采集得到的数据中32768的数据对应是0伏,32767对应是10伏。其中32768显然是负数得来,就是-32768得到。不知计算机中-32768怎么表示,应该是-32767才对呀。而-32767的表示形式应该是1000000000000001这样对于无符号数字而言数值应该是32769。就是说32769才对应0伏。请您 指点迷津。 非常感谢您们。

GaryLin

  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 1186回
  • 年度积分:0
  • 历史总积分:1263
  • 注册:2003年4月15日
发表于:2003-07-25 11:53:00
13楼
Sorry! 上一个计算式有误, 依李侃老师的说法... -32768 ~ 32767 (0v ~ 10v) dec: -32768 ........ -1, 0 ......... 32767 hex: 0x8000 .... 0xFFFF, 0x0000, ... 0x7FFF vol: 0v .......... 5v .......... 10v voltage = ((short)ai_buf[num]) / 32768 * 5.0 + 5; 32768 or 32769 在 I16 中是无意义的 (超出范围). 在 hex 中, 等于 0x8000, 0x8001. 转成 I16 等于 -32768, -32767 也就是说 ... -32768 (I16) = 0x8000 (hex) = 32768 (U16) -32767 (I16) = 0x8001 (hex) = 32769 (U16)

yoyo1101

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 590回
  • 年度积分:0
  • 历史总积分:645
  • 注册:2002年8月30日
发表于:2003-07-25 13:37:00
14楼
在凌华自带测试程序的基础上修改后进行测试,发现数值对应关系没有问题,也就是说选择0~10V Rang 8000对应0V,FFFF对应5V,7FFF对应10V。方便的话,把你的工程发过来,我们测试一下。

龙在江湖

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2003年7月25日
发表于:2003-07-25 21:41:00
15楼
谢谢GaryLin和李侃老师和yoyo1101及时的回复。现在问题差不多解决了。就是进行强制转化。可以将U16数据转化为-32768~+32767 的I16数据。 而且奇怪的是,对于采集到的U16数据,直接进行电压转换的话,看似不满足要求的数据(范围是0~65535的数据)居然可以得到正确电压值。其中奥妙只有凌华工程师知道了! 这真是一个不错的网站,当然是因为有你们这些愿意帮助他人的人!

国安

  • 精华:1帖
  • 求助:0帖
  • 帖子:3帖 | 242回
  • 年度积分:0
  • 历史总积分:256
  • 注册:2002年4月15日
发表于:2003-08-05 11:06:00
16楼
其实,同一个数据,转成unsigned short和short,看到的数据就是不一样的.看一下二进制的转换会比较清楚. hex unsigned short short 0xffff - 65535 - -1 0xfffe - 65534 - -2 0xfffd - 65533 - -3 0xfffc - 65532 - -4 0xfffb - 65531 - -5 ... ... ... 0x0 - 0 - 0 0x1 - 1 - 1 0x2 - 2 - 2 0x3 - 3 - 3 0x4 - 4 - 4

suntide

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 8回
  • 年度积分:0
  • 历史总积分:291
  • 注册:2003年8月04日
发表于:2003-08-05 11:21:00
17楼
今天早上我做了一个试验,PCI9118如采用单极编码,AD_U_10_V,计算方法使用。   for(num=0;num<data_size;num++) { adinput=ai_buf[num]>>4; vol[num]=(F64)(adinput-2048)/4095*20; } 可以得到正确结果,包括-10~10V的信号,都采集正确。

热门招聘
相关主题

官方公众号

智造工程师