# Big & Breaking Update to our Arduino Library

> We've just release a big and breaking update to our Arduino Library. Thanks to the hard work of our team, including Johan Stokking, Nicolas DeJean and myself th

- Type: Global update from The Things Network
- Author: Fokke Zandbergen
- Published: 2016-12-05
- Updated: 2026-10-06
- Web page: https://www.thethingsnetwork.org/article/big-breaking-update-to-our-arduino-library

![Arduino Board](https://www.thethingsnetwork.org/media/article/arduino.jpg)

We've just release a big and breaking update to our Arduino Library. Thanks to the hard work of our team, including Johan Stokking, Nicolas DeJean and myself the library now has a smaller footprint and more simple API. This does come at the cost of some breaking changes, which I'll lay out for you in this post.

## Constructor instead of init()

You used to initialize the class instance via an init method:

```c
#include "TheThingsNetwork.h"

#define loraSerial Serial1
#define debugSerial Serial

TheThingsNetwork ttn;

void setup() {
  debugSerial.begin(9600);
  loraSerial.begin(57600);

  ttn.init(loraSerial, debugSerial);
```

In the new version this has been replaced by a constructor, which now also requires a frequency plan:

```c
#include "TheThingsNetwork.h"

#define loraSerial Serial1
#define debugSerial Serial
const ttn_fp_t freqPlan = TTN_FP_EU868; // or TTN_FP_US915

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);

void setup() {
  loraSerial.begin(57600);
  debugSerial.begin(9600);
```

## No more reset()

We've dropped the public `reset()` method. This is now handled internally.

## Keys has hex string instead of byte array

This is a real click-saver. No longer do you need to toggle your keys to the MSB format and paste them like this:

```c
const byte appEui[8] = {0x70, 0xB3, 0xD5, 0x7E, 0xE0, 0xE0, 0x01, 0x4A1};
const byte appKey[16] = {0x73, 0x6D, 0x24, 0xD2, 0x69, 0xBE, 0xE3, 0xAE, 0x0E, 0xCE, 0xF0, 0xBB, 0x6C, 0xA4, 0xBA, 0xFE};
```

With the new version you can copy the default hex string:

```c
const char *appEui = "0000000000000000";
const char *appKey = "00000000000000000000000000000000";
```

## Receive messages via callback

Receiving downlink messages in response to an uplink messages used to be an adventure:

```c
void loop() {
  byte send[1] = { 0x01 };
  int downlinkBytes = ttn.sendBytes(send, sizeof(send));

  if (downlinkBytes > 0) {
    debugSerial.print("Received " + String(downlinkBytes) + " bytes via " + String(ttn.downlinkPort) + ": ")

    for (int i = 0; i < downlinkBytes; i++) {
      debugSerial.print(String(ttn.downlink[i]) + " ");
    }

    debugSerial.println();
  }

  delay(10000);
}
```

We have made this a lot friendlier with the new `onMessage()` method to register a callback:

```c
void setup() {
  // ..

  ttn.onMessage(message)
}

void message(const byte* payload, int length, int port) {
  debugSerial.print("Received " + String(length) + " bytes on port " + String(port) + ":");

  for (int i = 0; i < length; i++) {
    debugSerial.print(" " + String(payload[i]));
  }

  debugSerial.println();
}
```

## Poll for messages

If you don't have anything to send, you can now also use the handy `poll()` method to check for scheduled downlink messages by sending a single byte:

```c
void loop() {
  ttn.poll();
}
```

See the [updated documentation](https://www.thethingsnetwork.org/docs/current/arduino/) and [release notes](https://github.com/TheThingsNetwork/arduino-device-lib/releases/tag/v1.0.0) for more details and let us know if you run into any issues or have ideas for further improvements.

**PS:** You may also notice a new `TheThingsMessage` class. We'll explain how you can use this to encode and decode messages using protocol buffers in another post.
