Jon Phillips
Published © MIT

SafeChild Car Seat Monitoring System

A system designed to warn parents if they have left their child alone in a vehicle

IntermediateWork in progress20 hours79
SafeChild Car Seat Monitoring System

Things used in this project

Hardware components

Photon 2
Particle Photon 2
×1
Argon
Particle Argon
×1
Hall Effect Sensor
Hall Effect Sensor
×1
vibrating disk motor
×2
Flora RGB Neopixel LEDs- Pack of 4
Adafruit Flora RGB Neopixel LEDs- Pack of 4
×2
Magnet
×1
Buzzer
Buzzer
×1
Rechargeable Battery, 3.7 V
Rechargeable Battery, 3.7 V
×2
Terminal Block, generic
×1

Software apps and online services

Visual Studio 2017
Microsoft Visual Studio 2017
With Particle Workbench Extension
SolidWorks
For 3D Design of cases
Adafruit.IO
Used to create an online dashboard and provide feed data for Zapier
Zapier.com
monitors feed data from Adafruit and sends SMS message to parents phone if alarm is activated

Hand tools and fabrication machines

Breadboard, 170 Pin
Breadboard, 170 Pin
Bambu Labs 3D Printer
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Digital Multimeter
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

key fob

enclosure for the key fob device

Hall Sensor

Encloser for the hall sensor device

Magnet Case

The case that holds the magnet for the Hall Sensor Device

Schematics

Key Fob

Hall Effect Sensor

Code

Hall Sensor

C/C++
This is the device that monitors the safety belt and transmits the status to the reciever.
/* 
 * Project Hall effect sensor for SafeChild Car Seat Monitor
 * Author: Jon Phillips
 * Last Updated: 30 November 2023
 */


#include "Particle.h"
#include <NeoPixel.h>


