Introduction: Hugo, or 'U Go! for LinkIt ONE
What you need to assemble this kit is the LinkIt ONE board and your favourite pet. Hugo project is an enhancement kit for the Mediatek board to make an helpful wearable IoT device to meet your beloved best friend dog if you loose him.
There are situations when also the most calm and reliable dog can be panicked: during a night storm, hiking in the wood alone then loosing the direction to come back to you, coming crazy for the fireworks and escaping and many other. Not last the hunting dogs running for km following their prey; it is not rare that they forget how to come back.
How can we rescue our best-friend pet? We can, if the dog wears the Hugo device, based on the Mediatek LinkIt ONE board.
For all the Instructables community enthusiasts of this board the full assembly kit can be found on Tindie.com Don't forget to use the discount promo code 6708A90 to get 10% off!
Hugo is an Open Source device kit which software, developed with the Arduino IDE 1.6.5 (with the LinkIt ONE SDK installed) is released under the Apache 2.0 license. The last updated sources for the LinkIt ONE board are available on the GitHub repository at the following link:https://github.com/alicemirror/Hugo
Step 1: Wearable Container 3D Printable Design
The device has been designed thinking to the kind of stress it should support, wore by a dog, maybe running or escaping, eventually scared. The first goal designing the case was making a robust shell, to protect the board and sensors inside from strong solicitations.
The shell is 3D printed with ABS filament in three parts (the red ones in the images) plus an optional fourth thick component that can be used to fix the device with four M3 Allen screws to a rigid support. Hugo can be sewed with a strong wire like the 1 mm marine rope used in the images (3 mt. are included with the assembly kit).
The most important considered aspects in the design was:
- Strong and robust container
- Wearable, especially by a dog and sewable on the dog cloack
- Easy to produce at a reasonable low cost
- Easy to assemble
- All the electronic components should be included in a single shell
- As much possible lightweight (Hugo has a weight around 100 g)
- Waterproof and dust proof
You can find the stl printable files in attach
Step 2: LinkIt ONE Board and Sensors Assembly Instructions
To reduce as much as possible Hugo battery consumption there is only a single RGB LED for board visual information for benefit of the dog owner. More details about the adopted colour coding are explained in the next steps.
The available sensors are a vibration sensor and an LM35 sensor to monitor the environment temperature the animal is exposed. Using a multiple sampling strategy it is possible to reach good reliable results reflecting the real conditions the anima is exposed in any moment.
Note that as the temperature is monitored with an alarm level of max 42 C it is strategic where the device is positioned respect the animal body. The best results showed on his back.
When the shell components are printed it is possible to assemble the electronic hardware following the steps and notes described in the images.
Before starting the electronic assembly
Don't forget - to avoid to disassemble after finished - to insert the SIM card and the microSD card (optional) to the bottom of the LinkIt ONE board as first step.
Execute the following steps always with the board powered off!
- Place the battery in the battery holder area with the power cable in the passage. The cable should be sufficiently long to connect to the LinkIt ONE board on the top side
- Place the board in its position with the micro USB connector oriented to the shell connector slot. Follow the images comments paying attention to not crush the antennas cables
- Connect the antennas cables to the bottom of the board
- Check the cables positions (see the images)
- Fix the LinkIt ONE board with three screws Don't foce too much the closure; check that the board does not move when you plug/unplug the USB cable.
- Fix the three antennas with soft double-sided tape (it is included in the assembly kit). as shown in the images.
- Insert the top pin connectors with sensors and LED in the Arduino compatible pinouts (this part is provided as a single pre-assembled and tested component). The pin details to connect sensors and RGB LED are explained in the software section
- The top border of the shell should be fixed with the base hosting the electronic components, sensors and antennas with hot glue.
- Always using few drops of hot glue, fix the RGB LED to the back of the top cover (the last plastic component of the assembly). Distribute accurately the glue around the hole to make it impermeable.
- Now powering on the LinkIt ONE board you should see the on-board power green led lighting.
If you have uploaded the firmware on the board before starting the device assembly powering the LinkIt ONE board you will see the RGB LED showing once the startup sequence (all colours in sequence).
Step 3: Software and Device Control
As mentioned before, software is available under the Apache 2.0 license on GitHub.
The development of an efficient monitoring system, taking in account the need to save as much battery as possible involved some difficulties while giving reliable information with a relatively simple sensors architecture required to develop some efficient strategies that will be discussed below. For the full source (documented), please refer to the public repository above.
Visual notifications
Due its usage it is almost obvious that this device does not require a complete user interface to work. But by the other side it is very useful the ability to know the status of Hugo with just a look. The choice was to adopt a single RGB led to manage all the essential signals that has sense to be visually notified. The table explain the adopted color coding and light duration for every considered condition.
For an efficient color management has been created a bidimensional array with the RGB color settings of the RGB LED PINs and the different conditions has been associated to a specific color.
// Color coding struct<br>int rgb[8][3] = { { HIGH, LOW, LOW }, // RED { LOW, HIGH, LOW }, // GREEN { LOW, LOW, HIGH }, // BLUE { HIGH, HIGH, LOW }, // YELLOW { HIGH, LOW, HIGH }, // MAGENTA { LOW, HIGH, HIGH }, // CYAN { HIGH, HIGH, HIGH }, // WHITE { LOW, LOW, LOW } // BLACK };
#define SMS_COLOR C_YELLOW #define WEB_COLOR C_WHITE #define TEMPERATURE_ALERT_COLOR C_MAGENTA #define BATTERY_ALERT_COLOR C_RED #define MOTION_ALERT_COLOR C_BLUE #define MOTION_WARNING_COLOR C_YELLOW #define MOVING_COLOR C_GREEN
Then a simple setColor() function can set the LED of the desired color.
void setColor(int colorID) { digitalWrite(RED_PIN, rgb[colorID][L_RED]);<br> digitalWrite(GREEN_PIN, rgb[colorID][L_GREEN]);<br> digitalWrite(BLUE_PIN, rgb[colorID][L_BLUE]);<br>}
How the main loop works
The loop() function defines the entire logic of the program that is divided in three main parts:
- The SMS processor, always running accepting commands from the user
- The Web update process (if the user has updated the web cloud features)
- The alert and visual signals controls
The only activity always running is the SMS activity that periodically check the presence of messages in queue
As the linkIt ONE during the execution of the delay() command goes in power saving mode it is essential the strategy this call is used along the program; with a good optimisation it is possible to dramatically increase the device battery duration instead of having it working just few hours. The actual version of the software can remain for about 24 Hrs in standby without the need to recharge the battery. This mean, in a possible real scenario, that if the dog is in the backyard dog house and during a night I see is disappeared I can activate the device and start tracking him as well as seeing the environment temperature and his activity level.
The best calibration until now is based on the different settings of the delay periods to grand a good timing response of the Hugo device in any condition with e the less possible power consumption.
// Data update frequencies in ms<br>#define FREQ_REMOTE 10000 // (10 sec.) #define CYCLES_BATTERY_LEVEL 90 // The number of ms is CYCLES_BATTERY_LEVEL * FREQ_REMOTE (15 min) #define CYCLES_TEMPERATURE 15 // The number of ms is CYCLES_TEMPERATURE * FREQ_REMOTE (2.5 min) #define CYCLES_MOTION 30 // The number of ms is CYCLES_MOTION * FREQ_REMOTE (5 min) #define MAX_INACTIVITY_WARNING 30 // No-motion period before starting visual warning (5 min)
The SMS processor
The SMS processor check every loop cycle the presence of messages in queue and download them sending them to the parser (see the code below).
Note that after receiving the first (older) message in queue the SMS buffer is automatically cleaned so if the user send more messages without waiting the answers some of them can be lost.
void sendSMSAnswer(String smsMsg) {<br> String response = ""; // The response string to the command boolean sendResponse;
msgQueue = false; // Disable the queue. Will be reenable if impossible to send message sendResponse = false; // Set to true only if a valid command is received
// Check the message content for command // and prepare the response message
// ................................................... Hot // (this is a self-sending message) if(smsMsg.equals(CMD_OVERHEATING) ) { response = getTemperatureAlert(); sendResponse = true; // ................................................... Start } else if(smsMsg.equals(CMD_START) ) { if(!armed) { powerGPS(true); response = CMD_BOARDARMED; armed = true; sendResponse = true; } else { response = CMD_ALREADYRUNNING; sendResponse = true; } // ................................................... Stop } else if(smsMsg.equals(CMD_STOP) ) { if(armed) { powerGPS(true); response = CMD_BOARDSTOPPED; armed = false; sendResponse = true; } else { response = CMD_NOTRUNNING; sendResponse = true; } // ................................................... Info } else if(smsMsg.equals(CMD_INFO) ) { if(armed) { response = getBatteryLevel(); response += getTemperature(); response += getMotion(); response += getGPSPosition(); sendResponse = true; } else { response = CMD_NOINFO; sendResponse = true; } // ................................................... Firmware // (undocumented) } else if(smsMsg.equals(CMD_FIRMWARE) ) { char bl[MSG_BUFFER]; sprintf(bl, CMD_FIRMWAREINFO, checkBatteryLevel()); response = bl; sendResponse = true; // ................................................... Help } else if(smsMsg.equals(CMD_HELP) ) { response = CMD_HELPMSG; sendResponse = true; } // ................................................... Unknown else { response = CMD_UNKNOWN; sendResponse = true; }
// Send the answer SMS if(sendResponse) { // Set the target number beginning the SMS sending process LSMS.beginSMS(REMOTE_NUMBER); // Send the message (response) LSMS.print(response); // Try sending message or activate the queue if(!LSMS.endSMS()) { msgQueue = true; // Enable the queue for resend msgQueueMessage = smsMsg; // Saves the queued message } } // send response is true }
Note that the undocumented command Firmware is executed independently by the state of the device, returning the firmware version, release and build number the battery level and the date of the last update.
Controlling Hugo
May sound strange implementing a method to control the device via SMS, but there are many reasons that confirmed experimentally that his is probably the most reliable method.
- It is almost secure because only the authorised phone numbers can send commands.
- It is reliable, because the SMS (or text messaging) is not lost if the receiver has no coverage when it is sent. As there is coverage again the message is immediately received and processed.
- It is a low cost solution. There are many operators that gives hundreds of daily or monthly free SMS
- It does not need special services or dedicated applications to run
- Makes the remote system reachable in many conditions when more sophisticated methods fails.
- If to preferable to other wireless methods like WiFi, Bluetooth or BLE because it is supposed that in most of the cases the the device should be enables it is far away from the user.
The SMS control protocol is very simple and is based on a set of commands that should be sent to the mobile number of the device. The essential are implemented and works well, more other are under testing.
Start
This command enable the device that start tracking the position every 10 seconds and check the dog activity status and the environment temperature.
Info
Return a complete status of the sensors and the actual position. The position is shown as a Google Maps link that opens the browser on the mobile smartphone showing the position.
Stop
This command disable the system that returns in standby mode.
FUTURE IMPLEMENTATIONS:
Quiet
To save energy, the visual notification RGB LED is ignored and kept off
Collect
Enable/disable the data collection during the activity on a file saved on the microSD card.
Web
Enable/disable sending the tracking data to the web server. When enabled, the user can track the path of the dog real-time on the web but consumes more power.
Step 4: Mediatek Sandbox IoT Cloud Access
Available together with the direct inquiry through the SMS messaging as the Hugo device is activated it start also sending data to the Mediateck Cloud Sandbox server where it has been set the project Hugo. The specific variables definition are in the include file Globals.h
// Dataset fixed strings (remote variable IDs)<br>#define REMOTE_BATTERY "2001,," #define REMOTE_POSITION "1001,," #define REMOTE_MOTION "3001,," #define REMOTE_TEMPERATURE "4001,,"
Excluding the variable definition the call to the Meditech restful server remain the same, hardcoded in the program:
#define SERVER_GET "GET /mcs/v2/devices/"<br>#define SERVER_CONNECTIONS_HTTP "/connections.csv HTTP/1.1" #define SERVER_HOST "Host: " #define SERVER_DEVICE_KEY "deviceKey: " #define SERVER_CONNECTION_CLOSE "Connection: close" #define SERVER_POST "POST /mcs/v2/devices/" #define SERVER_DATAPOINTS_HTTP "/datapoints.csv HTTP/1.1" #define SERVER_DATALENGTH "Content-Length: " #define SERVER_CONTENT_TYPE "Content-Type: text/csv"
As the variable content is the only variable parameter while sending the data to the server restful APIs, this make possible to parametrise the web function as shown below:
void uploadstatus(String dataVariable){<br>
int dataLength = dataVariable.length();
if(globalClient.connect(SITE_URL, SITE_PORT)) { globalClient.print(SERVER_POST); globalClient.print(DEVICEID); globalClient.println(SERVER_DATAPOINTS_HTTP); globalClient.print(SERVER_HOST); globalClient.println(SITE_URL); globalClient.print(SERVER_DEVICE_KEY); globalClient.println(DEVICEKEY); globalClient.print(SERVER_DATALENGTH); globalClient.println(dataLength); globalClient.println(SERVER_CONTENT_TYPE); globalClient.println(SERVER_CONNECTION_CLOSE); globalClient.println(); globalClient.println(dataVariable); delay(HTTP_RESPONSE_DELAY); } }
As shown in the images from a single page it is possible to access all the last received value of the four variables shown on the server. Mediatek makes available a simple application to see the cloud data but the same information can be accesses also using a browser on any device: smartphone or computer.
In addition, two alarm triggers (low battery and over heating) has been set to send and extra email alarm as the conditions are detected by the server.
All the described steps has been tested and the software has been optimised for the best results but there are further enhancements that will be available using the same hardware platform.