|
作为一个创客,其中最大的一件好事就是能够制造属于自己的工具。在前几篇文章中,我们介绍了从电压表到电池测试仪等几种电子工具的开发。今天,在本篇文章中,我们将介绍danielrp @ www.instructables.com制造的一款毫欧表工具。
毫欧表是一种用于确定小型电阻、PCB迹线、电机线圈、电感线圈和变压器线圈的电阻或计算诸如电线长度之类的设备。它提供的分辨率并不是常规的万用表内置的,因此可以轻松获得毫欧范围内的精确读数。 互联网上有很多自制毫欧表的教程,但在本文中,我们将主要介绍Daniel制作的毫欧表。它基于精密电流吸收器和由Arduino Nano控制的高分辨率ADC。电流吸收器基于LT3092精密电流源/吸收器,该电流源/吸收器使用电阻器和晶体管网络设置为吸收器。对于ADC,使用了高分辨率的MCP3422A0。仅使用ADC的一个通道,并且将其差分连接到被测电阻“ S + S-”。 MCP3422配置为18位,但由于S +总是大于S-,因此有效分辨率为17位。 为减少测试引线电阻对测量的影响,设备使用开尔文连接器作为引线连接被测电阻到测量点。
该设备的测量范围包括: ● 分辨率0.1mOhm:0.1mOhm至12.9999欧姆。 ● 分辨率1m0:1mOhm至129.999欧姆。 ● 分辨率10m:10mOhm至1299.99欧姆。 用户可以使用设备上两个按钮的其中一个在上述测量范围之间进行选择。通过1602 LCD显示屏向用户提供有关选择和仪表读数的视觉反馈,整个项目都装在橙色的Hammond 1590B铝制盒子中,方便使用和展示。
所需的组件 使用的一些关键组件包括: ● Arduino Nano开发板 ● 1602 LCD显示屏 ● ULN2003A ● LT3092EST ● MCP3422A0 ● Kelvin连接器
原理图 由于项目的复杂性,在试验板上进行实施不仅耗时,而且会使项目容易出错。为防止这种情况,该项目在由Eagle设计的PCB上实施。下面提供了显示组件如何在PCB上连接的示意图:
根据原理图开发的PCB如下图所示:
下图显示了制造后的实际电路板。
外壳和组件 DanielrP为该项目开发了一种外壳,并采用PCB方法使该项目具有代表性和实用性,并使用Inkscape设计了对铝制外壳盒的修改。请按照以下步骤制作外壳。
1. 用油漆胶带盖住铝盒的顶部。然后切割前盖的模板并将其粘贴到铝盒的胶带上。 2. 接下来,标记孔和钻孔的位置,以使钢丝锯或顶盖锯片进入内部切口 3. 剪切所有形状。
4. 修剪文件,然后取下模具和胶带。
5. 使用双面胶带或热胶将按钮和屏幕一起安装。 6. 盖好盖子后,在盒子上标记出(螺钉)孔的位置。中心打孔。
7. 在安装完所有组件之后,盖子应如下图所示。在将外壳耦合在一起之前,先将PCB的某些组件安装到位可能是明智的。由于用于PCB的大多数组件都是SMT类型的,因此将它们安装到PCB上将需要使用热风枪或使用常规烙铁以及细尖镊子、一些焊芯和0.02英寸焊料。下图提供了一些组件在PCB上的放置位置。
由于开尔文(Kelvin)连接器和开关仅在外壳的外部有用,因此它们将通过跨接线连接到PCB,如上图所示。在准备好PCB和包装盒之后,将PCB安装在包装盒中并连接按钮和开尔文连接器。
为了方便在完成后将代码上传到设置中,您可以在Nano的USB端口附近打开一个小孔,以便可以轻松地将USB线连接到此。完成后,我们现在就可以编写该项目的代码。
代码 该项目代码背后的算法非常复杂。我们通过驱动连接到ULN2003的设置引脚来设置项目的分辨率。然后考虑分辨率和模式(由按钮的状态决定),并读取MCP3422以获取电阻值并将其显示在LCD上。由于草图已经很复杂了,因此稍微降低了复杂性,使用了许多库,包括: Wire.h库、LiquidCrystal_I2C库和EEPROM库。Wire库用于Arduino与项目的两个I2C组件LCD和MCP3422之间的I2C通信。另一方面,LiquidCrystal_I2C库有助于与LCD进行接口连接,而EEPROM库用于访问Arduino上的EEPROM以存储有关模式和仪表刻度的信息。 Arduino IDE已预装了 Wire和EEPROM库,LiquidCrystal_I2C库可以通过附加的链接安装,也可以通过Arduino库管理器安装。我们将快速讲解并解释一些Sketch /片段。代码相当庞大,可能难以覆盖全部内容,但幸运的是,Daniel在每一行代码上都做了注释,因此应该很容易理解。 接下来,我们指定显示的尺寸并为分辨率创建宏。基本上,这将设置与分辨率有关的引脚状态。 - //LCD display parameters
- #define N_ROWS 2u
- #define N_COLS 16u
- //General parameters
- #define DEBOUNCEHARDNESS 10u
- //Macros
- //Scale
- //0.0001ohm - 156mA
- #define SCALE_01 digitalWrite(10, LOW); \
- digitalWrite(11, HIGH); \
- digitalWrite(12, HIGH); \
- pinMode(10, OUTPUT); \
- pinMode(11, OUTPUT); \
- pinMode(12, OUTPUT)
- //0.001ohm - 15.6mA
- #define SCALE_1 digitalWrite(11, LOW); \
- digitalWrite(10, HIGH); \
- digitalWrite(12, HIGH); \
- pinMode(10, OUTPUT); \
- pinMode(11, OUTPUT); \
- pinMode(12, OUTPUT)
- //0.01ohm - 1.56mA
- #define SCALE_10 digitalWrite(12, LOW); \
- digitalWrite(11, HIGH); \
- digitalWrite(10, HIGH); \
- pinMode(10, OUTPUT); \
- pinMode(11, OUTPUT); \
- pinMode(12, OUTPUT)
复制代码
接下来,为Arduino内置led创建宏,该宏将用于提供有关状态的视觉反馈。我们在此之后配置了按钮。一个打开或关闭它,另一个使它进入和退出校准模式。接下来,我们声明一些将用于MCP3422相关数据的变量。 我们指定变量来保存通道、从站地址和其他内容。 - //MCP3422
- #define MCP3422_CH1 0x00
- #define MCP3422_CH2 0x01
- #define MCP3422_SR 0x03 //3.75 SPS (18bit)
- #define MCP3422_GAIN 0x00 //x1
- #define MCP3422_CR_STARTONESHOT 0x80 // /RDY bit = 1, /O/C bit = 0
- #define MCP3422_CR_READY 0x80 // /RDY bit mask
- #define MCP3422_NCH 2u //Number of channels available
- #define MCP3422_ADD 0x68 //Slave address
复制代码
接下来,我们创建将显示的消息字符串。 - //Messages
- const char strHOLD[5] = "HOLD";
- const char strRUN[5] = " RUN";
- const char strScale0m1[6] = "(0m1)";
- const char strScale1m0[6] = "(1m0)";
- const char strScale10m[6] = "(10m)";
- const char strScaleAuto[7] = "(Auto)";
- const char strFullScale[9] = "--------";
复制代码
然后是存储不同类型数据的EEPROM地址规范。 - //EEPROM Addresses
- #define EE_U8MODE 0x0000
- #define EE_U8SCALERUN 0x0002
- #define EE_U8SCALEHOLD 0x0004
- #define EE_U32MEASHOLD 0x0006
复制代码
接下来,我们创建某种类型的变量。 - //MCP3422 machine states
- enum eMCP3422ReadStates_t
- {
- eMS_WaitCurrent = 0,
- eMS_WaitVoltage = 1
- };
复制代码
创建LiquidCrystal_I2C库的实例,并创建其他一些常规变量。 - LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity (As descrived in the ebay link but with 0x3F address instead of 0x20)
- //General variables
- bool bIsHoldMode = false;
- uint8_t u8HoldScale = 0;
- uint32_t u32HoldValue = 0;
- uint8_t u8CurrentScale = 0; //Current Scale
- uint32_t u32CurrentMeasurement = 0; //Last conversion value from MCP3422
- bool bMCP3422ValIsPositive = true; //Last conversion sign, in this circuit it's always positive
- bool bSCALEPressed = false; //State of On push button
- bool bLastSCALEPressed = false; //Last state of On push button, used for flange detection
- bool bCALPressed = false; //State of Off push button
- bool bLastCALPressed = false; //Last state of Off push button, used for flange detection
- uint8_t u8SCALEDebounce = 0; //Debounce counter for On push button
- uint8_t u8CALDebounce = 0; //Debounce counter for Off push button
复制代码
接下来是void setup()函数。我们首先检查当前的分辨率,然后将分辨率设置为该值。 - void setup()
- {
- if(!eeReadU8(EE_U8SCALERUN , u8CurrentScale))
- {
- eeStoreU8(EE_U8SCALERUN, 0);
- u8CurrentScale = 0;
- }
- changeScale(u8CurrentScale);
复制代码
接下来,我们调用setupDisplay()函数来初始化LCD并显示初始界面初始屏幕。
接下来设置I2C通讯速度,将LCD的背光调高,然后初始化串口通讯,以便将串口监视器用于调试目的。 - Wire.setClock(400000); //Speed for both display and MCP3422
- lcd.setBacklight(HIGH);
- Serial.begin(9600);
- }
复制代码
接下来是void loop()函数。该函数从一行代码开始,以获得有关按钮状态、模式和分辨率等的更新。 - void loop()
- {
- updateInputs(); //Read pushbuttons, update modes and change scale
复制代码
其后是一条if语句,该语句检查设备是否处于保持模式。如果设备处于保持模式,则获得刻度和测量值,但如果不是(运行模式),则使用“ RUN”文本更新bufferA,读取RUN刻度,在当前接收器中设置RUN刻度,检查是否有数据可从MCP3422获得,并在通道上开始新的数据转换。 - if(true == eeIsHoldMode())
- {//Hold Mode
- writeString(1u, 12u, strHOLD); //Update bufferA with the "HOLD" text
- eeReadU8(EE_U8SCALEHOLD, u8CurrentScale); //Read the HOLD scale
- eeReadU32(EE_U32MEASHOLD, u32CurrentMeasurement); //Read the HOLD measurement
- }
- else
- {//Run Mode
- writeString(1u, 12u, strRUN); //Update bufferA with the "RUN" text
- eeReadU8(EE_U8SCALERUN, u8CurrentScale); //Read the RUN scale
- changeScale(u8CurrentScale); //Set the RUN scale in the current sink
- //Read the ADC if a new measurement is available.
- if(MCP3422_IsDataAndRead(u32CurrentMeasurement, bMCP3422ValIsPositive))
- {//New conversion available
- if(false == bMCP3422ValIsPositive)
- {
- u32CurrentMeasurement = 0;
- }
- MCP3422_StartConversion(MCP3422_CH1); //Restart conversion
- }
- }
复制代码
最后,显示缓冲区被更新,并且使用loop()的updateDisplay()函数在LCD上显示该值。 - updateDisplayBuffer(); //Update the rest of BufferA
- updateDisplay(); //Write the necessary chars in the display
- }
复制代码
上面讨论的void loop()和void setup()包含很少的代码行,因为大部分工作是在其他几个函数中完成的。从在MCP3422 ADC上处理数据转换的函数到用于设置比例尺的函数到用于更新显示的函数,所有这些函数都起着重要的作用,尽管有点难以一一遍解。由于它将使本教程体积很大,但Danielrp会正确注释实现这些代码的代码,因此应该易于遵循。完整的草图随附在以下下载部分的zip文件中。
演示 完成代码并安装好硬件后,将设备连接到计算机并将代码上传到计算机上,一段时间后,您将看到如下图所示的显示屏。
在将毫欧电阻器连接到导线上时,您应该看到该电阻器的值显示。
以上就是制作的毫欧表。本文使用的代码如下:
Milliohmeter.zip
(384.71 KB, 下载次数: 31)
|