Arduino多种传感器使用方法

Arduino项目: 智能窗户

前段时间参加了一个Arduino的比赛,具体内容就是用Arduino设计一个项目出来

我在的队伍的设计的项目就是智能窗户,智能窗户可以采集本地传感器采集到的环境参数,根据参数具有一套内部的逻辑判断,可以对温度,湿度,光强,粉尘等因素实现智能开闭(例如高温开窗通风),还能把这些参数发布到局域网上,用户访问192.168.4.1就能够看到

此外用户还自己控制开闭,定时开闭等等,考虑未来写一个手机APP来远程控制,在后台搭一个服务器,来在互联网上发布. 还准备训练一个神经网络放到服务器里跑,这样还可以根据采集的数据(例如过去三四天的温湿度光强等参数)预测未来的天气情况(估计是一个简单的分类任务,做起来也容易)

评委最后批评我们的项目没有实用性,但是本来Arduino做的东西就只是个模型,展示功能而已又不是直接拿去用,不知道评委怎么想的,反正最后距离国一 一步之遥,拿了一个国二

现在比赛已经结束,就把代码放出来开源,供大家参考,逻辑部分我删掉了,剩下的多种传感器的驱动方式可以参考下


技术描述

整个项目硬件分两部分,一部分是Arduino,负责底层的舵机执行和参数采集,另外一部分是NodeMCU,负责将数据发布到网上,时间问题NodeMCU用的是AP模式,未来考虑改成Client和服务器通信

两部分之间是软通信明文沟通,未来当然也可以加密数据传输.

代码

Arduino部分

#include <DHT11.h>
#include <Servo.h>
#include <Stepper.h>
#include <SoftwareSerial.h>

//whetherOpen用于判断窗户能否打开
//isOpen用于判断窗户是否已经打开
boolean whetherOpen = true;
boolean isOpen = false;

int servoOpenPin = 3;
int servoCleanPin = 4;
int steps = 120;
float humidity;
float temperature;
float lightIntensity;
long distance;

dht11 DHT11;
Servo servoClean;
Servo servoOpen;
Stepper aStepper(steps, 5, 6, 9, 10);
SoftwareSerial mySerial(2, 3); //实例化软串口,2为RX,3为TX

void setup()
{
    
    
    Serial.begin(9600);   //硬串口设置
    mySerial.begin(9600); //软串口设置
    mySerial.listen();

    //默认状态窗户关闭
    isOpen = false;

    //延迟一秒便于Debug
    //现在release版延迟0.1秒用于稳定系统
    delay(100);
}

void loop()
{
    
    
 	//主程序代码遮掉了,下面只是示意一下怎么用各种传感器
}

float GetTemperature()
{
    
    
    DHT11.read(A0);
    temperature = DHT11.temperature;
    humidity = DHT11.humidity;
    Serial.print("      Temperature(oC) :");
    Serial.println(temperature);
    delay(100);
    return temperature;
}

float GetHumidity()
{
    
    
    DHT11.read(A0);
    humidity = DHT11.humidity;
    temperature = DHT11.temperature;
    Serial.print("      Humidity(%) :");
    Serial.println(humidity);
    delay(100);
    return humidity;
}

int GetLightIntensity()
{
    
    
    /*
    * GetLightIntensity is used to get the light intensity
    * the light intensity sensor pin should be attached to A2
    */
    lightIntensity = analogRead(A2);
    Serial.print("      Light intensity(%):");
    Serial.println(lightIntensity/770*65);
    delay(100);
    return lightIntensity/770*65;
}

long GetDistance()
{
    
    
    int trigPin = 19;
    int echoPin = 18;
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(20);
    digitalWrite(trigPin, LOW);
    distance = pulseIn(echoPin, HIGH);
    distance = distance / 59;

    if (distance > 400 || distance < 0)
    {
    
    
        distance = 300;
    }

    Serial.print("      Distance(CM):");
    Serial.println(distance);

    delay(100);
    return distance;
}

void OpenWindow()
{
    
    
    Serial.println("      Called OpenWindow");
    if (!servoOpen.attached())
        servoOpen.attach(servoOpenPin);
    //servo write 87 means open window
    servoOpen.write(87);
    delay(1000);
    if (servoOpen.attached())
        servoOpen.detach();
}

void CloseWindow(int directions)
{
    
    
    /*
     * direction==1   :   Turn left
     * direction==2   :   Turn right
     */
    Serial.println("      Called CloseWindow");
    if (!servoOpen.attached())
        servoOpen.attach(servoOpenPin);
    if (directions == 1)
    {
    
    
        servoOpen.write(22);
        Serial.println("      Turn left");
        delay(1000);
    }
    else if (directions == 2)
    {
    
    
        servoOpen.write(150);
        Serial.println("      Turn right");
        delay(1000);
    }
    if (servoOpen.attached())
        servoOpen.detach();
}

void LockWindow(int directions)
{
    
    
    Serial.println("      Called LockWindow");
    CloseWindow(directions);
}

//Note Wawe() is for testing use,will be deleted in release version
void Wawe()
{
    
    
    if (!servoClean.attached())
        servoClean.attach(servoCleanPin);
    Serial.println("      Wave!");
    servoClean.write(95);
    delay(1000);
    servoClean.write(175);
    delay(1000);
    if (servoClean.attached())
        servoClean.detach();
}

