进阶制作

arduino W5100 PHPServer 微信 远程监控 2016.4.2更新

字号+ 作者:PLC工程师 来源:未知 2016-04-02 15:26 我要评论( )

利用arduino UNO R3 + W5100 + PHPServer + 微信公众号 远程监控和控制 远程监控和控制详细步骤和源代码

由于时间问题,本篇内容逐步更新,先把主要代码放出,陆续添加图片和注意事项.......


一  总体介绍
通过arduion采集温度和湿度通过W5100联网,利用web服务器托管的update.php对数据库进行更新;同时微信平台可以利用菜单或者语音及文字通过weixin.php对数据库进行LED开关的更新和温度湿度数据的读取,然后显示到微信界面。 




arduino端实物




 
微信端界面,监控菜单包括2个选项温度和湿度

 




控制菜单包括2个选项:开灯和关灯

 



第一个菜单为按钮,直接打开官网





下图是温度 /湿度/开灯/关灯所对应的结果显示
 



 


 
单独测试LCD时无所谓,LCD与W5100同时使用时,LCD不能再使用12,11脚,否则会出现乱码,改为9,8端口。



二  所需材料


三  用到的库文件

<Ethernet.h>
<LiquidCrystal.h>
<dht11.h>

四  arduino端

#include <Ethernet.h>
#include <LiquidCrystal.h>
#include <dht11.h>

dht11 DHT11;
#define DHT11PIN 6

LiquidCrystal lcd(9, 8, 5, 4, 3, 2);
//由于有W5100 pin 12,11 LCD不能使用

char state = '0';
char c;
int dht11state=0;
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 31, 177);
EthernetClient client;

byte sheng[8] = {
  0x04,0x14,0x1f,0x14,0x0e,0x04,0x1f,0x00
};
byte ri[8] = {
  0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00
};

byte kuai[8] = {
  0x0a,0x0a,0x1f,0x1b,0x1f,0x0a,0x0d,0x00
};

byte le[8] = {
0x1e,0x10,0x14,0x1f,0x04,0x15,0x15,0x00
};

byte tanhao[8] = {
0x02,0x02,0x04,0x04,0x00,0x00,0x08,0x00
};

byte du[8] = {
0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00
};

byte xin[8] = {
0x00,0x0a,0x1f,0x1f,0x1f,0x0e,0x04,0x00
};

char server[] = "plclive.com";//设置为自己的服务器地址
int hum = 0;
int temp = 0;

unsigned long lastConnectionTime = 0;          
boolean lastConnected = false;                 
const unsigned long postingInterval = 10*1000;  

void setup(){
  
  Serial.begin(9600);// 设置串口通信波特率
  delay(1000);
  Ethernet.begin(mac,ip);
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  pinMode(7, OUTPUT);           //设置第七个数字io为输出
  pinMode(10, OUTPUT);
  
  lcd.begin(16, 2);
  lcd.clear();
  lcd.createChar(0, sheng);
  lcd.createChar(1, ri);
  lcd.createChar(2, kuai);
  lcd.createChar(3, le);
  lcd.createChar(4, tanhao);
  lcd.createChar(5, du);
  lcd.createChar(6, xin);
}
 
void loop(void){ 

  int chk = DHT11.read(DHT11PIN);
  switch (chk)
  {
    case DHTLIB_OK: 
                dht11state=1;
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                dht11state=2;
                 break;
    case DHTLIB_ERROR_TIMEOUT: 
                dht11state=3;
                break;
    default: 
                dht11state=10;
                break;
  }

  hum=(int)DHT11.humidity;
  temp=(int)DHT11.temperature;

//显示温度湿度开始
  lcd.setCursor(0, 0);
  lcd.print("Temperatue:");
  lcd.print(temp);
  lcd.write(5);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("Hum:");
  lcd.print(hum);
  lcd.print("%");
  lcd.blink();
//显示温度湿度结束


//显示中文开始
  lcd.setCursor(9, 1);
  lcd.write(6);
  lcd.write(byte(0));
  lcd.write(1);  
  lcd.write(2);  
  lcd.write(3);  
  lcd.write(4);delay(100);  
  lcd.write(6);delay(200);   
//显示中文结束
   
  if(state == '0'){             //根据state的状态设置7脚的电平
    digitalWrite(7, HIGH);
    digitalWrite(10,LOW);    
  }else if(state == '1'){
    digitalWrite(7, LOW); 
    digitalWrite(10,HIGH);
  }

  while(client.available()) {
    c = client.read();
    if (c == '{'){
      state = client.read();
    }
  }

  if (!client.connected() && lastConnected) {
    Serial.println("disconnecting...");
    client.stop();
  }

  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    if (client.connect(server, 80)) {
      // send the HTTP PUT request: 
      client.print("GET http://www.plclive.com/api/update.php?token=**********&data1=");  
 //*部分修改为你的token,向自己的服务器发送数据及更新token要与downup.php中设置的token一致,data1\data2\....\dataN根据传感器数量添加,
 //并且要与downup.php里一致,同事数据库增加相应的记录值
      client.print(temp);
      client.print("&data2=");
      client.print(hum);
      client.println(" HTTP/1.1");
      client.println("Host: www.plclive.com");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println();

      lastConnectionTime = millis();
    }else {
      Serial.println("connection failed");
      Serial.println("disconnecting.");
      client.stop();
    }
  }
  lastConnected = client.connected();
}



