基于TDC-GP22和Arduino UNO的超声波流量计-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 30597|回复: 40

[未解决] 基于TDC-GP22和Arduino UNO的超声波流量计

[复制链接]
发表于 2019-6-27 15:54 | 显示全部楼层 |阅读模式
本帖最后由 dyn002000 于 2019-6-28 18:02 编辑

各位大大好,

最近尝试着用Arduino Uno和TDC-GP22 做超声波流量计。 用的是leokoppel的 library:https://github.com/leokoppel/GP22
简单的测试的代码如下:

[mw_shl_code=arduino,true]#include "GP22.h"
#include <SPI.h>
#include <avr/io.h>


/*
*
* Test setup (Arduino Uno, through 5->3.3V level shift)
*     10 -> SS
*     11 -> MOSI
*     12 -> MISO
*     13 -> SCK
*     2  -> INT
*     5V -> VCC
*     GND -> GND
*     4 -> DS18B20 temperature sensor (optional)
*/


const bool DEBUG = 1;
const int FAST_MODE = 1;
const int PIN_INT = 2;


GP22 tdc(PIN_INT, DEBUG);

float cycleFactor_ns = 0;


void setup() {
  
  Serial.begin(115200);
  Serial.println("Go !");
  
  tdc.init();

  tdc.writeRegister(0, CFG_KEEP_DEFAULT_BITMASKS[0]
                     
                      | CFG0_ANZ_FIRE_START_2*1        // Fire 20  (4)+16
                      | CFG0_DIV_FIRE_1*1
                      | CFG0_DIV_FIRE_0*1             // Fire divided by 4
                      | CFG0_DIV_CLKHS_0*0             // Clock divided by 1
                      | CFG0_START_CLKHS_START_1 * 1    // Setting time 480µs
                      | CFG0_CALIBRATE * 1              // Calibration on
                      | CFG0_MESSB2 * 1             // Measurement mode 2
                     
                      | CFG0_ANZ_PORT               //Modification with temperature(not used yet)
                      | CFG0_TCYCLE
                      | CFG0_ANZ_FAKE
                      | CFG0_SEL_ECLK_TMP
                     
                      | 0x00
                     );
                     
  tdc.writeRegister(1, CFG_KEEP_DEFAULT_BITMASKS[1]
                      | CFG1_HIT1_0 * 1     // Calculate 1st Stop Ch1 - Start
                      | CFG1_HIT2_1 * 1
                      | CFG1_HITIN1_2 * 1   // Wait for 4 hit on channel 1
                      | CFG1_HITIN2_1 * 0   // Wait for 0 hits on channel 2
                      | CFG1_SEL_START_FIRE * 1
                      | CFG1_EN_FAST_INIT * 0
                      | 0x00
                     );

  tdc.writeRegister(2, CFG_KEEP_DEFAULT_BITMASKS[2]
                      | CFG2_RFEDGE1 * 0           // Ch 1 sensitive to one edge
                      | CFG2_EN_INT_ALU            // Enable interrupt on ALU ready
                      | CFG2_EN_INT_TDC_TIMEOUT    // Enable interrupt on TDC timeout
                      | CFG2_DELVAL1_12            // DELVAL1= 5000
                      | CFG2_DELVAL1_9
                      | CFG2_DELVAL1_8
                      | CFG2_DELVAL1_7
                      | CFG2_DELVAL1_3
                      | 0x00
                     );
                     
  tdc.writeRegister(3, CFG_KEEP_DEFAULT_BITMASKS[3]
                      | CFG3_EN_AUTOCALC_MB2     // Automatic calculation of all enabled hits(mode 2 only)
                      | CFG3_EN_FIRST_WAVE       // Automatic first hit detection
                      | CFG3_SEL_TIMO_MB2_1      // Predivider for timeout = 1024µs
                      | CFG3_DELVAL2_15          // 10 periods after first hit for 3rd stop
                      | CFG3_DELVAL2_13
                      | CFG3_DELVAL2_9           // 9 periods for 2nd stop
                      | CFG3_DELVAL2_6
                      | CFG3_DELVAL2_3           // 8 periods for 1st stop
                      | 0x00
                     );

  tdc.writeRegister(4, CFG_KEEP_DEFAULT_BITMASKS[4]
                      | CFG4_KEEP_DEFAULT_2 * 0
                      | CFG4_KEEP_DEFAULT_1 * 1
                      | CFG4_DELVAL3_8 * 0       // Enable pulse width measurement
                      | CFG4_DELVAL3_7 * 0       // Rising edge
                      | CFG4_DELVAL3_6           // Additional offset shift by +20mv
                      | CFG4_DELVAL3_5 * 0       // No offset -20mv
                      | 0x00
                     );
                     
  tdc.writeRegister(5, CFG_KEEP_DEFAULT_BITMASKS[5]
                      | CFG5_CON_FIRE_1          // Enable output fire up  
                     );
                     
  tdc.writeRegister(6, CFG_KEEP_DEFAULT_BITMASKS[6]
                      | CFG6_EN_ANALOG           // Enable Analog section
                      | CFG6_NEG_STOP_TEMP       // Use internal Schmitt trigger
                      | CFG6_TW2_1               // 300µs to charge up the capacitor
                      | CFG6_TW2_0               
                      | CFG6_FIREO_DEF           // Low level by default of the inactive fire buffer
                      | CFG6_QUAD_RES            // Enable quad resolution
                      | CFG6_ANZ_FIRE_END_0*1      // Fire 20    4+(16)   
                                    
                     );



  tdc.printConfigRegisters();

  byte a = tdc.readRegister(READ_REG_1);            
  Serial.println(a,HEX);
  Serial.println("Test communication: ");
  Serial.print(tdc.testCommunication());
}



