Hypatia: Getting Started Guide

Initial Setup

Driver Installation: Start by installing the latest version of the Arduino IDE on your computer.
Package Installation: Once the IDE is installed, open Arduino IDE and go to the Tools menu
Select Tools > Board > Board Manager
In the Board Manager window, use the search bar to find esp32 by typing its name
per iniziare - IDE
Click on esp32 in the search results and select Board to open the installation window
In the Board Manager, use the search bar again to find Wroom by typing the name
IDE
From the search results, select Fri3d Badge 2024 (ESP32-S3-WROOM-1) and click OK to install the required package
The Fri3d Badge 2024 (ESP32-S3-WROOM-1) package includes support for several ESP32-based boards, including Hypatia. The selected board will appear in the status bar.

Configure the Arduino IDE Before Use

Choose the partition scheme: Tools > Partition Scheme > 16M Flash (3MB APP / 9.9MB FATFS)
Choose the upload mode: Tools > Upload Mode > USB-OTG CDC (TinyUSB)
Choose the USB mode: Tools > USB Mode > USB-OTG (TinyUSB)

After completing the installation steps, connect your Hypatia board to your computer using a USB-A to USB-C cable.
Finally, select the correct port: Tools > Port

Some Useful Tips

1. Upload Error: “A fatal error occurred: Failed to connect to ESP32: Timed out…Connecting…”
If you see this message while trying to upload a sketch to Hypatia, it means the ESP32 is not in flashing/upload mode. If you’ve correctly selected the board and COM port, follow these steps:

Press and hold the “Boot” button on your board
Click the “Upload” button in the Arduino IDE
When you see the message “Connecting…” in the IDE, release the “Boot” button
You should then see “Done uploading”

You’ll need to repeat this button sequence every time you upload a new sketch.

2. Error: “COM Port not found / not available”
If you get this error:

Open Windows Device Manager
Check the USB Ports section to verify if your board is recognized

3. Still seeing “COM Port not found / not available”?
You may need to install the correct USB drivers:

Install CP210x USB to UART Bridge drivers (for Windows)
Install CP210x USB to UART Bridge drivers (for macOS)

At startup, the microcontroller running MicroPython looks for and executes the following files in order:

boot.py (optional)
Always executed on power-up or reset. Typically used for initial configurations (e.g., Wi-Fi mode, pin setup, etc.).
It is optional, but if present, it runs first.
main.py (optional)
Executed after boot.py. It usually contains the main part of your code. This file is also optional, but if it exists, it runs automatically.

If you want your code to run automatically at startup, the file must be named main.py (or be called from within boot.py).
Se carichi ad esempio un file chiamato codice.py, per farlo partire all’avvio scrivi nel main.py: “import codice”

Connect your Hypatia

Wi-Fi

To begin configuring and programming your Hypatia board, follow these steps:

Install the Arduino IDE on your computer
Install the Adafruit library, required to correctly communicate with some of the board’s components
Verify all necessary settings for the Hypatia board are properly configured
Select the correct board and COM port in the Arduino IDE

Next, open your sketch and enter your Wi-Fi network’s SSID and password in the appropriate fields.
Make sure to replace the placeholder values with your actual credentials to allow the board to connect successfully.
Once that’s done:

Compile and upload the code to the ESP32 on your Hypatia board by clicking the Upload button
During the upload process, hold down the “Boot” button on the board when prompted
After the upload completes, open the Serial Monitor (button in the upper-right corner of the IDE)
Set the baud rate to 115200, matching the value defined in your code

Once the server is running, enter the displayed IP address in any browser connected to the same Wi-Fi network configured in your code.
If everything has been configured correctly and the Hypatia board’s Wi-Fi is working, a web page will load, allowing you to interact with the board. By pressing the buttons on the page, the RGB LED will change color between red, green, and blue. This confirms that both Wi-Fi connectivity and the web server are working properly.


#include <WiFi.h>         //including library for Wifi
#include <WebServer.h>    //including library for WebServer Design
#include <FastLED.h>    //including library for LED