五  web端,包括数据库和PHP页面两部分



update.php  负责数据中转


<?php
if (($_GET['data1']||$_GET['data2']) && ($_GET['token'] == "*********")) {//可以改token,这相当于密码,在Arduino端改成相应的值即可
	$con = mysql_connect('host:port','user','pass'); 
	mysql_select_db("database", $con);//要改成相应的数据库名

	$result = mysql_query("SELECT * FROM switch");
	while($arr = mysql_fetch_array($result)){//找到需要的数据的记录,并读出状态值
		if ($arr['id'] == 1) {
			$state = $arr['state'];
		}
	}	
	
	{$data2 = $_GET['data2'];
	$dati2 = date("h:i:sa");//获取时间
	$sql ="UPDATE sensor SET timestamp='$dati2',data = '$data2'
	WHERE id = '2'";}//更新相应的传感器的值
	
	if(!mysql_query($sql,$con)){
	    die('Error: ' . mysql_error());//如果出错,显示错误
	}
		
	{$data1 = $_GET['data1'];
	$dati1 = date("h:i:sa");//获取时间
	$sql ="UPDATE sensor SET timestamp='$dati1',data = '$data1'
	WHERE id = '1'";}//更新相应的传感器的值	
	
		
	if(!mysql_query($sql,$con)){
	    die('Error: ' . mysql_error());//如果出错,显示错误
	}
	mysql_close($con);
	echo "{".$state."}";//返回状态值,加“{”是为了帮助Arduino确定数据的位置
}	
else{
	echo "Permission Denied";//请求中没有type或data或token或token错误时,显示Permission Denied
}
?>




weixin.php 负责解析微信平台发送的命令和返回微信相关数据

<?php
//错误日志
function echo_server_log($log){
	file_put_contents("log.txt", $log, FILE_APPEND);
}
//定义TOKEN
define ( "TOKEN", "***********" );  //********与微信端定义的token一致
//验证微信公众平台签名
function checkSignature() {
	$signature = $_GET ['signature'];
	$nonce = $_GET ['nonce'];
	$timestamp = $_GET ['timestamp'];
	$tmpArr = array ($nonce, $timestamp, TOKEN );
	sort ( $tmpArr );
	
	$tmpStr = implode ( $tmpArr );
	$tmpStr = sha1 ( $tmpStr );
	if ($tmpStr == $signature) {
		return true;
	}else{
		return false;
	}
}
if(false == checkSignature()) {
	exit(0);
}
//接入时验证接口
$echostr = $_GET ['echostr'];
if($echostr) {
	echo $echostr;
	exit(0);
}


//以上部分为连接部分,修改token即可 by plclive.com

//获取POST数据
function getPostData() {
	$data = $GLOBALS['HTTP_RAW_POST_DATA'];
	return	$data;
}
$PostData = getPostData();
//验错
if(!$PostData){
	echo_server_log("wrong input! PostData is NULL");
	echo "wrong input!";
	exit(0);
}

//把数据装入XML
$xmlObj = simplexml_load_string($PostData, 'SimpleXMLElement', LIBXML_NOCDATA);
//验错
if(!$xmlObj) {
	echo_server_log("wrong input! xmlObj is NULL\n");
	echo "wrong input!";
	exit(0);
}

//准备XML
$fromUserName = $xmlObj->FromUserName;
$toUserName = $xmlObj->ToUserName;
$msgType = $xmlObj->MsgType;
$Event = $xmlObj->Event;

if($msgType == 'voice') {//判断是否为语音
	$content = $xmlObj->Recognition;
}elseif($msgType == 'text'){
	$content = $xmlObj->Content;
}
elseif($Event =='CLICK') {
	$content = $xmlObj->EventKey;
}
elseif($Event =='subscribe') {
	$content = 关注;
}
else{
	$retMsg = '只支持文本和语音消息';
}
if (strstr($content, "温度")) {
	$con = mysql_connect('你的数据库主机:端口','用户名','密码'); 
	mysql_select_db("数据库名", $con);//修改数据库名

	$result = mysql_query("SELECT * FROM sensor");
	while($arr = mysql_fetch_array($result)){

	  if ($arr['id'] == 1) {
	  	$tempr = $arr['data'];
		$timestamp=$arr['timestamp'];
	  }
	}
	mysql_close($con);

    $retMsg = "业主您好:"."\n"."当前温度:".$tempr."℃。"."\n"."更新时间:".$timestamp."";
	
}
else if (strstr($content, "湿度")) {
	$con = mysql_connect('你的数据库主机:端口','用户名','密码'); 
	mysql_select_db("数据库名", $con);//修改数据库名

	$result = mysql_query("SELECT * FROM sensor");
	while($arr = mysql_fetch_array($result)){

	  if ($arr['id'] == 2) {
	  	$tempr = $arr['data'];
		$timestamp=$arr['timestamp'];
	  }
	}
	mysql_close($con);

    $retMsg = "业主您好:"."\n"."当前湿度:".$tempr."%。"."\n"."更新时间:".$timestamp."";
	
}
else if (strstr($content, "噪声")) {
	$con = mysql_connect('你的数据库主机:端口','用户名','密码'); 
	mysql_select_db("数据库名", $con);//plclive.com修改数据库名

	$result = mysql_query("SELECT * FROM sensor");
	while($arr = mysql_fetch_array($result)){

	  if ($arr['id'] == 3) {
	  	$tempr = $arr['data'];
		$timestamp=$arr['timestamp'];
	  }
	}
	mysql_close($con);

    $retMsg = "业主您好:"."\n"."当前噪声:".$tempr."分贝。"."\n"."更新时间:".$timestamp."";
	
}
else if (strstr($content, "开灯")) {
	$con = mysql_connect('你的数据库主机:端口','用户名','密码'); 

	$dati = date("h:i:sa");
	mysql_select_db("数据库名", $con);//修改数据库名

	$sql ="UPDATE switch SET timestamp='$dati',state = '1'
	WHERE ID = '1'";//修改开关状态值

	if(!mysql_query($sql,$con)){
	    die('Error: ' . mysql_error());
	}else{
		mysql_close($con);
		$retMsg = "已经开灯";
	}
}else if (strstr($content, "关灯")) {
	$con = mysql_connect('你的数据库主机:端口','用户名','密码'); 

	$dati = date("h:i:sa");
	mysql_select_db("数据库名", $con);//修改数据库名

	$sql ="UPDATE switch SET timestamp='$dati',state = '0'
	WHERE ID = '1'";//修改开关状态值

	if(!mysql_query($sql,$con)){
	    die('Error: ' . mysql_error());
	}else{
		mysql_close($con);
		$retMsg = "已经关灯";
	}	
}else if (strstr($content, "关注")) {
		$retMsg = "谢谢关注,请点击下方菜单进行操作";
}		
else{
	$retMsg = "指令有误,请联系管理员或者使用菜单操作!http://www.plclive.com";
}

//装备XML
$retTmp = "<xml>
		<ToUserName><![CDATA[%s]]></ToUserName>
		<FromUserName><![CDATA[%s]]></FromUserName>
		<CreateTime>%s</CreateTime>
		<MsgType><![CDATA[text]]></MsgType>
		<Content><![CDATA[%s]]></Content>
		<FuncFlag>0</FuncFlag>
		</xml>";
$resultStr = sprintf($retTmp, $fromUserName, $toUserName, time(), $retMsg);

//反馈到微信服务器
echo $resultStr;
?>


六  微信端的设置和菜单的生成



如需更详细资料,如有好资源分享,请加入QQ交流群:214461008

欢迎阅读,欢迎转载,不用注明出处!本站只提供入门和进阶资料,做您学习的小伙伴!

老司机也欢迎光临指导!有好内容请加群:214461008 不要看声明了,看内容吧!

相关文章
网友点评