Sens'it is an electronic object with several sensors and the ability to communicate on the Sigfox network. This off‑the‑shelf device can be customized for many IoT use cases.
But how can I add features to my Sens'it ? Here I will show how to implement a cool feature which use the button of the Sens'it to send morse messages from your device to a phone !
Prepare environment to connect your Sens'it to your computer (with Windows) :- Install arm-gcc for Windows
https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
- Install MINGW and MSYS
- Install dfu-util for Windows
https://sourceforge.net/projects/dfu-util/
- Update your PATH environment variable to add bin/ subdirectories of arm-gcc, mingw, msys and dfu-util
- Install Zadig for WinUSB driver
- Put Sens'it in Bootloader mode
Run Zadig and install WinUSB driver for your device
This step is required to use dfu-util on Windows
dfu-util -l
Get messages directly to your Sigfox Backend :- Register your Sens'it here
- Get your PAC number
- Activate your device and access your Sigfox Backend
https://buy.sigfox.com/activate/devkit/FR
How morse works ?Basically, morse is an alphabet coded on 6 bits. Each '.' in our case is a short press representing the value 1, and '-' is a long press representing the value 0.
But if we take, for example, the following letters:
T - M -- O ---
We have a problem, because it will be 0, 00 and 000.
So, in morse we automaticaly add 1 and <<
For the letter T: 1 << = 000010 = 2
For the letter M: 1 << << = 000100 = 4
For the letter E: 1 << + 1 = 000011 = 3
For the letter I: 1 << + 1 << + 1 = 000111 = 7
Following this logic, we get the such binary tree:
Our first mission is to handle the input for pressing the button.
For that we are going to fork the button.c from the SDK and create the button_morse.c.
This function will take as an input an array of enum, where 1 is a short press and 0 is a long press, and it returns the number of times the button was pressed.
typedef enum {
BUTTON_LONG_PRESS = 0,
BUTTON_ONE_PRESS = 1,
BUTTON_LAST
} button_e;
button_morse.h
Following the morse alphabet we can press the button minimum 1 time, maximum 5 times.
Now let's write our algorithm - the main_MORSE.c
1 - Initialization
2 - Start algorithm loop
3 - Check battery
4 - Check if there is an interupt from the reed switch to reset the Sens'it. The big change here comes from the way we reset the Sens'it to put it in bootloader mode.
We are using the reed switch to detect if a magnet is next by.
So now to put your Sensit in bootloader mode you have to put the magnet next to it and when the led blinks, just long press the button.
5 - Check if the button was pressed
6 - Start to count how many times the button was pressed and return an array with 0 for long press, and 1 for short press.
7 - Convert the code written into bytes code.
int i;
i = -1;
while (++i < size)
{
if (btn[i] == 1)
letter = (letter << 1) + 1;
else
letter = letter << 1;
}
return (letter);
Example :.- -> 1 << + 1 << -> 110 bits -> 16 decimal -> Letter A
8 - Check if the message is ended : The buffer is full (16 characters are already in the buffer) or End of Transmission code was executed (4 long press).
if (letter == 16 || number_char == 15)
9 - If yes
// LED blink white
LED_control(1, RGB_WHITE);
//Resize the payload from a u32[3] to a u8[12]
RESIZE_buffer(buffer_final, payload);
// Led blink yellow and send payload
RADIO_API_send_message(RGB_YELLOW, payload, 12, FALSE, NULL);
// Initialize
number_char = 0;
INIT_values(buffer_final, payload);
10 - Else if check if the code executed matches with a valid letter
char *morse_bt =
"**TEMNAIOGKDWRUS**QZYCXBJP*L*FVH09*8***7*****/=61****+**2***3*45";
if (morse_bt[letter] != '*')
return (1);
else
return (0);
11 - If yes, Store the letter in the buffer (it fits 16 character into a u32[3]).
Each character have a size of 6 bits and we make it fit into an array of 3 variables of 32 bits.
int shiftbits;
if (number_char > 0 && number_char < 6)
{
shiftbits = 32 - (number_char * 6);
buffer_final[0] += letter << shiftbits;
}
else if (number_char == 6)
{
buffer_final[0] += letter >> 4;
buffer_final[1] += (letter & 0xF) << 28;
}
else if (number_char > 6 && number_char < 11)
{
shiftbits = 28 - ((number_char - 6) * 6);
buffer_final[1] += letter << shiftbits;
}
else if (number_char == 11)
{
buffer_final[1] += letter >> 2;
buffer_final[2] += (letter & 0x3) << 30;
}
else if (number_char > 11 && number_char < 17)
{
shiftbits = 30 - ((number_char - 11) * 6);
buffer_final[2] += letter << shiftbits;
}
The led blinks green to say "valid".
12 - Else, the led blinks red.
To summarize, we have 3 files :
1 - main_Morse.c -> The main program
2 - button_morse.c -> Functions called into the main program
3 - button_morse.h -> Header file
(Modification of the Makefile to add a rule morse)
Load it into your Sens'it :1 - Put the Sens'it in bootloader mode (4 short press + 1 long press)
2 - Put the Dfu files in the file SDK
3 - Access your cmd, change directory for your sdk file
4 - Compile your program
make morse
5 - Load the program into your Sens'it
make prog
Get a phone message with your morse message :Create an account on https://try.iotagency.sigfox.com.
(This platform will help us on quick prototyping to avoid creating a web server).
Once your account is created, login your Sigfox Backend to get your API access.
Then on IotAgency platform add a new connector.
On "device type" the connector you just created will appear, then create a callback on it.
You will see your messages appear now !
But as you can see, I have more elements under my payload : alert and morse message.
Let's create a parser to have the same result:
Here is our parser which converts the payload into byte code.
Then we split our byte code into 3 variables: part1, part2, part3 and translate all the message into an array of 16 characters.
Finally, we push the message into an object and return an array of objects with our message and an object, called alert with the value 1.
var payload,
binary = '',
ret = [],
final = "",
parsedData = [],
obj = {},
morse = "**TEMNAIOGKDWRUS**QZYCXBJP*L*FVH09*8***7*****/=61****+**2***3*45";
// Convert hexadecimal frame to binary frame
for (var i = 0; i <= (payload.length - 2); i = i + 2) {
var byte = parseInt(payload.slice(i, i + 2), 16).toString(2);
while (byte.length < 8) {
byte = '0' + byte;
}
binary = binary.concat(byte);
}
part1 = parseInt(binary.slice(0, 32), 2);
part2 = parseInt(binary.slice(33, 64), 2);
part3 = parseInt(binary.slice(65, 96), 2);
ret[0] = (part1 & 0xFC000000) >> 26;
ret[1] = (part1 & 0x3F00000) >> 20;
ret[2] = (part1 & 0xFC000) >> 14;
ret[3] = (part1 & 0x3F00) >> 8;
ret[4] = (part1 & 0xFC) >> 2;
ret[5] = ((part1 & 0x3) << 4) + ((part2 & 0xF0000000) >> 28);
ret[6] = (part2 & 0xFC00000) >> 22;
ret[7] = (part2 & 0x3F0000) >> 16;
ret[8] = (part2 & 0xFC00) >> 10;
ret[9] = (part2 & 0x3F0) >> 4;
ret[10] = ((part2 & 0xF) << 2) + ((part3 & 0xC0000000) >> 30);
ret[11] = (part3 & 0x3F000000) >> 24;
ret[12] = (part3 & 0xFC0000) >> 18;
ret[13] = (part3 & 0x3F000) >> 12;
ret[14] = (part3 & 0xFC0) >> 6;
ret[15] = (part3 & 0x3F);
var i = -1;
while (++i < 15)
{
if (morse[ret[i]] != '*')
final += morse[ret[i]];
}
obj = {};
obj.key = 'alert';
obj.value = 1;
obj.type = '';
obj.unit = '';
parsedData.push(obj);
obj = {};
obj.key = 'morse_message';
obj.value = final;
obj.type = '';
obj.unit = '';
parsedData.push(obj);
//console.log(parsedData);
return parsedData;
Now let's create an account on https://www.nexmo.com/.
When it's done get your API keys.
Create a new connector
Now let's create an alert to send a SMS automatically when we send a message with our Sens'it:
Congratulations ! I hope you enjoyed this tutorial !
Comments