//....................ENTER THE PIN NUMBER OF THE LED...........................................................
// Define the pin to which the WS2812B LED is connected
#define LED_PIN 21
#define NUM_LEDS 1

// Creating the object for the LED
CRGB leds[NUM_LEDS];

//....................ENTER THE NAME AND PASSWORD TO YOUR WIFI..................................................
// WiFi credentials
const char *ssid = "SSID_WIFI";
const char *password = "PASSWORD_WIFI";

// Creating WebServer object on port 80
WebServer server(80);

// Functions to handle LED colors
void handleRed() {
  leds[0] = CRGB::Red;      //Set the LED to red
  FastLED.show();
}

void handleGreen() {
  leds[0] = CRGB::Green;    //set the LED to green
  FastLED.show();
}

void handleBlue() {
  leds[0] = CRGB::Blue;    //set the LED to blue
  FastLED.show();
}

// html code to deinfe Website Design
void handleRoot() {
  String html = R"rawliteral(
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SYDE Hypatia Wifi connection check </title>
    <style>
      body {
        font-family: Arial, sans-serif;
        background-color: #f4f4f9;
        color: #333;
        text-align: center;
        margin: 0;
        padding: 0;
      }
      .container {
        max-width: 600px;
        margin: 20px auto;
        padding: 20px;
        background-color: white;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        border-radius: 10px;
      }
      h1 {
        color: #6e6e6e;
        margin-top: 10px;
      }
      button {
        background-color: #02aff3;
        color: white;
        padding: 10px 20px;
        margin: 10px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
        display: inline-block;
      }
      button:hover {
        background-color: #6e6e6e;
      }
      img {
        margin-top: 10px;
        margin-bottom: 20px;
        max-width: 80%;
        border-radius: 10px;
      }
      #color-circle {
        width: 100px;
        height: 100px;
        border-radius: 50%;
        background-color: lightgray;
        margin: 20px auto;
        box-shadow: 0 0 15px 5px rgba(0, 0, 0, 0.2); /* Glow effect */
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>SYDE Hypatia Wifi connection check</h1>
      <p>Control the LED on the Hypatia Board:.</p>

    <div id="color-circle" style="width: 20px; height: 20px; border-radius: 50%; background-color: lightgray; margin: 20px auto;"></div>
    <div style="display: flex; justify-content: center; gap: 10px; margin-top: 20px;">
    
    <button onclick="fetch('/H', { method: 'GET' }); changeCircleColor('red');" style="display: block; margin: 10px auto; padding: 10px 20px;">Turn LED RED</button>
    <button onclick="fetch('/L', { method: 'GET' }); changeCircleColor('green');" style="display: block; margin: 10px auto; padding: 10px 20px;">Turn LED GREEN</button>
    <button onclick="fetch('/K', { method: 'GET' }); changeCircleColor('blue');" style="display: block; margin: 10px auto; padding: 10px 20px;">Turn LED BLUE</button>
    </div>

    <script>
       function changeCircleColor(color) {
        document.getElementById('color-circle').style.backgroundColor = color;
        document.getElementById('color-circle').style.boxShadow = `0 0 15px 5px ${color}`;
        }
     </script>
     </div>
    
  </body>
  </html>
  )rawliteral";

  server.send(200, "text/html", html);
}


//setup communication with the esp system
void setup() {
  Serial.begin(115200);
  delay(5000);
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);   //Declare and initialize the LED
  FastLED.show();
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); 
    Serial.print(".");
  }

  //feedback to user of connecting wifi
  Serial.println("\nWiFi connected");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Define routes
  server.on("/", handleRoot);// Mainsite
  server.on("/H", handleRed);// LED red
  server.on("/L", handleGreen);// LED green
  server.on("/K", handleBlue);// LED blue
 
  // Start server
  server.begin();
  Serial.println("WebServer started!");
}

void loop() {
  server.handleClient(); // Handle incoming requests
}


When using Wi-Fi to connect Hypatia, the code is written to connect the board to the SSID and password defined within the code itself.

