Remember my first tutorial on Sigfox Connected Target for nerfs? Well few month have passed now and I decided to work a bit more on the project and I am now pleased to release a new tutorial: Nerf connected target on steroid. This version fixed few bugs, optimised the battery life and even count points depending how hard you hit the target. It also provides a visual integration using ArtikCloud.
For those who haven't read the first tutorial, it is using The AirBoard, an Arduino based dev kit, with a SigBee shield to send the results through Sigfox network. The advantage of The AirBoard is that it is very small and has battery integrated.
What is Sigfox?
Sigfox is a connectivity solution dedicated to the Internet of Things. The operated network is currently operating in +24 countries, on every continent. Focused on tiny messages (up to 12 bytes) & low energy consumption, it currently powers 7 million devices. Various Sigfox-compatible technical solutions are available, from different silicon vendors.
Step 1: Hardware requirementsIn this tutorial, we will be using:
- A cardboard lunch box
- A pair of scissors
- A nerf
- A lot of imagination
Connection
You just need to plug the negative wire onto the GND port and the positive to the D3~ port.
Step 2: Arduino codeInstallation
- Install Arduino IDE
- Get the Arduino library from API for ARM modules
- Copy/Past the armapi folder under Arduino/libraries
- You should also download the AirBoard libraries and copy/past it under Arduino/libraries folder to get specific data from the board such as the battery, etc...
- Download source code
Run the code
- Choose the Arduino Fio board
- Upload this program to The AirBoard via the BLE-LINK/XBee shield
- replace the BLE-LINK/XBee shield by the SIGFOX shield
- connect to the SIGFOX backend: http://backend.sigfox.com
Basic understanding of Arduino programmingBefore starting each program, we start with two "base" functions: void setup() and void loop().
- void setup() is executed in first. It is used to initialise the card.
- void loop() is executed infinitely (as long as power is provided)
See more on arduino.cc.
Code
Now we can have a look at the Arduino file:
// ---------------------------------------------------------------------
// This file is a example for use the library armapi with
// The AirBoard using the SigBee shield module
//
// This software send periodically the digital value of the pin D3~ to Sigfox network.
//
// Created date: 06.09.2016
// Author: Louis Moreau
// Adapted from: <a href="https://github.com/atim-radiocommunications/armapi"> https://github.com/atim-radiocommunications/armap...</a>
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Include
// ---------------------------------------------------------------------
#include <arm.h>
#include <avr/sleep.h>
#include <TheAirBoard.h>
// ---------------------------------------------------------------------
// Define
// ---------------------------------------------------------------------
#define GREEN 5 // GREEN LED
#define BLUE 6 // BLUE LED
#define RED 9 // RED LED
#define PIEZO 3 //Digital Pin
#define TIMEINTERVALL 900000 // 900 sec -> 15 min sleep time
// ---------------------------------------------------------------------
// Global variables
// ---------------------------------------------------------------------
//Instance of the class Arm
Arm SigFox;
//Instance of the air board class
TheAirBoard board;
bool debug = false;
//The message to send at sigfox - Set the size of your message in bytes within the brackets
uint8_t msg[2];
//downlink received message
uint8_t data[8];
bool blue = false;
bool sigfoxOK = false;
bool trigger = false;
int downlinkCounter = 0;
int points = 0;
int count = 0;
uint8_t rev;
armType_t armType;
// ---------------------------------------------------------------------
// Implemented functions
// ---------------------------------------------------------------------
void wakeUpNow() // here the interrupt is handled after wakeup
{
points++;
}
void setup()
{
//Pin modes
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(PIEZO, INPUT);
resetLeds();
if(debug){
Serial.begin(57600);
digitalWrite(GREEN, HIGH);
}else{
//Init Arm and set LED to on if error
if (SigFox.Init(&Serial) != ARM_ERR_NONE){
digitalWrite(RED, HIGH);
delay(1000);
resetLeds();
}else{
digitalWrite(GREEN, HIGH);
delay(1000);
resetLeds();
SigFox.Info(&armType, &rev, 0, 0, 0);
sigfoxOK=true;
SigFox.SetMode(ARM_MODE_SFX);
//Set Sigfox mode in uplink.
SigFox.SfxEnableDownlink(false);
//If downlink
/*
if(SigFox.SfxEnableDownlink(true)!= ARM_ERR_NONE){
digitalWrite(RED, HIGH);
}else{
digitalWrite(GREEN, HIGH);
}
*/
SigFox.UpdateConfig();
}
}
delay(1000);
resetLeds();
attachInterrupt(1, wakeUpNow, RISING);
}
void sleepNow() // here we put the device to sleep
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
attachInterrupt(1, wakeUpNow, RISING);
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
//detachInterrupt(digitalPinToInterrupt(PIEZO)); // disables interrupt so the
// wakeUpNow code will not be executed
// during normal running time.
}
void loop()
{
if(debug){
Serial.print("Awake for ");
Serial.print(count);
Serial.println(" sec");
Serial.print("Digital value :");
Serial.println(digitalRead(PIEZO));
Serial.print("Points :");
Serial.println(points);
}
blinkBlue();
delay(500);
count++;
if(count>10){
resetLeds();
if(points>1){ //to avoid sending message when switching on the device + to avoid false positive
sendMessage();
}else{
digitalWrite(RED, HIGH);
}
delay(1000);
resetLeds();
count = 0;
points = 0;
sleepNow();// sleep function called here
}
}
void sendMessage(){
if(sigfoxOK){
unsigned int i;
digitalWrite(BLUE, HIGH);
msg[0] = board.batteryChk() * 10;
msg[1] = points;
//Only if you want to check the software revision
/*
msg[2] = rev;
msg[3] = armType;
*/
//Send the message to sigfox
if(!debug){
SigFox.Send(msg, sizeof(msg));
resetLeds();
//@TODO Ask Atim why downlink doesn't work
/*SigFox.Receive(&data, sizeof(data), 60000);
if(data[i]){
digitalWrite(GREEN, HIGH);
}else{
digitalWrite(RED, HIGH);
}*/
}
resetLeds();
digitalWrite(GREEN, HIGH);
}else{
digitalWrite(RED, HIGH);
}
}
void blinkBlue(){
if(blue){
digitalWrite(BLUE, LOW);
blue = false;
}else{
digitalWrite(BLUE, HIGH);
blue = true;
}
}
void resetLeds(){
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(RED, LOW);
}
Step 3: Make the targetThis step is completely up to you.
I decided to make the target using some carton lunch box but you can use whatever support you want.
Step 4: Connect you're device to Artik CloudNow it's time to connect your device to Artik Cloud:
Artik Cloud for developers
First of all, navigate to the Artik Cloud developer platform.
- Sign up in or log in
- Create a new Device Type:I filled:"DEVICE DISPLAY NAME": "Connected Target""UNIQUE NAME": "sigfox.connected.target"
- Create a manifest for this device type
- Create some "Device Fields" and set:ID: Stringframe: Stringbattery: Integerpoints: Integer
- You can create some "Device Actions", we won't use the action for this device type. I still created a toggle action to see how it worked... :) Who knows, maybe in the future I will want to be able to shoot the target only for during a certain period...
- Activate manifest
- Fill the device info
Create your device in Artik Cloud
- Go to https://artik.cloud/my
- Log in your account (same credentials as the developers' platform)
- Click on "connect a device"
- Search for the "connected target" we just created
- Name your device
- Check its ID and copy it
Activate your device in the Sigfox Backend and configure it
- Now you can activate your device on Sigfox backend. Here is a how-to I wrote some time ago: http://blog.sigfox.com/activate-dev-kits/
- Go to your "DEVICE TYPE" and in the information tab, click on the upper right corner button "edit"
- At the bottom, you should see "Display type"
- Choose custom and add "battery::uint:8 points::uint:8"
- Save and go to the "Callback" tab
- Click on the upper right corner button "New"
- Check that the custom payload config is set to: "battery::uint:8 points::uint:8"
- Add the "https://api.artik.cloud/v1.1/messages" url to the url pattern
- Change the "Content-type" to: "application/json"
- Add the Body:
{ "data": { "frame": "{data}", "ID": "{device}", "battery": {customData#battery}, "points": {customData#points} }, "sdid": "theIdOfYourDeviceYouCopiedBefore", "type": "message" }
Check your credentials using the Artik Cloud developers API:
- Go to user and click on GET and then on try it
- You should see a field with the Authorization starting with Bearer plus some hexa characters.
- Copy it and past it in the Headers part on the Sigfox Callback
Now go back on your Artik Cloud device, go to the logs, hit the connected target, wait few seconds, you should see that the message has been received in Artik.
You can also navigate to charts and add the "points" as an entry of the chart or the battery.
Step 5: Connect to SlackNow we want the target to send a message to slack when it has been hit.
- Create a slack team or login your slack's team
- Click on your team's name and expand the menu
- Click on Apps & Integration
- Now search for incoming web hooks app
- Add a configuration
- Choose the channel you want to post your message in.
- You will see a Webhook URL, copy this link
- Go back in Sigfox Backend and create a new callback (Device Type -> Callback )
- Create a custom callback
- Past your link
- Add the content type: "application/json"
- Add the body:
{ "text": "Aouch!!! \n I've been hit again \n You just made {customData#points} points!!" }
Go back to your slack channel, you will see a message posted with your points every time your target have been hit!!
Step 6: Bonus: Create a rule to send you an email if your device battery is lowNow we can add something that can be a plus. I want Artik Cloud to send me an email if my device battery is low so that I can recharge it.
Ready?
- Create a new rule
- If Connected Target's battery is less than 31
- Then, Send Email
- Add your email address, subject and body
- Save your rule
You made it!
Thank you for your attention and do not hesitate to contact me or post a comment if you have any question.
Comments