数码之家

 找回密码
 立即注册
搜索
查看: 4832|回复: 18

[C51] 基于单片机ADC采样水位控制的净水机废水回收控制程序

[复制链接]
发表于 2019-3-15 13:04:28 | 显示全部楼层 |阅读模式
昨天在创意DIY板块发了一贴:也做了一套净水器废水利用装置:https://www.mydigit.cn/forum.php?mod=viewthread&tid=14685 ,这是带带拉拉弄了很久的制作,不认真做的原因就是因为净水机废水利用很是鸡肋,而最终做成了的原因是因为很闲且手痒难耐,这个系统使用了一片STC15W408AS单片机作为核心控制真的是小题大做,充其量就是一个玩单片机的制作,就单片机等利用率问题在此不作为讨论的话题,单片机的代码的编写属于菜鸟门外的水平,就代码问题欢迎指点、指正。

本系统利用单片机片内ADC编程对储水箱水位进行探测,利用外部中断对水流传感器(水流开关)进行检测,当水流传感器有信号传来时查询储水箱的水位,如果储水箱有水则输出开关量控制继电器启动水泵,否则等待;以下是电路图和C程序,在此声明:本文创意及代码仅供本坛朋友交流使用,不得转帖!不得用于商业用途!使用代码请标明出处!

-------呵呵----学话说话,弄的跟真的似的,其实说与不说-----哈哈:tongue:

电路图:



