icon

Enhiker | A Portable Smart Weather Decision Maker

Enhiker is a compact, 3D-printed device designed to assist outdoor enthusiasts in making informed decisions about their environment. Powered by Unihiker from DFRobot, it integrates environmental and GNSS sensors to assess real-time weather conditions and location data. Enhiker provides users with a clear recommendation on whether it's safe to set up camp or continue outdoor activities based on health and safety parameters.

The device features a touchscreen display that shows a comprehensive set of weather and environmental metrics, including Current date and time in UTC, Temperature, Humidity, Ultraviolet Intensity, Luminous Intensity, Atmospheric Pressure, Elevation, Latitude & Longitude, Altitude, Heat Index, Satellites. When connected to WiFi, Enhiker accesses additional data from openweathermap API, displaying: Air Quality, Wind Speed, Wind Direction, Sunrise & Sunset, Cloud Coverage.

Beyond its weather-monitoring capabilities, Enhiker functions as an emergency power bank and can be recharged via solar panel, making it an essential tool for any outdoor adventure. Additionally, it logs all collected data with timestamps and location coordinates into a CSV file, making it valuable for meteorological and agricultural research.

Enhiker is a versatile and reliable companion for anyone exploring the great outdoors, ensuring safety and preparedness in any environment.

Step 1: CAD & 3D Printing

To begin, I designed the Enhiker using Fusion 360. You can view the design directly in your browser and download it to open in Fusion 360 for any modifications or creative additions. Feel free to customize and enhance the design as you like!

Design File: https://a360.co/3XfKDYa

 

For 3D printing, you can directly download the STL files listed below:

Download Link: Enhiker/CAD

1x Housing.stl

1x Cover.stl

1x Board_Plate.stl

1x Antenna_Cover.stl

3x Button1.stl

1x Button2.stl

4x Spacer.stl

I used my Anycubic Kobra printer with matte black PLA filament for the printing process.

Step 2: Power Connection

To power the Enhiker, we are using a "2 Cell 18650 Battery Manager". Since the Unihiker can be powered via USB Type-C, we’re utilizing a Type-C extension cable, which has been modified to serve two purposes: providing power from the batteries and connecting to a PC for accessing and programming the Unihiker.

To modify the extension cable, follow these steps:

Take two male-to-female jumper wires and cut them in half.

Remove the heat shrink from the female side of the extension cable.

Solder the male jumper wires as shown in the diagram above.

Once soldered, cover the exposed parts with heat shrink tubing to ensure safety.

Step 3: Antenna Assembly

Position the antenna in its designated spot, ensuring that the antenna wire is routed inside the housing.

Place the 3D-printed antenna cover over the antenna.

Secure the cover in place using a screw.

Step 4: Board Plate Assembly

Next, let's prepare the board plate, which serves as the skeleton of the project and the mounting base for all components.

Take the 4 spacers that were 3D-printed.

Secure each spacer to the bottom side of the board plate using M3 screws.

Step 5: Sensors Assembly

In this step, we’ll mount the Environmental and GNSS sensors onto the base plate.

Position the GNSS sensor in the center of the base plate towards the bottom side.

Align the holes on the sensor with those on the base plate.

Secure the GNSS sensor using 4 M3 screws.

Place the Environmental sensor onto the designated bracket on the base plate and secure it in place using 2 M3 screws.

Step 6: Unihiker Assembly

Now it's time to mount the Unihiker onto the base plate.

Before mounting, plug in the Type-C extension cable that was prepared earlier.

Position the Unihiker on the base plate, aligning it with the three designated holes.

Route the cable through the designed slot on the base plate.

Secure the Unihiker in place using M3 screws.

Step 7: Sensors Connection

Connecting the sensors to the Unihiker is simple and hassle-free, thanks to Unihiker’s plug-and-play connectors, which make it easy to connect DFRobot sensors without worrying about wire alignment.

Use two 4-pin connectors that came with the Unihiker to plug both the Environmental and GNSS sensors into the Unihiker as shown in the diagram.

These sensors will communicate with the Unihiker via the I2C protocol.

Ensure that the small switch on each sensor is positioned towards the "I2C" setting.

 

Step 8: Housing Assembly

Now it's time to assemble everything into the housing.

Begin by placing the 3D-printed buttons into their designated holes in the housing.

