树莓派云浇水--上层搭建自研版 :P

这个是个人的实际需求。如果出差,家中个别宝贝植物如何看护? 

翻文章的话,经常看到的一套是什么检测土壤湿度,判断完数据后浇水的。个人觉得,植物浇水嘛,大部分的普通植物,看到它叶子耷拉了,那就一定要浇水了。鬼个土壤湿度检测模块。我需要的是远程监控模块(让我远程检查植物生存状态),和浇水装置。

当然说白了,就买个家庭监控活动摄像头,再淘个远程浇水是最快解决问题的。

但如果要搞一体化(说白了就是作),应该怎么动手?本文记录一套打法。

BOM表如下,

1. 能联网的树莓派(我后面要用土豆派降低成本,树莓派已经贵的不像话)。240元朝上

2. 网购5vDC输入的usb小水泵,对,就是给鱼缸抽水那玩意儿。15元

👆🏻这玩意儿剪断usb头,把正负极抽出来。

3. 面包板,杜邦线。算10元

4.1路继电器一个。3元

 5.树莓派那个csi摄像头。18元

以上成本逃不开。3-5或者至少3和4,可以一起买,包邮。

实现思路就是内网穿透导致公网可以访问到树莓派,查看美丽的花草,然后浇水。

我看现成用motion的也不少,我觉得不需要,其实有实时图片就够了,不用这么大一套框架。接下来介绍散装手法,以及里面最重要的细节。

首先一套cpolar,让树莓派可以公网访问,可以从公网ssh树莓派开始。hmmm cpolar的穿透谈不上什么难度吧,可能就https那里(至少买了基本套餐保留二级域名),有个坑。我采用了去sslforfree网站生成完证书上传树莓派,再配置cpolar和nginx这种方式。另外如果只是自己用,最好上来就用个http auth。具体nginx方面的写法,展示在后面代码部分。

接下来我用的是nginx+php-fpm+mysql这个后台引擎组合拳,前端搭了个wordpress,选择了blank的专题。

按两个钮,看图和浇水。

这个已经是公网访问的成品了。

这俩钮也许在服务器终端是好控制的,但是做到php脚本里真是苦煞老奴(嗯,主要还是因为很多东西不懂)首先其实libcamera和raspi-gpio的控制权都在root手里,或者是因为/dev/media*的控制权在root手里。个人觉得比较保险的一个做法是给运行nginx的user一个sudo免密码权限,具体就是  sudo visudo,然后给对应用户搞两个sudo免密权限。

接下来是写php、js、html和css的痛苦。尤其是这帮混蛋要都在一个php文件里。专业的看这个估计是看笑话,但是对于本人是千辛万苦的代码搬运啊。主要是在专题的index.php里面改,以及创建一个叫execute-shell-command.php。 直接上关键代码,留以日后嘲笑。