Additionally, the code will also include the local IP address, subnet mask, gateway, and DNS server.


from machine import Pin
from network import WLAN
import esp32
import network
import machine
import time
import ubinascii


station = None
id = str(ubinascii.hexlify(machine.unique_id()).decode().upper())
def wificonnect():
    global station
    print('INIT WIFI CONNECTION')
    Pin(21, Pin.OUT).value(0)
    station = WLAN(network.STA_IF)
    station.active(True)

    for (ssid, bssid, channel, RSSI, authmode, hidden) in station.scan():
        if (ssid == None):
            print(ssid)
        else:
            ssid = ssid.decode('utf-8')
            print(ssid)
            if str(ssid) == "SSID_WIFI":                     #SSID WiFi
                i = 0
                station.connect(str(ssid), "PASSWORD_WIFI")  #Password WiFi
                print('WIFI connecting....')
                while not station.isconnected():
                    i += 1
                    if i > 15:
                        print('WIFI forced closed')
                        return
                    machine.idle()  #save power while waiting
                    time.sleep(1)

    if station.isconnected():
        print('WIFI connected')
    time.sleep(5)
    print(station.ifconfig())
    return station

def close_wifi():
    global station
    station = WLAN(network.STA_IF)

    print('Closing WIFI...')
    station.active(False)
    print('WIFI Closed')

print("START WIFI")
wificonnect()
time.sleep(15)
close_wifi()

Sigfox

To begin configuring and programming your Hypatia board, follow these steps:

Install the Arduino IDE on your computer
Install the Adafruit library, required to properly communicate with some components on the board
Verify that all the correct configurations for the Hypatia board have been applied
Select the correct board and COM port in the Arduino IDE
Compile and upload the provided code to the ESP32 on the Hypatia board by clicking the Upload button

After a successful upload:

Open the Serial Monitor (via the button in the top-right corner of the IDE)
Make sure the baud rate is set to 9600, as initialized in the code
Ensure that you enter all three code snippets below into the IDE

#include <Arduino.h>
#include <SigfoxModule.h>

#include "SigfoxModule.h"

#define RXD2 13  //  RX-Pin
#define TXD2 14  //  TX-Pin
#define SIGFOX_PWR 6


// Builds Sigfox-Object with UART2
SigfoxModule sigfox(Serial2);

void setup() {
    Serial2.begin(9600);
    digitalWrite(SIGFOX_PWR, HIGH);  // Turn on the module
    Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
    delay(6000);

    Serial.println("Starting Sigfox Test...");
    
    // Initialisise the Sigfox-Modul
    sigfox.setSigFoxMode();

    // gets the Sigfox ID
    String sigfoxID = sigfox.getID();
    Serial.println("Device ID: " + sigfoxID);
}

void loop() {
    // Example to send a Message
    sigfox.sendMessage("HELLO1234");
    delay(10000);
}


#include "SigfoxModule.h"

SigfoxModule::SigfoxModule(HardwareSerial &uart){
  _uart = &uart;
  _uart->begin(9600, SERIAL_8N1, SIGFOX_RX, SIGFOX_TX);
  setSigFoxMode();
}

void SigfoxModule::setSigFoxMode() {
  Serial.println("Set SigFox Mode LMS100A");
  sendCommand("AT+MODE=0\r");
  }

String SigfoxModule::getID() {
  String id = sendCommand("AT$ID\r");
  while (id.indexOf("ERROR") >= 0) {
    Serial.println("Error, retrying...");
    id = sendCommand("AT$ID\r");
    }
  id.trim(); 
  Serial.println("SIGFOX ID: " + id);
  return id;
}

String SigfoxModule::sendCommand(String cmd) {
  _uart->print(cmd);
  delay(1000);

  String response = "";
  unsigned long startMillis = millis();
  while (!_uart->available() && millis() - startMillis < 5000) {
    delay(100);
  }

  while (_uart->available()) {
    response += (char)_uart->read();
  }

  Serial.println("Received response: " + response);//Debug

  return response;
}

void SigfoxModule::sendMessage(String message) {
  Serial.println("Sending SIGFOX message: " + message);
  String hexMessage = stringToHex(message);
  sendCommand("AT$SF=" + hexMessage + "\r");
}

String SigfoxModule::stringToHex(String input) {
  String hexString = "";
  for (unsigned int i = 0; i < input.length(); i++) {
    hexString += String(input[i], HEX);
  }
  return hexString;
}
void SigfoxModule::resetSigfox() {
  Serial.println("Resetting Sigfox module...");
  sendCommand("AT$RESET\r");
  delay(5000);
}




#include <Arduino.h>

#ifndef SIGFOX_MODULE_H
#define SIGFOX_MODULE_H

class SigfoxModule {
    private:
      HardwareSerial *_uart; // UART for Sigfox
      //Define the Sigfox Pinout
      int SIGFOX_TX = 14;  // USART2_TX
      int SIGFOX_RX = 13;  // USART2_RX
      int SIGFOX_RESET = 30;  // NRST (Reset Pin)
      int SIGFOX_POWER = 6;  // Power control pin (if applicable)

   

      //Define Variables for Sigfox ID and Pack
      String _sigfox_id = "";
      String _sigfox_pack = "";
    
    public:
      SigfoxModule(HardwareSerial &uart);
      String getID();
      void setSigFoxMode();
      String sendCommand(String cmd);
      void sendMessage(String message);
      String stringToHex(String input);
      void resetSigfox();
};  

#endif

Below is the code to use for connecting Hypatia via Sigfox.


from machine import Pin, UART
import esp32
import machine
import time
import ubinascii
from micropython import const


class SIGFOX(object):
    _sigfox_id = ""
    _sigfox_pack = ""

    def __init__(self, uart, debug=False):
        # turn on uart power
        if (uart == None):
            self._uart = UART(2, 9600, tx=14, rx=13, timeout=5000)
            self._uart.init(baudrate=9600, bits=8, parity=None, stop=1)
        else:
            self._uart = uart
        self.setSigFoxMode()

    def setSigFoxMode(self):
        print('Set SigFox Mode LSM100A')
        self._getuartcmd('AT+MODE=0\r')

    def setLoraMode(self):
        print('Set Lora Mode LSM100A: ' + str(self._getuartcmd('AT+MODE=1\r').decode('utf8')))

    def getid(self):
        id = self._getuartcmd('AT$ID\r')
        id = id.decode('utf8')
        while ("error" in id.lower()):
            print("errparse--->", id)
            id = self._getuartcmd('AT$ID\r')
            id = id.decode('utf8')
        id = id.lstrip('0').rstrip('\n').rstrip('\r')
        print("SIGFOX ID : " + id)
        return id

    def getpac(self):
        print('GET PAC')
        print("PAC : " + str(self._getuartcmd('AT$PAC\r').decode('utf8')))

    def getsigfoxlibrary(self):
        print('GET SIGFOX LIBRARY')
        print("SIGFOX LIBRARY : " + str(self._getuartcmd('AT$I=9\r').decode('utf8')))

    def _getuartcmd(self, cmd):
        self._uart.write(cmd)
        time.sleep(1)
        retry = 0
        ' CICLO IN ATTESA DI ATTIVAZIONE SENSORE '
        while (self._uart.any() < 1) and (retry < 10):
            retry = retry + 1
            print("retry", retry)
            self._uart.write(cmd)
            time.sleep(1)
        return self._uart.read()

    # send some bytes
    def sendmessage(self, message):
        print('Sending SIGFOX message : ' + str(message))
        self._uart.write("AT$SF=")
        self._uart.write(ubinascii.hexlify(message))
        self._uart.write("\r")
        print('Sended SIGFOX message : ' + str(message))

    def sendBytesmessage(self, message):
        print('Sending SIGFOX message : ' + str(message))
        self._uart.write("AT$SF=")
        self._uart.write(message.hex())
        self._uart.write("\r")
        print('Sended SIGFOX message : ' + str(message))

        while (self._uart.any() < 1):
            print('attendere prego')
            time.sleep(1)
        print("SIGFOX RETURN : " + str(self._uart.read()))


