For those who received their Badgerboard last week: the hardware seems nice, but its Arduino library seems to be in some beta state (if only given the many commented/disabled lines of code), for which nothing really changed since December 13th.
I wonder if their frequency plan is set up correctly. (See errors below; no documented way to select a plan, I think, but maybe that should be in the firmware?) Also, its core library includes helpers that send the temperature and humidity readings or status messages. Those are not only quite funny needlessly complex, but also reserve a whopping 60 bytes to send JSON (not a good practice) and are sent as confirmed uplinks (very limited). And worst of all: it includes a duplicate of the FaBo HTS221 library, which breaks compiling other Arduino sketches that use the original.
So, forget about trying to fix that, but get the TTN Arduino library to run on it.
Running the TTN library on Badgerboard
Main problem: one needs to reset the RN2483 after powering or flashing the board, otherwise it will just not respond to any command (or any Serial1.write
) and the TTN library will seem to wait forever. (I guess the boardâs electronics could have done that too, but well. Still no schematics, I think.)
-
Install the TTN library following its documentation.
-
Install the FaBo 208 Humidity library, which also supports the temperature. (Using the âSmartEverything ST HTS221â library gives me warnings on the latest Arduino IDE; it will work, but the warnings are annoying, and the FaBo library gives the same results though itâs a bit older.)
-
Uninstall any Badgerboard library (its included duplicate of the FaBo library throws errors; see below). -
In the Tools menu, set the board type to âLilyPad Arduino USBâ, as documented for the board, and select its port.
-
From the File, Examples menu, load one of the TTN example sketches.
-
Somewhere above
setup()
, add:#define BADGERBOARD_LORA_RESET_PIN 5 void resetBadgerboard() { debugSerial.println(F("Resetting Badgerboard RN2483 module")); pinMode(BADGERBOARD_LORA_RESET_PIN, OUTPUT); digitalWrite(BADGERBOARD_LORA_RESET_PIN, LOW); // In the original code, this has "sleep_wdt_approx(15)" here; unclear why digitalWrite(BADGERBOARD_LORA_RESET_PIN, HIGH); }
-
In
setup()
, call that function:resetBadgerboard();
Thatâs it. Your TTN example sketch should work now. (Of course, set your keys and freqPlan
.)
Getting temperature, humidity and battery level
Assuming you installed the FaBo HTS221 library above:
-
Add the library to the top of your sketch (alternatively see menu Sketch, Include Library), and define a variable to use it:
#include <FaBoHumidity_HTS221.h> FaBoHumidity_HTS221 hts221;
-
In
setup()
add:// Initialize the built-in temperature/humidity sensor if (hts221.begin()) { debugSerial.print(F("Configured built-in HTS221 sensor: ")); debugSerial.print(hts221.getTemperature()); debugSerial.print(F("C, ")); debugSerial.print(hts221.getHumidity()); debugSerial.println(F("%")); } else { debugSerial.println(F("Failed to configure built-in HTS221 sensor")); }
-
Somewhere above
loop()
, define a function to send the readings. The battery level is taken frombadger_read_vcc_mv
in the Badgerboard library, but only supporting LilyPadâs ATmega32U4. It yields higher values than the one TTNâsttn.showStatus()
prints.// Reserve 6 bytes (3 words) to send temperature, humidity and voltage byte data[6]; void sendTemperatureAndHumidity(bool includeStatus) { // Encode the 2 doubles into the first 4 bytes int temp = 100 * hts221.getTemperature(); int humi = 100 * hts221.getHumidity(); data[0] = temp >> 8; // or: highByte(temp) data[1] = temp; // or: lowByte(temp) data[2] = humi >> 8; data[3] = humi; if (!includeStatus) { // Send 4 bytes on port 1, to know the format in the payload functions ttn.sendBytes(data, 4, 1); } else { // Also encode the battery level into the next 2 bytes ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both // Vcc (in mV); 1125300 = 1.1*1023*1000 long vcc = 1125300L / ((high<<8) | low); data[4] = vcc >> 8; data[5] = vcc; // Send 6 bytes on port 2, to know the format in the payload functions ttn.sendBytes(data, 6, 2); // Just for debugging debugSerial.print(vcc); debugSerial.print(F("V, ")); } // Just for debugging debugSerial.print(temp / 100.0); debugSerial.print("C, "); debugSerial.print(humi / 100.0); debugSerial.println(F("%")); }
-
In
loop()
, send the readings; changefalse
totrue
to include the battery level:sendTemperatureAndHumidity(false);
-
In the applicationâs payload function in TTN Console, decode using:
function Decoder(b, port) { // Use the port to determine if we just got temperature and humidity, or // the battery level too. (We could also use the length of the payload.) // All are MSB, Most Significant Bit/Byte first. // Port 1: 09A60CD2 = 24.70C, 32.83%; FE020CDF = -5.10C, 32.95% // Port 2: 09A60CD20D0B = 24.70C, 32.83%, 3339 millivolts if (port === 1 || port === 2) { var d = {}; // Sign-extend the 1st and 3rd bytes into leading bytes to support // negative values (though humidity should always be larger than zero) d.celcius = ((b[0] & 0x80 ? 0xFFFF<<16 : 0) | b[0]<<8 | b[1]) / 100; d.fahrenheit = Math.round(100 * (32 + 1.8 * d.celcius)) / 100; d.humidity = ((b[2] & 0x80 ? 0xFFFF<<16 : 0) | b[2]<<8 | b[3]) / 100; if (port === 2) { // We should also have a battery level, which cannot be negative d.battery = (b[4]<<8 | b[5]) / 1000; } return d; } return { oops: "unsupported port" }; }
If the temperature readings seem high: of course, itâs an on-board sensor, and the board might be above room temperature. If things donât work for low temperatures, then see RN2483 problem temperature.
Known issues with the original Badgerboard library
Just for future readers/Google, some errors I got with the original library:
-
badger_print_EUI(devEUI)
only prints the last two bytes? -
Log shows (same for SF11) (solved?):
Lora: Adding sensitivity: SF 9
LoRa: warning. Spreading factor not set!
LoRa: power not set!
LoRa: datarate not set! -
The Fabo HTS221 library duplicated in the Badgerboard library may invalidate other non-Badgerboard sketches that use the FaBo library as well:This is solved, but I did not test it:libraries/badgerboard/badger.cpp.o (symbol from plugin): In function âsodaq_wdt_enable(wdt_period)â:
(.text+0x0): multiple definition of âfaboHumidityâ
sketch/humidity.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Multiple libraries were found for âFaBoHumidity_HTS221.hâ
Used: /Users/arjan/Arduino/libraries/badgerboard
Not used: /Users/arjan/Arduino/libraries/FaBo_208_Humidity_HTS221
And some warnings:
- Iâm not an Arduino nor RN2483 expert.
- I wonder if the original Badgerboard library does better for battery live, and/or watchdog timers, and/or when waking from sleep.
- Iâve not yet checked if battery level is reported correctly by the TTN library, nor what happens after sleep.
- Most TTN code uses
loraSerial.begin(57600)
which works fine, and is Microchipâs documented default. The Badgerboard library uses 19200, but it seems they are in doubt.