logo
carrot

太阳当空照,花儿对我笑

ESP8266&OLED

6/1/2022, 1:15:25 PM
  1. 首页
  2. /
  3. 正文

海绵宝宝队参赛部分代码。

详细代码见

开发板

https://arduino.esp8266.com/stable/package_esp8266com_index.json

(22条消息) nodeMCU_esp8266管脚示意图/特殊管脚的使用避坑(D3/D4/D8/..)_xuchaoxin1375的博客-CSDN博客_esp8266nodemcu引脚图及其功能

Websockets@2.3.6 by Markus Sattler
Adafruit_SSD1306@2.5.3 by Adafruit
DHT sensor library@1.4.3 by Adafruit

arduino

地址为0X3C。


/*--------------------WIFI-----------------------------------------*/
#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>

#include <DHT.h>
#define DHTPIN 12
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

WebSocketsClient wsClient;
#define SN  "abcdefg"
#ifndef STASSID
#define STASSID "1021"
#define STAPSK  "5p2O546L6YK16IuP546L5a6J"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

/*--------------------OLED-----------------------------------------*/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  //Adafruit_GFX
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setTextWrap(false);
  
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  println(F("Connecting to ")+String(ssid));
  Serial.println(ssid);

  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
     would try to act as both a client and an access-point and could cause
     network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
    print(F("."));
  }
  Serial.println("");
  Serial.println("WiFi connected");
  println(F("WiFi connected"));
  Serial.println("IP address: ");
  println(F("IP address: "));

  Serial.println(WiFi.localIP());
  println(WiFi.localIP().toString());

  // 启动WebSocketsClient,设定WebSocket服务器地址为remoteHost,端口号为81
  wsClient.begin("119.29.115.242", 80);
  // 指定事件处理函数
  wsClient.onEvent([](WStype_t type, uint8_t * payload, size_t length) {
  /* param:
    type: 事件类型
    payload: 事件携带数据
    length: 事件携带数据长度
  */
    if (type == WStype_TEXT){
      String data = (char*)payload;
      Serial.println(data);
      println(data);
      wsClient.sendTXT("你好!");
      if(data=="hello"){
        String msg="{\"cmd\":\"init\",\"args\":{\"sn\":\""+String(SN)+"\"}}";
        Serial.println(msg);
        wsClient.sendTXT(msg);
      }else if(data=="watering"){
        digitalWrite(14, HIGH);
      }else if(data=="stopWatering"){
        digitalWrite(14, LOW);
      }
    }
  });

  dht.begin();
  pinMode(14,OUTPUT);
  delay(3000);
}
String dhtData="";
void loop() {
  wsClient.loop();
  // Wait a few seconds between measurements.

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);
  if(dhtData!=String(h)+","+String(t)){
    dhtData=String(h)+","+String(t);
    println(F("H:")+String(h)+","+F("T:")+String(t));
    String msg="{\"cmd\":\"report\",\"args\":{\"type\":\"dht\",\"data\":\""+dhtData+"\"}}"; 
    Serial.println(msg);
    wsClient.sendTXT(msg);
  }
}

/*--------------------屏幕滚动-----------------------------------------*/
String lines[8];
int firstLineIndex=-7;
int lastLineIndex=0;
bool endlLock=true;
void println(String line) {
  
  if(!endlLock){
    lastLineIndex++;
    lastLineIndex%=8;
    firstLineIndex++;
    firstLineIndex%=8;
  }
  endlLock=true;
  lines[lastLineIndex]=line;
  display.clearDisplay();
  display.setCursor(0, 0);
  for(int i=0;i<8;i++){
    display.println(lines[(max(firstLineIndex,0)+i)%8]);
  }
  display.display();
  lastLineIndex++;
  lastLineIndex%=8;
  firstLineIndex++;
  firstLineIndex%=8;
}

void print(String line) {
  endlLock=false;
  lines[lastLineIndex]+=line;
  display.clearDisplay();
  display.setCursor(0, 0);
  for(int i=0;i<8;i++){
    display.println(lines[(max(firstLineIndex,0)+i)%8]);
  }
  display.display();
}

node.js

let {
	Sensor
} = require("./db.js")
const WebSocket = require('ws')
const wss = new WebSocket.Server({
	port: 80
})
let devices = {};
wss.on('connection', function(ws) {
	ws.on('message', function(message) {
		data = parse(message.toString())
		console.log(data['cmd'])
		implement(data, ws)
	})
	ws.on('close', function(message) {
		if (devices[ws.id] != undefined) {
			devices[ws.id] = undefined
			console.log(`设备${ws.id}离线`)
		}
	})
	ws.send("hello")
})

function parse(str) {
	let data;
	try {
		data = JSON.parse(str);
	} catch (e) {
		return {};
	}
	return data
}