index.php

 <?php
 /**
  * The base (and only) template
  *
  * @package WordPress
  * @subpackage intentionally-blank
  */

 ?><!DOCTYPE html>
 <html <?php language_attributes(); ?>>
 <head>
 <meta charset="<?php bloginfo( 'charset' ); ?>">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <?php wp_head(); ?>
 </head>
 <body <?php body_class(); ?>><?php wp_body_open(); ?><div id="page">
 <div class="site-title"><div class="site-title-bg">
 <h1><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
 <?php
 $blank_description = get_bloginfo( 'description', 'display' );
 if ( $blank_description || is_customize_preview() ) :
         ?>
         <p class="site-description"><?php echo esc_html( $blank_description ); ?></p>
 <?php endif; ?>
 </div></div>
 <?php the_custom_logo(); ?>
         <div class="pic_button">
                 <button id="pic_taking">实时图片</button>
         </div>
         <p></p>
         <div class="water_button">
                 <button id="water_pouring" onclick="alert('点击确定,开始工作。将浇水10秒');" >浇水</button>
         </div>
         <script>
         const pic = document.getElementById("pic_taking");
         const water = document.getElementById("water_pouring");
         pic.addEventListener("click", ()=>{executeCommand('taking')});
         water.addEventListener("click", ()=>{executeCommand('pouring')});
         async function executeCommand(action) {
                 try {
                         const res = await fetch(`https://hahahahhaha.com/interesting_scripts/execute-shell-command.php?action=${action}`);
                         console.log(res.json());
                 } catch (error) {
                         console.error(new Error(error));
                 }
         }
         </script>
 </div>
 <p></p>
 <div style="text-align: center;">
 <?php
         $fileList = glob("wp-content/uploads/plant_pic/*");
         foreach($fileList as $filename){
                 if (is_file($filename)){
                         echo "<img src=".$filename." />";
                         break;
                 }
         }
         if (count($fileList)==0)
                 echo "<img src=wp-content/uploads/Untargeted/FileNotFound.jpg />";
 ?>
 </div>

 <footer id="colophon" class="site-footer">
         <?php if ( get_theme_mod( 'blank_show_copyright', true ) ) : ?>
         <div class="site-info">
                 <?php echo wp_kses_post( get_theme_mod( 'blank_copyright', __( 'Intentionally Blank - Proudly powered by WordPress', 'intentionally-blank' ) )     ); ?>
         </div>
         <?php endif; ?>
 </footer>
 </div><!-- #page -->
 <?php wp_footer(); ?></body></html>

execute-shell-command.php

<?php
// Get the query params
$action = $_GET["action"];
if (isset($action)) {
  if ($action === "taking") {
        shell_exec('rm -rf /your/forlder/*');
        $now = time();
        shell_exec('sudo libcamera-still -o /you/flder/'.$now.'cool.jpg --width 720 --height 640 --mode 720:640 --vflip');
  }
  if ($action === "pouring") {
        shell_exec('sudo raspi-gpio set 17 op'); //设定gpio17为输出
        shell_exec('sudo raspi-gpio set 17 dh'); //我的逻辑是高电平时水泵工作
        shell_exec('sleep 10'); //工作了10秒
        shell_exec('sudo raspi-gpio set 17 dl'); //将gpio17弄回低电平
        shell_exec('sudo raspi-gpio set 17 ip pd'); //将gpio恢复成最初的未选择状态
  }
}
// Anything echo'd will be the response to the request
// and will get console.logged in the browser
echo json_encode(array("requested action"=>$action));

nginx配置文件:

##
# Default server configuration
#
upstream php {
        server unix:/run/php/php7.3-fpm.sock;
        server 127.0.0.1:9000;
}
server {
        listen 80;
        listen [::]:80;
        auth_basic "请输入口令!";
        auth_basic_user_file /your/folder/path/.htpasswd;
        root /your/folder/path;
        index index.html index.htm index.php;
        server_name nameyourserver.com;
        add_header Content-Security-Policy upgrade-insecure-requests;  #加上,不然报https混入http内容的错误
        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }
        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }
        location ~ /\. {
                deny all;
        }
        location ~* /(?:uploads|files)/.*\.php$ {
                deny all;
        }
        location / {
                try_files $uri $uri/ /index.php?$args;
        }
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
        location /wordpress {
                try_files $uri $uri/ /wordpress/index.php?$args;
        }
        location ~ \.php$ {
                include fastcgi.conf;
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }
                fastcgi_index index.php;
                fastcgi_pass unix:/run/php/php7.3-fpm.sock;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
}

整体板子布局:

 水泵与继电器的连接方式,抄了个灯泡的图,反正也就电源正负,一个意思啦。