SYSTEM_MODE(SEMI_AUTOMATIC);
const int PIXELCOUNT = 1;
Adafruit_NeoPixel pixel(PIXELCOUNT, D2 , WS2812B );
const int DETECT = D8;
bool magPres;
bool redFlash;
int Timer;
int isBuckled;
const int UART_TX_BUF_SIZE = 2;
const BleUuid serviceUuid("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
const BleUuid txUuid("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
BleCharacteristic txCharacteristic("tx", BleCharacteristicProperty::NOTIFY, txUuid, serviceUuid);
byte txBuf[UART_TX_BUF_SIZE];




void setup() {
    pinMode(DETECT,INPUT);
    pixel.begin();
    pixel.show();
    pixel.setBrightness(30);

    Serial.begin(9600);
    waitFor(Serial.isConnected, 15000);
    BLE.on();
    BLE.setTxPower(-30);
    BLE.addCharacteristic(txCharacteristic);
    BleAdvertisingData data;
    data.appendServiceUUID(txUuid);
    BLE.advertise(&data);

    Serial.printf("SafeChild Hall Effect Sensor BLE Address: %s\n", BLE.address().toString().c_str());


}


void loop() {

    magPres = digitalRead(DETECT);

    if(!magPres){
        pixel.setPixelColor(0,0xff0000);
        pixel.show();
        pixel.clear();
        isBuckled = 1;

        // Serial.printf("magnet present\n");

    }

    if(magPres){
        pixel.clear();
        pixel.show();
        isBuckled =0;
        // Serial.printf("magnet NOT present\n");
    }

    if(BLE.connected()){
        sprintf((char*)txBuf, "%i",isBuckled);
        txCharacteristic.setValue(txBuf , UART_TX_BUF_SIZE );
        // Serial.printf("buffer message: %s\n",(char *)txBuf);
        delay(1000);
  }

}

Key Fob

C/C++
This device attaches to the drivers key ring and monitors signal from the Hall effect sensor. This device also publishes information to the Adafruit.IO feed, and activates the alert system if needed.
/* 
 * Project: Key fob for SafeChild Care Seat Monitor
 * Author: Jon Phillips
 * Last Updated: 30 November 2023
 */


#include "Particle.h"
#include <NeoPixel.h>
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT/Adafruit_MQTT_SPARK.h>
#include <Adafruit_MQTT/Adafruit_MQTT.h>
#include <credentials.h>
#include <math.h>
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

void bleConnect();
void onDataReceived(const uint8_t *data, size_t len, const BlePeerDevice &peer, void *context);
void MQTT_connect();
bool MQTT_ping();
void publish();
void alert();
const int PIXELCOUNT = 1;
bool alertOn;


Adafruit_NeoPixel pixel ( PIXELCOUNT, SPI1 , WS2812B );


const BleUuid serviceUuid("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
const BleUuid rxUuid("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
const BleUuid txUuid("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
const size_t SCAN_RESULT_MAX = 20;


BleScanResult scanResults[SCAN_RESULT_MAX];
BleCharacteristic peerRxCharacteristic;
BleCharacteristic peerTxCharacteristic;
BlePeerDevice peer;
BleCharacteristic rxCharacteristic ("rx",BleCharacteristicProperty::WRITE_WO_RSP,rxUuid,serviceUuid,onDataReceived,NULL);
uint8_t i;

TCPClient TheClient; 
Adafruit_MQTT_SPARK mqtt(&TheClient,AIO_SERVER,AIO_SERVERPORT,AIO_USERNAME,AIO_KEY); 
Adafruit_MQTT_Publish pubFeedLt = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/SafeChildLight");
Adafruit_MQTT_Publish pubFeedTxt = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/SafeChildText");
Adafruit_MQTT_Publish pubFeedFR = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/SafeChildFobRange");
const int BUZZER = D16;
const int VIBRATE1 = D1;
const int VIBRATE2 = D6;
int count;
int RSSI;
int BuckleCheck;
bool lastBuckleCheck;
int timer;
int lastTime;

Thread thread("ALERT",alert);

void setup() {
    Serial.begin(9600);
    waitFor(Serial.isConnected, 15000);
    
    BLE.on();
    peerTxCharacteristic.onDataReceived(onDataReceived, &peerTxCharacteristic);

    pixel.begin();
    pixel.show();
    pixel.setBrightness(100);
    pinMode (BUZZER,OUTPUT);

    WiFi.on();
    WiFi.connect();
    while(WiFi.connecting()) {
    Serial.printf(".");
    
    }

}


void loop() {   
    MQTT_connect();
    MQTT_ping();
    bleConnect();

       
    while(peer.connected()){
    
        pixel.setBrightness(40);
        pixel.setPixelColor(0,0x0000ff);
        pixel.show();
        peer.getCharacteristicByUUID(peerRxCharacteristic, rxUuid);
        peer.getCharacteristicByUUID(peerTxCharacteristic, txUuid); 
        publish();    
        alertOn=false;               
    }

    while(!peer.connected()){
        
        if(lastBuckleCheck){
            // pixel.setBrightness(100);
            // pixel.setPixelColor(0,0xff0000);
            // pixel.show();                      
            alertOn=true;
            // pixel.clear();
            // pixel.show();
            publish();
            
        }
        if(!lastBuckleCheck){
            pixel.setBrightness(40);
            pixel.setPixelColor(0,0x00ff00);
            pixel.show();
            publish();
        }
        
        bleConnect();
    } 
 
}

void onDataReceived(const uint8_t *data, size_t len, const BlePeerDevice &peer, void *context){
 
    if(peer.address()[0]==0x05){

        
        BuckleCheck = atoi((char*)data);


       
        if(BuckleCheck==1){
            pixel.setPixelColor(0,0x0000ff);
            lastBuckleCheck=true;
            }

        if(BuckleCheck==0){
            pixel.setPixelColor(0,0x0000ff);
            pixel.show();
            lastBuckleCheck=false;
        }

        
    }
}

void bleConnect(){
    count = BLE.scan(scanResults, SCAN_RESULT_MAX);
    if(count > 0){
        for( i = 0; i < count; i++){
        BleUuid foundServiceUuid;
        size_t svcCount = scanResults[i].advertisingData().serviceUUID(&foundServiceUuid,1);
            if(svcCount > 0 && foundServiceUuid == txUuid){
                RSSI = scanResults[i].rssi();
                
                peer = BLE.connect(scanResults[i].address());        
            }
        }
    }
}

void MQTT_connect() {
  int8_t ret;
 
  // Return if already connected.
  if (mqtt.connected()) {
    return;
  }
 
  Serial.print("Connecting to MQTT... ");
 
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.printf("Error Code %s\n",mqtt.connectErrorString(ret));
       Serial.printf("Retrying MQTT connection in 5 seconds...\n");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds and try again
  }
  Serial.printf("MQTT Connected!\n");
}

bool MQTT_ping() {
  static unsigned int last;
  bool pingStatus;

  if ((millis()-last)>120000) {
      Serial.printf("Pinging MQTT \n");
      pingStatus = mqtt.ping();
      if(!pingStatus) {
        Serial.printf("Disconnecting \n");
        mqtt.disconnect();
      }
      last = millis();
  }
  return pingStatus;
}

void publish(){
    static int counter;


     if((millis()-lastTime) > 8000) {
        lastTime = millis();
            if(mqtt.Update()) {
           
            // Serial.printf("Publishing ---- %i \n",lastBuckleCheck); 
           
            
            if(lastBuckleCheck && peer.connected()){
                pubFeedTxt.publish("Car seat in range, Seat Belt Locked");                
                pubFeedFR.publish(0);
                pubFeedLt.publish(0);
            }
            if(!lastBuckleCheck && peer.connected()){
                pubFeedTxt.publish("Car seat in range,Seat Belt not locked");                
                pubFeedFR.publish(0);
                pubFeedLt.publish(0);
            }   
            if(!peer.connected() && !lastBuckleCheck){
                pubFeedTxt.publish("Car seat out of range, Seat belt not locked");
                pubFeedFR.publish(1);
                pubFeedLt.publish(0);
            }
            if(!peer.connected() && lastBuckleCheck){
                pubFeedTxt.publish("DANGER!!! IS YOUR CHILD SAFE???");                
                pubFeedFR.publish(0);
                pubFeedLt.publish(1);
            }

            
        }
     }


}

void alert(){
    static int i;
    static float t, t2;
    int sinWave, sinWave2;
    pinMode(VIBRATE1,OUTPUT);
    pinMode(VIBRATE2,OUTPUT);
    while(true){
    if(alertOn){
        t = millis()/1000.0;
        t2 = millis()/1000.0;
        sinWave = 500*sin(2*M_PI*(2)*t)+3000;
        sinWave2 = 126*sin(2*M_PI*(2)*t2)+127;
        tone(BUZZER,sinWave,500);
        pixel.setBrightness(sinWave2);
        pixel.setPixelColor(0,0xff0000);
        pixel.show();  
        delay(90);
        noTone(BUZZER);
        pixel.clear();
        pixel.show();
        digitalWrite(VIBRATE1,HIGH);
        digitalWrite(VIBRATE2,HIGH);          
    }
    else{
    digitalWrite(VIBRATE1,LOW);
    digitalWrite(VIBRATE2,LOW);
    }
    }
    
}

Credits

Jon Phillips
4 projects • 5 followers
Recently graduated a full time Deep Dive IoT bootcamp and interested in starting a career in robotics. Also pursing a degree in Comp Prog.
Contact

Comments

Please log in or sign up to comment.