代码:粘贴复制即可应用
注意:因为水位传感测试时需要获取真实的ADC数据以便确定监控数据,所以需要挂载显示器件,本系统使用了一个595段码+595位码串控的4位LED数码模块,数码管驱动代码就是下列代码中被封闭掉的步分;其他控制功能请详见代码注释。


  1. /*************************************************************/
  2. #include <STC15W.h>
  3. #include <intrins.h>
  4. #define uint unsigned int        
  5. #define uchar unsigned char
  6. /***********I/O口位功能定义*****************************/
  7. //sbit CE=P1^4;  //595(引脚12)锁存控制(用于调试时演示参数)
  8. //sbit CLK=P1^3;  //CLK
  9. //sbit DAT=P1^2;  //DATA
  10. sbit JK=P1^5;
  11. uint dda;
  12. bit  flag;
  13. /************应用变量设置(用于调试时演示参数)*******************************/
  14. //uchar d[4];  //设置显示变量缓存空间
  15. /***共阴极显示段码+黑屏码********************/
  16. //高电平有效;硬件接线为595=>Q0Q1Q2Q3Q4Q5Q6Q7=>abcdefgdp(其中dp未接线)
  17. //uchar SEG7[11]=   
  18. //{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x00};
  19. /************位选择显示编码*****************************/
  20. //uchar Wei[4]={0xf7,0xef,0xdf,0xbf};//由另一片595的Q1Q2Q3控制
  21. /****显示延迟-延时函数**********************************/
  22. void delay_1ms (uint a)
  23. {
  24. uchar i,j;
  25. while( a-- != 0)
  26. {
  27. i = 12;
  28. j = 169;
  29. do
  30. {
  31.   while (--j);
  32. } while (--i);
  33. }
  34. }
  35. /******************************************************************/
  36. void Delay(uint x)//用于ADC转换及其它
  37. {
  38.     uint y;
  39.     while (x--)
  40.     {
  41.         y = 5000;
  42.         while (y--);
  43.     }
  44. }
  45. /*****模拟串行1bit数据输出函数(用于调试时演示参数)**************************/
  46. //仅模拟串行输出数据
  47. /***********
  48. void bit_out(uchar dat)
  49. {
  50. uchar r;
  51. for(r=0;r<8;r++)//设置8位计数器
  52. {
  53. DAT=dat&0x01;//从bit0起逐位输出数据
  54. dat>>=1;
  55. CLK=0;//595时钟脉冲生成
  56. CLK=1;
  57. }
  58. }
  59. **********/
  60. /******初始模数转换寄存器函数**************************************/
  61. void InitADC()
  62. {
  63. P1ASF = 0x03; //设置P1.0,P1.1为AD口
  64. ADC_RES = 0; //清除结果寄存器
  65. ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  66. Delay(2); //ADC上电并延时               
  67. }
  68. /****ADC转换执行函数***********************************************/
  69. uint GetADCResult(uchar ch)
  70. {
  71. uint deta=0;
  72. ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  73. _nop_(); //等待4个NOP
  74. _nop_();
  75. _nop_();
  76. _nop_();
  77. while (!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成
  78. ADC_CONTR &= ~ADC_FLAG; //Close ADC
  79. deta=ADC_RES;
  80. deta=(deta<<2)+ADC_RESL;
  81. return deta; //返回10位ADC结果
  82. }
  83. /*********************************************/
  84. float AD_work(uchar ch)
  85. {
  86. float AD_val; //转换结果传递变量设为浮点数   
  87. uchar m;
  88. for(m=0;m<50;m++)
  89. {AD_val+=GetADCResult(ch);} //转换50次求平均值(提高精度)
  90. AD_val/=50;
  91. return AD_val;  //仅使用采样的数字量进行比对判断,不需要变换成模拟数据
  92. }
  93. /********显示函数(用于调试时演示参数)**********************************/
  94. /********
  95. void Display_convert(uint R)
  96. {
  97. uchar e;
  98. d[0]=R/1000;//拆分待显示数据存入显示数据缓存单元
  99. d[1]=R%1000/100;
  100. d[2]=R%100/10;
  101. d[3]=R%10;
  102. for(e=0;e<4;e++)
  103. {
  104. bit_out(SEG7[d[e]]);//先发送显示数据
  105. bit_out(Wei[e]);//再发送数位控制数据
  106. CE=0;//595锁存脉冲生成
  107. CE=1;
  108. delay_1ms(5);//点亮延迟
  109. }
  110. }
  111. ********/
  112. /******INT0中断函数**************************/
  113. //下降沿+下降沿触发模式,用于监测水流开关的状态
  114. void exint0() interrupt 0 //INT0中断入口
  115. {
  116. delay_1ms(20);  //等待稳定
  117. flag=INT0;   //上升沿出现时INT0=1;下降沿出现时INT0=0;
  118. }
  119. /*********主函数***********************************/
  120. main()
  121. {
  122. //-----------------------------------------------------------
  123. InitADC();//ADC初始化  
  124. //设置P1.0--ADC0通道;测量储水箱水位
  125. //-----------------------------------------------------------
  126. INT0 = 1; //设置外部中断0为最高优先级
  127. IT0 = 0; //设置INT0的中断模式 (1:仅下降沿 0:上升沿和下降沿)
  128. EX0 = 1; //使能INT0中断
  129. EA = 1;
  130. //-----------------------------------------------------------
  131. flag=1; //标志初始化
  132. JK=1;  //初始化继电器驱动输出口
  133. dda=0; //初始化储水箱水位采样变量
  134. //----------------------------------------------------------
  135. while(1)
  136. {
  137. if(flag==0)    //如果水流开关闭合
  138. {
  139. dda= AD_work(0);  //检测储水箱水位
  140. delay_1ms(5);
  141. if(dda>200)    //如果水箱有水  
  142. JK=0;//启动水泵
  143. else
  144. if(dda<190)    //如果水箱没水或水位过低
  145. {
  146. JK=1;     //关闭水泵
  147. EX0=0;    //关闭外部中断0
  148. //控制外部中断是为了解决水箱排水到了最低值时恰逢补水而产生的水泵闪动运行的问题。
  149. delay_1ms(40000);  //因为单片机无其他控制项目所以使用长延时函数
  150. delay_1ms(40000);  
  151. //马桶加满水需要约40S、延时80S可保证水流传感器信号失能确保不会再次启动电机
  152. EX0=1;    //重新开启外部中断0
  153. }
  154. }
  155. else if(flag==1)   //如果水流开关断开
  156. {
  157. JK=1;  //关闭水泵
  158. dda=0; //变量清空
  159. }
  160. }}
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 1家元 +10 收起 理由
数码家园 + 10 謝謝分享

查看全部打赏

发表于 2019-3-15 13:19:09 | 显示全部楼层
这个不错的,就是水位传感器的灵敏度问题怎么处理?
回复 支持 反对

使用道具 举报

发表于 2019-3-15 14:14:04 来自手机浏览器 | 显示全部楼层
厉害了,恭喜老哥完工:victory:
回复 支持 反对

使用道具 举报

发表于 2019-3-15 16:18:44 | 显示全部楼层
厉害了,谢谢分享!

打赏

参与人数 1家元 +12 收起 理由
慕名而来 + 12 多谢鼓励。

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-15 18:17:14 | 显示全部楼层
ccp 发表于 2019-3-15 13:19
这个不错的,就是水位传感器的灵敏度问题怎么处理?

只是测水位的话也没必要测的十分精确,并非用一根电极测不同的水电阻压降,我的方案中只是用到了一个低水位测量,其实多水位也没关系很简单的,如果是塑料水箱,箱底设一个电极连接+Vcc其他需要测试的位置加其他电极,没个电极接一路ADC即可,此后只要顺序的检查各路ADC的采样值就能区分了,水位电极与水面接触与不接触必定有不同的采样值,这个值加一些余量就可以存储起来作为比对依据了,例如我的系统在电极脱离水面时实测的采样值是210左右开始跳变的,所以我选择了大于200或小于190的参考值。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-15 18:20:46 | 显示全部楼层
触景情伤 发表于 2019-3-15 14:14
厉害了,恭喜老哥完工

多谢鼓励,这个东西做了好久总算是交工了,但完成后也有些失落不知道接下来玩啥才有些兴趣。
回复 支持 反对

使用道具 举报

发表于 2019-3-18 10:49:50 | 显示全部楼层
利害,改天我也写一个stm32的净水器控制程序。
回复 支持 反对

使用道具 举报

发表于 2019-3-18 22:55:22 | 显示全部楼层
文氏三通X宝上有链接吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-19 16:54:06 | 显示全部楼层
笔涛 发表于 2019-3-18 22:55
文氏三通X宝上有链接吗?

我是自己做了一个,宝上有的但不知道是否好用,你搜一下“文氏管 射流器”试试看。
回复 支持 反对

使用道具 举报

发表于 2019-3-20 08:06:14 | 显示全部楼层
慕名而来 发表于 2019-3-19 16:54
我是自己做了一个,宝上有的但不知道是否好用,你搜一下“文氏管 射流器”试试看。 ...

谢谢你,看来还得自己做。
回复 支持 反对

使用道具 举报

发表于 2019-3-21 17:36:54 | 显示全部楼层
佩服,可以把这个专利卖给美的。:titter:
回复 支持 反对

使用道具 举报

发表于 2019-12-8 21:57:30 | 显示全部楼层
厉害!太阳能控制器的水位也多是ADC做的多段检测显示&控制:victory:
回复 支持 反对

使用道具 举报

发表于 2019-12-9 20:09:36 | 显示全部楼层
ccp 发表于 2019-3-15 13:19
这个不错的,就是水位传感器的灵敏度问题怎么处理?

传感器长时间泡在水里并且通电,水还干净吗?
现在有专用的水位检测芯片,好用不贵,在水箱外面检测水位。46X是水位检测专用MCU,1T的8051核,电容式水位检测芯片,最多可检测4档水位。
8916B是水位检测专用IC,不需要写程序,可使用UART通讯,也可以使用一对一输出模式。
这两款芯片都可以做隔空水位检测,隔空的意思是PCB可以不用贴的水箱,可以有不大于3mm的缝隙。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2019-12-9 20:11:06 | 显示全部楼层
595953427@qq 发表于 2019-12-9 20:09
传感器长时间泡在水里并且通电,水还干净吗?
现在有专用的水位检测芯片,好用不贵,在水箱外面检测水位 ...

美的的净水器,雀巢的咖啡机都是用的这款芯片。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-10 19:22:15 | 显示全部楼层
595953427@qq 发表于 2019-12-9 20:09
传感器长时间泡在水里并且通电,水还干净吗?
现在有专用的水位检测芯片,好用不贵,在水箱外面检测水位 ...

多谢提供资料,百度一下得知这种单片机真心好用不贵,貌似需要烧录器的,抽空弄一片试试,谢了。
回复 支持 反对

使用道具 举报

发表于 2019-12-10 19:32:37 | 显示全部楼层
慕名而来 发表于 2019-12-10 19:22
多谢提供资料,百度一下得知这种单片机真心好用不贵,貌似需要烧录器的,抽空弄一片试试,谢了。 ...

专用仿真器也不贵,支持JATG在线仿真,在线烧录,离线烧录。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-10 19:56:17 | 显示全部楼层
595953427@qq 发表于 2019-12-10 19:32
专用仿真器也不贵,支持JATG在线仿真,在线烧录,离线烧录。

是的,宝上廉价的烧录器才三十几,真正用到的也无所谓了,只是我的这套系统正如帖子里谈到的,一直在用一直在完善,原本用于测水位的304不锈钢丝使用一段时间后结垢比较多,需要经常擦洗,现在已经将这种测水位的装置取消了,取而代之的是我自制的弹簧式称重开关,与底座的架子做成了一体,当水位降低到一定程度时压迫限位开关使接点闭合给电动阀门通电,电动阀门控制转换供水方式,更新后的系统用运行了半年多了非常稳定算是完工了。
回复 支持 反对

使用道具 举报

发表于 2019-12-13 11:13:15 | 显示全部楼层
慕名而来 发表于 2019-12-10 19:56
是的,宝上廉价的烧录器才三十几,真正用到的也无所谓了,只是我的这套系统正如帖子里谈到的,一直在用一 ...

时间久了触点会不会氧化?弹簧会不会疲劳?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-13 22:04:49 | 显示全部楼层
595953427@qq 发表于 2019-12-13 11:13
时间久了触点会不会氧化?弹簧会不会疲劳?

触点氧化到不是问题,用的是微波炉里的那种门碰开关控制220V市电,即使失效了更换一下也方便,弹簧老化倒是应该考虑的问题,我用了三个等高(20mm高)的弹簧,上下夹板构造弹簧中心有定位、限位销轴,称重行程间隙仅5mm,另外它并非准确称重,而是控制水桶水位在5cm至8cm之间就可以满足需要了,现在设定在8cm,即使弹簧适当疲劳至水位降低到5cm仍然可用或者换新。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-24 12:23 , Processed in 0.140401 second(s), 15 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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