sig = None
sigfoxid = ""

sig = SIGFOX(None, True)
sigfoxid = sig.getid()
sig.getpac()
sig.sendmessage("Hello World")

LoRaWan

To begin configuring and programming your Hypatia board, follow these steps:

Install the Arduino IDE on your computer
Install the Adafruit library, required to properly communicate with certain components on the board
Verify that all the correct settings for the Hypatia board have been applied
Select the correct board and COM port in the Arduino IDE
Compile and upload the provided code to the ESP32 on the Hypatia board by clicking the Upload button

After a successful upload:

Open the Serial Monitor (using the button in the top-right corner of the IDE)
Make sure the baud rate is set to 9600, as defined in the code

//P2P Hypatia to Gateway Up and Downlink works
#include <Arduino.h>
#include <HardwareSerial.h>

#define LORA_UART_NUM     2
#define LORA_RX_PIN       13
#define LORA_TX_PIN       14
#define LORA_BAUD_RATE    9600

HardwareSerial LoRaSerial(LORA_UART_NUM);

void sendCommand(const char* cmd);
void readDebugResponse();
void handleLoRaToSerial();
void handleSerialToLoRa();

void setup() {
  Serial.begin(115200);
  delay(5000);
  while (!Serial);
  Serial.println("[BOOT] ESP32 LoRa Gateway Initializing...");

  LoRaSerial.begin(LORA_BAUD_RATE, SERIAL_8N1, LORA_RX_PIN, LORA_TX_PIN);
  Serial.println("[INFO] LoRa UART initialized.");

  // Soft reset
  sendCommand("ATZ\r");
  delay(1000);
  readDebugResponse();

  // Set LoRa mode
  sendCommand("AT+MODE=1\r");
  delay(500);
  readDebugResponse();

  // Set frequency band to EU868 (Band ID 5)
  sendCommand("AT+BAND=5\r");
  delay(500);
  readDebugResponse();

  // Basic ping
  sendCommand("AT\r");
  delay(500);
  readDebugResponse();

  // Look for Gateway
  sendCommand("AT+JOIN=1\r");
  delay(500);
  readDebugResponse();

  Serial.println("[READY] LSM100A configured for EU868. Enter AT commands below.");
}

void loop() {
  handleLoRaToSerial();
  handleSerialToLoRa();
}

void sendCommand(const char* cmd) {
  Serial.print("[SEND] ");
  Serial.println(cmd);
  for (int i = 0; i < strlen(cmd); i++) {
    LoRaSerial.write(cmd[i]);
    Serial.print(" 0x");
    Serial.print(cmd[i], HEX);
  }
  Serial.println();
}

void readDebugResponse() {
  unsigned long start = millis();
  while (millis() - start < 1000) {
    if (LoRaSerial.available()) {
      uint8_t c = LoRaSerial.read();
      //Serial.print("[RECV] 0x");
      //Serial.print(c, HEX);
      //Serial.print(" ('");
      Serial.print((char)c);
      //Serial.print("')");
    }
  }
}

void handleLoRaToSerial() {
  while (LoRaSerial.available()) {
    char c = LoRaSerial.read();
    Serial.print(c);
  }
}

void handleSerialToLoRa() {
  while (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();
    if (!cmd.isEmpty()) {
      // Wenn es ein AT-Befehl ist, sende ihn direkt weiter
      if (cmd.startsWith("AT")) {
        Serial.print("[ESP32 > LoRa] Sending: ");
        Serial.println(cmd);
        LoRaSerial.print(cmd);
        LoRaSerial.write('\r');
      } else {
        // Text in HEX umwandeln
        String hexPayload = "";
        for (size_t i = 0; i < cmd.length(); i++) {
          char hex[3];
          sprintf(hex, "%02X", (uint8_t)cmd[i]);
          hexPayload += hex;
        }

        // AT+SEND-Befehl erzeugen
        String atCommand = "AT+SEND=1:0:" + hexPayload;
        Serial.print("[ESP32 > LoRa] Converted to: ");
        Serial.println(atCommand);
        LoRaSerial.print(atCommand);
        LoRaSerial.write('\r');
      }
    }
  }
}



