biubiu108 发表于 2022-8-20 09:32

基于智能液晶显示模块的水质监测设备

什么是水质监测设备?它是利用光学传感器、离子选择性传感器对水质进行检测,并将结果清晰展示在液晶屏幕上,可以通过触摸屏幕操作和控制。该设备被广泛的应用于地表水、工业污水、饮用水源水质监测、调查和筛选领域。其优点是操作简便,显示结果清晰直观,除了实时的显示,还可以形成**曲线,用于长期的跟踪和研究。本项目是基于Topway的7寸智能液晶显示模块,型号HMT070ETD-1D分辨率:1024x600
接口:RS232 RJ45
工作电压:11V~26V
工作温度:-20°C ~ 70°C
宽视角:是
外形尺寸:185.9mm x 109.5mm x 25.4mm
尺寸:7"
视窗 :154.21mm x 85.92mm
触摸屏:CTP一、项目需求分析:1.    采集数据(定时采集水体的PH值和温度,以及环境的温湿度)
2.    显示在屏幕上(将采集的值实时显示在屏幕上)
3.    曲线展示(以曲线的形式将一段时间内的变量值显示在屏幕上)二、项目流程1、屏幕内容设计1)一张背景图作为显示时间、日期和实时数据的主页2)2个图标和2个坐标轴作为水质曲线页面3)2个图标和2个坐标轴作为温度和湿度的显示页面4)使用TOPWAY SGTools工具创建工程导入图片和图标5)选择字库,菜单栏中的工具-字体设置中可以选择合适的字库6)创建所有页面
控件使用情况如下:7)编辑图标调整控件可以使用工具栏中的对齐工具,可以拯救强迫症患者8)添加变量并绑定编辑根据实际使用情况新建变量,这里只使用了16位数字变量和曲线变量在对应的控件属性VP地址里绑定对应的变量的地址,同时也可以修改颜色大小等。9)添加触摸键10)使用TOPWAY的屏内RTC时钟功能, 并使用"RTC键盘(PIP)”替代,让开发设计更加便捷。2、硬件设计3、软件设计1) 编写LCD 驱动程序根据协议内容,编写16位数字变量的动/**
brief LCD发送16位变量
param adr:变量地址
param dt:发送的变量
return 无
*/
voidlcd_send_pv16(uint32_tadr,uint16_tdt)
{
    uint8_tsend_buf;
    uint8_tidx = 0;    send_buf = 0xaa;
    send_buf = 0x3d;
    adr = ntohl(adr);//大小端转换
    memcpy((uint8_t*)&send_buf, (uint8_t*)&adr, sizeof(uint32_t));
    idx += sizeof(uint32_t);    dt = ntohs(dt);//大小端转换
    memcpy((uint8_t*)&send_buf, (uint8_t*)&dt, 2);
    idx += 2;
    send_buf = 0xcc;
    send_buf = 0x33;
    send_buf = 0xc3;
    send_buf = 0x3c;
    send_data1(send_buf, idx);
}LCD左推进写曲线数据/**
brief LCD左推进写曲线数据
param adr:变量地址
param adr_curve:插入位置
param dt:发送的变量
return 无
*/
voidlcd_send_curve(uint32_tadr,uint16_tadr_curve,uint16_tdt)
{
    uint8_tsend_buf;
    uint8_tidx = 0;    send_buf = 0xaa;
    send_buf = 0x4e;
    adr = ntohl(adr);
    memcpy((uint8_t*)&send_buf, (uint8_t*)&adr, sizeof(uint32_t));
    idx += sizeof(uint32_t);    adr_curve = ntohs(adr_curve);
    memcpy((uint8_t*)&send_buf, (uint8_t*)&adr_curve, sizeof(uint16_t));
    idx += sizeof(uint16_t);    dt = ntohs(dt);
    memcpy((uint8_t*)&send_buf, (uint8_t*)&dt, sizeof(uint16_t));
    idx += sizeof(uint16_t);    send_buf = 0xcc;
    send_buf = 0x33;
    send_buf = 0xc3;
    send_buf = 0x3c;
    send_data1(send_buf, idx);
}
跳转页面的驱动/**
brief LCD跳转页面
param page:页面地址
return 无
*/
voidlcd_send_page(uint16_tpage)
{
    uint8_tsend_buf;
    uint8_tidx = 0;    send_buf = 0xaa;
    send_buf = 0x70;
    page = ntohs(page);
    memcpy((uint8_t*)&send_buf, (uint8_t*)&page, sizeof(uint16_t));
    idx += sizeof(uint16_t);
    send_buf = 0xcc;
    send_buf = 0x33;
    send_buf = 0xc3;
    send_buf = 0x3c;
    send_data1(send_buf, idx);
}
设置时间的驱动/**
brief LCD设置时间
param page 无
return 无
*/
voidlcd_send_time(void)
{
    uint8_tsend_buf;
    uint8_tidx = 0;    send_buf = 0xaa;
    send_buf = 0x9c;    memcpy((uint8_t*)&send_buf, (uint8_t*)&my_rtc, sizeof(MYRTC));
    idx += sizeof(MYRTC);    send_buf = 0xcc;
    send_buf = 0x33;
    send_buf = 0xc3;
    send_buf = 0x3c;
    send_data1(send_buf, idx);
}
读取时间的驱动/**
brief LCD读取时间
param page 无
return 无
*/
voidlcd_read_time(void)
{
    uint8_tsend_buf;
    uint8_tidx = 0;    send_buf = 0xaa;
    send_buf = 0x9b;
    send_buf = 0xcc;
    send_buf = 0x33;
    send_buf = 0xc3;
    send_buf = 0x3c;
    send_data1(send_buf, idx);
}
接收LCD数据的程序voidlcd_pro(void)
{
    staticuint32_ttimer_lcd = 0;
    if (timer6 - timer_lcd<9)
      return;
    timer_lcd = timer6;
    if (lcd_rx.len<5)
      return;
    if (lcd_rx.rx_buff != 0xaa)
    {
      memset((uint8_t*)&lcd_rx.rx_buff, 0, lcd_rx.len);
      lcd_rx.len = 0;
      return;
    }
    else
    {
      switch (lcd_rx.rx_buff)
      {
      case0x79://触摸
            lcd.page = lcd_rx.rx_buff;
            lcd.touch_id = lcd_rx.rx_buff;
            break;
      case0x77://下发数据
            if(lcd_rx.rx_buff == 0x08)
            {
                if(lcd_rx.rx_buff == 0x0A)//年
                {
                  my_rtc.year = lcd_rx.rx_buff;
                }
                elseif(lcd_rx.rx_buff == 0x0C)//月
                {
                  my_rtc.month = lcd_rx.rx_buff;
                }
                elseif(lcd_rx.rx_buff == 0x0E)//日
                {
                  my_rtc.day = lcd_rx.rx_buff;
                }
                elseif(lcd_rx.rx_buff == 0x10)//时
                {
                  my_rtc.hour = lcd_rx.rx_buff;
                }
                elseif(lcd_rx.rx_buff == 0x12)//分
                {
                  my_rtc.min = lcd_rx.rx_buff;
                }
                elseif(lcd_rx.rx_buff == 0x14)//秒
                {
                  my_rtc.sec = lcd_rx.rx_buff;
                }
                lcd_send_time();
            }
            break;
      case0x9B://读取时间
            memcpy((uint8_t*)&my_rtc, (uint8_t*)&lcd_rx.rx_buff, sizeof(MYRTC));
            break;
      default:
            break;
      }
      memset((uint8_t*)&lcd_rx.rx_buff, 0, lcd_rx.len);
      lcd_rx.len = 0;
    }
}
2) PH值采集这里用的传感器是模拟信号,可以直接使用单片机的AD去采集值,转化为电压之后,根据拟合后的公式直接转换为PH值,程序如下voidph_pro(void)
{
staticuint32_ttimer_ph = 0;
uint16_tadc_value = 0;
floatvol = 0.0;
if (timer6 - timer_ph>PH_COLLECT_TIME)
{
    HAL_ADC_Start(&hadc1);                  //启动ADC单次转换
    HAL_ADC_PollForConversion(&hadc1, 50);//等待ADC转换完成
    if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
    {
      adc_value = HAL_ADC_GetValue(&hadc1);   //读取ADC转换数据
      vol = ((double)adc_value/4096)*3.3*2;//转化为实际电压值
      printf("sensor log:adc_value = %d, vol = %.2fV.\n", adc_value, vol);
      ph_buf = (uint16_t)((5.9647*vol+22.255)*10);//转换为PH值
      for (i = 0; i <FILTER_N; i++)
      {
          ph_buf = ph_buf;   // 所有数据左移,低位仍掉
      }
      pv.ph = MedianFilter(ph_buf, FILTER_N); //中值平均滤波
      printf("sensor log:ph %d\r\n", pv.ph);
    }
    lcd_send_pv16(0x080000,pv.ph);//给LCD发送数据
    lcd_send_curve(0x060000,224,pv.ph);//给LCD左推进发送曲线
    timer_ph += PH_COLLECT_TIME;
}
}
3) 水温数据采集使用的是经典的DS18B20,单总线获取温度,程序如下voidds18b20_pro(void)
{
uint16_ti = 0;
staticuint32_ttimer_ds18b20 = 0;
if (timer6 - timer_ds18b20>DS_COLLECT_TIME)
{
    te_buf = DS18B20_Get_Temp();
    for (i = 0; i<FILTER_N; i++)
    {
      te_buf = te_buf;   // 所有数据左移,低位仍掉
    }
    pv.te = MedianFilter(te_buf, FILTER_N); //中值平均滤波
    lcd_send_pv16(0x080002, pv.te);//给LCD发送数据
    lcd_send_curve(0x0600e0,224,pv.te+100);//给LCD左推进发送曲线
    printf("sensor log:te %d\r\n", pv.te);
    timer_ds18b20 += DS_COLLECT_TIME;
}
4) 环境温度数据采集使用的是国产的AHT10,IIC协议获取温湿度,程序如下voidaht_pro(void)
{
uint16_ti = 0;
staticuint32_ttimer_aht = 0;
if (timer6 - timer_aht>AHT_COLLECT_TIME)
{
    AHT10ReadData(&tem_buf, &hum_buf);
    for (i = 0; i<FILTER_N; i++)
    {
      hum_buf = hum_buf;   // 所有数据左移,低位仍掉
      tem_buf = tem_buf;   // 所有数据左移,低位仍掉
    }
    pv.tem = MedianFilter(tem_buf, FILTER_N); //中值平均滤波
    pv.hum = MedianFilter(hum_buf, FILTER_N); //中值平均滤波    printf("sensor log:tem %d\r\n", pv.tem);
    printf("sensor log:hum %d\r\n", pv.hum);
        lcd_send_curve(0x0602a0,224,pv.tem+100);//给LCD左推进发送曲线
    lcd_send_curve(0x0601c0,224,pv.hum);//给LCD左推进发送曲线
   
    lcd_send_pv16(0x080004,pv.hum);//给LCD发送数据
    lcd_send_pv16(0x080006,pv.tem);//给LCD发送数据    timer_aht += AHT_COLLECT_TIME;
}
}
5)    LCD操作流程图4.测试1) 主页2) 水质曲线界面3) 环境温湿度曲线界面5、总结本项目用到的硬件:NUCLEO-G070RB及硬件扩展板、PH温度采集传感器、Topway智能显示模块HMT070ETD-1D;开发工具及版本:TOPWAY SGTools V9.35、STM32CuBeMx V6.4.0 、KEILMDK V5.25、PhotoShop。其中TOPWAY智能显示屏HMT070ETD-1D让工程师摆脱繁琐的UI和触摸屏编程,主机只需要通过简单的串口命令把数据传输到智能显示屏,屏幕把显示、接收用户输入等工作全部接管过来。编程,它具有如下产品特点:
支持宽电压供电工作;
同时支持PC下载和U盘升级两种模式;
支持远程协议通信控制,远程显示工程升级;
支持电容屏支持多功能触摸按键;
支持Lua脚本多功能开发;
使用SGTools工具便捷使得开发过程十分简便。

biubiu108 发表于 2022-8-20 09:33

更多信息,请持续关注Topway官网 www.topwaydisplay.com
页: [1]
查看完整版本: 基于智能液晶显示模块的水质监测设备