mkrfox1200 et transmission des data

Bonjour
je cherche à transmettre les données de ma station meteo ( original comme projet :grin: ) à travers sigfox. C’est nouveau pour moi et j’ai pas tout compris.J’ai utilisé des sketch déjà fait et tenté de les mettre à ma sauce.

dans mon sketch j’ai déjà celà :

#define UINT16_t_MAX  65536           // ca sert à quoi ca ? 2^16
#define INT16_t_MAX   UINT16_t_MAX/2

typedef struct __attribute__ ((packed)) sigfox_message {
  int16_t moduleTemperature;
  int16_t capteurVitesse;
  uint16_t capteurOrientation;
  uint8_t lastMessageStatus;
} SigfoxMessage;

// Stub for message which will be sent
SigfoxMessage msg;

int vitMoy = 50; // je lui donne la valeur 50 km/h valeur comprise entre 0 et 110
int orienMoy = 355;  // l'angle est de 355 degré avec le nord valeur comprise entre 0 et 360

void setup {  // j'ai viré ce qui n'est pas intéressant
}
void loop {


msg.capteurVitesse = convertoFloatToUInt16(vitMoy, 110);
msg.capteurOrientation = convertoFloatToUInt16(orienMoy, 360);
 SigFox.begin();
  // Wait at least 30ms after first configuration (100ms before)
  delay(100);

  // We can only read the module temperature before SigFox.end()
  t = SigFox.internalTemperature();
  msg.moduleTemperature = convertoFloatToInt16(t, 60, -60);

  // Clears all pending interrupts
  SigFox.status();
  delay(1);

  SigFox.beginPacket();
  SigFox.write((uint8_t*)&msg, 12);

  msg.lastMessageStatus = SigFox.endPacket();

  SigFox.end();


}

int16_t convertoFloatToInt16(float value, long max, long min) {
  float conversionFactor = (float) (INT16_t_MAX) / (float)(max - min);
  return (int16_t)(value * conversionFactor);
}

uint16_t convertoFloatToUInt16(float value, long max) {
  float conversionFactor = (float) (UINT16_t_MAX) / (float)(max);
  return (uint16_t)(value * conversionFactor);
}

les données sont envoyées, et du coté de sigfox, je reçois bien les messages. J’ai mis en place le callback pour rediriger vers mon serveur perso

dans Custom payload config j’ai mis :

moduleTemp::int:16:little-endian capteurVitesse::int:16:little-endian capteurOrientation::uint:16:little-endian lastMsg::uint:8

et dans l’url à contacter :

http://xx.xx.xxx.xxx/dossiermeteo/w.php?o={ customData#capteurVitesse}&v={customData#capteurOrientation}&t={customData#moduleTemp}

du coté de mon serveur, le script php refuse ce qui arrive( mais pas de fichier de log), mais je peux contrôler les valeurs car il m’envoie aussi un email. mais voilà, je ne comprend pas ce qu’il m’envoie…

mon sigfox xxxxxx a envoyé à 1516464145, cette data :  dd0d0000a42f0000a7ffffff  

Sa location est à lat 51.0 et longitude :  2.0
le niveau de reception est : -126.00 et snr :24.88
vitesse : 0
orientation 12196
temperature module 3549
lastmsg  : 0

mon sigfox xxxxxx a envoyé à 1516464553, cette data :  cc0c0000499f0d00de000000  

Sa location est à lat 51.0 et longitude :  2.0
le niveau de reception est : -131.00 et snr :20.49
vitesse : 0
orientation 40777
temperature module 3276
lastmsg  : 13

Ais je besoin de faire la transformation des “int” vitMoy et orienMoy avec convertoFloatToUInt16 puisque à la base j’ai déjà des “int” ?

Comment transforme-ton la date en ici hex je suppose vers quelque chose de lisible ?

c’est quoi les little/big endian ?

Olivier ( un peu perdu…)

J’avais fait un petit tuto de prise en main si ça peut vous aider. pour les petits indiens c’est la partie du tuto où j’écris

