SmartPioneers DIY IOT Wind Direction Sensor
by hzqahusna in Circuits > Raspberry Pi
155 Views, 2 Favorites, 0 Comments
SmartPioneers DIY IOT Wind Direction Sensor
Hello! Today we are going to show you the DIY wind direction sensor that our group, SmartPioneer has done for the IoT Campus Environmental Monitoring System. The DIY sensor that we built also can measure temperature along with light intensity. All of the data is collected by a Micropython Pico W that sends the data via wifi then it will sent to thingspeak as an IoT analytics platform for collecting, analyzing, and acting on live data streams. Thingspeak allows devices to send sensor data via REST API. On the dashboard, we can see real-time data from the DIY wind direction sensor for example of the temperature and the light intensity graph. If this sounds difficult, don't worry, in this guide you can find all the information. To see more details about the construction, watch the video on YouTube.
Supplies
Supplies: The Smart Pioneer Toolkit
To build this optical weather station, our team combined standard DIY electronics with robust hardware to withstand the coastal environment. Here is exactly what we used to build the system:
The "Brain" & Electronics
- Raspberry Pi Pico W: The core controller, chosen for its ability to run MicroPython and connect to Wi-Fi.
- 4x IR Obstacle Avoidance Sensors: The eyes of our wind direction mechanism.
- Light Dependent Resistor (LDR): To measure sunlight intensity.
- 5V to 3.3V Level Shifters: Essential for protecting the Pico W (which is 3.3V logic) from the 5V signals coming from the sensors.
- Micro-USB Cable: For programming and power delivery.
- Breadboard & Jumper Wires: To organize the circuit inside the base.
The Mechanical "Tower" Structure
- Clear Plastic Storage Container: Serves as the heavy base and houses the microcontroller (the "Server Room").
- Blue IP65 Junction Box: Serves as the top compartment for the mechanical wind components.
- Metal Rod & Ball Bearing: Creates a low-friction axis for the wind vane to spin freely.
- 3D-Printed Arrow Vane: Custom-designed to catch the wind.
- The "Connector" (Shaft Coupler): A white plastic piece modified with Black Electrical Tape (crucial for our custom IR reflection logic).
Power & Tools
- Portable Power Bank: To power the station remotely during field testing.
- Soldering Iron: For securing connections on the level shifters and sensor pins.
- Hot Glue Gun: For waterproofing cable entry points and securing the sensors inside the lid.
- Power Drill: To create the shaft hole in the junction box and cable pass-throughs.
- Computer: Running Thonny IDE for coding and the ThingSpeak dashboard for monitoring.
The "Dual-Box" Structure & Base
Every weather station needs a stable foundation. Instead of a single heavy pole, Smart Pioneer opted for a modular "dual-box" tower design to keep our electronics organized and stable. For the base, we used a sturdy clear plastic storage container. This serves two purposes: it acts as a stable anchor for the station (which can be weighed down if needed), and it functions as the "server room," housing our microcontroller and breadboard safely away from the mechanical parts. On top of this base, we mounted a robust blue IP65 weatherproof junction box. This top box serves as the platform for the wind vane. We drilled a hole through the center of the blue lid to insert the rotating metal shaft. A 3D-printed arrow vane is friction-fitted to the top of this shaft, free to spin with the wind while the base remains rock solid.
The "Connector" & Black Tape Logic
The most critical part of our design was figuring out how to trigger the sensors accurately. We didn't use a standard encoder; we built a custom solution inside the blue box using a modified "Connector".
The Sensor Layout: Inside the blue box, we mounted four IR Obstacle Avoidance Sensors in a strict "Cross" (+) formation on the floor of the box. Each sensor faces inward toward the center, representing North, South, East, and West.
The "Connector" Modification: As shown in the image below, we attached a custom-shaped white plastic "connector" to the metal shaft that comes through the lid. This connector rotates as the wind vane spins.
The Physics of Reflection: We learned that IR sensors work by detecting reflected light. White surfaces reflect IR light well, while black surfaces absorb it. To get precise readings, we modified our white connector by wrapping specific sections in black electrical tape.
- White Surface: When the white part of the connector faces a sensor, it reflects the IR signal, triggering a "High" reading.
- Black Tape: When the taped section faces a sensor, the light is absorbed, preventing false triggers.
This simple "Tape & Plastic" tuning allowed us to calibrate exactly when the station registers a wind direction change without needing complex code.
Monitoring Light & System Health
While the blue box handles the wind, we needed to monitor the rest of the environment. We maximized our microcontroller's efficiency by adding a light sensor and using internal telemetry.
- Light Intensity (LDR): We wired a Light Dependent Resistor (LDR) into our circuit. By reading the analog values, the system detects if it is sunny, cloudy, or dark. This helps us correlate wind speed with sunlight intensity.
- Pico Internal Temperature: Rather than using external probes, we utilized the Raspberry Pi Pico W's onboard temperature sensor. This gives us a reliable reading of the ambient temperature inside the enclosure, acting as a system health check.
Wiring the "Brain"
The "brain" of our station—the Raspberry Pi Pico W—lives safely in the bottom clear container.
We used a breadboard to organize our connections. The challenge was routing the data cables from the four IR sensors in the top blue box down to the Pico in the bottom clear box. We carefully managed these wires to ensure they wouldn't snag as the boxes were stacked. This separation allows us to troubleshoot the code in the bottom box without disturbing the delicate sensor alignment in the top box.
Write the Code
Below shows the step on how to do the dashboard:
STEP 1: SET UP HTML FILE
1.1 Create index.html file
1.2 Add required libraries in <head>:
- Tailwind CSS (for styling)
- Chart.js (for graphs)
1.3 Create basic page structure with dark theme background
STEP 2: CREATE DASHBOARD SECTIONS
2.1 HEADER SECTION
- Add logo image
- Add "SmartPioneers" title
- Add connection status indicator
- Add "Last Cloud Read" timestamp display
2.2 WIND DIRECTION SENSOR SECTION
- Create compass visualization (SVG)
- Add wind direction display (degrees)
- Add compass direction text (N, NE, E, etc.)
- Add analog voltage estimate display
- Add data source indicator
2.3 TEMPERATURE & LIGHT CARDS
- Temperature display card
- Light intensity display card with progress bar
2.4 LIVE DATA LOG SECTION
- Add "Download CSV" button
- Add three chart containers (canvas elements):
* Wind Direction chart
* Temperature chart
* Light Intensity chart
2.5 COURSE INFORMATION SECTION
- Add course details
- Add team members list
STEP 3: CONFIGURE THINGSPEAK CONNECTION
3.1 Get your ThingSpeak credentials:
- Channel ID (e.g., 3217474)
- Read API Key (for reading data)
3.2 Set up configuration variables:
- Store Channel ID
- Store Read API Key
- Set update interval (15 minutes = 900000 milliseconds)
3.3 IMPORTANT: Verify your ThingSpeak field mappings:
- Field 1 = Temperature (°C)
- Field 2 = Light Intensity (%)
- Field 3 = Wind Direction (degrees, 0-360)
STEP 4: IMPLEMENT DATA READING FROM THINGSPEAK
This is the CORE functionality - how the dashboard gets data from ThingSpeak.
4.1 LOAD HISTORICAL DATA (On Page Load)
Purpose: Show past data when dashboard first opens
Process:
1. Call ThingSpeak API to get last 30 entries
2. API Endpoint:
/channels/{CHANNEL_ID}/feeds.json?api_key={KEY}&results=30
3. Parse the response (JSON format)
4. Extract temperature, light, and wind from each entry
5. Extract timestamp from each entry
6. Format time as HH:MM (no seconds)
7. Add all data points to chart arrays
8. Store the last entry_id to track new data
9. Update all three charts with historical data
Key Point: This gives users immediate context when they open the dashboard.
4.2 CHECK FOR NEW DATA (Every 15 Minutes)
Purpose: Update dashboard with latest sensor readings
Process:
1. Call ThingSpeak API to get ONLY the latest entry
2. API Endpoint: /channels/{CHANNEL_ID}/feeds/last.json?api_key={KEY}
3. Get the entry_id from response
4. Compare with stored lastEntryId
5. If entry_id is different = NEW DATA
6. If entry_id is same = NO NEW DATA (skip chart update)
7. Always update dashboard displays (current values)
8. Only add to charts if it's genuinely new data
9. Update lastEntryId if new data found
CRITICAL: Entry ID Tracking
- ThingSpeak assigns unique entry_id to each data point
- By comparing entry_id, we prevent duplicate data in charts
- Dashboard always shows latest values, but charts only grow with NEW data
4.3 UPDATE DASHBOARD DISPLAY
When new data arrives:
1. Parse temperature, light, and wind values
2. Update all display elements:
- Temperature number
- Light percentage and progress bar
- Wind direction degrees
- Compass direction (N, NE, E, etc.)
- Analog voltage (calculated: wind/360 * 5)
- Rotate compass arrow to match direction
- Update "Last Cloud Read" timestamp
3. If new data: Add to chart arrays and update charts
4. If not new: Skip chart update (prevents duplicates)
STEP 5: SET UP CHARTS
5.1 Initialize Chart.js
5.2 Create three line charts:
- Temperature chart (amber/yellow color)
- Light chart (yellow color)
- Wind Direction chart (green color, y-axis 0-360)
5.3 Configure charts:
- Responsive design
- Dark theme colors
- No legend
- Show grid lines
- Limit to 30 data points (remove oldest when exceeded)
5.4 Connect charts to data arrays:
- X-axis: Time labels (HH:MM format)
- Y-axis: Sensor values
STEP 6: CSV EXPORT FUNCTIONALITY
6.1 When user clicks "Download CSV" button:
6.2 Process:
1. Fetch last 7 days of data from ThingSpeak
2. API Endpoint: /channels/{CHANNEL_ID}/feeds.json?api_key={KEY}&days=7
3. Generate CSV format:
- Header row: timestamp, date, Temperature_C, Light_Percent, Wind_Degrees
- Data rows: One per feed entry
4. Format each row:
- Full timestamp (date + time)
- Date only
- Temperature (1 decimal place)
- Light (whole number)
- Wind (whole number)
5. Create downloadable file
6. Filename: smart_pioneers_iot_reading_export_YYYY-MM-DD.csv
7. Trigger browser download
STEP 7: STARTUP SEQUENCE
When page loads:
1. Initialize all three charts (empty at first)
2. Load historical data (last 30 entries)
3. Populate charts with historical data
4. Get latest current values
5. Update all dashboard displays
6. Start periodic checking (every 15 minutes)
Periodic Updates:
- Every 15 minutes: Check ThingSpeak for new data
- Only update charts if new data found
- Always update current value displays
THINGSPEAK API ENDPOINTS USED
1. GET LAST ENTRY (for periodic updates)
URL: https://api.thingspeak.com/channels/{CHANNEL_ID}/feeds/last.json?api_key={API_KEY}
Returns: Single most recent entry
Used: Every 15 minutes to check for new data
2. GET HISTORICAL DATA (for initial load)
URL: https://api.thingspeak.com/channels/{CHANNEL_ID}/feeds.json?api_key={API_KEY}&results=30
Returns: Last 30 entries
Used: Once on page load to populate charts
3. GET LAST 7 DAYS (for CSV export)
URL: https://api.thingspeak.com/channels/{CHANNEL_ID}/feeds.json?api_key={API_KEY}&days=7
Returns: All entries from last 7 days
Used: When user clicks CSV export button
Backend Code(Thonny) is in the attached file below:
Downloads
Data Logic (From Binary to Degrees)
One specific challenge we faced was translating the raw signals from our hardware into meaningful data for the cloud. Our IR sensors operate on digital logic, outputting simple "0" or "1" signals.
We couldn't just send these raw binary bits directly. We wrote a specific class in our Python code, WindVane, to interpret these signals in three stages:
- Combination Logic: The code doesn't just check one sensor at a time. It checks for pairs. For example, if both the North (Pin 12) and East (Pin 13) sensors are triggered simultaneously, the system intelligently identifies this as "North-East". This allows us to get 8 directions (N, NE, E, SE, etc.) from just 4 sensors.
- Degrees Conversion: ThingSpeak graphs work best with numbers, not text. So, we created a mapping dictionary (wind_map) that converts the text direction into degrees (e.g., North = 0, East = 90, South = 180).
- Dominant Wind Calculation: Instead of uploading every tiny fluctuation, our code collects readings into a list (wind_list) over 30 minutes. Before uploading, it calculates the "Dominant Wind"—the direction that appeared most frequently during that period.
The "Blackout" Solution
During initial testing, we faced a physics problem: sunlight is essentially giant IR interference! Even inside the blue box, strong daylight could confuse the sensors.
To solve this, we ensured the top blue box was strictly light-sealed. However, our LDR (Light Sensor) needs light. We solved this by positioning the LDR near a transparent section of the enclosure or a dedicated window. That is why we drilled the hole just nicely for the wire connector of the LDR sensor to detect the sunlight , while keeping the wind sensors in the dark. This ensures the wind sensors only see the IR light they emit, while the light sensor sees the sun.
Deployment & Testing
We deployed the Smart Pioneer station for a field test. The wide base of the bottom storage box proved very stable on the grass, especially with the added weight of the bricks.
The modified connector worked perfectly. Because we used black tape to fine-tune the reflection, the sensors were responsive and didn't "stutter" between directions. We verified the alignment with a compass and watched as the data started flowing to our dashboard.
What We Gained From the Project
At the end of our field deployment, this project gave us much more than just data points on a screen. It demonstrated how a complete engineering system is built from scratch—starting with a plastic storage box and a roll of electrical tape, moving through complex Python logic, and ending with a cloud ecosystem that serves both our custom dashboard and our lecturer's server simultaneously.
Seeing the Wind Direction (calculated from our custom "0 & 1" logic), Light Intensity, and Internal Temperature appear vividly on our web interface made the challenges of the build truly worth it. It proved that we didn't need expensive industrial sensors to get results; we just needed smart engineering.
This project also taught the Smart Pioneer team invaluable lessons about persistence and adaptability. We didn't just assemble parts; we had to solve real-world physics problems. When sunlight confused our sensors, we engineered a blackout solution. When the raw binary data was messy, we wrote code to calculate the "Dominant Wind." We experienced the reality of field work—managing battery life, troubleshooting Wi-Fi stability, and ensuring our "dual-box" tower stood firm against the coastal breeze.
In the end, Smart Pioneer didn't just build a weather station; we built a bridge between hardware and software. We learned to divide tasks, trust each other's code, and iterate on our design until it worked. That shared achievement—watching our station "talk" to the cloud from the beach—is the true success we will carry into our future engineering careers.