void loop() {

  tdc.sendOpcode(OPCODE_INIT);
  tdc.sendOpcode(OPCODE_START_TOF_RESTART);


  tdc.waitForInterrupt(10000000);
  delay(20);
  Serial.println(tdc.readRegister(READ_RES_3),HEX);

}[/mw_shl_code]

寄存器的配置是直接用的 GP22 使用手册的第22到第25页。 温度测量暂时没做所以相关的步骤就跳过了。校准也没做(不知道行不行,不过后来添加了校准也有问题),目前就是想测出个飞行时间(ToF)。但是代码的结果如下:

[mw_shl_code=arduino,true]Go !
attached pinChangeISR_debug

Register 0: 0x430be800
Register 1: 0x21444000
Register 2: 0xa0138800
Register 3: 0xd0a24800
Register 4: 0x10004000
Register 5: 0x40000000
Register 6: 0xc0c06100

21
Test communication:
\/Test took 180 us
1
69978000
69978000
69978000
69978000
69978000
69978000
69978000
...[/mw_shl_code]

21是寄存器1的第一个字节,1是testcommunication()的结果,这两个测试都表明了通讯应该是没问题的。但是当我读取RES_3的时候,值一直不变。不管我是把两个超声波传感器面对面的放还是中间隔着10mm厚的铁板,读数永远不会变。 不过我想应该是中断的问题,waitForInterrupt(10000000) 每次都超时, 用示波器和安培表看INT引脚也从来不回到0。

但是波形是可以正确发出的,比如传感器面对面紧贴着放的波形如下图:

0mm.jpg

中间隔着10mm铁板的如下图:
10mm.jpg
蓝色的是未经放大的发送波形,绿色的是放大后的,黄色的是接收的波形。

第二张图虽然丑了点但是还是能明显看出一个时间间隔的,我自己也放大了看过,大约2us, 乘以在铁里的音速 5000m/s,算出来大约10mm,还挺对的。但是就是代码读出来的值一直不变。。。。很无奈。。。

我用的1MHz传感器:
capteur.PNG

GP22的设备(CJMCU-22):
cjmcu-22.PNG

再附上datasheet的链接:
TDC-GP22 Datasheet:https://ams.com/documents/20143/36005/TDC-GP22_DS000323_1-00.pdf/aa6c41ca-1312-60ec-f6a8-82c90da3f856

求各位大大帮帮忙,卡了好久了,头疼。

万分感谢!!!!




 楼主| 发表于 2019-6-27 16:02 | 显示全部楼层
超链接不知道为什么加不了,,我就直接把网址复制下来了。
 楼主| 发表于 2019-7-1 14:50 | 显示全部楼层
有木有大佬帮帮忙呀。。。
发表于 2019-7-1 21:42 | 显示全部楼层
本帖最后由 fangchaoqun 于 2019-7-1 21:55 编辑

我也遇到了这样的问题,后来在网上买了个板子,里面带的源程序应该是STM的,要不我发给你参考一下。留个邮箱给我.
 楼主| 发表于 2019-7-3 16:51 | 显示全部楼层
Emm,,,STM 的代码还是搞不来呀。。。不过还是非常感谢啦!

有没有大佬直接用Arduino 做出来的,求帮帮忙咯~~!
发表于 2019-7-8 11:02 | 显示全部楼层
楼主你好,我在做一个跟你项目差不多的,用激光测距的项目。但我不怎么懂电子,我想咨询您这个模块的接线,不知道您方不方便分享一下这个模块的接线
发表于 2019-7-8 11:04 | 显示全部楼层
可以短信或者微信18811822025.静候您的答复
 楼主| 发表于 2019-7-8 15:09 | 显示全部楼层
klh123456 发表于 2019-7-8 11:02
楼主你好,我在做一个跟你项目差不多的,用激光测距的项目。但我不怎么懂电子,我想咨询您这个模块的接线, ...

你好,

你有试过leo koppel 的library嘛  这个地址的https://github.com/leokoppel/GP22

连线其实他也写了,
[mw_shl_code=arduino,true]Test setup (Arduino Uno, through 5->3.3V level shift)
       10 -> SS
       11 -> MOSI
       12 -> MISO
       13 -> SCK
       2  -> INT
       5V -> VCC
       GND -> GND[/mw_shl_code]

就是要注意一下 用的Arduino UNO 的话 得弄个5V-3.3V的电平转换芯片(双向的),不然是运不起来的甚至会弄坏GP22。。  SSN,SCK,MOSI这些pin都是单向传输的,所以你甚至可以直接用分压的方法来完成转换。但是MISO pin传输方向是相反的,那只能用双向转换芯片了。。INT的方向不确定,虽然感觉应该是单向的,保险起见还是用双向口接比较好。  你这些都接完了 试试看leo koppel的代码,要是testcommunication()成功的话那说明应该没问题了。要是不行的话 你把RTN(Reset)置于电平高位试试。
发表于 2019-7-8 21:48 | 显示全部楼层

回帖奖励 +1 金币

本帖最后由 klh123456 于 2019-7-8 21:51 编辑
dyn002000 发表于 2019-7-8 15:09
你好,

你有试过leo koppel 的library嘛  这个地址的https://github.com/leokoppel/GP22

这几个我连了,不过我是直接联的,不能直接联吗?我的电子技术真的太渣了~~
发表于 2019-7-8 22:04 | 显示全部楼层
本帖最后由 klh123456 于 2019-7-8 22:06 编辑
dyn002000 发表于 2019-7-8 15:09
你好,

你有试过leo koppel 的library嘛  这个地址的https://github.com/leokoppel/GP22

不能使用5v供电吗?
arduino里面有个3.3v可以用吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-30 23:40 , Processed in 0.107087 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表