Use masking tape to temporarily hold the buttons in place, as they might fall out during the assembly process.

Carefully position the base plate assembly inside the housing, aligning the buttons and routing the antenna wire.

Secure the base plate to the housing using 4 M3 screws.

Once the base plate is secured, remove the masking tape holding the buttons.

Finally, connect the antenna wire to the GNSS sensor.

Step 9: Battery Assembly

Solder the two female jumper wires (previously cut) to the GND(Brown/Black) and 5V(Red) terminals of the battery maintain the color code of the wire.

Plug the Type-C extension cable into the battery. This cable will be used for charging the batteries.

Position the Unihiker's Type-C female connector into the middle slot of the housing body and secure the connector using hot glue.

Insert the Button 3D printed into its designated slot in the housing.

Place the battery manager board onto the spacers, by aligning the USB ports with its corresponding opening in the housing and secure the board with 4 M3 screws.

Connect the female jumper wires to the male jumper wires of the Unihiker. (Please double check the Unihiker and battery connection before connecting as the wrong connection might permanently damage the components)

Insert the battery’s Type-C cable into its designated slot in the housing and secure the cable using hot glue to keep it in place.

Make sure that the switch on battery management board is positioned at Hold.

Step 10: Final Assembly

Before proceeding with the final assembly, power on the system to ensure everything is functioning correctly.

If the Unihiker board powers up, it indicates that all connections are properly made.

If the board does not power up, double-check all connections to identify and correct any issues.

 

Carefully tuck all the wires into the housing, making sure they are neatly arranged and not pinched and snap the cover onto the housing, ensuring it fits securely.

 

And that's it! The assembly of your Enhiker is now complete.

Step 11: Setup and Programming

Now that's everything is assembled and working, lets program the board:

Download and install Mind+ from here.

 

Connect your Unihiker (or "Enhiker"!) to your PC using a USB cable.

Open a browser (any browser except Internet Explorer) and navigate to http://10.1.2.3 to access the local web page menu on the Unihiker.

Go to the "Network Settings" on the web page and connect the Unihiker to your Wi-Fi network by entering your network credentials.

 

Open the Mind+ software.

Click on "Extensions" located at the bottom left side of the screen.

Select "Unihiker" and then click "Back" to return to the main menu.

 

Click on "Code" in Mind+ and then connect the Remote Terminal.

Once connected, you will see the Unihiker's file system on the right side of the screen.

Download the code from this GitHub repository and unzip the files.

Drag and drop the entire Enhiker folder into the Unihiker’s file system. This will copy the folder to the Unihiker.

 

Open the main.py file in the Unihiker's file system.

Go to OpenWeatherMap and log in to your account.

Navigate to "My API Keys" and copy your API key.

Paste the API key in the main.py file

# Your API Key

API_Key = '***************************'

Run the main.py file.

The program should execute without issues, as the packages used are the default ones that come pre-installed on the Unihiker.

If any issues arise, check the folder structure and the installed packages.

CODE
"""
Project: Enhiker - A Portable Weather Decision Maker
Author: Mukesh Sankhla
Website: https://www.makerbrains.com
Social Media: Instagram @mukesh.diy

Description:
This Python script interfaces with an environmental sensor and a GNSS (Global Navigation Satellite System) sensor,
displaying real-time data on a Pygame-powered graphical user interface (GUI). The script is designed to monitor 
various environmental parameters such as temperature, humidity, UV intensity, atmospheric pressure, and light intensity. 
It also gathers location data using the GNSS sensor and evaluates the environmental conditions, providing a health rating 
based on the collected data.
"""

import time
import os
import csv
from pinpong.board import Board
from lib.DFRobot_Environmental_Sensor import *
from lib.DFRobot_GNSS_I2C import DFRobot_GNSS_I2C, MODE_GPS_BEIDOU_GLONASS
from decision_maker import evaluate_conditions
from advance_decision_maker import evaluate_advance_conditions
from heat_index import calculate_heat_index
from internet_data import get_weather_data
from display import display_loading_screen, display_data

# Your API Key
API_Key = '***************************'

# Initialize the board
Board().begin()

# Initialize sensors
SEN0501 = DFRobot_Environmental_Sensor_I2C(bus=0x01, addr=0x22)
GNSS = DFRobot_GNSS_I2C()
GNSS.set_gnss_mode(MODE_GPS_BEIDOU_GLONASS)
GNSS.set_enable_power()