function implement(data, ws) {
	switch (data['cmd']) {
		case "init":
			ws.sn = data['args']['sn']
			devices[ws.sn] = ws
			ws.send(`Server Connected!`)
			console.log(`设备${ws.sn}已接入服务器`)
			break
		case "list":
			ws.send(`${Object.keys(devices).join('\n')}`)
			break
		case "call":
			let device
			if (devices[data['args']['sn']] != undefined) {
				device = devices[data['args']['sn']]
				if (device.readyState == 1) {
					device.send(data['args']['msg'])
				} else {
					devices[data['args']['sn']] = undefined
					ws.send(`该设备未上线`)
				}
			} else {
				ws.send(`该设备未上线`)
			}
			break
		case "report":
			//添加
			row = {}
			row[data['args']['type']] = data['args']['data']
			row['sn'] = ws.sn
			Sensor.create(row).then(row => {
				ws.send(`Uploaded!`)
			})
			break
		case "get":
			Sensor.findOne({
				where: {
					sn: data['args']['sn']
				},
				order: [
					["id", "DESC"]
				]
			}).then(row => {
				ws.send(JSON.stringify(row))
			})
	}
}

let {
	Sequelize,
	DataTypes,
	Op
} = require("sequelize")

let Tables = new Sequelize("galasp", "galasp", "a20030824.", {
	host: "119.29.115.242",
	dialect: "mysql",
	logging: false,
	define: {
		charset: "utf8",
		collate: "utf8_general_ci"
	},
	dialectOptions: {
		dateStrings: true,
		typeCast: true
	},
	timezone: "+08:00"
})

let Sensor = Tables.define("sensor", {
	sn: {
		type: DataTypes.STRING,
		allowNull: false,
		charset: "utf8"
	},
	dht: {
		type: DataTypes.STRING,
		charset: "utf8"
	}
})

Sensor.sync({
	alter: true
})


module.exports = {
	Sensor
}

mqtt

#include "conf.h"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "vkml.h"
#include "tasks.h"
#include <Ticker.h>
#include <DNSServer.h>
#include <WiFiUdp.h>
#include <Servo.h>

Servo servo;

VKML vkml;

WiFiUDP Udp;
char udpPacketBuffer[UDP_TX_PACKET_MAX_SIZE + 1];

DNSServer dnsServer;

Ticker ticker;

CONF conf;
WiFiClient wifiClient;
PubSubClient MQTT(wifiClient);

void (*resetFunc)(void) = 0;

void mqttCallback(char *topic, byte *payload, unsigned int length);

void connectWiFi();

void connectMQTT();

void udpServerLoop();

String ssid = conf.get("ssid"), pwd = conf.get("pwd"), sn = conf.get("sn"), sk = conf.get("sk");

TASKS fastLoopTasks;
TASKS slowLoopTasks;
bool slowLoopReady = false;

void setup() {
    Serial.begin(115200);
    delay(1000);
    Serial.println();
    //检测是否被设置过
    if (conf.get("status") == "") {
        WiFi.mode(WIFI_AP_STA);
        //没有配网,开启热点
        Serial.print("Setting soft-AP ... ");
        Serial.println(WiFi.softAP("rabbit-chameleon", "") ? "Ready" : "Failed!");
        Serial.println("IP address: ");
        Serial.println(WiFi.softAPIP());
        //开启dns服务器
        dnsServer.start(53, "rabbit.com", WiFi.softAPIP());
        fastLoopTasks.add([]() { dnsServer.processNextRequest(); });
        //开启udp
        Udp.begin(8888);
        fastLoopTasks.add([]() { udpServerLoop(); });
    } else {
        //已经配网连接wifi
        connectWiFi();
        //开启mqtt
        connectMQTT();
        fastLoopTasks.add([]() { MQTT.loop(); });
        slowLoopTasks.add([]() {
            //定时检测wifi连接状态
            if (WiFi.status() != WL_CONNECTED) {
                connectWiFi();
            }
            //定时检测mqtt连接状态
            if (!MQTT.connected()) {
                connectMQTT();
            }
        });
        servo.attach(13);
    }
//    conf.set("tip","hello");
//    Serial.println(conf.get("tip"));
    pinMode(16, INPUT);
    ticker.attach(1, []() {
        slowLoopReady = true;
    });
}

void loop() {
    fastLoopTasks.run();
    if (digitalRead(16) == LOW) {
        conf.set("status", "");
        delay(1000);
        Serial.println("设备已重置!");
        resetFunc();
    }
    if (slowLoopReady) {
        //slowLoop
        slowLoopTasks.run();
        slowLoopReady = false;
    }
}