et la magique je retrouve ma valeur B54 (correspondant à 29°)… bon ce n’est pas tout à fait B54 que l’on voit. la raison est simple 0x0B54 qui était mon nombre sur 2 octets était représenté en mémoire avec d’abord l’octet de poids faible, 0x54 puis l’octet de poids fort 0x0B. c’est ce qui a été envoyé. Comme je n’ai pas appris à Sigfox le format des données qu’il allait recevoir il m’affiche l’hexadécimal brut tel qu’il l’a reçu.

==> Pour les petits et grands indiens, il faut aller lire Wikipedia. Suivant votre architecture les octets ne sont pas rangés dans le même ordre et comme ils sont envoyés les uns après les autres il faut bien apprendre à sigfox dans quel sens les lire.

Votre structure de message

typedef struct __attribute__ ((packed)) sigfox_message {
  int16_t moduleTemperature;
  int16_t capteurVitesse;
  uint16_t capteurOrientation;
  uint8_t lastMessageStatus;
} SigfoxMessage;

ne fait pas 12 octets mais 7 donc au lieu de SigFox.write((uint8_t*)&msg, 12); il faut mettreSigFox.write((uint8_t*)&msg, sizeof(SigfoxMessage));histoire d’envoyer le bon nombre d’octets

Un int sur MKRFOX 1200 sera sur 4 octets et ceux que vous voulez envoyer dans la structure sont des int16_t soit des entiers sur 16 bits (2 octets) donc faut transformer à un moment mais effectivement ce ne sont pas des float. Tout dépend si vous voulez linéariser les valeurs sur un certain range

Pour la date dans le call back,la doc dit

time (int): the event timestamp (in seconds since the Unix Epoch)

donc Il s’agit du nombre de secondes écoulées depuis le 1er janvier 1970 00:00:00 UTC (heure unix)

Il semble que votre service web soit en PHP, pour convertir on fait

<?php
$timestamp=1516464553;
echo gmdate("Y-m-d\TH:i:s\Z", $timestamp);
?>

pour avoir l’heure GMT.

Avec une version récente de PHP, on peut aussi utiliser la classe DateTime

<?php
$date = new DateTime();
echo $date->format('U = Y-m-d H:i:s') . "\n";

$date->setTimestamp(1516464553);
echo $date->format('U = Y-m-d H:i:s') . "\n";
?>

Bonjour J'avais lu ce tuto... ( et plein d'autres)

j'ai écris ce skech, je n'ai besoin que d'envoyer les données vitMoy et orienMoy qui s’incrémentent à chaque loop, toute les deux minutes , mais rien n'arrive chez sigfox ( j'ai une réception chez sigfox si j'utilise le sketch qu'on retrouve un peu partout pour envoyer les données d'un dht)

#include "SigFox.h"
#include "ArduinoLowPower.h"


#define SLEEPTIME     3 * 60 * 1000   // Set the delay to 15 minutes (15 min x 60 seconds x 1000 milliseconds)

//#define UINT16_t_MAX  65536
//#define INT16_t_MAX   UINT16_t_MAX/2

typedef struct __attribute__ ((packed)) sigfox_message {
  uint8_t vitMoy ; //capteurVitesse;
  uint16_t orienMoy ; //capteurOrientation;
} SigfoxMessage;

// Stub for message which will be sent
SigfoxMessage msg;


uint8_t vitMoy = 55;
uint16_t orienMoy = 250; 

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.print("ready ?");
  if (!SigFox.begin()) {
    // Something is really wrong, try rebooting
    // Reboot is useful if we are powering the board using an unreliable power source
    // (eg. solar panels or other energy harvesting methods)
    reboot();
  }

  // Send module to standby until we need to send a message
  SigFox.end();

  LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, alarmEvent0, CHANGE);
}

void loop() {
  vitMoy = vitMoy + 1;
  orienMoy = orienMoy + 1;
  t = SigFox.internalTemperature();
  Serial.print(millis() / 1000); Serial.print("   ;   "); Serial.print(vitMoy); Serial.print("   en hex :   "); Serial.print(vitMoy, HEX);
  Serial.print("   ;   "); Serial.print(orienMoy); Serial.print("   en hex :   "); Serial.print(orienMoy, HEX);
  Serial.print("   ;   "); Serial.print(t); Serial.println("   en hex :   "); 



  delay(500);
  send_data();
  delay(2*50*1000);
  //LowPower.sleep(SLEEPTIME);
  alarmEvent0();

}



