TTN_Mapper_in_unter_10_Minuten

Schönen Abend für jeder Anhörer,

I followed this project : https://sensebox.de/projects/de/2020-03-06-ttn-mapper made by the developper Felix and I did not take me 10 minutes, but 15. Why ?

Because one step is missing in the paragraph about registering the device in TTN. Do not forget to change the payload format from Custom --> CayenneLPP
image
I already had some custom decoder in the application from previous projects and nothing was shown on https://ttnmapper.org/experiments/?experiment=sensebox_leuven (a public TTN gateway is at my place). So just to make sure for anyone struggling with this one.

In any case, a beautiful example of what is possible with blockly and thanks to Felix to spend his time for not only this project, but also for some other things I needed his support.

Good luck with it und bis zum nächsten Mahl.

Hi @wdebbaut,

thanks for your hint. I just added a corresponding paragraph and image to the project.

It’s quite interesting to see that the GPS coordinates are some kind of rasterized. That’s due to the Cayenne LPP specification as it’s GPS accuracy is at 0.0001° (source) which is an accuracy of 11.1m in north-south direction (source). You can also check that using the measurement tool of TTN Mapper :smile:.

Best
Felix

1 Like

Genau Felix was die GPS accuracy betrifft due to the Cayenne encoding:
image
And even more disaccurate than the 11.1m : at some place 55m due to the performance of the CAM-MQ8 receiver.

The payload is indeed according to the LPP of Cayenne as one can see in the example below
.
018807C3DE00B93000111C hex decoded as:
01 --> Data Channel
88 --> GPS Data Type
07C3DE --> Latitude 50.8894
00B930 --> Longitude 4.7408
00111C --> Altitude 43.8

Nice project Felix!

Hallo miteinander,

schönes Projekt, allerdings habe ich über eine Stunde gebraucht, um auf TTN den Mapper anzulegen.
Er funktioniert im Prinzip nur meldet er nach einem ersten Übertragenen Koordinatensarz immer Beite=0, Länge=0 und Höhe =0.
Woran kann das liegen?
Das Kartenbild sieht wie folgt aus:
04

Der Code sieht so aus:


#include "SenseBoxMCU.h"
#include <SPI.h>
#include <lmic.h>
#include <hal/hal.h>
#include <CayenneLPP.h>

CayenneLPP lpp(51);


  static const u1_t PROGMEM APPEUI[8]= { 0x64, 0xDB, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 } ;
  void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI , 8);}

  static const u1_t PROGMEM DEVEUI[8]= { 0x20, 0x63, 0x23, 0xDD, 0x14, 0x3C, 0x61, 0x00 };
  void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI , 8);}

  // This key should be in big endian format (or, since it is not really a
  // number but a block of memory, endianness does not really apply). In
  // practice, a key taken from ttnctl can be copied as-is.
  // The key shown here is the semtech default key.
  static const u1_t PROGMEM APPKEY[16] = { 0x93, 0xF3, 0x94, 0x3A, 0xEC, 0x79, 0x80, 0x56, 0x60, 0xFE, 0xF3, 0xF5, 0x56, 0x3D, 0x86, 0x27 };
  void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY , 16);}

  static osjob_t sendjob;

  // Schedule TX every this many seconds (might become longer due to duty
  // cycle limitations).
  const unsigned TX_INTERVAL = 300;

  // Pin mapping
  const lmic_pinmap lmic_pins = {
      .nss = PIN_XB1_CS,
      .rxtx = LMIC_UNUSED_PIN,
      .rst = LMIC_UNUSED_PIN,
      .dio = {PIN_XB1_INT, PIN_XB1_INT, LMIC_UNUSED_PIN},
  };
GPS gps;
float latitude;
float longitude;
float height;


  void initLora() {
    delay(2000);
    // LMIC init
    os_init();
    // Reset the MAC state. Session and pending data transfers will be discarded.
    LMIC_reset();

    // Start job (sending automatically starts OTAA too)
    do_send(&sendjob);
  }


  void onEvent (ev_t ev) {
    Serial.print(os_getTime());
    Serial.print(": ");
    switch(ev) {
        case EV_SCAN_TIMEOUT:
            Serial.println(F("EV_SCAN_TIMEOUT"));
            break;
        case EV_BEACON_FOUND:
            Serial.println(F("EV_BEACON_FOUND"));
            break;
        case EV_BEACON_MISSED:
            Serial.println(F("EV_BEACON_MISSED"));
            break;
        case EV_BEACON_TRACKED:
            Serial.println(F("EV_BEACON_TRACKED"));
            break;
        case EV_JOINING:
            Serial.println(F("EV_JOINING"));
            break;
        case EV_JOINED:
            Serial.println(F("EV_JOINED"));

            // Disable link check validation (automatically enabled
            // during join, but not supported by TTN at this time).
            LMIC_setLinkCheckMode(0);
            break;
        case EV_RFU1:
            Serial.println(F("EV_RFU1"));
            break;
        case EV_JOIN_FAILED:
            Serial.println(F("EV_JOIN_FAILED"));
            break;
        case EV_REJOIN_FAILED:
            Serial.println(F("EV_REJOIN_FAILED"));
            break;
            break;
        case EV_TXCOMPLETE:
            Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
            if (LMIC.txrxFlags & TXRX_ACK)
              Serial.println(F("Received ack"));
            if (LMIC.dataLen) {
              Serial.println(F("Received "));
              Serial.println(LMIC.dataLen);
              Serial.println(F(" bytes of payload"));
            }
            // Schedule next transmission
            os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
            break;
        case EV_LOST_TSYNC:
            Serial.println(F("EV_LOST_TSYNC"));
            break;
        case EV_RESET:
            Serial.println(F("EV_RESET"));
            break;
        case EV_RXCOMPLETE:
            // data received in ping slot
            Serial.println(F("EV_RXCOMPLETE"));
            break;
        case EV_LINK_DEAD:
            Serial.println(F("EV_LINK_DEAD"));
            break;
        case EV_LINK_ALIVE:
            Serial.println(F("EV_LINK_ALIVE"));
            break;
         default:
            Serial.println(F("Unknown event"));
            break;
    }
}


void do_send(osjob_t* j){
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
        lpp.reset();
          lpp.addGPS(1, latitude, longitude, height);


        // Prepare upstream data transmission at the next possible time.
        LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
        Serial.println(F("Packet queued"));
    }
    // Next TX is scheduled after TX_COMPLETE event.
}


void setup() {
  Serial.begin(9600);
  gps.begin();
  initLora();
}

void loop() {

gps.getGPS();
latitude = gps.getLatitude();
longitude = gps.getLongitude();
height = gps.getAltitude();
os_runloop_once();

}

Wir hätten das selbe Problem am Anfang @altprog
Siehe hier im Fall GPS data Lat=0°; Long=0° (which is at the equator).


But as soon as our GPS got a fix from three satelites above, the results were these:

My advice: attach a LED display to your sensebox MCU and see if the GPS data is displaying. Then you know there is LOS (LineOfSight) at your position of the u-block device. The Arduino code for the GPS module can easily be found for instance at https://sensebox.de/projects/de/2020-03-09-mobilemessstation
Hope you will find out soon!

@altprog @wdebbaut

Als kleiner Workaround funktionert folgendes:


Solange kein GPS Signal erfasst wurde wird leerer Payload zu TTN geschickt:

Nicht unbedingt die schönste Lösung aber es erfüllt seinen Zweck. Funktioniert natürlich nur solange ihr kein Urlaub auf Null Island macht :desert_island:.

1 Like

Moin @Felix,

Am Moment bin ich beschäftigt mit CayenneLPP für die PM sensor. Die GPS module hat schon geklappt um sie über TTN nach TTNMapper zu integrieren, weil TTN Mapper ‚versteht‘ diesen LPP format.
Leider gelangt es mir nicht um die PM sensor data mit die CayenneLPP format nach OSeM zu schicken.

