磁动力电子网-雕刻机DIY论坛,单片机论坛,CNCDIY,DIYCNC

 找回密码
 加入磁动力

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 583|回复: 2

[应用实例] 野路子Arduino第二弹:定时浇花~

[复制链接]
发表于 2018-8-13 16:07:44 | 显示全部楼层 |阅读模式
首先感谢【明浩老大】、【刘兴宇老师】、以及【磁动力数控群】微信群里的各位大佬,对俺这个小白不抛弃不放弃的持续及时抢救。

代码一半是【明浩老大】提供的定时器范例,一半是在【刘兴宇老师】指导下学习的[中断函数应用]和[状态机]等众多概念科普与教学。
俺学么着拼凑了一番,好歹凑合出个貌似能用的程序啦~ 哈哈~先发上来开心一下,代码不科学的地方还望诸位大佬帮忙指正一下~

测试中~

测试中~
IMG_20180813_160544.jpg

材料清单:
Arduino-Uno 一片
土壤湿度传感器 一套
Dc3v小气泵 一个
光耦继电器模块 一个

试验目标:
uno 每8小时读取一次 土壤湿度传感器 判断需要浇水
就打开继电器模块接通气泵电源 气泵往封闭的可乐瓶里打气
用气压将水从瓶内另一根管子里挤出 实现浇水动作
每浇水3秒就停止 然后延时6秒等待水渗入土壤
6秒后再次检测土壤湿度 判断是否需要继续浇水 然后再重复 浇水、等待、检测...
直到湿度达标 进入间隔8小时的定时检测状态

