IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Arduino MKRFOX1200 et Sigfox backend


Sujet :

Arduino

  1. #1
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut Arduino MKRFOX1200 et Sigfox backend
    Bonjour à tous,

    Je ne sais pas s'il y a des spécialistes Sigfox sur le forum mais je souhaitais savoir s'il est possible d'envoyer et recevoir des messages entre l'Arduino (MKRFOX1200) et le backend ?
    Plus précisément ce que j'arrive à faire:
    - l'envoi tels que des données de capteurs (ex: temp et humidité) sur le backend Sigfox et les afficher sur un portail Iot.

    Ce que je souhaitais réaliser:
    - envoyer depuis le backend vers l'arduino, une donnée du portail Iot (ex: un entier représentant une limite de température qui serait réceptionné par l'arduino comme un Serial.read())

    Je ne trouve pas d'exemples de ce genre d'action et je doute que cela soit possible.

    Savez-vous svp me le confirmer ?

  2. #2
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut
    J'ai trouvé des infos intéressantes: https://github.com/sigfox/sigfox-downlink

    et encore à creuser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int ret = SigFox.endPacket(true);  // send buffer to SIGFOX network and wait for a response
    ...
    if (SigFox.parsePacket()) {
        Serial.println("Response from server:");
        while (SigFox.available()) {
          Serial.print("0x");
          Serial.println(SigFox.read(), HEX);
        }

  3. #3
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 882
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    C’est possible mais très limité
    De mémoire 4 downlink par jour, 8 octets de data du serveur vers votre arduino...

    Le backend standard peut répondre directement mais ce sont quelques variables côtés serveur ou un bout d’hexa.

    Vous pouvez aussi router la demande vers votre propre serveur http. Plus d’infos ici

  4. #4
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut
    Ca ne s'est pas fait sans mal mais après je ne sais combien de tentatives, j'arrive enfin à uploader et surtout downloader depuis le backend Sigfox.

    Mais il y a un mais... je ne sais pas comment exploiter les données qui arrivent en HEX.

    Voici le début de mes tests en sachant:
    - les données du downlink sont initialement de types String converties en HEX (exemple : 25.30.01 donne en HEX : 32352e33302e3031)
    - les données sont affichées par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    if (SigFox.parsePacket()) {
     
        Serial.println("Response from server:");
     
        while (SigFox.available()) {
     
          //Serial.print("0x");
     
        Serial.println(SigFox.read(), HEX);
     
        }
     
      } else {
     
        Serial.println("Could not get any response from the server");
     
        Serial.println("Check the SigFox coverage in your area");
     
        Serial.println("If you are indoor, check the 20dB coverage or move near a window");
     
      }
    cela affiche dans la console:
    Response from server:
    32
    35
    2E
    33
    30
    2E
    30
    31


    Ce que je souhaiterai c'est de pouvoir exploiter les données téléchargées comme par exemple un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    String incomingData = Sigfox.read()
    afin de décortiquer la chaine en paramètres exploitables.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int doorOpeningTemp = incomingData.substring(0,4).toInt(); // = 25 à partir de 3235 en HEX

    Voici le code complet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    #include <SigFox.h>
    String incomingData;
     
    void sendAndReadData(){
     
      SigFox.begin();
      delay(100);
      SigFox.debug();
     
    // define sigfox payload data structure for uplink to Iot portal
       struct data{
         int temp;
         int hum;
         int lit;
        };
     
       struct data reading;
       reading.temp = 27;
       reading.hum = 80;
       reading.lit = 50;
     
      SigFox.beginPacket();
     
      SigFox.write((const char*)&reading, sizeof(reading));
     
      int ret = SigFox.endPacket(true);  // send buffer to SIGFOX network and wait for a response
     
      if (ret > 0) {
        Serial.println("No transmission");
      } else {
        Serial.println("Transmission ok");
      }
     
    // reading downlink data from Sigfox backend
     
      if (SigFox.parsePacket()) {
        Serial.println("Response from server:");
        while (SigFox.available()) {
          //Serial.print("0x");
          Serial.println(SigFox.read(), HEX);
          //return SigFox.read();
        }
      } else {
     
        Serial.println("Could not get any response from the server");
        Serial.println("Check the SigFox coverage in your area");
        Serial.println("If you are indoor, check the 20dB coverage or move near a window");
      }
     
     // Serial.println();
      SigFox.end();
     
    }
     
     
     
    void setup() {
      Serial.begin(9600);
      sendAndReadData();
     
     
    }  
     
    void loop(){
     
    }
    Si vous savez un peu m'aider sur ce coup ce serait vraiment super de votre part.

  5. #5
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 882
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    Salut

    vous lisez vos octets en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (SigFox.available()) Serial.println(SigFox.read(), HEX);
    vous obtenez 32 35 2E 33 30 2E 30 31 et si je comprends bien c'est une réponse en ASCII qui serait donc la chaîne "25.30.01" et vous souhaitez extraire les 3 valeurs 25, 30 et 1?
    Si vous voulez utiliser la classe String (ce ne serait pas ma recommendation, une cString fera l'affaire sans souci et prendra moins de mémoire) vous pouvez modifier le code comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    String message; // on crée une chaîne
    int a,b,c; // les 3 valeurs attendues
    
    void setup() {
      Serial.begin(115200);
      message.reserve(10); // on pré-réserve 10 caractères
      ...
    }
    
    void loop() {
      ...
      if (SigFox.parsePacket()) {
        Serial.print("Response from server:");
        message = "";
        while (SigFox.available()) message += (char) SigFox.read();
        Serial.println(message);
        { // extraction dans un statement pour limiter l'impact du morcellement mémoire lié aux substring
          a = message.toInt();
          b = message.substring(message.indexOf('.') + 1).toInt();
          c = message.substring(message.lastIndexOf('.') + 1).toInt();
        }
        Serial.print(F("a = ")); Serial.println(a);
        Serial.print(F("b = ")); Serial.println(b);
        Serial.print(F("c = ")); Serial.println(c);
      } else {
        Serial.println(F("Could not get any response from the server"));
        Serial.println(F("Check the SigFox coverage in your area"));
        Serial.println(F("If you are indoor, check the 20dB coverage or move near a window");)
      }
      ...
    }
    attention il n'y a aucun test d'erreur dans ce que l'on reçoit, il faut donc que le message soit bien sous la forme "a.b.c"


    PS: je vous laisse un peu de boulot pour l'intégration à votre code

  6. #6
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut
    Merci beaucoup Jay M pour votre réponse.

    Je n'ai par contre pas été notifié par email de l'arrivée de celle-ci...

    Entretemps j'ai solutionné le problème comme ceci sans savoir si c'est optimisé ou non:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    if (SigFox.parsePacket()) {
        Serial.println("Response from server:");
        while (SigFox.available()) {
          //Serial.print("0x");
          //Serial.println(SigFox.read(), HEX);
          
          char buf = SigFox.read();
          //Serial.print(buf);
          String incomingData += buf;
    
        }
      } else {
    
        Serial.println("Could not get any response from the server");
        Serial.println("Check the SigFox coverage in your area");
        Serial.println("If you are indoor, check the 20dB coverage or move near a window");
      }
    
    
    Serial.print("settings:")  ;
    Serial.println(incomingData);
    int doorOpeningTemp = incomingData.substring(0,2).toInt();
    Serial.println(doorOpeningTemp);
    int windowOpeningTemp = incomingData.substring(3,5).toInt();
    Serial.println(windowOpeningTemp);
    Je vais étudier votre réponse car je me doute bien qu'elle doit être meilleure que la mienne

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 882
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    Salut

    votre solution est quasi identique à la mienne pour constituer la String mais vous ça ne doit pas marcher car vous déclarez une variable locale dans le while
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String incomingData += buf;
    dont la portée ne sera que le while... donc si ça compile c'est que vous avez une autre variable globale incomingData mais elle n'aura pas été mise à jour

    L'extraction de l'information doit aussi être effectuée dans le if de réception car en dehors vous ne savez pas ce qu'il y a dans incomingData. J'ai choisi de trouver les points '.' comme séparateur de l'information mais si vous êtes sûr qu'il y aura toujours 2 caractères pour chaque valeur, votre approche en utilisant les index est OK aussi

    sinon attention aux String et morcellement mémoire, donc prendre quelques précautions comme l'appel à reserve() ou traiter les substrings dans un bloc (ce qui libèrera rapidement la mémoire allouée pour calculer les Sub String intermédiaire pour faire le toInt).

  8. #8
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut
    Je reviens sur votre suggestion qui fait appel à la fonction reserve().

    En lisant la doc, cette fonction permet d'allouer un nombre défini de bytes en mémoire.
    Par rapport à ma solution de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char buf = SigFox.read();
    incomingData += buf;
    savez-vous svp me dire quel serait l'impact mémoire sur ma solution ?

    Et en dernière question, savez-vous m'expliquer la différence entre un Serial.println() et Serial.prinln(F()) ?

    Merci d'avance pour vos éclaircissements

  9. #9
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 882
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 882
    Par défaut
    si vous ne faites pas un reserve(), à chaque fois que vous ajoutez un caractère votre ancienne String devient trop petite et donc une nouvelle String est créée, l'ancienne copiée dedans puis le caractère rajouté à la fin et l'ancienne String est détruite... C'est beaucoup de traitement pour un truc tout simple et ça morcelle potentiellement la mémoire.

    Une bonne pratique donc si vous avez une idée de la taille habituelle de votre String, c'est de pré-allouer cette taille. comme cela quand vous faites
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    incomingData +=  (char) SigFox.read();
    vous rajoutez juste le caractère dans l'espace dispo. Si vous veniez à dépasser la place pré-allouée, alors le comportement décrit ci dessus viendrait s'appliquer pour pouvoir stocker les caractères supplémentaires.

    L'idée donc d'appeler reserve() c'est pour éviter ces allocations répétées. ça coûte un peu en mémoire si tout n'est pas utilisé - par exemple si vous faites reserve(20) vous aurez pré-alloué 20 octets et dans le cas présent vous n'en utilisez que 6 - mais vous gagnez en performance et stabilité éventuelle du code. Rien ne vous empêche de faire reserve(7) cependant pour être "au plus juste".

    la macro F("...") va dire au compilateur de mettre la chaîne de caractère en mémoire flash. ça évite de manger de la mémoire RAM (en plus de la mémoire FLASH qui sera de toutes façons allouée) pour pas grand chose. Regardez à la fin de la page sur PROGMEM pour en savoir plus.

  10. #10
    Membre éclairé Avatar de legrandse
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2010
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 354
    Par défaut
    Merci d'avoir donné de votre temps pour ces explications

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Communication entre sigfox et arduino uno
    Par tlg18 dans le forum Arduino
    Réponses: 4
    Dernier message: 17/09/2018, 13h08
  2. [1.x] Symfony, frontend et backend
    Par JoceC dans le forum Symfony
    Réponses: 1
    Dernier message: 21/04/2008, 15h09
  3. [Joomla!] Gestion Acces Backend
    Par jakkihm dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 15/12/2007, 20h04
  4. [newbeee] différence entre database front-end et backend
    Par mlequim dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 20/01/2006, 12h40
  5. [erreur] Backend message type 0x44 arrived while idle
    Par shwin dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 28/11/2005, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo