亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Domotic 温室

组件和用品

Arduino MKR1000
× 1
Arduino UNO
× 1
DHT22 温度传感器
× 1
Arduino Wifi Shield 101
× 1
Android 设备
× 1
Arduino Infineon 的 BTN8982 直流电机控制屏蔽
× 1

应用和在线服务

Arduino IDE
Eclipse

关于这个项目

概览

温室环境条件不断变化,因此我们需要有效的监测。

使用自动系统有很多好处,例如减少工作量,或者最重要的是,用户可以在家里通过 PC 或智能手机查看自己的投资。

另一个重要的优点是可以将数据存储到数据库中。这可以决定赚钱还是亏钱。

此外,由于实时系统控制,我们可以立即干预,防止种植问题。

温室中的自动监控系统由读取环境数据的传感器和执行器组成,称为“奴隶”。它们通过无线与称为“主”的中央设备进行通信。后者将可能的更改发送给从站(例如阈值的更改),并将数据通过 WiFi 发送到网络服务器。

1. 它是如何运作的?

我们可以将这个项目分成三个不同的部分:

  • 大师
  • 奴隶
  • 网络服务器

我们已经将 Arduino/Genuino MKR1000 用于主设备,将 Arduino/Genuino Uno 用于从设备。

Master通过WiFi(集成WINC1500)与Web Server通信,Slave通过DHT22传感器获取温度和湿度,然后通过WiFi(WiFi shield WINC1500)将这些数据发送给Master。

2.大师

Master 处于“接入点模式”,等待 Slave 连接接收精心设计并发送到 Web Server 的温度和湿度。

Master 检查是否有可用数据,在这种情况下,它会创建一个由新阈值和 CRC 形成的 UDP 数据包。事实上,它会计算 Slave 将使用的 CRC 来验证收到的设置。

Master退出“接入点模式”后,连接到WiFi,将数据发送到WebServer,在那里它们将被放入图形中。

3. 奴隶

Slave 通过 DHT22 传感器获取温度和湿度,并在 5 分钟后将数据发送给 Master。它还创建一个 UDP 数据包,它连接到 Master,然后发送数据。

稍后它会等待是否有可用数据,例如新阈值。在这种情况下,Slave 接收新设置并使用 Dallas-Maxim 公式计算 CRC。

随后将计算出的 CRC 与从主机接收到的 CRC 进行比较。如果两个 CRC 相同,则 Slave 将新设置保存在 EEPROM 中。

4. 网络服务器

Web Server 保存所有以后可以存储在历史记录中的数据。

为了做到这一点,我们使用了一个 PHP 脚本,它连接到数据库并以两种不同的方式显示数据

  • 在图表中,使用另一个 PHP 脚本
  • 在 Android 应用中,使用另一个 PHP 脚本以 JSON 格式

5. 应用程序

该应用程序允许我们将数据查阅到数据库中。

在第一个屏幕中,我们可以选择要显示的时间范围,并通过“GRAPHIC”按钮联系网络服务并获取数据。

该应用程序将数据显示为图形。


代码

  • 创建图形
  • 脚本网站连接
  • 创建表
  • 温室Domotic大师
  • 温室 Domotic Slave
  • 获取数据
创建图形PHP
我们用它创建了一个图形
SetScale("textlin");$theme_class=new UniversalTheme;$graph->SetTheme($theme_class);$graph->img->SetAntiAliasing( false);$graph->title->Set('Title');$graph->SetBox(false);$graph->img->SetAntiAliasing();$graph->yaxis->HideZeroLabel();$graph ->yaxis->HideLine(false);$graph->yaxis->HideTicks(false,false);$graph->xgrid->Show();$graph->xgrid->SetLineStyle("solid");$图形->xaxis->SetTickLabels($time_axis);$graph->xgrid->SetColor('#E3E3E3');$graph->xaxis->SetLabelAngle(90);$graph->legend->SetPos(0.5, 0.08,'center','top');// 创建第一行$p1 =new LinePlot($parameter1);$graph->Add($p1);$p1->SetColor("#6495ED");$ p1->SetLegend('your_parameter1');$graph->yscale->SetGrace(0);// 创建第二行$p2 =new LinePlot($parameter2);$graph->Add($p2);$p2 ->SetColor("#B22222");$p2->SetLegend('your_parameter2');$graph->yscale->SetGrace(0);$graph->legend->SetFrameWeight(1);// 输出行$图->描边();?>
脚本网站连接PHP
我们已经使用它将数据保存到 DB
";echo "parameter1 "。 $_GET['参数 1']。 "
";echo "parameter2 "。 $_GET['parameter2']。 "
";// 创建连接$conn =mysqli_connect($servername, $username, $password, $dbname);// 检查连接if (!$conn) { die("连接失败:" .mysqli_connect_error() );}$sql ="INSERT INTO 温室 (name, parameter1, parameter2)VALUES ('".$name."', '".$parameter1."', '".$parameter2."')";if ( mysqli_query($conn, $sql)) { echo "新记录创建成功";} else { echo "错误:"。 $sql 。 “
”。 mysqli_error($conn);}mysqli_close($conn);?>
创建表SQL
我们已经使用这个脚本来创建表
CREATE TABLE IF NOT EXISTS `greenhouse` ( `id` int(11) NOT NULL, `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `temp` float NOT NULL, `umid` float NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;
温室Domotic MasterC/C++
这是大师的代码
/*自动化温室项目*//*Autors:Antonio La Mura, Umberto Festa*//*Date:03/03/2016*//*我们的想法是让购买水果的用户和温室种植的蔬菜,准确了解产品的所有种植步骤,例如使用化肥和其他类似产品。销售的产品上会贴上二维码,特定的智能手机应用程序可以读取该二维码。它提供有关产品生长的环境条件和使用的化学产品的信息。温室中的自动监控系统由读取环境数据的传感器和称为 Slaves 的执行器组成。它们通过无线与称为 Master 的中央设备进行通信。后者通过 WiFi 向从站发送可能的更改(如阈值的更改)和数据也发送到网络服务器。当产品准备出售时,向网络服务请求生成二维码,并将其放在包装上。系统的最后一部分是移动应用程序,负责扫描二维码并将相关信息显示给用户。*//*Master*//*DEVO AGGIUNGERE SOLO LA PARTE CHE MI SERVE PER RICEVERE LE NUOVE SOGLIE CHE VENNGONO INVIATE DALL'APP*//*使用的库*/#include #include #include #include #include /*连接变量*/char ssid[] ="SSID"; /*您的网络SSID(名称)*/char pass[] ="pass"; /*您的网络密码(用于WPA,或用作WEP的密钥)*/int keyIndex =0; /* 您的网络密钥索引号(仅 WEP 需要)*/char ssid_ap[] ="Arduino"; /*创建的AP名称*/char pass_ap[] =""; /*(尚不支持)*/int status =WL_IDLE_STATUS;unsigned int localPort =2390; /*本地监听端口*/char server[] ="www.cormaz.altervista.org"; /*谷歌的名称地址(使用DNS)*/WiFiServer server_ap(80);WiFiClient client_ap;WiFiUDP Udp;RTCZero rtc;WiFiClient client;char packetBuffer[255]; /* 保存传入数据包的缓冲区*/char ReplyBuffer[255]; /*发回的字符串*//*新阈值的变量*/float humax =0;float humin =0;float tumax =0;float tumin =0;/*像接入点一样工作(标志=假),连接to WebServer (flag =true)*/boolean flag =false;boolean Threeshold_available =false;void setup() { /*初始化串口并等待端口打开:*/ Serial.begin(9600); while (!Serial) {; /*等待串口连接。仅适用于本机 USB 端口*/ } Serial.println();}void loop() { int packetSize;双温;双嗡嗡声;内部标识;字节CRC;字符串 strURL; //检查是否有屏蔽:/******************************************* ***********************************************/ 如果 ( WiFi.status() ==WL_NO_SHIELD) { Serial.println("WiFi 屏蔽不存在"); /*不要继续:*/ while (true); } /**************************************************** **************************************/ //尝试连接WiFi网络:/* ****************************************************** ************************************/ while (status !=WL_CONNECTED) { Serial.print("Creating网络名称:"); Serial.println(ssid_ap); /*连接到WPA/WPA2网络。如果使用开放或 WEP 网络,请更改此行:*/ status =WiFi.beginAP(ssid_ap); /*等待10秒连接:*/ delay(10000); server_ap.begin(); } Serial.println("连接到wifi"); /***************************************************** ************************************/ //开始UDP通信/****** ****************************************************** ******************************/ udp.begin(localPort);打印无线状态(); client_ap =server_ap.available(); if (client_ap) { /*If you get a client*/ /*I'm waitinf for some information*/ Serial.println("new client"); /*从串口打印一条消息*/ /*如果有数据可用,读取一个包*/ packetSize =Udp.parsePacket(); if (packetSize) { Serial.print("收到大小的数据包"); Serial.println(packetSize); Serial.print("来自"); IPAddress remoteIp =Udp.remoteIP(); Serial.print(remoteIp); Serial.print(", 端口 "); Serial.println(Udp.remotePort()); /*将数据包读入packetBuffer*/ int len =Udp.read(packetBuffer, 255); if (len> 0) packetBuffer[len] =0; Serial.println("内容:"); Serial.println(packetBuffer); char* command =strtok((char *)packetBuffer, ";");整数计数 =0; while (command !=0) { /*划分信息*/ switch (count) { case 0:id =atoi(command);休息;情况 1:temp =atof(command) / 10;休息;情况 2:hum =atof(command) / 10;休息; } command =strtok(0, ";");计数++; } Serial.print("收到的包裹"); Serial.print(id); Serial.print(" T:"); Serial.print(temp, 1); Serial.print(" H:"); Serial.println(hum, 1); /***************************************************** ****************************************/延迟(20); /*计算CRC-8,因此创建字节数组*/ /*************************************** *************************************************/字节 bhmax =(字节)humax;字节 bhmin =(byte)humin;字节 btmax =(字节)tumax;字节 btmin =(byte)tumin;字节 crc32_str[4] ={ bhmax, bhmin, btmax, btmin }; CRC =CRC8(crc32_str); Serial.println("CRC:"); Serial.println(crc); /***************************************************** ********************************/ if (threeshold_available ==true) { snprintf(ReplyBuffer, sizeof(ReplyBuffer), " %d;%d;%d;%d;%d;%d", id, (int)humax, (int)humin, (int)tumax, (int)tumin, (int)crc); /*发送一个回复,到发送我们收到的数据包的IP地址和端口*/ Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); udp.write(ReplyBuffer); udp.endPacket(); } } /*打印出串口监视器*/ /*关闭连接:*/ client_ap.stop(); Serial.println("客户端断开连接");标志 =真; }/*精细AP*/ /******************************************** **************************************/ /*连接服务器并发送数据到DataBase */ /**************************************************** *********************************/ if (flag ==true) { /*尝试连接到Wifi网络:*/ while (status !=WL_CONNECTED) { Serial.print("Attempting to connect to SSID:"); Serial.println(ssid); /*连接到WPA/WPA2网络。如果使用开放或 WEP 网络,请更改此行:*/ status =WiFi.begin(ssid, pass); /*等待10秒连接:*/ delay(10000); } Serial.println("连接到wifi");打印无线状态(); strURL ="GET /YourAddress.php?id="; strURL +=id; strURL +="¶meter1="; strURL +=温度; strURL +="¶meter2="; strURL +=嗡嗡声; strURL +=" HTTP/1.1"; Serial.println("\n开始连接服务器..."); // 如果获得连接,则通过串行报告: if (client.connect(server, 80)) { Serial.println("connected to server"); // 发出一个 HTTP 请求:client.println(strURL); client.println("主机:www.cormaz.altervista.org"); client.println("连接:关闭");客户端打印();客户端停止(); Serial.println("好的!"); } /*如果服务器断开连接,停止客户端:*/ if (!client.connected()) { Serial.println(); Serial.println("与服务器断开连接。");客户端停止(); /*永远什么都不做:*/ while (true); } 标志 =假; } /**************************************************** ********************************/}/*计算算法CRC-8——基于Dallas/Maxim公式*/ byte CRC8(const byte * data) { byte crc =0x00; while (*data) { 字节提取 =*data++; for (byte tempI =8; tempI; tempI--) { byte sum =(crc ^ extract) &0x01; CRC>>=1;如果(总和){ crc ^=0x8C; } 提取>>=1; } } return crc;}void printWifiStatus() { /*打印你连接的网络的SSID:*/ Serial.print("SSID:"); Serial.println(WiFi.SSID()); /*打印你的WiFi屏蔽的IP地址:*/ IPAddress ip =WiFi.localIP(); Serial.print("IP 地址:"); Serial.println(ip); /*打印接收到的信号强度:*/ long rssi =WiFi.RSSI(); Serial.print("信号强度(RSSI):");串行打印(RSSI); Serial.println("dBm");}
温室Domotic SlaveC/C++
这是奴隶的代码
/*自动化温室项目*//*Autors:Antonio La Mura, Umberto Festa*//*Date:21/03/2016*//*我们的想法是让购买水果的用户和温室种植的蔬菜,准确了解产品的所有种植步骤,例如使用化肥和其他类似产品。销售的产品上会贴上二维码,特定的智能手机应用程序可以读取该二维码。它提供有关产品生长的环境条件和使用的化学产品的信息。温室中的自动监控系统由读取环境数据的传感器和称为 Slaves 的执行器组成。它们通过无线与称为 Master 的中央设备进行通信。后者通过 WiFi 向从站发送可能的更改(如阈值的更改)和数据也发送到网络服务器。当产品准备出售时,向网络服务请求生成二维码,并将其放在包装上。系统的最后一部分是移动应用程序,负责扫描二维码并将相关信息显示给用户。*//*Slave*//*使用的库*/#include #include #include #include #include //定义所有PIN#define HUMIDIFIER A4#define HEATER A5#define DHT22_PIN 4//定义电机#define IS_1 0 #define IS_2 1#define IN_1 3#define IN_2 11#define INH_1 12#define INH_2 13#define TCONST 100 //步间延迟时间//变量重置millis()extern unsigned long timer0_millis;int status =WL_IDLE_STATUS;char ssid [] ="阿杜诺"; // 您的网络 SSID (name)char pass[] =""; // 您的网络密码(用于 WPA,或用作 WEP 的密钥)int keyIndex =0; // 您的网络密钥索引号(仅 WEP 需要)unsigned int localPort =2390; // 本地监听端口 onchar packetBuffer[255]; //缓冲区保存传入的数据包WiFiUDP Udp;//Define DHT22DHT22 myDHT22(DHT22_PIN);//发送变量float hmin =0;float hmax =0;float tmin =0;float tmax =0;int duty_motor =0;float湿度; float temperature;//变量每10秒发送一次unsigned long interval =600000;void setup() { Serial.begin(9600); while (!Serial) {; // 等待串口连接。仅原生 USB 端口需要 } //初始化 PIN (INPUT - OUTPUT) pinMode(HEATER, OUTPUT);数字写入(加热器,低); pinMode(加湿器,输出);数字写入(加湿器,低); //设置风扇pinMode(IN_1, OUTPUT); pinMode(IN_2,输出); pinMode(INH_1,输出); pinMode(INH_2,输出); //重置reset_ports();数字写入(INH_1,1);数字写入(INH_2,1); Serial.println("开始……"); delay(2000);}void loop() { // 如果有数据可用,读取一个数据包 int packetSize =Udp.parsePacket();无符号长时间 =毫秒(); unsigned long currentMillis =millis(); DHT22_ERROR_t 错误代码; int i =0;字符名称[] ="clie1";湿度 =myDHT22.getHumidity() * 10;温度 =myDHT22.getTemperatureC() * 10;字符发送[32]; errorCode =myDHT22.readData();字节CRC; int crc_ric; //检查传感器湿度和温度DHT22错误/**************************************** ****************************************/ switch (errorCode) { case DHT_ERROR_NONE:char缓冲区[128]; sprintf(buf, "整数读数:温度 %hi.%01hi C, 湿度 %i.%01i %% RH", myDHT22.getTemperatureCInt() / 10, abs(myDHT22.getTemperatureCInt() % 10), myDHT22. getHumidityInt() / 10, myDHT22.getHumidityInt() % 10);休息; case DHT_ERROR_CHECKSUM:中断; case DHT_BUS_HUNG:中断; case DHT_ERROR_NOT_PRESENT:中断;案例 DHT_ERROR_ACK_TOO_LONG:中断; case DHT_ERROR_SYNC_TIMEOUT:中断; case DHT_ERROR_DATA_TIMEOUT:中断; case DHT_ERROR_TOOQUICK:中断; } /**************************************************** ********************************/ //打印值,当它改变时/******** ****************************************************** ************************/ if (湿度 !=myDHT22.getHumidity() * 10 || 温度 !=myDHT22.getTemperatureC() * 10) { Serial.print("T:"); Serial.print(myDHT22.getTemperatureC(), 1); Serial.print("C"); Serial.print(" H:"); Serial.print(myDHT22.getHumidity(), 1); Serial.println("%"); } /**************************************************** ********************************/ //每10分钟发送一次参数/******** ****************************************************** **********************/ if (millis()> interval) { //连接AP /************ ****************************************************** ******************/ // 检查屏蔽是否存在: if (WiFi.status() ==WL_NO_SHIELD) { Serial.println("WiFi shield not present "); // 不要继续:while (true); } // 尝试连接到 Wifi 网络:while ( status !=WL_CONNECTED) { Serial.print("Attempting to connect to SSID:"); Serial.println(ssid); // 连接到 WPA/WPA2 网络。如果使用开放或 WEP 网络,请更改此行: status =WiFi.begin(ssid); // 等待 10 秒连接:delay(10000); } Serial.println("连接到wifi"); /***************************************************** ********************************/ Serial.println("\n开始连接服务器..."); // 如果获得连接,则通过串行报告: Udp.begin(localPort); snprintf(toSend, sizeof(toSend), "%s;%d;%d", name, (int)湿度, (int)温度); // 发送回复,发送给我们收到的数据包的 IP 地址和端口 Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); udp.write(toSend); udp.endPacket(); Serial.println("发送完毕");重置米利斯(); while (millis() <10000) { packetSize =Udp.parsePacket(); if (packetSize) { /*将数据包读入packetBuffer*/ int len =Udp.read(packetBuffer, 255); if (len> 0) packetBuffer[len] =0; Serial.println("内容:"); Serial.println(packetBuffer); char* command =strtok((char *)packetBuffer, ";");整数计数 =0; while (command !=0) { /*分割信息*/ switch (count) { case 0:snprintf(name, sizeof(name), "%s", command);休息;情况 1:hmax =atof(command) / 10; //atof(char* ) mi 转换 un tipo char* in double break;情况 2:hmin =atof(command) / 10;休息;情况 3:tmax =atof(command) / 10;休息;情况 4:tmin =atof(command) / 10;休息;案例 5:crc_ric =atoi(command);休息; } command =strtok(0, ";");计数++; Serial.print("答案:"); Serial.print(name); Serial.print(";"); Serial.print(hmax, 1); Serial.print(";"); Serial.print(hmin, 1); Serial.print(";"); Serial.print(tmax, 1); Serial.print(";"); Serial.println(tmin, 1); Serial.print("收到CRC:"); Serial.println(crc_ric); //计算CRC-8,得到字节数组/************************************ ************************************************/ 字节 bhmax =(字节)hmax;字节 bhmin =(byte)hmin;字节 btmax =(byte)tmax;字节 btmin =(byte)tmin;字节 crc32_str[4] ={ bhmax, bhmin, btmax, btmin }; CRC =CRC8(crc32_str); Serial.println("CRC:"); Serial.println(crc); /***************************************************** ********************************/ if (crc_ric ==(int)crc) { //保存在 EEPROM 中 EEPROM_writeDouble (0, tmax); EEPROM_writeDouble(4, tmin); EEPROM_writeInt(8, hmax); EEPROM_writeInt(10, hmin); } } } 延迟(10); } /**************************************************** ************************************/ WiFi.disconnect(); //根据传感器的值管理加湿器、加热器和风扇 /*************************************** ****************************************************** */ //加热器 if (myDHT22.getTemperatureC()>=tmax) { digitalWrite(HEATER, HIGH); } if (myDHT22.getTemperatureC() <=tmin + 1) { digitalWrite(HEATER, LOW); } //加湿器 if ((int)myDHT22.getHumidity()>=hmax) { digitalWrite(HUMIDIFIER, HIGH); } if ((int)myDHT22.getHumidity() <=hmin + 1) { digitalWrite(HUMIDIFIER, LOW); } //风扇,无刷电机 if (myDHT22.getTemperatureC()>=tmax + 4) { //电机根据温度旋转,占空比 -> 0 per t =tmax+4 and duty -> 100 per t> tmax+10 //Rotazione del motore al variare della tempatura, duty -> 0 per t =tmax+4 e duty -> 100 per t> tmax+10 duty_motor =map(i , tmax + 4, tmax + 10, 0, 100);如果(tmax> tmax + 10){duty_motor =100;模拟写入(IN_2,duty_motor);延迟(TCONST); } if (myDHT22.getTemperatureC() <=(tmax + tmin) / 2) { reset_ports(); //电机根据温度旋转,duty -> 0 per t =tmax+4 and duty -> 255 per t> tmax+10 duty_motor =0;模拟写入(IN_2,duty_motor);延迟(TCONST); } /**************************************************** **************************************/ delay(1000);}//存双入EEPROM void EEPROM_writeDouble(int ee, double value) { byte* p =(byte*)(void*)&value; for (int i =0; i >=1;如果(总和){ crc ^=0x8C; } 提取>>=1; } } return crc;}//用于重置millis()void resetMillis() { cli(); timer0_millis =0; sei();}
getdatiPHP
我们已经用它来连接我们的应用程序和数据库
";//选择要连接的数据库使用 $selected =mysql_select_db("serra",$dbhandle) 或 die("Could not select examples"); $datada =$_GET["datada"];$dataa =$_GET["dataa"];//执行SQL查询并返回记录$result =mysql_query("SELECT hum,temp,date FROM record WHERE date>=' ".$datada."' and date <='".$dataa."'");$records=array();//从数据库中获取数据 while ($row =mysql_fetch_array($result)) { $ tmp =array("hum"=>$row{'hum'}, "temp"=>$row{'temp'}, "date"=>$row{'date'}); array_push($records,$tmp); //echo "HUM:".$row{'hum'}." TEMP:".$row{'temp'}."Date:". //显示结果 $row{'date'}."
";}echo json_encode($records);//关闭连接mysql_close($dbhandle);?>
App GrenHouse
在第一页中,您必须使用两个 DatePicker 设置日期。当您按下按钮“GRAPHIC”时,它会向 PHP 脚本“getdati”发出 HTTP GET 调用,发送您选择的参数和日期。然后它接收 JSON 并解码,在它使用库 GraphView 创建图形之后 https://github.com/cormaz/app_greenhouse.git

示意图

连接:Arduino UNO - DHT22 - 继电器

制造工艺

  1. ILI9341 TFT 触摸屏显示盾上的位图动画
  2. Web 操作的 DMX 控制器
  3. Arduino Spybot
  4. FlickMote
  5. 自制电视 B-Gone
  6. 主时钟
  7. HSVClock
  8. 使用 Raspberry Motor Shield 的 Android 控制玩具
  9. 找到我
  10. Arduino Power
  11. BLUE_P:无线 Arduino 编程扩展板
  12. Arduino Nano 的 TFT 扩展板 - 开始