void reboot() {
  NVIC_SystemReset();
  while (1) ;
}

void send_data() {
  SigFox.begin();
  // Wait at least 30ms after first configuration (100ms before)
  delay(100);

  SigFox.status();
  delay(1);

  SigFox.beginPacket();
  SigFox.write((uint8_t*)&msg, sizeof(SigfoxMessage));

  SigFox.end();

}

void alarmEvent0() {
  int alarm_source = 0;
}

dans la console serie j'ai

ready ?2   ;   56   en hex :   38   ;   251   en hex :   FB   ;   -108   en hex :   
103   ;   57   en hex :   39   ;   252   en hex :   FC   ;   -5   en hex :   
203   ;   58   en hex :   3A   ;   253   en hex :   FD   ;   -5   en hex :   
304   ;   59   en hex :   3B   ;   254   en hex :   FE   ;   -5   en hex :   
405   ;   60   en hex :   3C   ;   255   en hex :   FF   ;   -5   en hex :   
506   ;   61   en hex :   3D   ;   256   en hex :   100   ;   -5   en hex :   
607   ;   62   en hex :   3E   ;   257   en hex :   101   ;   -5   en hex :   
708   ;   63   en hex :   3F   ;   258   en hex :   102   ;   -5   en hex :

Quelle est donc mon erreur ?

Olivier

À la fin du setup() vous avez gardé SigFox.end();... il faut donc un nouveau begin() pour faire des trucs avec le module

Sinon faire delay(2*50*1000); ou #define SLEEPTIME    3 * 60 * 1000 vous jouera de sales tours sur un Uno ou mega car le calcul sera fait par le preprocesseur en entier sur 16 bits donc Max 65535 et là vous dépassez largement. Il faut mettre un ul sur au moins un des nombres pour signifier au préprocesseur que l’on veut faire le calcul sur des entiers longs non signés (et sur un define il faut toujours mettre des parenthèses pour éviter toute gestion des priorités d’opérateurs Non voulue (ici ça passe car la multiplication a une bonne priorité)

Merci beaucoup pour l'aide et les liens

j'ai encore une ou deux questions

je devrais remplacer

#define SLEEPTIME     15 * 60 * 1000

par

ulong timer= (15*60 *1000);
#define SLEEPTIME ( timer)

et dans le choix de mes variables, j'ai mis

typedef struct __attribute__ ((packed)) sigfox_message {

  int8_t capteurVitesse;          //car vitesse sera comprise entre 0 et 100 km/h
  uint16_t capteurOrientation;  // valeur entre 0 et 360
  int16_t moduleTemperature;  // entre -20 et 60 degré
} SigfoxMessage;

et plus loin , je met : msg.capteurVitesse = (int32_t) (vitMoy); msg.capteurOrientation = (int32_t) (orienMoy); msg.moduleTemperature = (int32_t) (SigFox.internalTemperature() );

J'ai bêtement recopié, mais pourquoi des int32_t et pas ce qu'il y avait dans la structure du msg ?

dernière chose,

j'ai mis ca dans le callback : " capteurVitesse::uint:8:little-endian capteurOrientation::uint:16:little-endian moduleTemperature::int:16:little-endian "

quand je réceptionne un message de sigfox, j'ai ca par exemple :

a envoyé à 1516570484, cette data : 6402000b00

Sa location est à lat 51.0 et longitude : 2.0 le niveau de reception est : -138.00 et snr :12.78 vitesse : 100 orientation 2 temperature module 11

alors 100km/h c'est le 64 du data ; 2 correspond au 02 et 00 et 11 au 0b et 00. Donc je peux économiser deux octets en passant le moduleTemperature en int8_t . non ??

Cordialement Olivier

#define SLEEPTIME    (15 * 60 * 1000ul) va faire le job

Oui l’idéal serait de convertir au bon format et optimiser le nombre d’octets

SigFox.internalTemperature(); retourne un float mais vous pouvez choisir de coder cela sur un octet signé (-128° à +127° ça devrait aller)