Hardware components | ||||||
| × | 1 | ||||
Hand tools and fabrication machines | ||||||
|
This is a project that I can use to monitor the environment temperature and humidity. Also, I can use it to monitor the air quality such as PM2.5. All the info will be showing up on the OLED screen. And since I am using a Photon to work on this project, I can also display all the info on my computer by designing a webpage. Also, I can control something like a fan or lamp remotely through that webpage.
I'm always interested in controlling something. And it would be better if I can control it remotely from my computer or phone. But I didn't have a strong background on designing an app on phone and wireless control. But when I get the Photon, I know I can use it to do some great project with my limited knowledge on HTML/Javascript. I then came up with this project. On one hand, I will practice my knowledge on HTML and coding. On another hand, it can make me have a deeper understanding on wireless control.
This project contains two part. One part is the control system. Which includes a Photon from www.particle.io, temperature and humidity sensor AM2302 and a air quality sensor PM3003. Another part is more related with the computer; a webpage. Through this webpage, I can get all the monitored info and also control something through the button on page.
Below is the part one of this board. Photon control all those sensors and also send out the info to my webpage through Particle cloud.
Below is the part two. In this part, I can read out all the information remotely and also I can control something like a fan or lamp on the board through the button on webpage, and also setting parameters for those.
source code for photon
C/C++// This #include statement was automatically added by the Particle IDE.
#include "idDHT22/idDHT22.h"
// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_SSD1306/Adafruit_SSD1306.h"
// This #include statement was automatically added by the Particle IDE.
#include "ThingSpeak/ThingSpeak.h"
#include"application.h"
#include"stdlib.h"
#define LENG 24
// use hardware SPI,so only need to config DataCommand, ChipSelect, Reset Pins
//#define OLED_MOSI A5 //DI
//#define OLED0_MISO A4
//#define OLED_SCK A3 //DO
#define OLED_CS A0
#define OLED_DC A1
#define OLED_RESET A2
#define ITEM_NONE 0
#define ITEM_LAMP 1
#define ITEM_PUMP 2
#define ITEM_FAN 3
#define PIN_FAN D0
#define PIN_PUMP D1
#define PIN_LAMP D2
Adafruit_SSD1306 oled(OLED_DC, OLED_RESET, OLED_CS);
int idDHT22pin = D3; //Digital pin for comunications
void dht22_wrapper(); // must be declared before the lib initialization
// DHT instantiate
idDHT22 DHT22(idDHT22pin, dht22_wrapper);
unsigned char buf[LENG];
int PM01Value=0; //define PM1.0 value of the air detector module
int PM2_5Value=0; //define PM2.5 value of the air detector module
int PM10Value=0; //define PM10 value of the air detector module
#define SENSOR PMS3003 //have another type of sensor
unsigned char ledFlip=0;
void dht22_wrapper() {
DHT22.isrCallback();
}
int handlepara(String value);
void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
pinMode(D7,OUTPUT);
// digitalWrite(D7,LOW);
analogWrite(A4,1);
/// ThingSpeak.begin(client);
Particle.function("handlepara",handlepara); // handles all parameters.
oled.begin(SSD1306_SWITCHCAPVCC); //init the oled
oled.display();
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
DHT22.acquire();
while (DHT22.acquiring())
;
int result = DHT22.getStatus();
switch (result)
{
case IDDHTLIB_OK:
Serial.println("OK");
break;
case IDDHTLIB_ERROR_CHECKSUM:
Serial.println("Error\n\r\tChecksum error");
break;
case IDDHTLIB_ERROR_ISR_TIMEOUT:
Serial.println("Error\n\r\tISR Time out error");
break;
case IDDHTLIB_ERROR_RESPONSE_TIMEOUT:
Serial.println("Error\n\r\tResponse time out error");
break;
case IDDHTLIB_ERROR_DATA_TIMEOUT:
Serial.println("Error\n\r\tData time out error");
break;
case IDDHTLIB_ERROR_ACQUIRING:
Serial.println("Error\n\r\tAcquiring");
break;
case IDDHTLIB_ERROR_DELTA:
Serial.println("Error\n\r\tDelta time to small");
break;
case IDDHTLIB_ERROR_NOTSTARTED:
Serial.println("Error\n\r\tNot started");
break;
default:
Serial.println("Unknown error");
break;
}
}
int handlepara(String value)
{
static unsigned char counter=0;
static uint8_t item_update = ITEM_NONE; //no item will be udpated at first.
unsigned char adjust_value = 0;
if((value=="FanON")||(value=="FanOFF"))
item_update = ITEM_FAN;
else
if((value=="LampON")||(value=="LampOFF"))
item_update = ITEM_LAMP;
else
if((value=="PumpON")||(value=="PumpOFF"))
item_update = ITEM_PUMP;
if(value=="FanON")
digitalWrite(D7,HIGH);
else
if(value=="FanOFF")
digitalWrite(D7,LOW);
else
if(value=="LampON")
digitalWrite(D7,HIGH);
else
if(value=="LampOFF")
digitalWrite(D7,LOW);
else
if(value=="PumpON")
digitalWrite(D7,HIGH);
else
if(value=="PumpOFF")
digitalWrite(D7,LOW);
else
adjust_value= atoi(value); //must be a value from adjust panel
{
if(adjust_value==5)
digitalWrite(D7,HIGH);
else
if(adjust_value==6)
digitalWrite(D7,LOW);
if((adjust_value>=0)&&(adjust_value<=10)) //make sure it's the right value
{
uint16_t pwm = (uint16_t)(adjust_value/10.0)*4095;
if(item_update==ITEM_FAN)
analogWrite(PIN_FAN,pwm);
else
if(item_update==ITEM_LAMP)
analogWrite(PIN_LAMP,pwm);
else
if(item_update==ITEM_PUMP)
analogWrite(PIN_PUMP,pwm);
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////
// SYSTEM_MODE(SEMI_AUTOMATIC);
#ifdef SENSOR //we use the sensor from plantower
float Tempp=0.0;
float Humii=0.0;
float PM2_5=0;
void loop()
{
unsigned char flag=0;
char pubstring[64];
bool success;
static unsigned char update=0;
if(Serial1.available())
{
buf[0]=Serial1.read();
if(buf[0]==0x42)
while(!Serial1.available());
buf[1]=Serial1.read();
if(buf[1]==0x4d)
{
Serial.print("PMS3003\r\n");
for(unsigned char i=2;i<24;i++)
{
while(!Serial1.available());
buf[i]= Serial1.read();
}
flag=1;
}
}
if(flag==1) //upate the data every time when sensor udpated
{
flag=0;
if(checkValue(buf,LENG))
{
PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
PM2_5=PM2_5Value;
PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
}
update++;
if(update==3) //only update all the value five times later.
{
update=0;
DHT22.acquire();
while (DHT22.acquiring());
oled.clearDisplay();
oled.setCursor(0,0);
oled.print("Temperature:"); //the first line
Tempp=DHT22.getCelsius();
oled.print(Tempp, 2);
oled.println("C");
oled.println(""); //do nothing here,just to leave one space line
oled.print("Humidity:"); //the second line
Humii=DHT22.getHumidity();
oled.print(Humii, 2);
oled.println("%");
oled.println(""); //do nothing here,just to leave one space line
oled.print("PM2.5:"); //the third line
oled.print(PM2_5Value,DEC);
oled.println("ug/m3");
oled.println(""); //do nothing here,just to leave one space line
oled.print("PM10:"); //the fourth line
oled.print(PM10Value,DEC);
oled.print("ug/m3");
oled.display();
sprintf(pubstring,"{\"t\":%0.2lf,\"h\":%0.2lf,\"p\":%0.1lf}", Tempp, Humii,PM2_5);
success=Particle.publish("temp", pubstring);
if(!success)
Serial.println("Failed to publish this event");
else
Serial.println("Event had published successfully");
}
// Update the 2 ThingSpeak fields with the new data
/*this is only used if i want to publish all the value to website
ThingSpeak.setField(1, (int)PM01Value);
ThingSpeak.setField(2, (int)PM2_5Value);
ThingSpeak.setField(3, (int)PM10Value);
// Write the fields that you've set all at once.
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
*/
}
}
char checkValue(unsigned char *thebuf, char leng)
{
char receiveflag=0;
int receiveSum=0;
char i=0;
for(i=0;i<leng;i++)
{
receiveSum=receiveSum+thebuf[i];
}
if(receiveSum==((thebuf[leng-2]<<8)+thebuf[leng-1]+thebuf[leng-2]+thebuf[leng-1])) //check the serial data
{
receiveSum=0;
receiveflag=1;
}
return receiveflag;
}
int transmitPM01(unsigned char *thebuf)
{
int PM01Val;
PM01Val=((thebuf[4]<<8) + thebuf[5]); //count PM1.0 value of the air detector module
return PM01Val;
}
//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
int PM2_5Val;
PM2_5Val=((thebuf[6]<<8) + thebuf[7]);//count PM2.5 value of the air detector module
return PM2_5Val;
}
//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
int PM10Val;
PM10Val=((thebuf[8]<<8) + thebuf[9]); //count PM10 value of the air detector module
return PM10Val;
}
#else //sendsor for liudu
void loop()
{
unsigned char i=0;
unsigned char flag=0;
if(Serial1.available())
{
buf[0]=Serial1.read();
if(buf[0]==0xAA) //get the start frame
{
for(i=1;i<7;i++)
{
while(!Serial1.available());
buf[i]= Serial1.read();
}
if(buf[6]==0xff) //get the end frame
{
flag=1;
Serial.print("LMLPM05K\r\n");
}
else
flag=0;
}
}
if(flag==1)
{
flag=0;
if(checkValue(buf,7))
{
PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
}
Serial.print("PM2.5: "); //send PM1.0 data to bluetooth
PM2_5Value/=10;
Serial.print(PM2_5Value);
Serial.println(" ug/m3");
Serial.print("PM10: "); //send PM1.0 data to bluetooth
PM10Value/=10;
Serial.print(PM10Value);
Serial.println(" ug/m3");
if(ledFlip==0)
{
ledFlip=1;
digitalWrite(D7,LOW);
}
else
{
ledFlip = 0;
digitalWrite(D7,HIGH);
}
}
}
char checkValue(unsigned char *thebuf, char leng)
{
char receiveflag=0;
unsigned char receiveSum=0;
char i=0;
for(i=1;i<5;i++)
{
receiveSum=receiveSum+thebuf[i];
}
if(receiveSum==thebuf[5]) //check the serial data
{
receiveSum=0;
receiveflag=1;
}
return receiveflag;
}
//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
int PM2_5Val;
PM2_5Val=((thebuf[1]<<8) + thebuf[2]);//count PM2.5 value of the air detector module
return PM2_5Val;
}
//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
int PM10Val;
PM10Val=((thebuf[3]<<8) + thebuf[4]); //count PM10 value of the air detector module
return PM10Val;
}
#endif
<!DOCTYPE html>
<html>
<head>
<title>MyFirstApp</title>
<script type="text/javascript" src="http://cdn.jsdelivr.net/particle-api-js/5/particle.min.js"></script>
<style>
button#button1{color:black;padding:5px}
button#button1:hover{background-color: blue}
button#button1:active{background-color: antiquewhite}
button#button2{color:black;padding:5px}
button#button3{color:black;padding:5px}
legend{text-align:center}
fieldset{border: block}
img#buttonPanelImage{width:100px; height:100px;float:right;}
</style>
</head>
<body>
<!---------------------For the Button Coltorl Panel------->
<div>
<br>
<fieldset>
<legend>Button Control Panel</legend>
<!--<button id="button1" onclick="function_fan()" onmouseover="style.backgroundColor='blue'"
onmouseout="style.backgroundColor='grey'" onmousedown="style.backgroundColor='green'" >Turn ON Fan</button> <br> -->
<img id="buttonPanelImage" src="fanOff.gif">
<!-- <img id="fanImage" src="fanOff.gif" style="wdith:50px;height:90px;float:right"> -->
<!--<img id="myImage" src="LampOff.gif" width="50" height=90 float:right> -->
<button id="button1" onclick="function_fan()" >Turn ON Fan</button> <br>
<button id="button2" onclick="function_lamp()">Turn ON Lamp</button> <br>
<button id="button3" onclick="function_pump()">Turn ON Pump</button><br>
</fieldset>
</div>
<!--------------For the Value Tune Panel------------------->
<div>
<fieldset>
<legend>Adjust Panel</legend>
<p id="tuneTitle">Set Fan Speed</p> <!--Why the layout will change if i didnot use <p> -->
<input id="Range" type="range" style="width:200px;height:30px" min="0" max="10" value="5" onclick="Function_Adjust()"> <!--set the default value as 5-->
</fieldset>
</div>
<!--For read out value-->
<div>
<fieldset>
<legend>Sensor</legend>
<p id="Temp">Temperature:</p>
<p id="Humidity">Humidity:</p>
<p id="PM2.5">PM2.5:</p>
<p id="Time">Time:</p>
</fieldset>
</div>
<p id="debug"></p> <!--THIS syntax is just for debug---------->
<!-----------------Java script section-------------------->
<script>
var image=document.getElementById("buttonPanelImage"); //define the image for the button panel image
var FanStatus = 0,
LampStatus = 0,
PumpStatus = 0,
DeviceId = "xxxxchagne it with your own deviceID for photonxxx",
token="xxxxxxxxchange it with your own tokenxxxxxxxxxxxxx";
var particle = new Particle();
particle.login({username: '------your user name for web IED-----', password: '---your password for IED--------'}).then(
function(data){
console.log('API call completed on promise resolve: ', data.body.access_token);
token = data.body.access_token;
},
function(err) {
console.log('API call completed on promise fail: ', err);
}
);
function function_cloud(FunctionName, FunctionVar){
var fnPr = particle.callFunction({ deviceId: DeviceId, name: FunctionName, argument: FunctionVar, auth: token });
fnPr.then(
function(data) {
console.log('Function called succesfully:', data);
},
function(err) {
console.log('An error occurred:', err);
}
);
}
var tune_fan =5;
var tune_pump = 5;
var tune_lamp = 5;
var tune_current = 0; //define the current tune status-->the last time that the user pused the turn on button
//Get test event for specific device
particle.getEventStream({ deviceId:DeviceId, name: 'temp', auth:token }).then(function(stream) {
stream.on('event', function(data) {
console.log("Event: ", data);
var ParseData=JSON.parse(data.data);
console.log("temperature: " + ParseData.t + " degrees C, Humidity: " + ParseData.h + "%");
document.getElementById("Temp").innerHTML="Temperature: "+ParseData.t+"C";
document.getElementById("Humidity").innerHTML="Humidity: "+ParseData.h+"%";
document.getElementById("PM2.5").innerHTML="PM2.5: "+ParseData.p +"mg/m3";
});
});
/**********************************************************************************/
function function_fan()
{
var x=0;
var State;
x=document.getElementById("button1").innerHTML;
x=(x=="Turn OFF Fan")? "Turn ON Fan":"Turn OFF Fan";
document.getElementById("button1").innerHTML=x;
if(x=="Turn OFF Fan")
{
image.src="FanOn.gif";
document.getElementById("tuneTitle").innerHTML="Set Fan Speed";
//document.getElementById("Range").value = tune_fan;
State="FanON";
tune_current=State; //which means the last time the user pused the turn on button is turn Fan on
}
else
if(x=="Turn ON Fan")
{
image.src="FanOff.gif";
State="FanOFF";
}
function_cloud("handlepara",State);
document.getElementById("Range").value = tune_fan;
}
function function_lamp()
{
var x=0;
var State;
x=document.getElementById("button2").innerHTML;
x=(x=="Turn OFF Lamp")? "Turn ON Lamp":"Turn OFF Lamp";
document.getElementById("button2").innerHTML=x;
if(x=="Turn OFF Lamp")
{
image.src="LampOn.gif";
document.getElementById("tuneTitle").innerHTML="Set Lamp brightness";
//document.getElementById("Range").value = tune_lamp;
State="LampON";
tune_current=State;
}
else
if(x=="Turn ON Lamp")
{
image.src="LampOff.gif";
State="LampOFF";
}
function_cloud("handlepara",State);
document.getElementById("Range").value = tune_lamp;
}
function function_pump()
{
var x=0;
var State;
x=document.getElementById("button3").innerHTML;
x=(x=="Turn OFF Pump")? "Turn ON Pump":"Turn OFF Pump";
document.getElementById("button3").innerHTML=x;
if(x=="Turn OFF Pump")
{
image.src="PumpOn.gif";
document.getElementById("tuneTitle").innerHTML="Set Pump Volume";
// document.getElementById("Range").value = tune_pump;
State="PumpON";
tune_current=State;
}
else
if(x=="Turn ON Pump")
{
image.src="PumpOff.gif";
State="PumpOFF";
}
function_cloud("handlepara",State);
document.getElementById("Range").value = tune_pump;
}
function Function_Adjust()
{
var x;
if(tune_current=="FanON")
tune_fan = document.getElementById("Range").value;
else
if(tune_current=="LampON")
tune_lamp = document.getElementById("Range").value;
else
if(tune_current=="PumpON")
tune_pump = document.getElementById("Range").value;
x=document.getElementById("Range").value;
document.getElementById("debug").innerHTML=x;
function_cloud("handlepara",x);
}
(function(){
function checkTime(i)
{
return (i<10)?"0"+i:i;
}
function function_time()
{
var Time = new Date();
var h=checkTime(Time.getHours());
var m=checkTime(Time.getMinutes());
var s=checkTime(Time.getSeconds());
// var temp=document.getElementById(Time).innerHTML;
document.getElementById("Time").innerHTML="Time:"+h+":"+m+":"+s;
setTimeout(function(){function_time()},500);
}
function_time();
})();
</script>
</body>
</html>
Comments