浇水时间、等待渗透时间、定时检测间隔时间 都设为常量 在程序开头部位可以酌情修改。
还未正式装机使用,电源啦水箱啦什么的都还没准备好,等全折腾好了再来补图~
程序还有哪些不完美的地方,请大伙帮忙指出,帮助俺继续学习~非常感谢~

  1. #include <MsTimer2.h>

  2. // AD转换的引脚号
  3. #define ADC0  A0

  4. // 水泵开关的引脚号
  5. int LED13 = 13;

  6. // 状态变量 [byte=0-255] [unsigned=0-65,535] [unsigned long=0-4,294,967,295]
  7. volatile byte ST_RUN = 2; // 运行状态: [0 待机定时检测湿度] [1 运行浇水中] [2 暂停等待水在土壤中缓慢渗透 并 再次检测是否需要补水]
  8. //开机直接就进入暂停等待状态 【刚加电就 延时6秒检测一下土壤湿度 决定要不要浇水 然后再进入待机定时检测】
  9. volatile byte LED13_SW = 0; // 水泵状态: [0 停止] [1 运行中]
  10. const unsigned int LED13_Time = 30; // 水泵浇水运行时长 【3秒(30)】
  11. const unsigned int LED13_Delay = 60; // 暂停等待水在土壤中缓慢渗透时长 【6秒(60)】
  12. volatile unsigned int LED13_temp = 0; //循环计时 计划作为【共享】使用 [水泵浇水]和[暂停等待]都用这个计时

  13. const unsigned long ADC0_Delay = 100;//土壤湿度检测 间隔时间设定 【8小时(288000)】
  14. volatile unsigned long ADC0Delay = 0;//土壤湿度检测 间隔计时
  15. const unsigned int ADC0_val = 900; // 土壤湿度临界值设定 模拟量数值范围0-1023 数大干燥 数小湿润
  16. volatile unsigned int ADC0val = 0; // 土壤湿度实时测量值


  17. // 函数名 TM_IntFun
  18. // 功能   定时中断用函数
  19. // 参数   无
  20. // 返回值 无
  21. void TM_IntFun(void)
  22. {
  23. //--------------------------------------------
  24.   if (ST_RUN == 0) //如果是运行在 待机状态 就加一次计数器湿度检测间隔时间 并结束返回 【不再进行下面的条件判断???】
  25.   {
  26.     ADC0Delay++;
  27.     return;
  28.   }
  29. //---------------------------------------------  
  30.   if ((ST_RUN == 1) && (LED13_SW == 1)) //如果是在 运行状态 并且 水泵也进入运行状态
  31.     {
  32.       LED13_temp++;
  33.     }
  34. //---------------------------------------------
  35.   if  (ST_RUN == 2) //如果是在 暂停等待水在土壤中缓慢渗透状态
  36.     {
  37.       LED13_temp++;
  38.     }
  39. //--------------------------------------------
  40. /*
  41. //调试 ST_RUN [1] 和 [2] 模式
  42. Serial.println("TM_IntFun ok");
  43. Serial.print("Run:");
  44. Serial.println(ST_RUN);
  45. Serial.print("ADC0Delay:");
  46. Serial.println(ADC0Delay);
  47. Serial.print("LED13_SW:");
  48. Serial.println(LED13_SW);
  49. Serial.print("LED13:");
  50. Serial.println(LED13_temp);
  51. */
  52. }

  53. // 函数名 LED_Fun
  54. // 功能   LED功能 水泵开关控制 光耦继电器
  55. // 参数   无
  56. // 返回值 无
  57. void LED_Fun(void)
  58. {
  59.   switch(ST_RUN) // 根据运行的状态 选择开关水泵
  60.     {
  61.       case 0: //如果是待机状态 确保关闭水泵 并将水泵模式转为关闭状态
  62.           LED13_SW = 0;
  63.           digitalWrite(LED13, LOW);
  64.       break;
  65.       
  66.       case 1:
  67.         if (LED13_SW == 0) //运行状态 0关泵 1开泵
  68.           {
  69.             digitalWrite(LED13, LOW);
  70.           }
  71.         else
  72.           {
  73.             digitalWrite(LED13, HIGH);
  74.           }
  75.       break;
  76.       
  77.       case 2://运行在暂停状态时 延时6秒等待渗水后再检测土壤湿度 这个状态时肯定不会开水泵的!
  78.         if (LED13_SW == 0) //暂停状态 0关泵 1开泵
  79.           {
  80.             digitalWrite(LED13, LOW);
  81.           }
  82.         else
  83.           {
  84.             digitalWrite(LED13, LOW);
  85.           }
  86.       break;
  87.       
  88. /*                       
  89.       case 255: //开机时 清除变量 备用复位使用
  90.             ADC0val = 0; //清除检测测量值
  91.             ADC0Delay = 0; //清除检测间隔时间计数器
  92.             LED13_SW = 0; //切换水泵模式 关泵
  93.             LED13_temp = 0; //清空水泵计时器
  94.           ST_RUN = 2;//切换到待机模式
  95.       break;
  96. */
  97.      // default:
  98.     }
  99.    
  100. //调试    Serial.println("LED_Fun ok");
  101. }


  102. void setup()
  103. {
  104.   // 设置引脚模式
  105.   pinMode(ADC0, INPUT);
  106.   pinMode(LED13, OUTPUT);
  107.   digitalWrite(LED13, LOW);
  108.    
  109.   // 设置串行口波特率
  110.   Serial.begin(9600);

  111.   // 设置并启动定时器中断
  112.   MsTimer2::set(100, TM_IntFun);
  113.   MsTimer2::start();

  114. }

  115. void loop()
  116. {
  117.   
  118.    if (ST_RUN == 0)  // 如果是待机状态
  119.     {
  120.       if (ADC0Delay >= ADC0_Delay) //如果检测间隔计时器数值 大于等于 设定的检测间隔时间数值
  121.       {
  122.         ADC0val = analogRead(ADC0);  //就读一次A0口的土壤湿度检测传感器 存入实时检测值

  123. //调试 ST_RUN [0]模式
  124. //调试        Serial.print("Run0adc:");
  125. //调试        Serial.println (ADC0val);
  126.         
  127.         if (ADC0val >= ADC0_val) //如果实时检测值 大于等于 临界设定值
  128.         {
  129.          ST_RUN = 1;//就改变状态到运行状态
  130.          ADC0Delay = 0; //并清除间隔时间计数器
  131.         }
  132.         else //如果实时检测值 没有大于等于 临界设定值
  133.         {
  134.           ADC0Delay = 0; //则清除间隔时间计数器 重新计时
  135.         }
  136.       }
  137.     }

  138.         
  139.   if (ST_RUN == 1) // 如果是运行状态
  140.     {
  141.      if (LED13_temp >= LED13_Time) //如果计时器 大于等于 设定的浇水时间 认为浇水完成
  142.      {
  143.       LED13_SW = 0; //则切换水泵模式实现关泵
  144.       LED13_temp = 0; //清空计时器
  145.       ST_RUN = 2; //并切换到暂停等待渗透补水
  146.      }
  147.      else //时间没到 认为还要继续浇水
  148.      {
  149.       LED13_SW = 1;
  150.      }
  151.     }

  152.   if (ST_RUN == 2) // 如果是暂停状态
  153.     {
  154.       if (LED13_temp >= LED13_Delay) //如果计时器 大于等于 设定的等待渗透时间
  155.        {
  156.         ADC0val = analogRead(ADC0);  //就读一次A0口的土壤湿度检测传感器 存入实时检测值

  157. //调试        Serial.print("Run2adc:");
  158. //调试        Serial.println (ADC0val);

  159.            if (ADC0val >= ADC0_val) //如果实时检测值 大于等于 临界设定值 认为缺水 【还需补水】
  160.             {
  161.               ADC0Delay = 0; //并清除间隔时间计数器
  162.               LED13_temp = 0; //清空计时器
  163.              ST_RUN = 1;//就改变状态到运行状态
  164.             }
  165.            else //如果实时检测值 没有大于等于 临界设定值 认为不缺水 【浇花完毕】
  166.             {
  167.              ADC0Delay = 0; //则清除间隔时间计数器 重新计时
  168.              LED13_SW = 0; //则切换水泵模式实现关泵
  169.              LED13_temp = 0; //清空计时器
  170.             ST_RUN = 0; //并切换到 待机状态 重新等待下个计时周期唤醒
  171.             }
  172.        }
  173.     }
  174.    
  175. LED_Fun(); // 处理水泵开关状态

  176. //调试  Serial.println("Loop ok");
  177. }
复制代码
发论坛_自动浇花.rar (1.47 MB, 下载次数: 20)
回复

使用道具 举报

 楼主| 发表于 2018-8-13 16:12:08 | 显示全部楼层
还有点小问题:开机时水泵自己哆嗦3下,俺想了半天也没想通怎么回事。。。。。。
回复 支持 反对

使用道具 举报

发表于 2018-8-14 07:49:46 | 显示全部楼层
应该是arduino启动代码的问题吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入磁动力

本版积分规则

QQ|小黑屋|手机版|Archiver|www.cdle.net 磁动力电子网 2001-2017 ( 粤ICP备10098153号

粤公网安备 44040402000001号

GMT+8, 2018-11-20 00:19

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.