【Ai-M61-32S开发板】水位监测计 Part II —— 水位的数码管显示
本文介绍了安信可 Ai-M61-32S 开发板通过 ADC 采集水位传感器的模拟信号电压,拟合计算获得水位高度,并使用 4 位数码管实时显示,最终实现水位监测计的项目设计。

💡 方案设计
在前面关于 ADC 读取电压并结合水位传感器实现电压-水位高度转换的基础上,
详见:【Ai-M61-32S开发板】水位监测计 -安信可论坛 .
增加 4 位共阳 数码管显示 水位高度的功能。
⚙️ 硬件连接
这里采用 2 个 74HC595 驱动的 4 位共阳数码管,支持 3.3V 至 5V 的宽电压输入,仅需 3 个信号引脚即可驱动。
水位传感器接线方式
Water-sensor_S
-> IO19
Water-sensor_+
-> 3V3
Water-sensor_-
-> GND
数码管接线方式
4Bit-segment_SCLK
-> IO23
4Bit-segment_RCLK
-> IO24
4Bit-segment_DIO
-> IO11
🛎️ 示意图

#️⃣ 工程代码
#include <stdio.h>
const int sensorPin = 19; // water-level sensor pin
// 74HC595 引脚设置
const int latchPin = 24; // RCLK
const int clockPin = 23; // SCLK
const int dataPin = 11; // DIO
unsigned char num[]={0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90 //"9"
};
void setup()
{
pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
pinMode(dataPin,OUTPUT);
pinMode(sensorPin, INPUT);
// uart setting
Serial.begin(115200);
}
/* ------------ loop for serial print and segment display -------------- */
void loop() {
int count = 0;
int val = analogRead(sensorPin); // analog sensor value
float vlt = val * (3.3 / (3199-21)); // real voltage conversion
float wl = 41.774 * vlt - 38.686; // water level (mm)
//Serial.print("Analog Value: ");
Serial.print(val); // in order to serial plot
Serial.print(", ");
//Serial.print("Voltage: ");
Serial.print(vlt);
//Serial.print("V");
Serial.print(", ");
//Serial.print("Water Level: ");
Serial.println(wl);
//Serial.println("mm");
Serial.println((String)"Analog Value: " + val + ", Valtage: " + vlt + "V, Water Level: " + wl + "mm"); // serial print string
while (count < 25) // loop 25 times for delay 500ms (20ms every display)
{
if (wl < 0){
disp(0);
}else{
disp(wl); // display water level
}
count++;
}
}
/* ------------ segment display number (dynamics scanning) -------------- */
void disp(float n)
{
int t = 5;
int yi = ((int)(n*10))%10;
int ge = (int)n%10;
int shi = ((int)n/10)%10;
int bai = ((int)n/100)%10;
if(bai>0){
shiftOut(dataPin,clockPin,MSBFIRST,num[bai]);
}else{
shiftOut(dataPin,clockPin,MSBFIRST,0xFF);
}
shiftOut(dataPin,clockPin,MSBFIRST,0b00001000);
digitalWrite(latchPin, HIGH);
delay(t);
digitalWrite(latchPin,LOW);
if(shi>0){
shiftOut(dataPin,clockPin,MSBFIRST,num[shi]);
}else{
if(bai>0){
shiftOut(dataPin,clockPin,MSBFIRST,num[0]);
}else{
shiftOut(dataPin,clockPin,MSBFIRST,0xFF);
}
}
shiftOut(dataPin,clockPin,MSBFIRST,0b00000100);
digitalWrite(latchPin, HIGH);
delay(t);
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,num[ge]&0x7F);//与运算加入小数点
shiftOut(dataPin,clockPin,MSBFIRST,0b00000010);
digitalWrite(latchPin, HIGH);
delay(t);
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,num[yi]);
shiftOut(dataPin,clockPin,MSBFIRST,0b00000001);
digitalWrite(latchPin, HIGH);
delay(t);
digitalWrite(latchPin,LOW);
}
/* ------------ shiftOut -------------- */
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
- ⚠️注意
shiftOut
函数需要定义;
- 🔁由于每次采样数值均存在较大波动,为了避免数码管动态刷新过于频繁,加入循环延长数据刷新时间;
- 🗂️ 或者多次采样取平均值,进而减小水位数值的波动,使数码管的显示更稳定。
💬效果演示
展示了数码管显示、串口文本打印、串口绘图效果。
数码管显示水位

动态

串口输出电压和水位值

动态水位的演化曲线

静态水位的演化曲线

📝总结
本文介绍了安信可 Ai-M61-32S 开发板实现水位监测计的项目设计。
使用 Arduino IDE 编程,通过 ADC 采集水位传感器的模拟信号电压、电压-水位校准等流程,实现水位高度的串口打印和串口绘图,并使用 4 位共阳数码管实时显示水位高度,最终实现水位监测计的项目设计,为该模组的快速开发和相关产品的应用提供了参考。