# Define constants
MINIMUM_SATELLITES = 3  # Minimum number of satellites required for reliable data
DELAY_SECONDS = 5  # Delay between each loop iteration

# Function to check Wi-Fi connection status
def check_wifi():
    return os.system("ping -c 1 google.com") == 0

# Setup function to initialize sensors
def setup():
    while not SEN0501.begin():
        print("Sensor initialization failed!")
        time.sleep(1)
    print("Sensor initialization successful!")

# Main loop function to read sensor data, evaluate conditions, and display the data
def loop():
    # Wait until the required number of satellites is found
    while True:
        num_satellites = GNSS.get_num_sta_used()
        if num_satellites > MINIMUM_SATELLITES:
            break
        print(f"Searching... Satellites found: {num_satellites}")
        display_loading_screen()
        time.sleep(1)

    # Read data from sensors
    temperature = SEN0501.get_temperature(TEMP_C)
    humidity = SEN0501.get_humidity()
    uv_intensity = SEN0501.get_ultraviolet_intensity()
    light_intensity = SEN0501.get_luminousintensity()
    pressure = SEN0501.get_atmosphere_pressure(HPA)
    elevation = SEN0501.get_elevation()
    heat_index = calculate_heat_index(temperature, humidity)

    # Get GNSS data if the satellite count is sufficient
    latitude, longitude, altitude = None, None, None
    current_date, current_time = None, None
    if num_satellites > MINIMUM_SATELLITES:
        lat_data = GNSS.get_lat()
        lon_data = GNSS.get_lon()
        alt_data = GNSS.get_alt()
        
        latitude = f"{lat_data[0]:.6f}° {lat_data[1]}"
        longitude = f"{lon_data[0]:.6f}° {lon_data[1]}"
        altitude = f"{alt_data:.2f} m"

        # Get the date and time from GNSS
        current_date = GNSS.get_date()
        current_time = GNSS.get_time()

    wifi_connected = check_wifi()

    air_quality, wind_speed, wind_direction, sunrise, sunset, clouds = None, None, None, None, None, None
    if wifi_connected:
        air_quality, wind_speed, wind_direction, sunrise, sunset, clouds = get_weather_data(latitude, longitude, API_Key)

    if wifi_connected:
         # Evaluate environmental advance conditions based on sensor and internet data
        rating, message = evaluate_advance_conditions(current_time, temperature, humidity, uv_intensity, light_intensity, pressure, elevation, heat_index, air_quality, wind_speed, wind_direction, clouds)
    else:
        # Evaluate environmental conditions based on sensor data
        rating, message = evaluate_conditions(temperature, humidity, uv_intensity, light_intensity, pressure, elevation, heat_index)
    # Display data
    display_data(wifi_connected, current_date, current_time, num_satellites, temperature, humidity, heat_index, light_intensity, uv_intensity, pressure, elevation, latitude, longitude, rating, message, air_quality, wind_speed, wind_direction, sunrise, sunset, clouds)
    
    # Log data into csv
    with open('data_log.csv', mode='a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([wifi_connected, current_date, current_time, num_satellites, temperature, humidity, heat_index, light_intensity, uv_intensity, pressure, elevation, latitude, longitude, rating, message, air_quality, wind_speed, wind_direction, sunrise, sunset, clouds])
    
    # Delay before the next loop iteration
    time.sleep(DELAY_SECONDS)

if __name__ == "__main__":
    setup()  # Initialize the sensors
    while True:
        loop()  # Continuously read and display sensor data

Step 12: Conclusion

Enhiker may not be a groundbreaking innovation in the rapidly evolving world of smartphones and advanced technology, but it serves a unique purpose by offering valuable lessons in IoT, communication, and offline functionality—features that many modern devices often overlook. This project stands out for its ability to operate independently of the internet, making it a reliable companion for those who venture into the great outdoors where connectivity is limited.

Whether you're an outdoor enthusiast, an engineer, or a professional in meteorology or agriculture, Enhiker is a practical tool worth considering. It bridges the gap between technology and nature, providing essential data and insights in environments where conventional tech falls short.

 

Thank you! See you next time ;)

License
All Rights
Reserved
licensBg
2