Garage Door Monitor and Opener

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Introduction

This system implements a simple garage door opener and environmental monitor. The hardware connects to the internet using Wi-Fi then on to the Pelion Device Management Platform which provides device monitoring and secure firmware updates over the air (FOTA). Pelion Device Management provides a flexible set of REST APIs which we will use to communicate to a web application running on an EC-2 instance in AWS. The web application will serve a web page where we can monitor and control our garage..

This project is intended to work on the DISCO-L475VG-IOT01A from ST Microelectronics It implements a simple actuator to drive a relay to simulate pushing the "open" button on older style garage doors which do not use a rolling code interface.

The system is designed to be mounted over the door so that the on board time of flight sensor can be used to detect if the door is open or closed.

The system also monitors temperature, humidity and barometric pressure.

https://os.mbed.com/media/uploads/JimCarver/garageopener.jpg

Hardware Requirements:

DISCO-L475G-IOT01A https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/

Seeed Studio Grove Relay module https://www.seeedstudio.com/Grove-Relay.html

Seeed Studio Grove cable, I used this one: https://www.seeedstudio.com/Grove-4-pin-Male-Jumper-to-Grove-4-pin-Conversion-Cable-5-PCs-per-Pack.html

Connect to the PMOD connector like this:

https://os.mbed.com/media/uploads/JimCarver/opener.jpg

This shows how I installed so that the time of flight sensor can detect when the door is open

https://os.mbed.com/media/uploads/JimCarver/opener1.jpg https://os.mbed.com/media/uploads/JimCarver/opener2.jpg

To use the project:

You will also need a Pelion developers account.

I suggest you first use the Pelion quick state to become familiar with Pelion Device Management. https://os.mbed.com/guides/connect-device-to-pelion/1/?board=ST-Discovery-L475E-IOT01A

Web Interface

For my web interface I am running node-red under Ubuntu in an EC2 instance on AWS. This can run for 12 month within the constraints of their free tier. Here is a tutorial: https://nodered.org/docs/getting-started/aws

You will also need to install several node-red add ons:

sudo npm install -g node-red-dashboard

sudo npm install -g node-red-contrib-mbed-cloud

sudo npm istall -g node-red-contrib-moment

After starting node-red import the contents of GarageFlow.txt from the project, pin the flow into the page.

To enable your web app to access your Pelion account you need an API key.

First you will neet to use your Pelion account to create an API key.

https://os.mbed.com/media/uploads/JimCarver/api_portal.jpg

Now we need to apply that API key to your Node-Red flow.

https://os.mbed.com/media/uploads/JimCarver/api_node-red.jpg