Unterstützt überhaupt OSeM CayenneLPP decoding? Siehe mal die blockly hierunter wo Sie feststellen können das ich die PM sensor encodiere mit CayenneLPP in vier verschiedene Channel wie die Reference vorschreibt:


Note : die Analog Value ist ein output device (i.e. an actuator). In die Arduino code habe ich die Methode nach addAnalogInput selbst geändert:
cayenneLPP_code

Trotzdem functioniert die Integration von TTN nach https://ttn.opensensemap.org/v1.1 nicht. Keine Measurements wirden geschaut auf https://opensensemap.org/explore/5e9ed85c45f937001c67aba8
obwohl in TTN die decodierung statt findet:ttn_cayenneLPP_format

Welchen Decoding Profile soll ich wählen im fall OSeM die CayenneLPP format jedoch unterstützt?

Vielen Dank um diesen Case zu untersuchen. Unsere Idee in der HochSchule ist um Blockly so viel wie möglich zu gebrauchen und die Integration nach OSeM mit TTN möglich zu machen ohne Node-Red hineinzufügen. Bis später!

Zur Info: auf myDevices decodiert CayenneLPP meine PM sensoren als analogue Sensoren mit grösse Genauigkeit:

Hi @wdebbaut,

aktuell haben wir noch keine Integration von Cayenne LPP Daten für die openSenseMap aber wir überlegen bereits wie wir das einbauen können. Allerdings kann ich noch nicht abschätzen wann es soweit sein wird.

Viele Grüße
Felix

Danke vielmal für Ihre schnelle Antwort Felix.

Weil eine Integration mit CayenneLPP noch nicht für Morgen ist, warte ich noch ein bischen um das vor zu schlagen in meiner Hochschule diese Monat. Hoffentlich werden Sie nach die Summerferien es möglich machen, weil eine directe Link zwischen ein sensebox PM sensor und OSeM für DIY Amateure einfacher ist ohne Node-Red zu arbeiten. Im zwischenzeit werde ich mich vorwärts hilfen mit Cayenne.

Ist es viele Arbeit um Ihr Analog block zu änderen nach die Methode addAnalogInput ? Da glaube ich nicht dass viele Anwender von Senseboxen ein Actuator brauchen werden (addAnalogOutput).

Bis zum nächsten Mahl und wenn mein mangelhaftiges Deutsch Sie stören, sagen Sie es…

Hi @wdebbaut,

wir haben zu addAnalogInput geändert. Evtl. musst du einmal für die Blockly Seite den Cache löschen und neu laden.

Viele Grüße
Mario

Super @mario !
Ich habe es soeben probiert und die Blocke ‘Anolog Value’ ist jetzt für ein Sensor und kein Actuator mehr. In der Code wird nun addAnlogInput als Methode eingeschrieben.

Ich werde heute Abend oder Morgen einmal probieren om die gesamte Cayenne Payload Blocke zu brauchen und nach Cayenne zu schicken (mit BME680).
Mal sehen ob das da functioniert, austehend OpenSenseMap, die leider noch kein CayenneLPP spricht: :face_with_raised_eyebrow:

  lpp.addAnalogInput(1, 0);
  lpp.addAccelerometer(1, 0, 0, 0);
  lpp.addGPS(1, 0, 0, 0);
  lpp.addLuminosity(1, 0);
  lpp.addBarometricPressure(1, 0);
  lpp.addRelativeHumidity(1, 0);
  lpp.addTemperature(1, 0);

We will keep you posted!

Moin @mario,

we are trying to imitate your project on IAQ with the BME680 sensor. We do not succeed in the switch - case programming with the blocks you are using.

How do you manage to have this setup with your blocks as in your example below?image
While each time I insert the blocks this way:
image
the following code is inserted and not working due to the extra switch (variable) statement when inserting the second Variable block:

switch (status) {
  case 0:
      display.setCursor(0,0);
      display.setTextSize(1);
      display.setTextColor(WHITE,BLACK);
      display.println(bmeTemperatur);
    display.display();
 break;
  }
  switch (status) {
  case 1:
      display.setCursor(0,0);
      display.setTextSize(1);
      display.setTextColor(WHITE,BLACK);
      display.println(bmeHumidity);
    display.display();
break;
  }

Any hints on how to do this programming visually? I could write the code myself in the Arduino IDE, but my Sensebox MUC board does not compile directly with the bsec.h library, though the bin file does :persevere: - no explanation for this.

Hi,

you can click on the small gear in the block and add more cases:

I’ll add a hint to project. Hope everythings works for you. If you want to compile the code in the Arduino IDE you have to change the platform.txt of the samd package on your computer. See here

Perfect @mario,
the Variable block for the switch-case-do procedure is now working. It all depends on those little things…

For the compiling in the Arduino code on my laptop, I still have to look for the correct platform.txt file as explained on the Bosch Github. At the present, the bootloader method works fine. As soon as I need to debug in the serial console, I will edit the platform.txt file under the condition I will have found him somewhere in my file system.

At present, the OLED display is working fine with the all the BME680 sensor values (still calibrating though). I will try to upload them to OSeM with Wifi and during the weekend with lorawan to TTN/Cayenne.

Ein schönes WochenEnde noch.

Moin @mario, or other system operator,

are there any connectivity problems on ingress.workshop.opensensemap.org ?

To be sure that our sketch is correct (project IAQ-Station), I wrote a test sketch for the BMP280 on the workshop OSeM platform to see if this sensor would be visualised. No result, in contrast to the normal ingress.opensensemap.org server where we have no problem with this test sketch.

One can see clearly in my serial debug in my Arduino IDE that there is a time-out in connecting to workshop.opensensemap.org where it normally should connect every 10s.

18:26:44.793 -> Attempting to connect to SSID: telenet-8131370
18:26:51.040 -> Successfully connected to your WiFi.
18:26:53.569 -> connecting...
18:26:53.736 -> connecting...
18:27:03.548 -> connecting...
18:27:03.649 -> connecting...

Dear @wdebbaut,

we would like to write a project about an integration to send data from the senseBox via cayenne to mydevices. As you are already familiar with both topics and you got it running, we would like to ask you if have some documentation about your project?

Kind regards
Mario

Moin Mario,
the small project of sending PM data with the Sensebox, not to TTN Mapper, but instead to https://cayenne.mydevices.com/, still works fine, at least when the sensebox is active. Here is screenshot of a simple dashboard created by default in Cayenne. The widgets can be changed easily in graphs based on historical data.



The steps to create all this, are in fact already explained in the TTN mapper project :https://sensebox.de/projects/de/2020-03-06-ttn-mapper
Except for the TTN integration, there you have to choose for Cayenne:
ttn_integration

Of course you need to have a free account, but then it is important to follow the next steps:
In their console, at the new project page select, Add Device & Widgets, pick Lora --> TheThingsNetwork.


Then choose among all the other hardware devices, this one:
config_cayenne_ttn1
Scroll to the top of the window and fill out a name and the DevEUI choosen in the TTN Application/Device console.

About Blockly, here is an example of what I did. Do not forget to choose a different channel for each sensor.

If any questions, do not hesitate to ask on this forum. Happy hacking! For the time being, one can follow real time the levels of fine dust around Leuven/Brussels Airport here

2 Likes

Thank you very much @wdebbaut!

@Felix @mario
I followed this project TTN Mapper in unter 10 Minuten | senseBox.de made by the developer Felix, in the TTN under „Live data“ I only got a Forward Join accept message , but I didn’t get a forward uplink message. What could be the reason?

Thanks in advance

Due to a new backend that TTN deployed last year, the library we use to connect to it can take up to multiple hours before successfully joining the network, that is probably what you’re seeing. Let it run for a few hours, then check again, it should (hopefully) have joined and be sending uplink packets.