diff --git a/lib/LoRaRadio/LoRaRadio.h b/lib/LoRaRadio/LoRaRadio.h index 1463a76..71d1d99 100644 --- a/lib/LoRaRadio/LoRaRadio.h +++ b/lib/LoRaRadio/LoRaRadio.h @@ -1,13 +1,3 @@ -/** -* Anatole SCHRAMM-HENRY -* Tim THUREL -* Projet température de la ruche GROUPE 3 -* Wrapper C++ afin d'utiliser la LMIC (en C) façon objets. -* Commenté en anglais pour le plaisir des yeux. -* -* Tout droits réservés -*/ - #ifndef LORARADIO_H #define LORARADIO_H @@ -15,16 +5,94 @@ #include #include #include -/** -* Here, we define the onEvent function required by the LMIC -**/ -void onEvent(ev_t ev); +/*! \mainpage Guide de démarrage rapide + * + * \section intro_sec Introduction + * + * Cette bibliothèque inclue deux classes : PinMap et LoRaRadio. + * Attention, il faut préalablement installer la LMIC dans le dossier Documents\Arduino\libraries téléchargeable ici. + * + * Voici un code d'exemple de l'utilisation de l'objet LoRaRadio : + * + * \code{.cpp} + * #include + * #include "LoRaRadio.h" + * #include "PayloadFormatter.h" + * + * u1_t dio[3] = {26,33,32}; + * + * void os_getArtEui (u1_t* buf) { } + * void os_getDevEui (u1_t* buf) { } + * void os_getDevKey (u1_t* buf) { } + * + * static u1_t NWKSKEY[16] = { 0x1F, 0x9E, 0xE2, 0x7A, 0xC8, 0xBA, 0xE8, 0xEA, 0xF5, 0xC2, 0x5E, 0x47, 0x5D, 0xE0, 0x77, 0x55 }; + * static u1_t APPSKEY[16] = { 0x3B, 0x89, 0x86, 0x96, 0xBB, 0xAA, 0x38, 0x1E, 0x1F, 0xC4, 0xAD, 0x03, 0xEF, 0x3F, 0x56, 0x12 }; + * static u4_t DEVADDR = 0x260113D3;//0x03FF0001 ; // <-- Change this address for every node! + * + * unsigned long lapse(0); + * + * PinMap pinMap(18, LMIC_UNUSED_PIN, 14, dio); + * LoRaRadio radio(pinMap); + * + * PayloadFormatter pf(1,4); + * DateTime payloadDate(2020,12,26,8,42); + * double temps[4] = {21.31, 20.35, 21.25, 21.36}; + * + * void setup() + * { + * Serial.begin(115200); + * Serial.println("Starting setup"); + * radio.init(); + * radio.setTTNSession(0x1, DEVADDR, NWKSKEY, APPSKEY); + * radio.setRadioEUChannels(); + * radio.setMCUClockError(); + * lapse = millis(); + * Serial.println("Ending setup"); + * } + * + * void loop() + * { + * radio.run(); + * if(millis() - lapse > 30000) + * { + * Serial.printf("Building payload\n"); + * pf.startSession(1); + * uint8_t *p(NULL); + * uint8_t size = pf.buildPayload(&p, &payloadDate,temps); + * pf.endSession(); + * Serial.printf("Sending data\n"); + * radio.send(1, p, size); + * lapse = millis(); + * } + * } + * \endcode + * + * \author Anatole SCHRAMM-HENRY + * \author Tim THUREL + * \date 29 Jan 2020 + * \copyright All Right Reserved + */ +//void onEvent(ev_t ev); + +/*! @brief La classe PinMap permet de mapper les différentes connections faites entre le module SX127X physique et le microcontrôleur. + * + * Cet objet est ensuite utilisé par la classe LoRaRadio lors de son initialisation. + */ class PinMap { friend class LoRaRadio; public: + /*! + * Le constructeur de la classe prend en paramètres : + * @param nss : la broche du microcontrôleur qui est reliée au chip select du SX127X + * @param rxtx : la broche du microcontrôleur qui est reliée à la broche rxtx du SX127X. Si cette broche n'éxiste pas, mettre la valeur : LMIC_UNUSED_PIN. + * @param rst : la broche du microcontrôleur qui est reliée à la broche reset du SX127X. + * @param dio : un tableau de type u1_t de 3 éléments contenant les broches du microcontrôleur qui sont respectivement reliée aux broches DIO0, DIO1 et DIO2 du SX127X. + * Les broches DIOX transmettent des informations à la LMIC. Par exemple dans le mode LoRa, DIO0 correspond à TxDone et RxDone et DIO1 à RxTimeout. + * DIO2 peut quand à lui prendre la valeur LMIC_UNUSED_PIN. + */ PinMap(u1_t nss, u1_t rxtx, u1_t rst, const u1_t dio[3]) : _nss(nss), _rxtx(rxtx), _rst(rst) { _dio[0] = dio[0]; @@ -36,28 +104,86 @@ class PinMap u1_t _nss, _rxtx, _rst, _dio[3]; }; +/*! @brief La classe LoRaRadio permet de manipuler le module radio. + * + */ class LoRaRadio { public: + /*! + * Le constructeur de la classe prend en paramètres : + * @param pinMap : un objet de type PinMap créé préalablement. + * @param dataRate : de type dr_t indiquant quel spreading factor utiliser lors des envoies de données. Les valeurs possibles : DR_SF7B, DR_SF7, DR_SF8, DR_SF9, DR_SF10, DR_SF11, DR_SF12, DR_FSK et DR_NONE. + * Plus le SF choisi est faible, plus le débit est élevé mais plus l'imunité face au bruit est mauvaise. + * @param txPower : puissance d'émission comprise entre 7 et 27 inclu (à vérifier). + */ LoRaRadio(PinMap pinMap, dr_t dataRate = DR_SF7, s1_t txPower = 23); + /*! + * Initialise le SX127X. Cette méthode doit obligatoirement être appelée en premier. + */ void init(); + /*! + * Permet de renseigner les informations de la session TTN à utiliser. + * @param channelId : l'id du canal + * @param deviceAddress : l'adresse unique du noeud LoRa. Information disponible dans la console TTN. + * @param networkSystemKey : la clef de chiffrement réseau. Information disponible dans la console TTN. + * @param applicationSystemKey : la clef de chiffrement application. Information disponible dans la console TTN. + * @param linkCheckMode : Active ou désactive la vérification périodique du lien. + */ void setTTNSession(u4_t channelId, devaddr_t deviceAddress, xref2u1_t networkSystemKey, xref2u1_t applicationSystemKey, bit_t linkCheckMode = 0); + /*! + * Paramètre la radio pour utiliser les fréquences européennes comprises entre 867.1Mhz et 868.1Mhz. + */ void setRadioEUChannels(); + /*! + * Directive permettant de compenser les imprécisions dû au cristal en alongeant la fenêtre de réception. Cette méthode est à utiliser si le downlink n'est pas reçu par le noeud. + * @param percent : l'erreur de précision en % à corriger. + */ void setMCUClockError(u2_t percent = 30); + /*! + * Envoi une trame à la gateway LoRa. + * @param port : port de réception de la trame dans la console TTN. Peut prendre la valeur 1,2,3,4,5... + * @param *data : pointeur sur un tableau d'uint8_t contenant les données à envoyer. La longueur maximale des données et de 51 octets/trame quelque soit le spreading factor selectionné. + * @param length : le nombre d'octets de données. + * @param confirmed : demander un accusé de réception lors de l'envoi. + */ void send(u1_t port, uint8_t *data, uint8_t length, u1_t confirmed = false); + /*! + * Méthode à appeler dans la boucle principale afin que le module opère correctement. + * + */ void run(); + /*! + * Méthode qui enregistre un callback (pointeur de fonction) qui sera appelé lors de la réception d'un downlink. + * @param *funcP : un pointeur sur fonction qui prend 3 paramètres. la longueur de la données reçu, l'indice de la première donnée dans le buffer et un pointeur sur le buffer. + */ void setDownlinkHandler(void (*funcP)(u1_t, u1_t, u1_t*)); + /*! + * Méthode qui enregistre un callback (pointeur de fonction) qui sera appelé lorsque les donnée auront fini d'être envoyées suite à un appel à send. + * @param *funcP : un pointeur sur fonction qui ne prend pas de paramètre. + */ void setSendCompleteHandler(void (*funcP)(void)); + /*! + * Permet de désactiver un canal et donc une fréquence d'envoie. + * @param channel : le canal en question. + */ void disableEUChannel(u1_t channel); + /*! + * Permet de désactiver tous les canaux sauf un. + * @param channel : le canal à laisser actif. + */ void disableAllEUChannelsBut(u1_t channel); - + /** + * Here, we define the onEvent function required by the LMIC + **/ + friend void onEvent(ev_t ev); + protected: + private: //Function pointers used to interact with events //Parameters : dataLen, dataBeg, dataBuffer static void (*downlinkHandler)(u1_t, u1_t, u1_t*); - static void (*sendCompleteHandler)(void); - protected: - private: + static void (*sendCompleteHandler)(void); dr_t _dataRate; s1_t _txPower; PinMap _pinMap;