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.
Akene.cpp@1:ce17068deacf, 2015-11-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |