Please note that broadcasting data on the APRS (Automatic Packet Reporting System) network requires a valid amateur radio license. In the United States, this typically entails obtaining at least a Technician Class license from the Federal Communications Commission (FCC).

Legal Requirements:

Amateur radio operators are subject to regulations set forth by their respective national regulatory authorities. These regulations govern the allocation and usage of radio frequencies, as well as the permissible modes of communication.

License Requirement:

To legally transmit data on the APRS network, you must hold an appropriate amateur radio license. In the United States, the Technician Class license is the entry-level license that grants privileges to operate on certain frequencies and modes, including those used for APRS communication.

Compliance with Regulations:

It is essential to comply with all applicable regulations and licensing requirements when operating amateur radio equipment. Failure to do so may result in legal consequences, including fines and penalties.

Responsibility of Operators:

As licensed amateur radio operators, we have a responsibility to operate our equipment in a manner that promotes safety, professionalism, and respect for the radio spectrum. This includes adhering to established operating procedures and respecting the privacy and rights of other users.

Get Licensed:

If you're interested in becoming an amateur radio operator and gaining access to the exciting world of APRS and other radio communication technologies, we encourage you to pursue obtaining your amateur radio license. Resources and study materials are available to help you prepare for the licensing exam and embark on your journey into amateur radio.

Disclaimer Acknowledgment:

By accessing or using the information provided on this website related to APRS and amateur radio, you acknowledge and agree to abide by all applicable regulations and licensing requirements governing the operation of amateur radio equipment.

Arduino Sensor Data Broadcasting Setup


I've set up a system to monitor temperature and humidity using an Arduino microcontroller along with a DHT sensor. This system allows me to access real-time sensor data through a web page hosted on my internal network. Additionally, I've integrated this setup with UISS software and my 2m radio for broadcasting the sensor data over the airwaves.




This setup allows for seamless monitoring and broadcasting of temperature and humidity data using readily available hardware and software tools. By integrating Arduino, Python scripting, UISS, and amateur radio equipment, I've created a robust system for transmitting environmental data over the airwaves.

I'm thrilled to share with you a project that blends the realms of Arduino microcontrollers, Python scripting, and APRS (Automatic Packet Reporting System) communication to create a truly fascinating endeavor.

Exploring the Frontier of Amateur Radio:

In today's interconnected world, the possibilities for leveraging technology to push the boundaries of communication are endless. As an avid enthusiast of both amateur radio and DIY projects, I've embarked on a journey to harness the power of these technologies in a unique and impactful way.

Arduino at the Core:

At the heart of this project lies the versatile Arduino microcontroller, a staple tool in the arsenal of any electronics hobbyist. By interfacing Arduino with a DHT sensor, I've empowered myself to monitor real-time environmental data such as temperature and humidity with precision and accuracy.

Bringing APRS into the Mix:

But why stop at local monitoring? With the integration of APRS, a digital communications protocol widely used in amateur radio, I've unlocked the ability to broadcast this sensor data to a wider audience. APRS facilitates the transmission of data packets over radio frequencies, allowing for real-time dissemination of information over the airwaves.

The Marriage of Arduino, Python, and UISS:

But here's where the magic truly happens. By complementing the Arduino setup with a Python script running on a computer, I've established a seamless pipeline for scraping the sensor data from the Arduino's web interface and converting it into APRS-compatible messages. This integration is made possible through UISS (Universal Internet Satellite Service), a powerful software application that bridges the gap between amateur radio and digital communication technologies.

Embarking on an Exciting Journey:

Join me on this exciting journey as we delve deeper into the intricacies of amateur radio experimentation, DIY technology exploration, and the boundless possibilities that emerge when we combine innovation with passion. Whether you're a seasoned enthusiast or a curious newcomer, there's something here for everyone to discover and explore.

Together, let's push the boundaries of what's possible and chart a course towards a future filled with endless possibilities.

The Arduino code

Overall, this code sets up a web server on the Arduino that serves temperature and humidity data to clients over HTTP, while also periodically printing the sensor data to the Serial monitor for debugging purposes.

Arduino R4 WIFI and DHT 11 Sensor 

An Arduino Uno is in picture but a Arduino R4 WIFI must be used. Follow the same pinout/hookup

#include <DHT.h>
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID;        // your network SSID (name)char pass[] = SECRET_PASS;        // your network password
int status = WL_IDLE_STATUS;
WiFiServer server(80);
#define DHTPIN 2            // Pin where the DHT11 is connected#define DHTTYPE DHT11       // DHT 11
void setup() {  Serial.begin(9600);  while (!Serial) {    ;  }
  if (WiFi.status() == WL_NO_MODULE) {    Serial.println("Communication with WiFi module failed!");    while (true);  }
  String fv = WiFi.firmwareVersion();  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {    Serial.println("Please upgrade the firmware");  }
  while (status != WL_CONNECTED) {    Serial.print("Attempting to connect to SSID: ");    Serial.println(ssid);    status = WiFi.begin(ssid, pass);    delay(10000);  }
  server.begin();  dht.begin();  printWifiStatus();}
