Jump to content
Electronics-Lab.com Community

Akshayan Sinha

Members
  • Posts

    5
  • Joined

  • Last visited

1 Follower

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Akshayan Sinha's Achievements

  1. Have you watched the movie 'Project Almanac'? Which was released in the year 2015. If not, then let me brief you a scene about it. In the movie, the main character wishes to get into MIT and therefore, builds a project for his portfolio. The project was about a drone, that could be controlled using a 2.4GHz remote controller, but when the software application on the laptop was run, the main character was seen controlling the drone with his hands in the air! The software application used a webcam to track the the movement of the character's hand movements. Custom PCB on your Way! Modern methods of development 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 little delivery time Get a 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 them printed in a few steps! Getting Started As we already saw, this technology was well displayed in the movie scene. And the best part is, in 2023 it is super easy to rebuild it with great tools like OpenCV and MediaPipe. We will control a machine but with a small change in the method, than the one the character uses to let the camera scan his fingers. He used color blob stickers on his fingertips so that the camera could detect those blobs. When there was a movement in the hands, which was visible from the camera, the laptop sent the signal to the drone to move accordingly. This allowed him to control the drone without any physical console. Using the latest technological upgrades, we shall make a similar, but much simpler version, which can run on any embedded Linux system, making it portable even for an Android system. Using OpenCV and MediaPipe, let us see how we can control our 2wheeled battery-operated car, over a Wi-Fi network with our hands in the air! OpenCV and MediaPipe OpenCV is an open-source computer vision library primarily designed for image and video analysis. It provides a rich set of tools and functions that enable computers to process and understand visual data. Here are some technical aspects. Image Processing: OpenCV offers a wide range of fuctions for image processing tasks such as filtering, enhancing, and manipulating images. It can perform operations like blurring, sharpening, and edge detection. Object Detection: OpenCV includes pre-trained models for object detection, allowing it to identify and locate objects within images or video streams. Techniques like Haar cascades and deep learning-based models are available. Feature Extraction: It can extract features from images, such as keypoints and descriptors, which are useful for tasks like image matching and recognition. Video Analysis: OpenCV enables video analysis, including motion tracking, background subtraction, and optical flow. MediaPipe is an open-source framework developed by Google that provides tools and building blocks for building various types of real-time multimedia applications, particularly those related to computer vision and machine learning. It's designed to make it easier for developers to create applications that can process and understand video and camera inputs. Here's a breakdown of what MediaPipe does: Real-Time Processing: MediaPipe specializes in processing video and camera feeds in real-time. It's capable of handling live video streams from sources like webcams and mobile cameras. Cross-Platform: MediaPipe is designed to work across different platforms, including desktop, mobile, and embedded devices. This makes it versatile and suitable for a wide range of applications. Machine Learning Integration: MediaPipe seamlessly integrates with machine learning models, including TensorFlow Lite, which allows developers to incorporate deep learning capabilities into their applications. For example, you can use it to build applications that recognize gestures, detect facial expressions, or estimate the body's pose. Efficient and Optimized: MediaPipe is optimized for performance, making it suitable for real-time applications on resource-constrained devices. It takes advantage of hardware acceleration, such as GPU processing, to ensure smooth and efficient video processing. From above if you have noticed, this project will require one feature from each of these tools, to be able to make our project work. Video Analysis from OpenCV and HandTracking from MediaPipe. Let us begin with the environment to be able to work seamlessly. Below is the complete architecture of this project - Hand Tracking and Camera Frame UI As we move ahead, we need to know how to use OpenCV and Mediapipe to detect hands. For this part, we shall use the Python library. Make sure you have Python installed on the laptop, and please run below command to install the necessary libraries - Run the command to install the libraries - python -m pip install opencv-python mediapipe requests numpy To begin with the the control of car from the camera, let us understand how it will function - The camera must track the hands or fingers to control the movement of the car. We shall track the index finger on the camera for that. Based on the location of finger with reference to the given frame, there will be forward, backward, left, right and stop motion for the robot to function. While all the movements are tracked on real time, the interface program should send data while reading asynchronously. To perform the above task in simple steps, methods used in the program have been simplified in beginner's level. Below is the final version! As we see above, the interface is very simple and easy to use. Just move your index finger tip around, and use the frame as a console to control the robot. Read till the end and build along to watch it in action! Code - Software Now that we know what the software UI would look like, let us begin to understand the UI and use HTTP request to send signal to the car to make actions accordingly. Initializing MediaPipe Hands mp_hands = mp.solutions.hands hands = mp_hands.Hands() mp_drawing = mp.solutions.drawing_utils Here, we initialize the MediaPipe Hands module for hand tracking. We create instances of mp.solutions.hands and mp.solutions.drawing_utils, which provide functions for hand detection and visualization. Initializing Variables tracking = False hand_y = 0 hand_x = 0 prev_dir = "" URL = "http://projectalmanac.local/" In this step, we initialize several variables that will be used to keep track of hand-related information and the previous direction. A URL is defined to send HTTP requests to the hardware code of ca Defining a Function to Send HTTP Requests def send(link): try: response = requests.get(link) print("Response ->", response) except Exception as e: print(f"Error sending HTTP request: {e}") This step defines a function named send that takes a link as an argument and sends an HTTP GET request to the specified URL. It prints the response or an error message if the request fails. These are the initial setup steps. The following steps are part of the main loop where video frames are processed for hand tracking and gesture recognition. I'll explain these steps one by one: MediaPipe Hands Processing ret, frame = cap.read() frame = cv2.flip(frame, 1) rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = hands.process(rgb_frame) Inside the loop, it captures a frame from the camera (cap.read()) and flips it horizontally (cv2.flip) to mirror the image. The code converts the captured frame to RGB format (cv2.cvtColor) and then uses the MediaPipe Hands module to process the frame (hands.process) for hand landmark detection. The results are stored in the results variable. Hand Landmarks and Tracking if results.multi_hand_landmarks: hand_landmarks = results.multi_hand_landmarks[0] index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP] hand_y = int(index_finger_tip.y * height) hand_x = int(index_finger_tip.x * width) tracking = True This section checks if hand landmarks are detected in the frame (results.multi_hand_landmarks). If so, it assumes there's only one hand in the frame and extracts the y-coordinate of the index finger tip. It updates hand_y and hand_x with the calculated coordinates and sets tracking to True. Direction Calculation frame_center = (width // 2, height // 2) if trackin direction = find_direction(frame, hand_y, hand_x, frame_center) if(direction != prev_dir): try: link = URL+direction http_thread = threading.Thread(target=send, args=(link,)) http_thread.start() except Exception as e: print(e) prev_dir = direction print(direction) In this step, the code calculates the center of the frame and, if tracking is active, it uses the find_direction function to calculate the direction based on the hand's position. The direction is stored in the direction variable. We used current direction and previous direction variables. It helps in keeping a semaphore of sending only one HTTP request for every change in command. Then overall store it in a single URL to send the HTTP request. Visualization opacity = 0.8 cv2.addWeighted(black_background, opacity, frame, 1 - opacity, 0, frame) cv2.imshow("Project Almanac", frame) If tracking is active, this section of the code adds visual elements to the frame, including a filled circle representing the index finger tip's position and text indicating the detected direction. The code blends a black background with the original frame to create an overlay with adjusted opacity. The resulting frame is displayed in a window named "Project Almanac". Code - Hardware Now that we are done with the software side code, let us look into the software side code - Importing Libraries: #include <WiFi.h> #include <ESPmDNS.h> #include <WebServer.h> In this section, the code includes necessary libraries for WiFi communication (WiFi.h), setting up mDNS (ESPmDNS) for local network naming, and creating a web server using the WebServer library. Defining Pin Constants: int LeftA = 33; // IN1 int LeftB = 25; // IN2 int RightA = 26; // IN3 int RightB = 27; // IN4 Here, the code defines constants for pin numbers corresponding to motor control pins (presumably for a robotic project). These pins will control the movement of motors. Setting Up Wi-Fi Credentials: const char* ssid = " "; // Enter SSID here const char* password = " "; // Enter Password here You need to fill in your Wi-Fi network's SSID and password here to connect the ESP8266 device to your local Wi-Fi network. Configuring Motor Control Pins: pinMode(LeftA, OUTPUT); pinMode(LeftB, OUTPUT); pinMode(RightA, OUTPUT); pinMode(RightB, OUTPUT); pinMode(2, OUTPUT); In this part, the code sets the motor control pins (LeftA, LeftB, RightA, RightB) as OUTPUT pins, presumably to control motors for a robotic project. It also sets pin 2 as an OUTPUT, possibly for controlling an indicator LED. Connecting to Wi-Fi: Serial.begin(115200); delay(100); Serial.println("Connecting to "); Serial.println(ssid); // Connect to your local Wi-Fi network WiFi.begin(ssid, password); // Check if the device is connected to the Wi-Fi network while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } // Display connection status and IP address Serial.println(""); Serial.println("WiFi connected..!"); Serial.print("Got IP: "); Serial.println(WiFi.localIP()); digitalWrite(2, HIGH); // Turn on a blue LED to indicate a connected WiFi This part of the code initiates a connection to the specified Wi-Fi network using the provided SSID and password. It waits until the device successfully connects to the Wi-Fi network and then displays the IP address. Additionally, it turns on an LED on pin 2 to indicate a successful connection. Setting up mDNS (Multicast DNS): if (!MDNS.begin("projectalmanac")) { Serial.println("Error setting up MDNS responder!"); while(1) { delay(1000); } } Serial.println("mDNS responder started"); Here, the code sets up mDNS with the hostname "projectalmanac." This allows the device to be reachable on the local network using the hostname instead of an IP address. Defining HTTP Server Endpoints: server.on("/", handle_OnConnect); server.on("/left", left); server.on("/right", right); server.on("/forward", forward); server.on("/backward", backward); server.on("/stop", halt); server.onNotFound(handle_NotFound); This part defines different HTTP server endpoints that can be accessed via URLs. For example, "/left" will trigger the left function when accessed. Starting the Web Server: server.begin(); Serial.println("HTTP server started"); MDNS.addService("http", "tcp", 80); } The code starts the web server, making it available for handling HTTP requests on port 80. It also registers the HTTP service with mDNS. Handling Client Requests: void loop() { server.handleClient(); } In the loop function, the server continuously handles client requests, responding to various endpoints defined earlier. HTTP Request Handling Functions:The code defines several functions (forward, backward, left, right, halt, handle_OnConnect, handle_NotFound) that are called when specific endpoints are accessed. These functions are responsible for controlling motors and responding to client requests. The HTML page provides information about available commands and instructions for interacting with the device. Project Almanac in action! Now that we have understood the code sequence, let us see the work! We can further add more features if you'd like to. Rest, the UI is simple enough to handle, which comes with not many features, but important one's. cameracontroller_on_python.py carfirmware.cpp
  2. 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
  3. In 2022, over 1 million theft cases, which is a 7% rise compared to 2021, have become a great concern in India. With a population of more than 1.4 billion, you never know whom to trust apart from your own self. Hence, we are left with only one solution - Track Your Belongings With the increased availability of devices to access the internet, we all need an automated system, that keeps us updated on our physical product and informs us if it has been moved from its designated location. But, how do we track them? And how should one get an alert of a theft? We shall see and build a project on that. What is a Virtual Fence? A Fence is a physical boundary, which is used to restrict kids and dogs from exiting the border Boundaries provide a layer of security, which also restricts entry from outside. But these boundaries need to be maintained heavily. And once an object has moved out or stolen, then the theft cannot be further located. This brings us to a solution, which is geofencing a physical device attached to our belonging. This belonging would be a mere part of the IoT - Internet of 'Things'. The above pictorial is a sample of Geofence in a public area. Best part? Since it is on a virtual map, having a virtual fence would have no effect on whether you own the area. This area could be your Home, Office, favorite Coffee Shop, or even parlor. But before we get started - 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. Cellular + GPS To be able to have global connectivity and uninterrupted internet, the ideal network protocol is cellular technology. With a GPS Module attached to it, it is just perfect. This amazing combination can only be carried by an integrated device. And at the cheapest, we considered SIM808 Module+GPS as the primary module to continue with this project. Let us look more into its features and specifications - SIM808 GSM : Supports Quad-band 850/900/1800/1900MHz, compatible with all 2G networks all around the world. Inner MT3337 GPS receiver, -165dBm precision, control on a same serial port. Earphone/ microphone outputs on a card or external 32-ohm speaker + supports voice calls with an electret microphone. Sending and receiving SMS. Sending and receiving GPRS data (TCP/IP, HTTP vb). UART communication with automatic baud rate settings. GPRS multi-slot class 12/10 GPRS mobile station class B Comply with GSM phase 2/2 +Class 4 (2 W @ 850 / 900MHz)Class 1 (1 W @ 1800 / 1900MHz) Support low power consumption mode: 100mA @ 7V-GSM mode Support AT command control (3GPP TS 27.007, 27.005 and SIMCOM enhanced AT Commands) Supports GPS satellite navigation technology Support LED status indicator: Power supply status, network status, and operating modes Working environment: -40 ℃ ~ 85 ℃ SIM808 GPS : 22 tracking/66 acquisition channel GPS L1 C/A code Precision: Tracking: -165dBm, Cold start: -148dBm Finding Location Time(typical): Cold start: 32sn, Hot start: 1sn, Warm start: 5sn Accuracy: ~2.5m With all these features, it is nearly a handheld portable phone. Yes, you can make a phone call too One grieving concern is, whether going ahead with a smaller size module would fit the portability requirements - Even if a SIM800 module was taken into consideration, for a prolonged secure network that requires more uptime it is a much safer option to go ahead with its successor. Hence, the SIM808 module was chosen for this project. Even though based on availability and price we can always go ahead with the SIM800. Let us first understand the module and how to get started with a SIM module - Prologue: We'll use Arduino UNO to use it as a USB TTL device and send AT commands to SIM808 x module to test the working of the module using PUTTY or Arduino IDE’s Serial Monitor. Hardware Side - 1. Make following connections > GND of both modules connected to each other. 2. (For PuTTY) TXD of SIM808 connect with TX1 (PIN 1) of Arduino UNO. Similarly RXD ->RX0. 3. (For Arduino) TXD of SIM808 connect with (PIN 10) of Arduino UNO. Similarly RXD ->11. 4. Connect the Arduino UNO to Arduino IDE and upload a default code that does not interface the serial monitor. Eg: Blink LED sketch.5. Press Normal button for 2 seconds and leave - the Device will start after that. (Different from power sliding switch) Software side (PuTTy) - 1. Install PuTTY Application software from https://www.putty.org/ 2. Change 'Connection Type' to 'Serial'. 3. Enter Serial port on PuTTY. eg: COM8 > With baudrate as '9600'. 4. Click on 'Open' to open the serial terminal Software side (Arduino IDE) - 1. Use the below code - #include <SoftwareSerial.h> SoftwareSerial mySerial(10, 11); void setup() { Serial.begin(9600); mySerial.begin(9600); } void loop() { Serial.println("AT"); if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available()) { mySerial.write(Serial.read()); } delay(500); } Testing Commands - AT - Check serial communication with module | if no response recheck connections / redo connections / loose connection /module turned off AT+CMEE=1 - 1 to disable error &the 2 for verbose errors with error codes AT+CPIN? - Check SIM availability with module #Make Phone Calls ATD9989758468; - Phone calls to the number - use Mic and Speaker jack for i/o ATH - End phone call ATA - Pick up phone call when serial monitor says ‘RING’ repeatedly AT+CLCC - Check caller number #Make TextMessages AT+CSMP=17, 167, 0, 0 - Avoid error messages or delivery of empty SMS AT+CMGF=1 - Text Mode AT+CMGS="+917002834895" - Send message to this number> Enter your message> //After pressing 'Enter' move to next line or/and Press Ctrl+Z to send the message AT+CMGS: 55 - Responses with the packet command after a few seconds to show that message was delivered. AT+CMGL="ALL” - Read all messages #For GPS Coordinates (GNS because using v2.0 of SIM808) AT+CGNSPWR= 1 - Turn on GPS module - use 0 to turn OFF AT+CGNSSEQ="RMC" - Proper sequence of NMEA according to RMC AT+CGNSINF - Prints Time and GPS according to module - returns 0 if GPS not set. Returns 1 when outdoors for setting with GPS satellite Now that we know how to use the device, let us understand the logic on preparing a virtual fence, and how to use the Arduino to perform this logic - Code Breakdown 1. Communication between Arduino & SIM808 #include <SoftwareSerial.h> SoftwareSerial mySerial(5, 6); It sets up a SoftwareSerial instance named mySerial using digital pins 5 (RX) and 6 (TX) on the Arduino, which will be used to communicate with the SIM808 module. 2. Function Prototypes and Global Variables void(* resetFunc) (void) = 0; void GPS_data(); void check_GPS(); void sendSMS(); char frame[256]; byte GNSSrunstatus; byte Fixstatus; char UTCdatetime[15]; char latitude[10]; float latitude_val; char longitude[11]; float longitude_val; long lat_val; long lon_val; long lat_high; long lat_low; long lon_high; long lon_low; int lat_check; int lon_check; char altitude[8]; char speedOTG[6]; char course[6]; char fixmode[1]; char HDOP[4]; char PDOP[4]; char VDOP[4]; char satellitesinview[2]; char GNSSsatellitesused[2]; char GLONASSsatellitesused[2]; char cn0max[2]; char HPA[6]; char VPA[6]; Pre-declaration of Functions without function body, to inform the program about the existence of function, before defining, so as to manipulate the arrangement within the program. Global variables like altitude, speedOTG are to be used within the program, and since the device will run indefinitely, the values are most likely to get reset on setting up new locations as Geo-Fencing 3. Initialization of Arduino with Cellular Device void setup() { Serial.begin(9600); mySerial.begin(9600); mySerial.println("AT\r"); updateSerial(); mySerial.println("AT+CSQ"); updateSerial(); mySerial.println("AT+CCID"); updateSerial(); mySerial.println("AT+CPIN?"); updateSerial(); GPS_data(); lat_high = lat_val + 900; lat_low = lat_val - 900; lon_high = lon_val + 900; lon_low = lon_val - 900; } AT+CSQ- Returns the signal strength of the device. AT+CCID - Read SIM information, which returns the unique Integrated Circuit Card Identifier (ICCID) of the installed SIM card. AT+CPIN - Checks if the SIM is locked with a PUK code, or whether it is ready to use. Calling GPS_data() function to initialize the current location, as the center of the Geo-Fence Next, set the fence around the center by selecting coordinates values with 300m-500m towards lat and long. 4. Hardware-Software Serial Interconnection void updateSerial() { delay(500); while (Serial.available()) { mySerial.write(Serial.read()); } while(mySerial.available()) { Serial.write(mySerial.read()); } } mySerial.write(Serial.read()) : Forwards from Hardware Serial to Software Serial Serial.write(mySerial.read()) : Forwards from Software Serial received to Serial Port 5. GPS Module Initialization void GPS_data(){ mySerial.println("AT+CGNSPWR=1"); updateSerial(); mySerial.println("AT+CGNSSEQ=\"RMC\""); updateSerial(); mySerial.println("AT+CGNSINF"); check_GPS(); } AT+CGNSPWR=1: Turns ON the SIMCOM module AT+CGNSSEQ=RMC : Configure the GPS module for settings (RMC - Time, date, position, course and speed data) AT+CGNSINF : GNSS navigation information parsed from NMEA sentences Next, let us call check_GPS() function to update the current GPS data. 6. Update GPS Data void check_GPS(){ ... } This function includes the main section of the whole project, which requests for the current GPS location, and then checks whether it is within the Geo Fence limits. Let us break down the code even further! 7. Initialization of Local Variables for GPS int8_t counter, answer; long previous; counter = 0; answer = 0; memset(frame, '\0', sizeof(frame)); previous = millis(); int8_t counter, answer;: Two variables to keep track of loop iterations and whether the expected response is received. long previous;: Holds the previous time value for timeout calculation. previous = millis(); : Initialize current time in milliseconds. char frame[256];: An array to store received characters for constructing the response frame. void *memset(void *str, int c, size_t n) str − This is a pointer to the block of memory to fill. c − This is the value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value. n − This is the number of bytes to be set to the value. memset function returns a pointer to the memory area str. 8. Check for Response on UART do { if (mySerial.available() != 0) { frame[counter] = mySerial.read(); counter++; if (strstr(frame, "OK") != NULL) { answer = 1; } } } while ((answer == 0) && ((millis() - previous) < 2000)); This code repeatedly reads characters from the mySerial interface to construct a response frame. It checks if the response contains "OK" to set the answer flag. The loop continues until either "OK" is found or a timeout of 2000 milliseconds is reached. This ensures the program waits for the expected response before proceeding. 9. Parse the String for GPS data frame[counter - 3] = '\0'; strtok(frame, ": "); GNSSrunstatus = atoi(strtok(NULL, ",")); Fixstatus = atoi(strtok(NULL, ",")); strcpy(UTCdatetime, strtok(NULL, ".")); strtok(NULL,","); strcpy(latitude, strtok(NULL, ",")); strcpy(longitude, strtok(NULL, ",")); strcpy(altitude, strtok(NULL, ",")); frame[counter - 3] = '\0';: Terminate the response frame at a specific index. strtok(frame, ": ");: Tokenize the frame using colons and spaces as delimiters. GNSSrunstatus = atoi(strtok(NULL, ", "));: Get GNSS run status as an integer. Fixstatus = atoi(strtok(NULL, ", "));: Get fix status as an integer. strcpy(UTCdatetime, strtok(NULL, "."));: Copy UTC date and time. strtok(NULL, ", ");: Skip irrelevant tokens. strcpy(latitude, strtok(NULL, ", "));: Copy latitude. strcpy(longitude, strtok(NULL, ", "));: Copy longitude. strcpy(altitude, strtok(NULL, ", "));: Copy MSL altitude. This code takes the string data in theframe and then copies it to the variables like GNSSrunstatus, Fixstatus, UTCdatetime, lat, long & altitude. byte GNSSrunstatus, Fixstatus;: Byte variables to store GNSS run status and fix status. char UTCdatetime[15];: A character array to store UTC date and time. char latitude[10], longitude[11], altitude[8];: Character arrays to store latitude, longitude, and altitude data. 10. Print & Store the Data in the MESSAGE String if (Fixstatus != 0){ Serial.println("GPS Data received"); Serial.print("Runstatus: "); Serial.println(GNSSrunstatus); Serial.print("Fixstatus: "); Serial.println(Fixstatus); Serial.print("UTCdatetime: "); Serial.println(UTCdatetime); Serial.print("latitude: "); Serial.println(latitude); Serial.print("longitude: "); Serial.println(longitude); Serial.print("altitude: "); Serial.println(altitude); latitude_val = atof(latitude); lat_val = latitude_val*1000000; Serial.println(lat_val); longitude_val = atof(longitude); lon_val = longitude_val*1000000; Serial.println(lat_high); . . . If Fixstatus does not return '0', it means we have the complete GPS data. And so it can be further used according to our project. 11. Setting the SafeHouse and Alert Logic if (lat_high == 0){ sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nAltitude : %s km\n\nInitial Position of the Module\n\nhttp://maps.google.com/maps?q=%s,%s\n", latitude, longitude, altitude, latitude, longitude); sendSMS(); } else{ lat_check = inRange(lat_val, lat_high, lat_low); lon_check = inRange(lon_val, lon_high, lon_low); Serial.print(lat_check); Serial.println(lon_check); if (!(lat_check)){ sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nAltitude : %s km\n\nALERT!! Module is outside the GeoFence\n\nhttp://maps.google.com/maps?q=%s,%s\n", latitude, longitude, altitude, latitude, longitude); sendSMS(); } } } else if ((Fixstatus == 0) && (lat_high == 0)){ Serial.println("Resetting Arduino to check GPS data"); delay(5000); resetFunc(); } } If lat_high=0, or a value exists in it, using sprintf() function, we are storing it in the global variable MESSAGE. This MESSAGE is different for the initial positioning (SafeHouse), & Alerting in case the data is received. In case, the Fixstatus is again 0 during execution, reset the Arduino to start fresh the connection 12. Send GPSdata to Another SIMnumber void sendSMS() { Serial.println("Start to send message ..."); Serial.println(MESSAGE); Serial.println(phone); mySerial.println("AT+CSMP=17,167,0,0"); updateSerial(); mySerial.println("AT+CMGF=1"); updateSerial(); String sim_sms = "AT+CMGS=\"" + phone + "\"\r"; mySerial.println(sim_sms); updateSerial(); mySerial.print(MESSAGE); delay(500); mySerial.print((char)26); Serial.println("Check SMS"); } AT+CSMP=17, 167, 0, 0;: This line sends the AT command "AT+CSMP=17, 167, 0, 0" to the SIM808 module. It's used for setting SMS parameters. AT+CMGF=1;: This line sends the AT command "AT+CMGF=1" to the SIM808 module. It sets the SMS mode to text mode. String sim_sms = "AT+CMGS=\"" + phone + "\"\r";: This line creates a string sim_sms that represents the AT command "AT+CMGS=" followed by the recipient's phone number enclosed in double quotes and terminated with a carriage return. sim_sms: This line sends the sim_sms command to the SIM808 module. It initiates sending an SMS to the specified phone number. That's it! Now that we have shared the GPS data using SMS to the specified number, it is in fact a great method to safeguard your belongings! Working Let us make the connections between Arduino - SIM808 - GPS Module Initial Position - After we flash the code to the Arduino, the code sends the initial location of the GPS while creating a Geo-Fence around the center of the location. SMS Message Latitude : 23.009152 Longitude : 50.252952 Altitude : 86.200 km Initial Position of the Module http://maps.google.com/maps?q=23.009152,50.252952 The device keeps checking its location on a loop, indefinitely Till the time the device is within half a kilometer (500m) of the above location, the device is considered within the safe house. Geo-Fence Breach - The moment, the device moves out of the GeoFence, the device detects it as an alert and sends an SMS immediately. SMS Message Latitude : 24.008693 Longitude : 51.253190 Altitude : 85.000 km ALERT!! Module is outside the GeoFence http://maps.google.com/maps?q=24.008693,51.253190 Congratulations! You willbe now able to build your own device to GeoFence. We hope that this tutorial has provided you with the information you need to buildand learn throughout. If you have any questions or need further assistance, please letme know in the comments! GeoFence.ino
  4. 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
  5. 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()); }
×
  • Create New...