发帖
4 0 0

【Ai-M61-32S开发板】水位监测计 Part II

无垠的广袤
论坛元老

28

主题

32

回帖

3221

积分

论坛元老

积分
3221
QQ
电子DIY 29 4 5 小时前

【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

🛎️ 示意图

diagram_connect.jpg

#️⃣ 工程代码

#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 函数需要定义;
  • 🔁由于每次采样数值均存在较大波动,为了避免数码管动态刷新过于频繁,加入循环延长数据刷新时间;
  • 🗂️ 或者多次采样取平均值,进而减小水位数值的波动,使数码管的显示更稳定。

💬效果演示

展示了数码管显示、串口文本打印、串口绘图效果。

数码管显示水位

connect_segment.jpg

动态

segment_display.gif

串口输出电压和水位值

uart_print.gif

动态水位的演化曲线

serial_plot.gif

静态水位的演化曲线

serial_plot_steady.gif

📝总结

本文介绍了安信可 Ai-M61-32S 开发板实现水位监测计的项目设计。

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

──── 0人觉得很赞 ────

使用道具 举报

感谢论坛元老提出的 Markdown 美化方案
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=46239
哈哈哈排版颜色确实好看
漂亮
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28627 个
  • 话题数: 40788 篇