void loop() {  WiFiClient client = server.available();  if (client) {    Serial.println("new client");    boolean currentLineIsBlank = true;    while (client.connected()) {      if (client.available()) {        char c = client.read();        Serial.write(c);        if (c == '\n' && currentLineIsBlank) {          client.println("HTTP/1.1 200 OK");          client.println("Content-Type: text/html");          client.println("Connection: close");          client.println("Refresh: 60");  // Refresh the page automatically every 60 seconds          client.println();          client.println("<!DOCTYPE HTML>");          client.println("<html>");          client.println("<head><title>DHT11 Sensor</title></head>");          client.println("<body>");          client.println("<h1>DHT11 Sensor Data</h1>");          client.println("<p>Temperature: ");          client.print(readTemperature());          client.print(" &#176;C / ");          client.print(toFahrenheit(readTemperature()));          client.println(" &#176;F</p>");          client.println("<p>Humidity: ");          client.print(readHumidity());          client.println(" %</p>");          client.println("</body>");          client.println("</html>");          break;        }        if (c == '\n') {          currentLineIsBlank = true;        } else if (c != '\r') {          currentLineIsBlank = false;        }      }    }    delay(1);    client.stop();    Serial.println("client disconnected");  }
  // Update serial output every minute  static unsigned long previousMillis = 0;  unsigned long currentMillis = millis();  if (currentMillis - previousMillis >= 30000) {    previousMillis = currentMillis;    Serial.print("Temperature: ");    Serial.print(readTemperature());    Serial.print(" °C / ");    Serial.print(toFahrenheit(readTemperature()));    Serial.println(" °F, Humidity: ");    Serial.print(readHumidity());    Serial.println(" %");  }}
float readTemperature() {  return dht.readTemperature();}
float readHumidity() {  return dht.readHumidity();}
void printWifiStatus() {  Serial.print("SSID: ");  Serial.println(WiFi.SSID());  IPAddress ip = WiFi.localIP();  Serial.print("IP Address: ");  Serial.println(ip);  long rssi = WiFi.RSSI();  Serial.print("Signal Strength (RSSI): ");  Serial.print(rssi);  Serial.println(" dBm");}
float toFahrenheit(float celsius) {  return celsius * 9.0 / 5.0 + 32.0;} 

The Python code

This Python script interacts with the Arduino's web server to scrape temperature and humidity data and then saves it to a file. Here's a rundown of what the code does:

Overall, this script periodically fetches sensor data from the Arduino's web server, saves it to a file, and then exits. It could be set up as a recurring task using a scheduler like cron or Task Scheduler, depending on your operating system.

import osimport timefrom pathlib import Pathimport re
# Arduino's IP address and portarduino_ip = ""arduino_port = 80
def scrape_temperature():    try:        # Make an HTTP GET request to the Arduino's webpage        response = requests.get(f"http://{arduino_ip}:{arduino_port}")        # Check if the request was successful (status code 200)        if response.status_code == 200:            # Extract temperature data from the response content            content = response.text            print("Content:", content)  # Print out the content for debugging            # Use regular expressions to extract temperature in Celsius and Fahrenheit, and humidity            celsius_match = re.search(r"Temperature:\s*([\d.]+)\s*&#176;C", content)            fahrenheit_match = re.search(r"([\d.]+)\s*&#176;F", content)            humidity_match = re.search(r"Humidity:\s*([\d.]+)\s*%", content)
            if celsius_match and fahrenheit_match and humidity_match:                temperature_celsius = float(celsius_match.group(1))                temperature_fahrenheit = float(fahrenheit_match.group(1))                humidity = float(humidity_match.group(1))                return temperature_celsius, temperature_fahrenheit, humidity            else:                print("Failed to extract temperature and humidity data from Arduino response.")                return None        else:            print("Failed to retrieve temperature data from Arduino.")            return None    except Exception as e:        print(f"An error occurred: {e}")        return None
def save_temperature_to_file(temperature_celsius, temperature_fahrenheit, humidity):    try:        # Get the user's profile directory        profile_folder = os.path.join(Path.home(), "OneDrive", "Documents")        # Create the file path        file_path = os.path.join(profile_folder, "TempData.txt")        # Format the data as desired        data_to_write = f"Temperature: {temperature_celsius} °C / {temperature_fahrenheit} °F, Humidity: {humidity} %"        # Remove HTML tags using regular expressions        data_to_write = re.sub(r"<.*?>", "", data_to_write)        # Open the file in write mode (which will overwrite existing data)        with open(file_path, "w") as file:            # Write the formatted data to the file            file.write(data_to_write + "\n")        print(f"Temperature data saved to {file_path} successfully.")        return True    except Exception as e:        print(f"Failed to save temperature data to file: {e}")        return False

# Scrape temperature data from Arduinotemperature_data = scrape_temperature()if temperature_data is not None:    # Unpack the temperature data    temperature_celsius, temperature_fahrenheit, humidity = temperature_data    # Save temperature data to file    if save_temperature_to_file(temperature_celsius, temperature_fahrenheit, humidity):        # Exit the script after saving data        exit()    else:        # If saving failed, wait for a while before exiting        time.sleep(10)

The UISS Software

UISS is a popular software application used by amateur radio operators (hams) to communicate over radio frequencies, particularly via satellite links. It provides features for sending and receiving messages, as well as handling various digital modes commonly used in amateur radio, such as AX.25 packet radio and APRS (Automatic Packet Reporting System).

To use UISS in conjunction with your Arduino temperature and humidity sensor project, you would typically set up a system where UISS reads the temperature data from the file saved by your Python script and then broadcasts it over the radio using your ham radio callsign, KB3WON.

Here's a general outline of how you might set up this system:

Remember to comply with relevant regulations and operating procedures for amateur radio operations, including frequency usage and transmission protocols. Additionally, ensure that you have the necessary licenses and permissions to operate your radio equipment in your jurisdiction.

Here is a nice tutorial on YouTube that you can follow to help set up UISS. Setting up Soundmodem and UISS