Committer:
JimCarver
Date:
Thu Dec 05 19:03:48 2019 +0000
Revision:
37:ec1124e5ec1f
Parent:
10:b27c962b3c3f
Bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 10:b27c962b3c3f 1 /*
screamer 10:b27c962b3c3f 2 * Copyright (c) 2018 ARM Limited. All rights reserved.
screamer 10:b27c962b3c3f 3 * SPDX-License-Identifier: Apache-2.0
screamer 10:b27c962b3c3f 4 * Licensed under the Apache License, Version 2.0 (the License); you may
screamer 10:b27c962b3c3f 5 * not use this file except in compliance with the License.
screamer 10:b27c962b3c3f 6 * You may obtain a copy of the License at
screamer 10:b27c962b3c3f 7 *
screamer 10:b27c962b3c3f 8 * http://www.apache.org/licenses/LICENSE-2.0
screamer 10:b27c962b3c3f 9 *
screamer 10:b27c962b3c3f 10 * Unless required by applicable law or agreed to in writing, software
screamer 10:b27c962b3c3f 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
screamer 10:b27c962b3c3f 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 10:b27c962b3c3f 13 * See the License for the specific language governing permissions and
screamer 10:b27c962b3c3f 14 * limitations under the License.
screamer 10:b27c962b3c3f 15 */
screamer 10:b27c962b3c3f 16 #include "BlockDevice.h"
screamer 10:b27c962b3c3f 17 #include "FileSystem.h"
screamer 10:b27c962b3c3f 18 #include "FATFileSystem.h"
screamer 10:b27c962b3c3f 19 #include "LittleFileSystem.h"
screamer 10:b27c962b3c3f 20
screamer 10:b27c962b3c3f 21 #if COMPONENT_SPIF
screamer 10:b27c962b3c3f 22 #include "SPIFBlockDevice.h"
screamer 10:b27c962b3c3f 23 #endif
screamer 10:b27c962b3c3f 24
screamer 10:b27c962b3c3f 25 #if COMPONENT_QSPIF
screamer 10:b27c962b3c3f 26 #include "QSPIFBlockDevice.h"
screamer 10:b27c962b3c3f 27 #endif
screamer 10:b27c962b3c3f 28
screamer 10:b27c962b3c3f 29 #if COMPONENT_DATAFLASH
screamer 10:b27c962b3c3f 30 #include "DataFlashBlockDevice.h"
screamer 10:b27c962b3c3f 31 #endif
screamer 10:b27c962b3c3f 32
screamer 10:b27c962b3c3f 33 #if COMPONENT_SD
screamer 10:b27c962b3c3f 34 #include "SDBlockDevice.h"
screamer 10:b27c962b3c3f 35 #endif
screamer 10:b27c962b3c3f 36
screamer 10:b27c962b3c3f 37 #if COMPONENT_FLASHIAP
screamer 10:b27c962b3c3f 38 #include "FlashIAPBlockDevice.h"
screamer 10:b27c962b3c3f 39 #endif
screamer 10:b27c962b3c3f 40
screamer 10:b27c962b3c3f 41 #if COMPONENT_NUSD
screamer 10:b27c962b3c3f 42 #include "NuSDBlockDevice.h"
screamer 10:b27c962b3c3f 43 #endif
screamer 10:b27c962b3c3f 44
screamer 10:b27c962b3c3f 45 using namespace mbed;
screamer 10:b27c962b3c3f 46
screamer 10:b27c962b3c3f 47 // Align a value to a specified size.
screamer 10:b27c962b3c3f 48 // Parameters :
screamer 10:b27c962b3c3f 49 // val - [IN] Value.
screamer 10:b27c962b3c3f 50 // size - [IN] Size.
screamer 10:b27c962b3c3f 51 // Return : Aligned value.
screamer 10:b27c962b3c3f 52 static inline uint32_t align_up(uint32_t val, uint32_t size)
screamer 10:b27c962b3c3f 53 {
screamer 10:b27c962b3c3f 54 return (((val - 1) / size) + 1) * size;
screamer 10:b27c962b3c3f 55 }
screamer 10:b27c962b3c3f 56
screamer 10:b27c962b3c3f 57 BlockDevice *BlockDevice::get_default_instance()
screamer 10:b27c962b3c3f 58 {
screamer 10:b27c962b3c3f 59 #if COMPONENT_SPIF
screamer 10:b27c962b3c3f 60
screamer 10:b27c962b3c3f 61 static SPIFBlockDevice default_bd(
screamer 10:b27c962b3c3f 62 MBED_CONF_SPIF_DRIVER_SPI_MOSI,
screamer 10:b27c962b3c3f 63 MBED_CONF_SPIF_DRIVER_SPI_MISO,
screamer 10:b27c962b3c3f 64 MBED_CONF_SPIF_DRIVER_SPI_CLK,
screamer 10:b27c962b3c3f 65 MBED_CONF_SPIF_DRIVER_SPI_CS,
screamer 10:b27c962b3c3f 66 MBED_CONF_SPIF_DRIVER_SPI_FREQ
screamer 10:b27c962b3c3f 67 );
screamer 10:b27c962b3c3f 68
screamer 10:b27c962b3c3f 69 return &default_bd;
screamer 10:b27c962b3c3f 70
screamer 10:b27c962b3c3f 71 #elif COMPONENT_QSPIF
screamer 10:b27c962b3c3f 72
screamer 10:b27c962b3c3f 73 static QSPIFBlockDevice default_bd(
screamer 10:b27c962b3c3f 74 MBED_CONF_QSPIF_QSPI_IO0,
screamer 10:b27c962b3c3f 75 MBED_CONF_QSPIF_QSPI_IO1,
screamer 10:b27c962b3c3f 76 MBED_CONF_QSPIF_QSPI_IO2,
screamer 10:b27c962b3c3f 77 MBED_CONF_QSPIF_QSPI_IO3,
screamer 10:b27c962b3c3f 78 MBED_CONF_QSPIF_QSPI_SCK,
screamer 10:b27c962b3c3f 79 MBED_CONF_QSPIF_QSPI_CSN,
screamer 10:b27c962b3c3f 80 MBED_CONF_QSPIF_QSPI_POLARITY_MODE,
screamer 10:b27c962b3c3f 81 MBED_CONF_QSPIF_QSPI_FREQ
screamer 10:b27c962b3c3f 82 );
screamer 10:b27c962b3c3f 83
screamer 10:b27c962b3c3f 84 return &default_bd;
screamer 10:b27c962b3c3f 85
screamer 10:b27c962b3c3f 86 #elif COMPONENT_DATAFLASH
screamer 10:b27c962b3c3f 87
screamer 10:b27c962b3c3f 88 static DataFlashBlockDevice default_bd(
screamer 10:b27c962b3c3f 89 MBED_CONF_DATAFLASH_SPI_MOSI,
screamer 10:b27c962b3c3f 90 MBED_CONF_DATAFLASH_SPI_MISO,
screamer 10:b27c962b3c3f 91 MBED_CONF_DATAFLASH_SPI_CLK,
screamer 10:b27c962b3c3f 92 MBED_CONF_DATAFLASH_SPI_CS
screamer 10:b27c962b3c3f 93 );
screamer 10:b27c962b3c3f 94
screamer 10:b27c962b3c3f 95 return &default_bd;
screamer 10:b27c962b3c3f 96
screamer 10:b27c962b3c3f 97 #elif COMPONENT_SD
screamer 10:b27c962b3c3f 98
screamer 10:b27c962b3c3f 99 static SDBlockDevice default_bd(
screamer 10:b27c962b3c3f 100 MBED_CONF_SD_SPI_MOSI,
screamer 10:b27c962b3c3f 101 MBED_CONF_SD_SPI_MISO,
screamer 10:b27c962b3c3f 102 MBED_CONF_SD_SPI_CLK,
screamer 10:b27c962b3c3f 103 MBED_CONF_SD_SPI_CS
screamer 10:b27c962b3c3f 104 );
screamer 10:b27c962b3c3f 105
screamer 10:b27c962b3c3f 106 return &default_bd;
screamer 10:b27c962b3c3f 107
screamer 10:b27c962b3c3f 108 #elif COMPONENT_NUSD
screamer 10:b27c962b3c3f 109
screamer 10:b27c962b3c3f 110 static NuSDBlockDevice default_bd;
screamer 10:b27c962b3c3f 111
screamer 10:b27c962b3c3f 112 return &default_bd;
screamer 10:b27c962b3c3f 113
screamer 10:b27c962b3c3f 114 #elif COMPONENT_FLASHIAP
screamer 10:b27c962b3c3f 115
screamer 10:b27c962b3c3f 116 #if (MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE == 0) && (MBED_CONF_FLASHIAP_BLOCK_DEVICE_BASE_ADDRESS == 0xFFFFFFFF)
screamer 10:b27c962b3c3f 117
screamer 10:b27c962b3c3f 118 size_t flash_size;
screamer 10:b27c962b3c3f 119 uint32_t start_address;
screamer 10:b27c962b3c3f 120 uint32_t bottom_address;
screamer 10:b27c962b3c3f 121 FlashIAP flash;
screamer 10:b27c962b3c3f 122
screamer 10:b27c962b3c3f 123 int ret = flash.init();
screamer 10:b27c962b3c3f 124 if (ret != 0) {
screamer 10:b27c962b3c3f 125 return 0;
screamer 10:b27c962b3c3f 126 }
screamer 10:b27c962b3c3f 127
screamer 10:b27c962b3c3f 128 //Find the start of first sector after text area
screamer 10:b27c962b3c3f 129 bottom_address = align_up(FLASHIAP_ROM_END, flash.get_sector_size(FLASHIAP_ROM_END));
screamer 10:b27c962b3c3f 130 start_address = flash.get_flash_start();
screamer 10:b27c962b3c3f 131 flash_size = flash.get_flash_size();
screamer 10:b27c962b3c3f 132
screamer 10:b27c962b3c3f 133 ret = flash.deinit();
screamer 10:b27c962b3c3f 134
screamer 10:b27c962b3c3f 135 static FlashIAPBlockDevice default_bd(bottom_address, start_address + flash_size - bottom_address);
screamer 10:b27c962b3c3f 136
screamer 10:b27c962b3c3f 137 #else
screamer 10:b27c962b3c3f 138
screamer 10:b27c962b3c3f 139 static FlashIAPBlockDevice default_bd;
screamer 10:b27c962b3c3f 140
screamer 10:b27c962b3c3f 141 #endif
screamer 10:b27c962b3c3f 142
screamer 10:b27c962b3c3f 143 return &default_bd;
screamer 10:b27c962b3c3f 144
screamer 10:b27c962b3c3f 145 #else
screamer 10:b27c962b3c3f 146
screamer 10:b27c962b3c3f 147 return NULL;
screamer 10:b27c962b3c3f 148
screamer 10:b27c962b3c3f 149 #endif
screamer 10:b27c962b3c3f 150
screamer 10:b27c962b3c3f 151 }
screamer 10:b27c962b3c3f 152
screamer 10:b27c962b3c3f 153 FileSystem *FileSystem::get_default_instance()
screamer 10:b27c962b3c3f 154 {
screamer 10:b27c962b3c3f 155 #if COMPONENT_SPIF || COMPONENT_QSPIF || COMPONENT_DATAFLASH || COMPONENT_NUSD
screamer 10:b27c962b3c3f 156
screamer 10:b27c962b3c3f 157 static LittleFileSystem flash("flash", BlockDevice::get_default_instance());
screamer 10:b27c962b3c3f 158 flash.set_as_default();
screamer 10:b27c962b3c3f 159
screamer 10:b27c962b3c3f 160 return &flash;
screamer 10:b27c962b3c3f 161
screamer 10:b27c962b3c3f 162 #elif COMPONENT_SD
screamer 10:b27c962b3c3f 163
screamer 10:b27c962b3c3f 164 static FATFileSystem sdcard("sd", BlockDevice::get_default_instance());
screamer 10:b27c962b3c3f 165 sdcard.set_as_default();
screamer 10:b27c962b3c3f 166
screamer 10:b27c962b3c3f 167 return &sdcard;
screamer 10:b27c962b3c3f 168
screamer 10:b27c962b3c3f 169 #elif COMPONENT_FLASHIAP
screamer 10:b27c962b3c3f 170
screamer 10:b27c962b3c3f 171 static LittleFileSystem flash("flash", BlockDevice::get_default_instance());
screamer 10:b27c962b3c3f 172 flash.set_as_default();
screamer 10:b27c962b3c3f 173
screamer 10:b27c962b3c3f 174 return &flash;
screamer 10:b27c962b3c3f 175
screamer 10:b27c962b3c3f 176 #else
screamer 10:b27c962b3c3f 177
screamer 10:b27c962b3c3f 178 return NULL;
screamer 10:b27c962b3c3f 179
screamer 10:b27c962b3c3f 180 #endif
screamer 10:b27c962b3c3f 181
screamer 10:b27c962b3c3f 182 }