2024年4月23日 星期二

Wokwi ESP32 Simulator : ESP32 + NTP+MQTT+ Node-RED Dashboard

Wokwi ESP32 Simulator : ESP32 + NTP+MQTT+ Node-RED Dashboard 








Wokwi ESP32程式

// Learn about the ESP32 WiFi simulation in

// https://docs.wokwi.com/guides/esp32-wifi
/*
  Definition of struct tm:
  Member  Type  Meaning Range
  tm_sec  int seconds after the minute  0-61*
  tm_min  int minutes after the hour  0-59
  tm_hour int hours since midnight  0-23
  tm_mday int day of the month  1-31
  tm_mon  int months since January  0-11
  tm_year int years since 1900
  tm_wday int days since Sunday 0-6
  tm_yday int days since January 1  0-365
  tm_isdst  int Daylight Saving Time flag
*/
#include "time.h"
#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <PubSubClient.h>

LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);

#define NTP_SERVER     "pool.ntp.org"
#define UTC_OFFSET     28800  // 3600*8 = 28800
#define UTC_OFFSET_DST 0

unsigned long lastMsg = 0;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

String Time1="";
char jsonChar1[50];
char jsonChar2[50];

void spinner() {
  static int8_t counter = 0;
  const char* glyphs = "\xa1\xa5\xdb";
  LCD.setCursor(15, 1);
  LCD.print(glyphs[counter++]);
  if (counter == strlen(glyphs)) {
    counter = 0;
  }
}

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    LCD.setCursor(0, 1);
    LCD.println("Connection Err");
    return;
  }

  LCD.setCursor(8, 0);
  LCD.println(&timeinfo, "%H:%M:%S");

  LCD.setCursor(0, 1);
  LCD.println(&timeinfo, "%d/%m/%Y   %Z");
}

void printLocalTime2(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

  int current_hour = timeinfo.tm_hour;
  int current_min = timeinfo.tm_min;
  int current_sec = timeinfo.tm_sec;
  Time1 = String (current_hour)+":"+ String (current_min)+":"+ String (current_sec);
  Serial.println(Time1);
  int current_year = 1900+ timeinfo.tm_year;
  int current_mon = timeinfo.tm_mon;
  int current_mday = timeinfo.tm_mday;
  Time1 = Time1 + " " + String (current_year)+"/"+ String (current_mon)+"/"+ String (current_mday);
  Serial.println(Time1);
 

  Serial.print("Day of week: ");
  Serial.println(&timeinfo, "%A");
  Serial.print("Month: ");
  Serial.println(&timeinfo, "%B");
  Serial.print("Day of Month: ");
  Serial.println(&timeinfo, "%d");
  Serial.print("Year: ");
  Serial.println(&timeinfo, "%Y");
  Serial.print("Hour: ");
  Serial.println(&timeinfo, "%H");
  Serial.print("Hour (12 hour format): ");
  Serial.println(&timeinfo, "%I");
  Serial.print("Minute: ");
  Serial.println(&timeinfo, "%M");
  Serial.print("Second: ");
  Serial.println(&timeinfo, "%S");

  Serial.println("Time variables");
  char timeHour[3];
  strftime(timeHour,3, "%H", &timeinfo);
  Serial.println(timeHour);
  char timeWeekDay[10];
  strftime(timeWeekDay,10, "%A", &timeinfo);
  Serial.println(timeWeekDay);
  Serial.println();
}

void callback(char* topic, byte* payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i = 0; i < length; i++) {
   Serial.print((char)payload[i]);
 }}

void reconnect() {
 while (!client.connected()) {
   Serial.print("Attempting MQTT connection...");
   String clientId = "ESP32Client-";
   clientId += String(random(0xffff), HEX);
   if (client.connect(clientId.c_str())) {
     Serial.println("Connected");
     client.publish("alex9ufo/ThinkIOT/Publish", "Welcome");
     client.subscribe("alex9ufo/ThinkIOT/Subscribe");
   } else {
     Serial.print("failed, rc=");
     Serial.print(client.state());
     Serial.println(" try again in 5 seconds");
     delay(5000);
   }}
}

void setup_wifi() {
 delay(10);
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);


 WiFi.mode(WIFI_STA);
 WiFi.begin(ssid, password);


 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());
}
void setup() {
  Serial.begin(115200);

  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
 
  LCD.init();
  LCD.backlight();
  LCD.setCursor(0, 0);
  LCD.print("Connecting to ");
  LCD.setCursor(0, 1);
  LCD.print("WiFi ");

  WiFi.begin("Wokwi-GUEST", "", 6);
  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    spinner();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  LCD.clear();
  LCD.setCursor(0, 0);
  LCD.println("Online");
  LCD.setCursor(0, 1);
  LCD.println("Updating time...");

  configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
}

void loop() {
  printLocalTime();
  delay(250);

 if (!client.connected()) {
   reconnect();
 }
 client.loop();

 unsigned long now = millis();
 if (now - lastMsg > 12000) {
   printLocalTime2();
   lastMsg = now;
   Time1.toCharArray(jsonChar1, Time1.length()+1);
 
   client.publish("alex9ufo/ThinkIOT/NTPTime1", jsonChar1);

 }

}

WOKWI diagram.json

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "board-esp32-devkit-c-v4", "id": "esp", "top": -76.8, "left": 43.24, "attrs": {} },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": -70.4,
      "left": 236,
      "attrs": { "pins": "i2c" }
    }
  ],
  "connections": [
    [ "esp:TX", "$serialMonitor:RX", "", [] ],
    [ "esp:RX", "$serialMonitor:TX", "", [] ],
    [ "lcd1:SDA", "esp:21", "green", [ "v-4.49", "h-28.8", "v23.89" ] ],
    [ "lcd1:GND", "esp:GND.2", "black", [ "h-16.67", "v162.78" ] ],
    [ "lcd1:VCC", "esp:3V3", "red", [ "h-9.6", "v-57.5", "h-134.55" ] ],
    [ "lcd1:SCL", "esp:22", "purple", [ "h-19.2", "v-18.9" ] ]
  ],
  "dependencies": {}
}

Node-Red 程式

[ { "id": "9741629b8510891f", "type": "mqtt in", "z": "2ded2ffb8cb68caa", "name": "", "topic": "alex9ufo/ThinkIOT/NTPTime1", "qos": "1", "datatype": "auto-detect", "broker": "603bb104.d6134", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 200, "y": 300, "wires": [ [ "70f6524c6b60447d" ] ] }, { "id": "70f6524c6b60447d", "type": "ui_text", "z": "2ded2ffb8cb68caa", "group": "ed796d698b021723", "order": 2, "width": 0, "height": 0, "name": "", "label": "收到 NTP的訊息", "format": "{{msg.payload}}", "layout": "row-spread", "className": "", "x": 460, "y": 300, "wires": [] }, { "id": "603bb104.d6134", "type": "mqtt-broker", "name": "", "broker": "broker.mqtt-dashboard.com", "port": "1883", "clientid": "", "autoConnect": true, "usetls": false, "compatmode": false, "protocolVersion": "4", "keepalive": "15", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "ed796d698b021723", "type": "ui_group", "name": "NTP_Time", "tab": "b83c5c221c74411b", "order": 2, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "b83c5c221c74411b", "type": "ui_tab", "name": "Wokwi", "icon": "dashboard", "order": 121, "disabled": false, "hidden": false } ]


沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...