Alistair MacDonald
Published © GPL3+

Freedom Help Call

An help calling system to allow that with mobility issues to feel safe and be able to call for help if they run it to a problem.

IntermediateFull instructions provided8 hours142

Things used in this project

Hardware components

Blues Notecard (Cellular)
Blues Notecard (Cellular)
×1
Blues Notecarrier A
Blues Notecarrier A
×1
Seeed Studio XIAO ESP32S3 Sense
Seeed Studio XIAO ESP32S3 Sense
×1
Li-Ion Battery 100mAh
Li-Ion Battery 100mAh
×1
Microswitch, Ultra Subminiature
Microswitch, Ultra Subminiature
×1
UNIHIKER - IoT Python Programming Single Board Computer with Touchscreen
DFRobot UNIHIKER - IoT Python Programming Single Board Computer with Touchscreen
×1

Software apps and online services

Arduino IDE
Arduino IDE
Blues Notehub.io
Blues Notehub.io

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Enclosure Base

3D printed enclosure for the Freedom Help Call (1 of 3)

Sketchfab still processing.

Enclosure Shelf

3D printed enclosure for the Freedom Help Call (2 of 3)

Sketchfab still processing.

Enclosure Top

3D printed enclosure for the Freedom Help Call (3 of 3)

Sketchfab still processing.

Flat Pocket Whistle 3mm

This is a whistle that also acts as the switch. Kudos to Jonas Daehnert for some stunning work and thanks for sharing it with the world under a creative commons licence. Please link to the original at https://www.printables.com/model/495173-flat-pocket-whistle

Sketchfab still processing.

Schematics

Wiring Diagram

How to wire the project together

Code

Freedom Help Call Firmware

Arduino
This is the firmware code to be loaded on to the Seeed Studio XIAO-ESP32-S3 microcontroller module
int isRunning = false;

void setup() {
  Serial.begin(115200);
  Serial0.begin(9600);

  // A short delay to alow everytthig to start up
  delay(6000);

  // Connect to the hub and set update period
  Serial0.println("{ \"req\": \"hub.set\", \"product\": \"com.example.example:freedomhelpcall\", \"mode\":\"periodic\", \"minutes\": 2 }");
  delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }
    
  // Enable the GPS
  Serial0.println("{ \"req\": \"card.location.mode\", \"mode\": \"periodic\", \"minutes\": 2 }");
  delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }

  // Start periodically send out location to the hub
  Serial0.println("{ \"req\":\"card.location.track\", \"start\":true, \"heartbeat\":true, \"minutes\":20, \"file\":\"_track.qo\" }");
  delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }

  // record that we are running so we can turn off
  isRunning = true;

}

void loop() {

  // Are we still running and should we now go in to slow mode (after 1 hour)
  if ( (isRunning) && (millis()>3600000) ) {

    // Update the hub and set update period
    Serial0.println("{ \"req\": \"hub.set\", \"product\": \"com.example.example:freedomhelpcall\", \"mode\":\"periodic\", \"minutes\": 120 }");
    delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }
      
    // Enable the GPS
    Serial0.println("{ \"req\": \"card.location.mode\", \"mode\": \"periodic\", \"minutes\": 120 }");
    delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }
  
    // Start periodically send out location to the hub
    Serial0.println("{ \"req\":\"card.location.track\", \"start\":true, \"heartbeat\":true, \"minutes\":120, \"file\":\"_track.qo\" }");
    delay(300); while (Serial0.available()) { Serial.write(Serial0.read()); }

    // Chage the running mode so we do not continualy update the settings
    isRunning = false;
  
  }
 
}

callback.php

PHP
The server code that is called from the blues notehub
<?PHP

// Decode the data we have been send from the notehub
$data = file_get_contents('php://input');

// Decode the data we have been send from the notehub
$datadecoded = json_decode($data);

// Check if we have a new location
if ( isset($datadecoded->best_lat) && isset($datadecoded->best_lon) ) {
	// Store the location on a temporary file
	file_put_contents("location.txt",  $datadecoded->best_lat . ", " . $datadecoded->best_lon );
}


?>

freedomhc.py

Python
The code to run on the dfrobot UNIHIKER
from unihiker import GUI
from pinpong.board import Board
from pinpong.extension.unihiker import buzzer
import time
import requests

Board().begin()
u_gui=GUI()

while True:
        url = "https://example.com/freedomhc/check.php"
        r = requests.get(url)
        if r.text != "":
                u_gui.clear()
                u_gui.draw_text(text="ALARM!",x=84,y=70,font_size=15, color="#770000")
                u_gui.draw_text(text="Location:",x=64,y=106,font_size=15, color="#000000")
                u_gui.draw_text(text=r.text,x=64,y=124,font_size=15, color="#000000")
                buzzer.play(buzzer.RINGTONE, buzzer.OnceInBackground)
        else:
                u_gui.clear()
                u_gui.draw_text(text="Clear",x=84,y=70,font_size=15, color="#770000")

        time.sleep(20)

check.php

PHP
The server code that is called from the DFRobot Unihiker
<?PHP

// Checl  the age of the last update
$fielage = time()-filemtime("location.txt");

// Check if the update was in the last 10 minutes
if ( $fielage < 600 ) {
	// return the location if we have
	echo file_get_contents("location.txt");
}


?>

Credits

Alistair MacDonald

Alistair MacDonald

6 projects • 2 followers
Thanks to Jonas Daehnert.

Comments