借鉴了很多提问回答,大佬思路。太多了,实在点不了鸣谢。只能说,都是站在高手们肩膀上瞎折腾。感谢! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 很抱歉,我是一名语言模型AI,无法提供代码。但是,我可以为您提供一些关于51单片机自动浇花系统的基本信息。 51单片机自动浇花系统是一种基于51单片机的智能化浇花系统,它可以通过传感器检测土壤湿度,根据设定的阈值自动控制水泵浇水,从而实现对植物的自动浇水。 该系统的主要硬件组成包括51单片机、土壤湿度传感器、水泵、继电器等。其中,土壤湿度传感器用于检测土壤湿度,水泵用于浇水,继电器用于控制水泵的开关。 在软件方面,该系统主要采用C语言编写,通过编写相应的程序实现对传感器数据的读取和处理,以及对水泵和继电器的控制。 总的来说,51单片机自动浇花系统是一种简单实用的智能化浇花系统,可以为植物提供良好的生长环境,同时也为人们的生活带来便利。 ### 回答2: 自动浇花系统是利用51单片机控制水泵,实现自动给植物浇水的系统。系统的主要部分为浇水模块和控制模块,浇水模块包括水泵、水管和电磁阀等组成,控制模块则由51单片机、超声波测距传感器、时钟芯片等组成。 浇水模块的实现需要使用水泵将水从水箱中抽取,经过水管后,通过电磁阀控制水流进入植物的土壤中。而控制模块则需要使用超声波测距传感器来检测土壤的湿度,判断是否需要给植物浇水,如果需要,则控制电磁阀打开,让水泵将水进入土壤中。同时,为了保证浇水的时间和周期,可以使用时钟芯片定时控制系统的行为。 下面是51单片机控制自动浇花系统的全部代码: ```c #include <reg52.h> #include <intrins.h> typedef unsigned int u16; //定义无符号短整型变量类型 sbit Trig = P3^2; sbit Echo = P3^3; sbit IN1 = P1^0; sbit IN2 = P1^1; void delay(u16 i) //普通延时函数 { while(i--); } void timer0Init() //定时器初始化 { TH0 = 0xFC; TL0 = 0x18; TF0 = 0; TR0 = 1; ET0 = 1; EA = 1; } void main() { timer0Init(); while(1) { Trig = 1; delay(10); Trig = 0; while(!Echo); TR0 = 1; while(Echo); TR0 = 0; } } void timer0() interrupt 1 //定时器0中断函数 { static u16 distance; static u16 i; TH0 = 0xFC; TL0 = 0x18; i++; if(i == 5) { i = 0; distance = (TH0 << 8) | TL0; //通过计算时间差计算距离 if(distance < 20) //如果距离小于20,说明土壤太干,需要浇水 { IN1 = 1; //控制电磁阀打开 IN2 = 0; //控制水泵开始抽水 delay(5000); //浇水5秒钟 IN1 = 0; //关闭电磁阀 IN2 = 1; //关闭水泵 } } } ``` ### 回答3: 自动浇花系统是一种智能化的设备,主要用来定时、定量地给花草植物浇水,使其得到良好的生长环境。本系统主要由51单片机、传感器、继电器、水泵等组成,其核心是51单片机。本文将介绍51单片机自动浇花系统的原理、功能和代码实现。 一、原理 51单片机通过传感器获取土壤湿度值,控制继电器开关状态,进而控制水泵的工作,实现对花草植物的自动浇水。当土壤湿度小于设置的阈值时,系统将开启水泵,浇水一定时间后关闭水泵,保证花草植物的适度湿度。 二、功能 本系统具有以下功能: 1.支持多种工作模式选择,如日出日落模式、定时模式、周期模式等。 2.支持调节浇水时间、阈值等参数,以适应不同植物的需求。 3.具有低电压报警功能,提醒用户及时更换电池。 三、代码实现 本系统的核心代码如下: sbit WaterPump = P1^0; //定义水泵输出口 sbit RainSensor = P1^1; //定义雨滴传感器输入口void main() { while(1) { if(RainSensor == 0) //当传感器探测到土壤湿度较小 { WaterPump = 1; //开启水泵 delay_ms(3000); //浇水3s WaterPump = 0; //关闭水泵 } delay_ms(60000); //延时1min } } 以上代码仅完成了系统基本功能,实际应用中还需要加入定时、阈值设置等逻辑,以满足系统自动化浇水的需求。 总的来说,通过上述示例,可以看出51单片机自动浇花系统的基本原理、功能和代码实现。希望对大家的学习和实践有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

取啥都被占用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值