This library is a Snootlab's library's translation to use Akene on mbed boards instead of Arduino ones. The functions Akene.begin() and Akene.send() work perfectly, but no real checkup has been made for the other functions. Feel free to implement what you want to make your device work on mbed.

Dependencies:   mbed

Committer:
Remitte
Date:
Fri Nov 27 15:43:32 2015 +0000
Revision:
1:ce17068deacf
Parent:
0:48c5b5c0395e
This library is a Snootlab's library's translation to use Akene on mbed boards instead of Arduino ones.; The functions Akene.begin() and Akene.send() work perfectly, but no real checkup has been made for the other functions.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Remitte 0:48c5b5c0395e 1 /*
Remitte 0:48c5b5c0395e 2 This file is a Snootlab's source code file's translation to use Akene on mbed boards instead of Arduino ones.
Remitte 0:48c5b5c0395e 3 The functions Akene.begin() and Akene.send() work perfectly, but no real checkup has been made for the other functions.
Remitte 0:48c5b5c0395e 4 Feel free to implement what you want to make your device work on mbed.
Remitte 0:48c5b5c0395e 5
Remitte 0:48c5b5c0395e 6 This translation is due to a Polytech Paris UPMC project led by Rémi Jourdain with the help of Clément Maciejewski.
Remitte 0:48c5b5c0395e 7
Remitte 0:48c5b5c0395e 8 Visit <http://snootlab.com>
Remitte 0:48c5b5c0395e 9 Copyright (C) 2013-2015 Snootlab. All rights reserved.
Remitte 0:48c5b5c0395e 10
Remitte 0:48c5b5c0395e 11 Akene is free software: you can redistribute it and/or modify
Remitte 0:48c5b5c0395e 12 it under the terms of the GNU General Public License as published by
Remitte 0:48c5b5c0395e 13 the Free Software Foundation, either version 3 of the License, or
Remitte 0:48c5b5c0395e 14 (at your option) any later version.
Remitte 0:48c5b5c0395e 15
Remitte 0:48c5b5c0395e 16 Akene is distributed in the hope that it will be useful,
Remitte 0:48c5b5c0395e 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
Remitte 0:48c5b5c0395e 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Remitte 0:48c5b5c0395e 19 GNU General Public License for more details.
Remitte 0:48c5b5c0395e 20
Remitte 0:48c5b5c0395e 21 You should have received a copy of the GNU General Public License
Remitte 0:48c5b5c0395e 22 along with Akene. If not, see <http://www.gnu.org/licenses/>.
Remitte 0:48c5b5c0395e 23 */
Remitte 0:48c5b5c0395e 24
Remitte 0:48c5b5c0395e 25
Remitte 0:48c5b5c0395e 26 #include "mbed.h"
Remitte 0:48c5b5c0395e 27 #include "Akene.h"
Remitte 0:48c5b5c0395e 28
Remitte 0:48c5b5c0395e 29 Akene_ Akene;
Remitte 0:48c5b5c0395e 30
Remitte 0:48c5b5c0395e 31 Akene_::Akene_() :
Remitte 0:48c5b5c0395e 32 _serial(P4_28, P4_29) { //P4_25 = Tx P4_29 = Rx
Remitte 0:48c5b5c0395e 33 //Since _lastSend is unsigned, this is infinity
Remitte 0:48c5b5c0395e 34 _lastSend = -1;
Remitte 0:48c5b5c0395e 35 _T.start();
Remitte 0:48c5b5c0395e 36 }
Remitte 0:48c5b5c0395e 37
Remitte 0:48c5b5c0395e 38 Akene_::~Akene_() {
Remitte 0:48c5b5c0395e 39 _T.stop();
Remitte 0:48c5b5c0395e 40 }
Remitte 0:48c5b5c0395e 41
Remitte 0:48c5b5c0395e 42 void Akene_::begin() {
Remitte 0:48c5b5c0395e 43 _serial.baud(9600);
Remitte 0:48c5b5c0395e 44 //Remove un-ended commands from TST's buffer
Remitte 0:48c5b5c0395e 45 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 46 _serial.putc((uint8_t)';');
Remitte 0:48c5b5c0395e 47 //Wait for the "KO;"
Remitte 0:48c5b5c0395e 48 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 49 _serial.getc(); //'K'
Remitte 0:48c5b5c0395e 50 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 51 _serial.getc(); //'O'
Remitte 0:48c5b5c0395e 52 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 53 _serial.getc(); //';'
Remitte 0:48c5b5c0395e 54 }
Remitte 0:48c5b5c0395e 55
Remitte 0:48c5b5c0395e 56
Remitte 0:48c5b5c0395e 57 bool Akene_::isReady() {
Remitte 0:48c5b5c0395e 58
Remitte 0:48c5b5c0395e 59 // IMPORTANT WARNING. PLEASE READ BEFORE MODIFYING THE CODE
Remitte 0:48c5b5c0395e 60 //
Remitte 0:48c5b5c0395e 61 // The Sigfox network operates on public frequencies. To comply with
Remitte 0:48c5b5c0395e 62 // radio regulation, it can send radio data a maximum of 1% of the time
Remitte 0:48c5b5c0395e 63 // to leave room to other devices using the same frequencies.
Remitte 0:48c5b5c0395e 64 //
Remitte 0:48c5b5c0395e 65 // Sending a message takes about 6 seconds (it's sent 3 times for
Remitte 0:48c5b5c0395e 66 // redundancy purposes), meaning the interval between messages should
Remitte 0:48c5b5c0395e 67 // be 10 minutes.
Remitte 0:48c5b5c0395e 68 //
Remitte 0:48c5b5c0395e 69 // Also make sure your send rate complies with the restrictions set
Remitte 0:48c5b5c0395e 70 // by the particular subscription contract you have with your Sigfox
Remitte 0:48c5b5c0395e 71 // network operator.
Remitte 0:48c5b5c0395e 72 //
Remitte 0:48c5b5c0395e 73 // FAILING TO COMPLY WITH THESE CONSTRAINTS MAY CAUSE YOUR MODEM
Remitte 0:48c5b5c0395e 74 // TO BE BLOCKED BY YOUR SIFGOX NETWORK OPERATOR.
Remitte 0:48c5b5c0395e 75 //
Remitte 0:48c5b5c0395e 76 // You've been warned!
Remitte 0:48c5b5c0395e 77
Remitte 0:48c5b5c0395e 78 unsigned long currentTime = _T.read_ms();
Remitte 0:48c5b5c0395e 79 if(currentTime >= _lastSend && (currentTime - _lastSend) <= 600000) {
Remitte 0:48c5b5c0395e 80 return false;
Remitte 0:48c5b5c0395e 81 }
Remitte 0:48c5b5c0395e 82
Remitte 0:48c5b5c0395e 83 // Time is ok, ask the modem's status
Remitte 0:48c5b5c0395e 84 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 85 _serial.putc((uint8_t)'S');
Remitte 0:48c5b5c0395e 86 _serial.putc((uint8_t)'F');
Remitte 0:48c5b5c0395e 87 _serial.putc((uint8_t)'P');
Remitte 0:48c5b5c0395e 88 _serial.putc((uint8_t)';');
Remitte 0:48c5b5c0395e 89
Remitte 0:48c5b5c0395e 90 return _nextReturn() == OK;
Remitte 0:48c5b5c0395e 91 }
Remitte 0:48c5b5c0395e 92
Remitte 0:48c5b5c0395e 93 bool Akene_::send(const void* data, uint8_t len) {
Remitte 0:48c5b5c0395e 94 uint8_t* bytes = (uint8_t*)data;
Remitte 0:48c5b5c0395e 95
Remitte 0:48c5b5c0395e 96 if(!isReady()) {
Remitte 0:48c5b5c0395e 97 return false;
Remitte 0:48c5b5c0395e 98 }
Remitte 0:48c5b5c0395e 99
Remitte 0:48c5b5c0395e 100 // See comment in isReady()
Remitte 0:48c5b5c0395e 101 _lastSend = _T.read_ms();
Remitte 0:48c5b5c0395e 102
Remitte 0:48c5b5c0395e 103 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 104 _serial.putc((uint8_t)'S');
Remitte 0:48c5b5c0395e 105 _serial.putc((uint8_t)'F');
Remitte 0:48c5b5c0395e 106 _serial.putc((uint8_t)'M');
Remitte 0:48c5b5c0395e 107 _serial.putc(len);
Remitte 0:48c5b5c0395e 108 for(uint8_t i = 0; i < len; ++i) {
Remitte 0:48c5b5c0395e 109 _serial.putc(bytes[i]);
Remitte 0:48c5b5c0395e 110 }
Remitte 0:48c5b5c0395e 111 _serial.putc(';');
Remitte 0:48c5b5c0395e 112
Remitte 0:48c5b5c0395e 113 uint8_t ok = _nextReturn();
Remitte 0:48c5b5c0395e 114 if(ok == OK) {
Remitte 0:48c5b5c0395e 115 _nextReturn(); //SENT
Remitte 0:48c5b5c0395e 116 return true;
Remitte 0:48c5b5c0395e 117 }
Remitte 0:48c5b5c0395e 118 return false;
Remitte 0:48c5b5c0395e 119 }
Remitte 0:48c5b5c0395e 120
Remitte 0:48c5b5c0395e 121 uint8_t Akene_::getRev() {
Remitte 0:48c5b5c0395e 122 char c;
Remitte 0:48c5b5c0395e 123 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 124 _serial.putc((uint8_t)'S');
Remitte 0:48c5b5c0395e 125 _serial.putc((uint8_t)'F');
Remitte 0:48c5b5c0395e 126 _serial.putc((uint8_t)'v');
Remitte 0:48c5b5c0395e 127 _serial.putc((uint8_t)';');
Remitte 0:48c5b5c0395e 128
Remitte 0:48c5b5c0395e 129 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 130 c = _serial.getc(); //'K' or something else
Remitte 0:48c5b5c0395e 131 if(c == 'K'){
Remitte 0:48c5b5c0395e 132 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 133 _serial.getc(); //'O'
Remitte 0:48c5b5c0395e 134 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 135 _serial.getc(); //';'
Remitte 0:48c5b5c0395e 136 return 0;
Remitte 0:48c5b5c0395e 137 }
Remitte 0:48c5b5c0395e 138 else {
Remitte 0:48c5b5c0395e 139 uint8_t rev = 10 * c - '0';
Remitte 0:48c5b5c0395e 140 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 141 rev += (_serial.getc() - '0');
Remitte 0:48c5b5c0395e 142 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 143 _serial.getc(); //'O'
Remitte 0:48c5b5c0395e 144 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 145 _serial.getc(); //'K'
Remitte 0:48c5b5c0395e 146 while(_serial.readable() == 0);
Remitte 0:48c5b5c0395e 147 _serial.getc(); //';'
Remitte 0:48c5b5c0395e 148 return rev;
Remitte 0:48c5b5c0395e 149 }
Remitte 0:48c5b5c0395e 150 }
Remitte 0:48c5b5c0395e 151
Remitte 0:48c5b5c0395e 152 unsigned long Akene_::getID() {
Remitte 0:48c5b5c0395e 153 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 154 _serial.putc((uint8_t)'S');
Remitte 0:48c5b5c0395e 155 _serial.putc((uint8_t)'F');
Remitte 0:48c5b5c0395e 156 _serial.putc((uint8_t)'I');
Remitte 0:48c5b5c0395e 157 _serial.putc((uint8_t)'D');
Remitte 0:48c5b5c0395e 158 _serial.putc((uint8_t)';');
Remitte 0:48c5b5c0395e 159
Remitte 0:48c5b5c0395e 160 //Response is [byte1, byte2, ..., byteN, 'O', 'K']
Remitte 0:48c5b5c0395e 161 uint8_t response[8] = {0};
Remitte 0:48c5b5c0395e 162 uint8_t i = 0;
Remitte 0:48c5b5c0395e 163 uint8_t c;
Remitte 0:48c5b5c0395e 164 while(!_serial.readable());
Remitte 0:48c5b5c0395e 165 c = _serial.getc();
Remitte 0:48c5b5c0395e 166 while(c != ';') {
Remitte 0:48c5b5c0395e 167 response[i] = c;
Remitte 0:48c5b5c0395e 168 while(!_serial.readable());
Remitte 0:48c5b5c0395e 169 ++i;
Remitte 0:48c5b5c0395e 170 c = _serial.getc();
Remitte 0:48c5b5c0395e 171 }
Remitte 0:48c5b5c0395e 172
Remitte 0:48c5b5c0395e 173 unsigned long id = 0;
Remitte 0:48c5b5c0395e 174
Remitte 0:48c5b5c0395e 175 for(uint8_t j = 0; j < i-2; ++j) {
Remitte 0:48c5b5c0395e 176 id += response[j] << ((i-3-j) * 8);
Remitte 0:48c5b5c0395e 177 }
Remitte 0:48c5b5c0395e 178
Remitte 0:48c5b5c0395e 179 return id;
Remitte 0:48c5b5c0395e 180 }
Remitte 0:48c5b5c0395e 181 //Power value:
Remitte 0:48c5b5c0395e 182 //0 -25 -30 dBm
Remitte 0:48c5b5c0395e 183 //1 0dBm
Remitte 0:48c5b5c0395e 184 //2 14dBm
Remitte 0:48c5b5c0395e 185 //3 16dBm
Remitte 0:48c5b5c0395e 186 //4 18dBm
Remitte 0:48c5b5c0395e 187 //5 Max (18-19dBm)
Remitte 0:48c5b5c0395e 188 bool Akene_::setPower(uint8_t power) {
Remitte 0:48c5b5c0395e 189 power = power % 6; //It's 0-5
Remitte 0:48c5b5c0395e 190 _serial.putc((uint8_t)'\0');
Remitte 0:48c5b5c0395e 191 _serial.putc((uint8_t)'S');
Remitte 0:48c5b5c0395e 192 _serial.putc((uint8_t)'F');
Remitte 0:48c5b5c0395e 193 _serial.putc((uint8_t)'G');
Remitte 0:48c5b5c0395e 194 _serial.putc(power);
Remitte 0:48c5b5c0395e 195 _serial.putc((uint8_t)';');
Remitte 0:48c5b5c0395e 196
Remitte 0:48c5b5c0395e 197 return _nextReturn() == OK;
Remitte 0:48c5b5c0395e 198 }
Remitte 0:48c5b5c0395e 199
Remitte 0:48c5b5c0395e 200 uint8_t Akene_::_nextReturn() {
Remitte 0:48c5b5c0395e 201 while(!_serial.readable());
Remitte 0:48c5b5c0395e 202 char fstChar = _serial.getc();
Remitte 0:48c5b5c0395e 203 while(_serial.getc() != ';');
Remitte 0:48c5b5c0395e 204 return fstChar;
Remitte 0:48c5b5c0395e 205 }