void Wawe(Servo aServo)
{
    
    
    /*
        * Note:
        * For cleanServo, 95 is close, 175 is open
     */
    Serial.println("      Wave!");
    aServo.write(95);
    delay(1000);
    aServo.write(175);
    delay(1000);
}

void CleanWindow()
{
    
    
    /*
         * Note: 
         * servoClean is attched to servoCleanPin
         * default aStepper pin is 5 6 9 10
         * aStepper max speed is set to 60
         * default steps per circle is 120
         * Wait for adding length
        */
    Serial.println("      Called CleanWindow");
    if (!servoClean.attached())
        servoClean.attach(servoCleanPin);

    // Serial.print('1')
    aStepper.setSpeed(60);
    Serial.println("      Steeped!");
    int i;
    for (i = 0; i < 4; i++)
    {
    
    
        aStepper.step(-960);
        Wawe();
    }
    if (servoClean.attached())
    {
    
    
        servoClean.detach();
    }
}

void GoBack()
{
    
    
    aStepper.setSpeed(60);
    Serial.println("      Steeped Back!");
    aStepper.step(960 * 4);
}

NodeMCU部分

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <SoftwareSerial.h>
#include <stdlib.h>

//实例化软串口
SoftwareSerial mySerial(D5, D6);
//实例化服务器
ESP8266WebServer server(80); //端口号设置为80

int requireState = 1;
//Buffers用于接受单个数据传输时的所有字节
//Results用于存储接受到的所有数据
char Buffers[10];
float Results[6];
char aNumber[20];
const char *ssid = "IoTWindow";    // 设置WIFI名称
const char *password = "88888888"; // 设置WIFI密码

void GetData()
{
    
    
    //请求数据
    mySerial.write(requireState);
    delay(100);
    mySerial.write(requireState);
    //存储数据
    memset(Buffers, 0, sizeof(Buffers));
    //记录传来的数据
    int i = 0;
    for (int j = 0; j < 6; j++)
    {
    
    
        //只要还在传输数据
        while (mySerial.available() > 0)
        {
    
    
            //读取传输来的一个字节
            char aByte = mySerial.read();
            //只要当前数据的字节流未完成
            if (aByte != '\n')
            {
    
    
                Buffers[i++] = aByte; //隐式循环
            }
            else
            {
    
    
                //若当前数据字节流已经完毕,则将其转化为浮点数
                Results[j++] = atof(Buffers);
                Serial.println(Results[j - 1]);
                //重置Buffers
                memset(Buffers, 0, sizeof(Buffers));
                i = 0;
            }
        }
    }
}

//设置网页内容,重写方法
void handleRoot()
{
    
    
    //请求数据
    mySerial.write(1);
    //存储数据
    memset(Buffers, 0, sizeof(Buffers));
    //记录传来的数据
    int i = 0;
    for (int j = 0; j < 5; j++)
    {
    
    
        //只要还在传输数据
        while (mySerial.available() > 0)
        {
    
    
            //读取传输来的一个字节
            char aByte = mySerial.read();
            //只要当前数据的字节流未完成
            if (aByte != '\n')
            {
    
    
                Buffers[i++] = aByte; //隐式循环
            }
            else
            {
    
    
                //若当前数据字节流已经完毕,则将其转化为浮点数
                Results[j++] = atof(Buffers);
                Serial.println(Results[j - 1]);
                //重置Buffers
                memset(Buffers, 0, sizeof(Buffers));
                i = 0;
            }
        }
    }

    delay(1500);
    //Results内容分别为:
    //温度,湿度,光强,是否打开,能否打开
    GetData();
    String str = "<!doctype HTML><head><meta charset=\"utf-8\" /><title>智能窗户</title></head><body><h1 align=\"center\">智能窗户实时监测</h1>";
    str += "<h2 align=\"center\">当前温度为(℃):";
    itoa(int(Results[1]), aNumber, 10);
    str += aNumber;
    str += "</h2><h2 align=\"center\">当前湿度为(%):";
    itoa(int(Results[2]), aNumber, 10);
    str += aNumber;
    str += "</h2><h2 align=\"center\">当前光照强度为(CD):";
    itoa(int(Results[3]), aNumber, 10);
    str += aNumber;
    str += "</h2><h3 align=\"center\">当前窗户";
    if (int(Results[4]) == 1)
        str += "已经打开</h3><h3 align=\"center\">";
    else
        str += "没有打开</h3><h3 align=\"center\">";
    if (int(Results[5]) == 1)
        str += "窗户前没有小孩,窗户可以正常打开</h3>";
    else
        str += "窗户前有小孩,窗户默认无法开启</h3>";
    str += "</body></html>";
    server.send(200, "text/html", str);
}

void setup()
{
    
    
    delay(1000);
    Serial.begin(9600);
    mySerial.begin(9600);
    Serial.println();
    Serial.print("Configuring access point...");

    //启动AP热点
    WiFi.softAP(ssid, password);
    Serial.println(ssid);
    //显示热点信息
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);

    //绑定HTTP服务器/目录下所发布的信息,并启动服务
    server.on("/", handleRoot);
    server.begin();

    Serial.println("HTTP server started");
}

//作用:检测软通信是否可用
void loop()
{
    
    
    Serial.println("In Loop");
    server.handleClient();
}

猜你喜欢

转载自blog.csdn.net/qq_45488242/article/details/111268693