void mqttCallback(char *topic, byte *payload, unsigned int length) {
    char message[5] = {0x00};
    for (int i = 0; i < length; i++)
        message[i] = (char) payload[i];
    message[length] = 0x00;
    VKML data;
    data.text = String(message);
    String cmd = data.get("cmd");
    Serial.println(data.text);
    if (cmd == "reset") {
        conf.set("status", "");
        MQTT.publish(("from-" + sn + "-" + sk).c_str(), "设备已重置!");
        delay(1000);
        resetFunc();
    } else if (cmd == "hello") {
        MQTT.publish(("from-" + sn + "-" + sk).c_str(), "我在!");
    } else if (cmd == "turn") {
        int angle = data.get("angle").toInt();
        servo.write(angle);
        MQTT.publish(("from-" + sn + "-" + sk).c_str(), ("已转至" + String(angle) + "度!").c_str());
    }
}

//void httpCallback() {
//    conf.set("status", "already");
//    conf.set("ssid", WebServer.arg("ssid"));
//    conf.set("pwd", WebServer.arg("pwd"));
//    conf.set("sn", WebServer.arg("sn"));
//    conf.set("sk", WebServer.arg("sk"));
//    WebServer.send(200, "text/plain", "ok");
//    Serial.println(WebServer.arg("ssid"));
//    Serial.println(WebServer.arg("pwd"));
//    Serial.println(WebServer.arg("sn"));
//    Serial.println(WebServer.arg("sk"));
//    delay(1000);
//    resetFunc();
//}

void connectWiFi() {
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid.c_str(), pwd.c_str());
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(F("."));
        if (digitalRead(16) == LOW) {
            conf.set("status", "");
            delay(1000);
            Serial.println("设备已重置!");
            resetFunc();
        }
    }
    Serial.println();
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.println("Way IP: ");
    Serial.println(WiFi.gatewayIP().toString());
    Serial.println(WiFi.hostname());
}

void connectMQTT() {
    MQTT.setServer("119.29.115.242", 1883);
    MQTT.setCallback(mqttCallback);
    if (MQTT.connect((sn + "-" + sk).c_str(), NULL, NULL)) {
        Serial.println("Connected to MQTT Broker");
    } else {
        Serial.println("MQTT Broker connection failed");
        Serial.print(MQTT.state());
        delay(200);
    }
    MQTT.publish(("from-" + sn + "-" + sk).c_str(), "我他妈来啦!");
    MQTT.subscribe(("to-" + sn + "-" + sk).c_str());
}

void udpServerLoop() {
    int packetSize = Udp.parsePacket();
    if (packetSize) {
        Serial.printf("Received packet of size %d from %s:%d\n    (to %s:%d, free heap = %d B)\n",
                      packetSize,
                      Udp.remoteIP().toString().c_str(), Udp.remotePort(),
                      Udp.destinationIP().toString().c_str(), Udp.localPort(),
                      ESP.getFreeHeap());

        // read the packet into udpPacketBuffer
        int n = Udp.read(udpPacketBuffer, UDP_TX_PACKET_MAX_SIZE);
        udpPacketBuffer[n] = 0;
        Serial.println("Contents:");
        Serial.println(udpPacketBuffer);
        //验证是否为配置信息
        vkml.text = udpPacketBuffer;
        if (vkml.get("cmd") == "set") {
            ssid = vkml.get("ssid"), pwd = vkml.get("pwd"), sn = vkml.get("sn"), sk = vkml.get("sk");
            //回复ok
            Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
            Udp.write("201");
            Udp.endPacket();
            //打印信息
            Serial.println(ssid);
            Serial.println(pwd);
            Serial.println(sn);
            Serial.println(sk);
            //尝试连接
            Serial.println("正在尝试连接到WiFi");
            WiFi.begin(ssid.c_str(), pwd.c_str());
            int count = 0;
            while (WiFi.status() != WL_CONNECTED) {
                count++;
                if (count > 25) {
                    Serial.println("连接失败!");
                    //回复403
                    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
                    Udp.write("403");
                    Udp.endPacket();
                    return;
                }
                delay(500);
                Serial.print(F("."));
                if (digitalRead(16) == LOW) {
                    conf.set("status", "");
                    delay(1000);
                    Serial.println("设备已重置!");
                    resetFunc();
                }
            }
            //配置成功回复200
            Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
            Udp.write("200");
            Udp.endPacket();
            conf.set("status", "already");
            conf.set("ssid", ssid);
            conf.set("pwd", pwd);
            conf.set("sn", sn);
            conf.set("sk", sk);
            delay(1000);
            resetFunc();
        }
        // send a reply, to the IP address and port that sent us the packet we received

    }
}
热门文章
标签云
© 2021 Copyright 本站由 upyun 提供储存服务