tock.stdtime.gov.tw watch.stdtime.gov.tw time.stdtime.gov.tw clock.stdtime.gov.tw tick.stdtime.gov.tw
+MQTT Message Queuing Telemetry Transport
MQTT訊息傳遞原理
MQTT通訊為一對多的M2M傳輸,使用發佈(Publish)/訂閱(Subscribe)的訊息傳送機制,此機制中包含4個主要的元素,發佈者(Publisher)、訂閱者(Subscriber)、主題(Topic)、訊息中轉站(Broker)。Publisher為訊息的來源,傳送夾帶有Topic資訊的訊息至Broker,訂閱者向Broker註冊想要接受到之訊息的Topic,例如有一Publisher發佈一則Topic為”Test”的訊息,只要是有對Broker註冊Topic為”Test”的Subscriber都能接收到此訊息。
ESP8266 NodeMCU NTP (Network Time Protocol) Example
Hardware: NodeMCU Date: 2018
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
char ssid[] = "PTS-2F"; // your network SSID (name)
char pass[] = ""; // your network password
//Your UTC Time Zone Differance Taiwan +8:00
char HH = 8;
char MM = 0;
char hours, minutes, seconds;
unsigned int localPort = 2390; // local port to listen for UDP packets
/* Don't hardwire the IP address or we won't get the benefits of the pool.
* Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.stdtime.gov.tw"; //time.nist.gov";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
//=======================================================================
int ledPin = D0; // choose the pin for the LED
int relayInput = D1; // choose the pin for the relay
int inputPin = D2; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
int cnt=0;
//=======================================================================
const char* mqtt_server = "broker.mqttdashboard.com";
//const char* mqtt_server = "iot.eclipse.org";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//=======================================================================
void callback(char* topic, byte* payload, unsigned int length)
{
} //end callback
//=======================================================================
void reconnect() {
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
//if you MQTT broker has clientID,username and password
//please change following line to if (client.connect(clientId,userName,passWord))
if (client.connect(clientId.c_str()))
{
Serial.println("connected");
//once connected to MQTT broker, subscribe command if any
client.subscribe("alex9ufo_PIR_Command");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 6 seconds before retrying
delay(6000);
}
}
} //end reconnect()
//=======================================================================
// SETUP
//=======================================================================
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println();
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(relayInput, OUTPUT); // declare relay as output
digitalWrite(relayInput, HIGH);//assuming relay is off
// We start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setServer(mqtt_server, 1883);//the default mqqt port is 1883.
client.setCallback(callback);
Serial.println("Starting UDP");
udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(udp.localPort());
}
//=======================================================================
// send an NTP request to the time server at the given address
//=======================================================================
unsigned long sendNTPpacket(IPAddress& address)
{
Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}
//=======================================================================
// LOOP
//=======================================================================
void NTP_loop()
{
//char hours, minutes, seconds;
//get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
int cb = udp.parsePacket();
if (!cb) {
Serial.println("no packet yet");
}
else {
Serial.print("packet received, length=");
Serial.println(cb);
// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
minutes = ((epoch % 3600) / 60);
minutes = minutes + MM; //Add UTC Time Zone
hours = (epoch % 86400L) / 3600;
if(minutes > 59)
{
hours = hours + HH + 1; //Add UTC Time Zone
minutes = minutes - 60;
}
else
{
hours = hours + HH;
}
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print(hours,DEC); // print the hour (86400 equals secs per day)
Serial.print(':');
if ( minutes < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print(minutes,DEC); // print the minute (3600 equals secs per minute)
Serial.print(':');
seconds = (epoch % 60);
if ( seconds < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(seconds,DEC); // print the second
}
// wait ten seconds before asking for the time again
}
//=======================================================================
void loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
if (pirState == LOW) {
// we have just turned on
Serial.print("<");
Serial.print(String(cnt,DEC));
Serial.println(">. Motion detected!");
NTP_loop();
// We only want to print on the output change, not state
pirState = HIGH;
digitalWrite(relayInput, LOW); // The Relay Input works Inversly
Serial.print("Turn on the Lamp!");
Serial.println(".....Wait for 10 seconds");
delay(10000); // delay for 30 seconds
digitalWrite(relayInput, HIGH);// Relay input operation is positive
Serial.println("Turn off the Lamp!");
cnt++;
if (cnt >=9999)
cnt=0;
//=========================================================
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
//send data every 6 second
if (now - lastMsg > 500) {
lastMsg = now;
String msg="";
msg= msg+ String(hours,DEC) ;
msg= msg+ ":";
msg= msg+ String(minutes,DEC) ;
msg= msg+ ":";
msg= msg+ String(seconds,DEC);
msg= msg+ " <";
msg= msg + (String(cnt,DEC));
msg= msg +">. Motion detected!";
char message[58];
msg.toCharArray(message,58);
Serial.println(message);
//publish sensor data to MQTT broker
client.publish("alex9ufo_PIR_Data", message);
} //end (now - lastMsg > 500)
//=========================================================
}
}
else
{
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH)
{
// we have just turned of
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
}
//=======================================================================
沒有留言:
張貼留言