msg.query = "select mean(temp) as temp, mean(humd) as humd from studioTemp where location='studio' and time > now() - ";
msg.query += flow.get("hours") + "h GROUP by time(" + flow.get("interval") + "m) FILL(0)";
return msg;
Format DB data 程式碼(B):
var My_series = ["Temperature °C", "Humidity %"];
var My_labels = ["temp", "Humd"];
var data = msg.payload;
// var data = msg.payload;
// Not sure the same query produced differnet results...?
temp = data.map(point=> {return {x:point.time , y:point.temp.toFixed(2)}});
humd = data.map(point=> {return {x:point.time , y:point.humd.toFixed(2)}});
var My_data = [temp, humd];
msg.payload = [{ series: My_series, data: My_data, labels: My_labels}]
return msg;
// Create the object key to match DB filed name from topic name(studio/temp1)
msg.payload["temp"] = msg.payload["studio/temp1"];
// Delete the unwanted studio/temp1
delete msg.payload["studio/temp1"];
// Update temp from string to float
msg.payload["temp"] = parseFloat(msg.payload["temp"]);
msg.payload["humd"] = msg.payload["studio/humd1"];
delete msg.payload["studio/humd1"];
msg.payload["humd"] = parseFloat(msg.payload["humd"]);
//remove unused topic
delete msg.topic;
//Create a temporary array
var data = [];
data.push(msg.payload);
//Add object to DB Tag(index field)
data.push({"location":"studio"});
//msg.payload.push({"location":"studio"});
//Copy temporary array to msg.payload
msg.payload = data;
return msg;
Format code for reading historical InfluxDB data
//Source from: https://discourse.nodered.org/t/display-2-extracts-from-influxdb-in-an-ui-chart/29665
var series = ["Temperature °C", "Humdity %"];
var labels = ["temp", "Humdity"];
var data0 = "[";
var thetime0;
for (var i=0; i < msg.payload.results[0].series[0].values.length; i++) {
thetime0 = (msg.payload.results[0].series[0].values[i][0]); // Some manipulation of the time may be required
thetime0 = Date.parse(thetime0);
data0 += '{ "x":' + thetime0 + ', "y":' + (msg.payload.results[0].series[0].values[i][1]) + '}';
if (i < (msg.payload.results[0].series[0].values.length - 1)) {
data0 += ","
} else {
data0 += "]"
}
}
var data1 = "[";
var thetime1;
for (var j=0; j < msg.payload.results[0].series[0].values.length; j++) {
thetime1 = (msg.payload.results[0].series[0].values[j][0]); // Some manipulation of the time may be required
thetime1 = Date.parse(thetime1);
data1 += '{ "x":' + thetime1 + ', "y":' + (msg.payload.results[0].series[0].values[j][2]) + '}';
if (j < (msg.payload.results[0].series[0].values.length - 1)) {
data1 += ","
} else {
data1 += "]"
}
}
var data = [data0, data1];
var jsondata = [JSON.parse(data0), JSON.parse(data1)];
msg.payload = [{"series": series, "data": jsondata, "labels": labels}];
msg.dataPoints = data;
return msg;
//---- Setup update frequency -----//
const long TEMP_updateInterval = 10000; // How long to change temp and update, 10000 = 10 sec
unsigned long TEMP_currentMillis = 0;
unsigned long TEMP_previousMillis = 0; // store last time temp update
#include "DHT.h"
#define DHTPIN 23 //ESP32 pin 23
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor
/*
SimpleMQTTClient.ino
The purpose of this exemple is to illustrate a simple handling of MQTT and Wifi connection.
Once it connects successfully to a Wifi network and a MQTT broker, it subscribe to a topic and send a message to it.
It will also send a message delayed 5 seconds later.
*/
#include "EspMQTTClient.h"
EspMQTTClient client(
"Your_WiFi_AP", // Wi-Fi AP name
"Wi-FI_Password", // Wi-Fi Password
"192.168.0.119", // MQTT Broker server ip
"", // Broker user name; Can be omitted if not needed
"", // Broker password; Can be omitted if not needed
"ESP32_Client", // Client name that uniquely identify your device
1883 // The MQTT port, default to 1883. this line can be omitted
);
void setup()
{
Serial.begin(115200);
//Start DH11 sensor
dht.begin();
// Optionnal functionnalities of EspMQTTClient :
client.enableDebuggingMessages(); // Enable debugging messages sent to serial output
//client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password").
//client.enableLastWillMessage("TestClient/lastwill", "I am going offline"); // You can activate the retain flag by setting the third parameter to true
}
// This function is called once everything is connected (Wifi and MQTT)
// WARNING : YOU MUST IMPLEMENT IT IF YOU USE EspMQTTClient
void onConnectionEstablished()
{
// Subscribe to "mytopic/test" and display received message to Serial
client.subscribe("message/hello", [](const String &payload)
{ Serial.println(payload); });
// Subscribe to "mytopic/wildcardtest/#" and display received message to Serial
//client.subscribe("mytopic/wildcardtest/#", [](const String &topic, const String &payload)
// { Serial.println("(From wildcard) topic: " + topic + ", payload: " + payload); });
// Publish a message to "mytopic/test"
client.publish("studio/temp1", "Let's go!"); // You can activate the retain flag by setting the third parameter to true
// Execute delayed instructions
//client.executeDelayed(5 * 1000, []()
// { client.publish("mytopic/wildcardtest/test123", "This is a message sent 5 seconds later"); });
}
void loop()
{
TEMP_currentMillis = millis();
if(TEMP_currentMillis - TEMP_previousMillis >= TEMP_updateInterval){
TEMP_previousMillis = TEMP_currentMillis;
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float humidity = dht.readHumidity();
float temperature = 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(humidity) || isnan(temperature))
{
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
String tmp = "Current Temperature: ";
String hud = "Current Humidity: ";
Serial.print(tmp);
Serial.println(String(temperature));
Serial.print(hud);
Serial.println(String(humidity));
//Publish
client.publish("studio/temp1", String(temperature));
client.publish("studio/humd1", String(humidity));
// Here is how to subscribe
//client.subscribe("message/hello", [](const String &payload) { Serial.println(payload); });
}
client.loop();
}
*** 影片中忘了說明, 在 VS Code 裡, 按下 F1 到 Arduino Library Manager 裡,
搜尋 EspMQTTClient V.11.1版本, 並按下安裝 , 程式才能正確執行喔~~ ***
In order to use the newly purchased 0.96" OLED SD1306 display, I studied the u8g2 library and made this video to share with you on how to use U8g2 library with monochrome display. In the video, I also included a section on how to use the free 5000+ traditional Chinese font created by Mr. Yang. The file is free for anyone to use. Really appreciated what he did for Arduino community!
For those who do not have time to watch the entire video , here is the video timeline.
Video Timeline:
00:22 Install u8g2
01:04 Open PrintUTF8 example
02:00 Define display used
02:23 Explain display naming rules
04:13 Uncomment the line selected
04:33 Explain the code
04:42 enableUTF8Print() for symbol and Chinese
05:14 u8g2 supported font list06:23 display location setCursor(X,Y)
07:05 Upload the sketch & show characters
07:23 Can't overwrite characters!
08:08 Char overwrite solution
08:37 OledOverlayPrint() function
09:06 Use OledOverlayPrint() in code
10:08 Use Open Iconic Fonts
11:29 Display cloud symbol
11:52 \u with number to show cloud
13:02 Change fonts for different lines
14:34 Download 5000+ Chinese font
15:11 Install 5000+Chinese font
15:39 Test missing fonts again
16:42 Reminder of memory usage
17:45 End of tutorial
Recently, I acquired an ESP32-CAM Wi-Fi + Bluetooth + OV2640 camera module. My first intent was to learn how to use new Arduino ESP32 compatible modules. Then, I quickly found out with ESP3D that I could use ESP32-CAM to monitor and control my Ender 3 Pro 3D printer remotely, what a bonus!
This is my personal notebook and you are welcome to follow along and hope it might actually help!
Goal for this post
Config ESP32-CAM to use it as a web server to stream videos.
Long term goal is to use ESP32-CAM and ESP3D to make a 3D printer remote monitoring device.
ESP32-CAM Spec
ESP32 32bit dual core 600 DIMPS
520KB SRAM + 4MB PSRAM
I/O: UART, SPI, I2C, PWM
MicroSD: Up to 4GB
Baud Rate: Default 115200 bps
Photo format: JPEG( OV2640 only), BMP, GRAYSCALE
Wi-Fi: 802.11 b/g/n/d/e/i/k/r
Bluetooth: V4.2 BR/EDR and BLE
Power: 5V/2A
Built-in flash light
Camera module: OV2640, 200 Mega pixels
Schematic
Since there is no USB on ESP32, I use a CP210x USB to UART bridge to upload.
Or, you can use a FTDI USB to UART bridge to upload sketches.
IMPORTANT NOTICE:
Enable ESP32 upload mode: Connect ESP32 IO0 to GND
ESP32 Normal operation mode: Remove ESP32 IO0 to GND connection
Power: must connect ESP32 VCC (5V) to VCC
Wiring:
ESP32 GND <-> ESP32 IO0 (Upload only, remove for normal operation)->
ESP32 GND <-> CP210x GND->
ESP32 VCC(5V) <-> CP210x VCC->
ESP32 U0R <-> CP210x TXD->
ESP32 U0T <-> CP210x RXD->
Then, connect
Camera module to ESP32-CAM
Then, plug CP210x dongle to PC USB port
Download Arduino IDE version greater than V1.8.9
Version 1.8.9 or above is required for ESP32-CAM. Please visit Arduino official website to download the version, if needed.
After installation follow the steps below:
1. Click File -> Preferences
2. Click the small square at end of Additional Boards Manager URL:
This URL allows Arduino IDE to download ESP32 package. If you had two URLs, separate them with a ',' common. Click OK to exit. Usually, the first one is for ESP8266 related package.
3. Select Boards Manager to install ESP32 library
4. Type 'ESP32' in the search box and hit enter
Board manager will start to search ESP32 library. When 'esp32 by Espressif Systems' is found, click Install.
5. Wait till the installing process finish
6. Click 'Close' when ESP32 package is INSTALLED
7. From Arduino IDE, Tools, select Board, and select "ESP32 Wrover Module"
Also, change Upload Speed to "115200", the ESP32 default baud rate. (No screenshot shown here)
8. From Tools, select Partition Scheme, select Huge APP (3MP No OTA/1MB SPIFFS)
Due to ESP32-CAM sketch size is quite large, select this item is necessary to keep program memory at it's maximum for ESP32
By now, Arduino IDE setting is completed.
9. (Optional) Only needed if you do not have FTDI/CP210x USB drivers in PC/Mac
Change baud rate to 115200 to match default ESP32 baud rate setting
11. Load a sketch from File->Examples->WiFi->WiFiScan
Load WiFiScan sketch to ensure the hardware and software /IDE settings are correct.
12. Upload the sketch
Just click the small arrow circled below to upload to ESP32
If you encountered ERROR: Upload failed: "Timed out waiting for packet header"
CAUSE: This error indicates ESP32 IO0 didn't connect to GND. This connection is needed enable ESP32 upload mode.
Push reset button: when you see ....._____....._____.....____
After the connection made from ESP32 IO0 to GND and the uploading worked.
Message window shows "Writing at .......100%" indicates the upload completed!
13. Check out serial monitor for messages
In this step, ESP32 will scan available AP nearby and show them in the monitor.
If you encountered ERROR: "waiting for download" message! This error indicates that you need to remove ESP32 IO0 Pin to GND pin (Mentioned above that this connection must be removed for ESP32 to work properly!)
After remove the connection, and push reset, ESP32 found few Wi-Fi AP nearby
14. Load CameraWebServer sketch
It's time to test out the ESP32 web server and stream videos
From "File"->"Examples"->"ESP32"->"Camera"->CameraWebServer
15. Change Wi-Fi AP SSID and Password to match your own Wi-FI SSID/Password
16. Change the camera model to AI_THINKER
The camera module is the in the package came with ESP32. So I selected the default "AI_THINKER"
17. Get web server IP address
If everything goes well, the camera IP address would show on the serial monitor
Copy the IP address shown
18. Open a browser and type the IP address specified above
The screen below shows ESP32 web server is running successfully
Select the resolution on the top
Click Start Stream and the video will show on the right hand side
19. Real-time camera video stream in browser
If you like, you could change the resolution and play around many OV2640 parameters.
For the resolution, the larger the resolution, the fewer the frame rates.
If you encountered ERROR message "Brownout detector was triggered", many articles indicated causes could be:
Poor quality USB cable
USB cable is too long
Or not enough power to USB port
After I changed to dedicated USB port to connect ESP32, the video came back alright and running for a while without the error messages.
What's Next
After 2-3 hours, the config/setting on ESP32 was done. Next step is to install ESP3D to remote monitoring my 3D printer. Until next time, see you!