Lavoro in corso

Bluetooth

To begin configuring and programming the Hypatia board:

Install the Arduino IDE on your computer
Install the Adafruit library, required to properly communicate with some components on the board
Verify that all the correct configurations for the Hypatia board have been applied
Select the correct board and COM port
Compile and upload the provided code to the ESP32 on the Hypatia board by clicking the Upload button

Once the upload is successfully completed, you need to:

Open the Serial Monitor (via the button in the upper-right corner of the IDE)
Make sure the baud rate is set to 115200, as initialized in the code
assicurarsi che la velocità di trasmissione (baudrate) sia impostata su 115200, come inizializzato nel codice

#include <BLEDevice.h> 
#include <BLEUtils.h>
#include <BLEServer.h>

#include <FastLED.h>               // Library for controlling WS2812B LED strip   

// Define the pin to which the WS2812B LED is connected
#define LED_PIN 21
#define NUM_LEDS 1

// UUIDs for the BLE service and characteristic (can be customized)
#define SERVICE_UUID        "b0cee666-6f5c-48fa-9b6b-ee42fec51a13"
#define CHARACTERISTIC_UUID "4b15cd64-97b9-4ff2-9599-88ccd01f07f1"

// Create the object to control the LED
CRGB leds[NUM_LEDS];

// Function to set the LED color to green
void handleGreen() {
  leds[0] = CRGB::Green;  // Set color to green
  FastLED.show(); // Apply the color change
}

// BLE callback class to handle incoming data
class MyCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    String value = pCharacteristic->getValue(); // Get received data
    if (value.length() > 0) {
      Serial.println("*********");
      Serial.print("New value: ");
      for (int i = 0; i < value.length(); i++) {
        Serial.print(value[i]); // Print received data character by character
      }
      Serial.println();
      
      // Check if received value is "on"
      if (strncmp(value.c_str(), "on", 2) == 0) {
        leds[0] = CRGB::Blue;  // Set LED to blue
        FastLED.show(); 
      } 
      // Check if received value is "off"
      else if (strncmp(value.c_str(), "off", 3) == 0) {
        leds[0] = CRGB::Black;  // Turn off LED
        FastLED.show();
      }
      Serial.println("*********");
    }
  }
};

void setup() {
  Serial.begin(115200); // Start serial communication
  delay(2000); // Wait for initialization

  // Initialize the LED strip
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);   //Declare and initialize the LED
  FastLED.show(); // Ensure the LED is off initially

  Serial.println("Starting BLE initialization...");
  
  // Initialize BLE and set device name
  BLEDevice::init("MyESP32");
  Serial.println("BLE initialized!");

  // Create BLE server
  BLEServer *pServer = BLEDevice::createServer();
  Serial.println("BLE server created!");

  // Create BLE service
  BLEService *pService = pServer->createService(SERVICE_UUID);
  Serial.println("BLE service created!");

  // Define BLE characteristic with read/write properties
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
  );
  Serial.println("BLE characteristic created!");

  // Assign callback to handle characteristic writes
  pCharacteristic->setCallbacks(new MyCallbacks());
  Serial.println("Callback for characteristic set!");

  // Set initial value for the characteristic
  pCharacteristic->setValue("Hello World");

  // Start the BLE service
  pService->start();
  Serial.println("BLE service started!");

  // Start advertising BLE service
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID); // Include service in advertisements
  pAdvertising->start();
  Serial.println("BLE advertising started! Ready for connections.");
}

void loop() {
  // The loop runs continuously, but BLE handles communication automatically
  delay(2000); // Wait before next loop iteration
}


Lavoro in corso

Scroll to Top