# Using LoraWAN and The Things Network with CircuitPython

## Overview

Danger: 

![](https://cdn-learn.adafruit.com/assets/assets/000/067/119/medium800/wireless_P1000318.jpg?1544117179)

In this project, we're going to build a small weather-logging node using a Feather and a temperature sensor. The captured data will then be sent over LoRaWAN to The Things Network.

_Wait, this sounds [similar to the a previous guide we have](https://learn.adafruit.com/the-things-network-for-feather). What's different?_

Good catch - the difference is that **this guide is for use with&nbsp;[CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython)**, meaning **you can get your project up and running on the Things Network quicker than ever**. Also, since we're using CircuitPython, this guide is compatible with Python Linux boards, like the Raspberry Pi family.&nbsp;

## What is The Things Network?
https://www.youtube.com/watch?v=U4UrXl-SGEo

The [Things Network](https://www.thethingsnetwork.org/) is a project dedicated to building a [network](https://www.thethingsnetwork.org/tech-stack) for the Internet of Things. While WiFi is used in most Internet of Things devices, The Things Network uses a protocol called **LoRaWAN** which allows devices to talk to the internet _without cellular or WiFi connectivity_. This means you don't need to worry about protected wireless hotspots, cellular data plans, or spotty WiFi connectivity.&nbsp;

It's **ideal** for most internet of things projects, and unlike cellular plans or WiFi - it's&nbsp; **free to use**.

There are many gateways available to connect your CircuitPython device to - [if you'd like to find a gateway in your area, check the Gateway Map.](https://www.thethingsnetwork.org/community)

## Parts
Our **Feather M0 RFM9x** is an all-in-one Feather with an onboard RFM9x radio module cooked in, built-in USB, and battery charging (highly useful for deploying LoRa nodes).&nbsp;

Featured
### Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz

[Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz](https://www.adafruit.com/product/3178)
This is the **Adafruit Feather M0 RFM95 LoRa Radio (900MHz)****. **We call these _RadioFruits** ,**_ our take on an microcontroller with a "[Long Range (LoRa)](https://www.lora-alliance.org/)" packet radio transceiver with built...

In Stock
[Buy Now](https://www.adafruit.com/product/3178)
[Related Guides to the Product](https://learn.adafruit.com/products/3178/guides)
![Angel shot Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz](https://cdn-shop.adafruit.com/640x480/3178-07.jpg)

**Already have a CircuitPython-Compatible board (or a Raspberry Pi)?** There are **multiple** ways to connect - the all-in-one Feather M0 LoRa and the stack-able Radio FeatherWing:

Featured
### Adafruit RFM95W LoRa Radio Transceiver Breakout - 868 or 915 MHz

[Adafruit RFM95W LoRa Radio Transceiver Breakout - 868 or 915 MHz](https://www.adafruit.com/product/3072)
_"You see, wire telegraph is a kind of a very, very long cat.&nbsp; You pull his tail in New York and his head is meowing in Los Angeles.&nbsp; Do you understand this? And radio operates exactly the same way: you send signals here, they receive them there.&nbsp; The only difference is..._

In Stock
[Buy Now](https://www.adafruit.com/product/3072)
[Related Guides to the Product](https://learn.adafruit.com/products/3072/guides)
![Angled shot of a Adafruit RFM95W LoRa Radio Transceiver Breakout.](https://cdn-shop.adafruit.com/640x480/3072-07.jpg)

Featured
### Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz

[Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz](https://www.adafruit.com/product/3231)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3231)
[Related Guides to the Product](https://learn.adafruit.com/products/3231/guides)
![Angled shot of a Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz - RadioFruit.](https://cdn-shop.adafruit.com/640x480/3231-13.jpg)

We'll also use a Si7021 temperature and humidity sensor to log and record whether it's sweltering or freezing.

Featured
### Adafruit Si7021 Temperature & Humidity Sensor Breakout Board

[Adafruit Si7021 Temperature & Humidity Sensor Breakout Board](https://www.adafruit.com/product/3251)
It's summer and you're sweating and your hair's all frizzy and all you really want to know is why the weatherman said this morning that today's relative humidity would max out at a perfectly reasonable 42% when it feels more like 77%. Enter the&nbsp; **Si7021 Temperature +...**

In Stock
[Buy Now](https://www.adafruit.com/product/3251)
[Related Guides to the Product](https://learn.adafruit.com/products/3251/guides)
![Angled shot of black, rectangular temperature and humidity sensor breakout.](https://cdn-shop.adafruit.com/640x480/3251-05.jpg)

## Materials

You'll want to pick these up from the Adafruit Store if you don't have them on-hand already:

### Half Sized Premium Breadboard - 400 Tie Points

[Half Sized Premium Breadboard - 400 Tie Points](https://www.adafruit.com/product/64)
This is a cute, half-size breadboard with&nbsp;400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm&nbsp;x 5.5cm&nbsp;with a standard double-strip in the middle and two power rails on both sides.&nbsp;You can pull the power rails off easily to make the breadboard as...

In Stock
[Buy Now](https://www.adafruit.com/product/64)
[Related Guides to the Product](https://learn.adafruit.com/products/64/guides)
![Angled shot of half-size solderless breadboard with red and black power lines.](https://cdn-shop.adafruit.com/640x480/64-06.jpg)

### Breadboarding wire bundle

[Breadboarding wire bundle](https://www.adafruit.com/product/153)
75 flexible stranded core wires with stiff ends molded on in red, orange, yellow, green, blue, brown, black and white. These are a major improvement over the "box of bent wires" that are sometimes sold with breadboards, and faster than stripping your own solid core wires. Makes...

In Stock
[Buy Now](https://www.adafruit.com/product/153)
[Related Guides to the Product](https://learn.adafruit.com/products/153/guides)
![Bundle of multi-colored multi-length wire jumpers](https://cdn-shop.adafruit.com/640x480/153-04.jpg)

If you're running a weather logger, you'll want to include a LiPo Battery in your build. LoRa has less power-draw than WiFi, so your node should be able to run unattended for a while.

### Lithium Ion Battery - 3.7V 2000mAh

[Lithium Ion Battery - 3.7V 2000mAh](https://www.adafruit.com/product/2011)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 2000mAh. If you need a larger (or smaller!) battery,&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/2011)
[Related Guides to the Product](https://learn.adafruit.com/products/2011/guides)
![Lithium Ion Polymer Battery 3.7v 2000mAh with JST 2-PH connector](https://cdn-shop.adafruit.com/640x480/2011-05.jpg)

# Using LoraWAN and The Things Network with CircuitPython

## Wiring

There's quite a few ways to connect to The Things Network with CircuitPython. You can use a Feather RFM9x (an all-in-one), a breakout or FeatherWing and a CircuitPython-compatible board, or a Python Linux computer/board.&nbsp;

## Wiring with a Feather M0 RFM9x
### Attaching an Antenna
Your _Feather M0 does not come with an antenna_, but there are _two_ ways of wiring one up.

For this guide, and to keep the build cost-effective, we soldered a small, 82mm wire to the&nbsp; **ANT&nbsp;** pad.

- Antenna Options and installation instructions are detailed on this product's learn guide's&nbsp;[**antenna options&nbsp;** page.&nbsp;](https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module/antenna-options)
- **Note:&nbsp;** Antenna length differs between regions, **make sure you cut the antenna to the correct length for your region.**

![wireless_featherm0.png](https://cdn-learn.adafruit.com/assets/assets/000/066/597/medium640/wireless_featherm0.png?1543511508)

### Wiring
Make the following connections between the&nbsp; **SI7021** &nbsp;and the&nbsp; **Feather RFM9x** :

- **Feather**  **3V** &nbsp;to&nbsp; **SI7021**** &nbsp;VIN**
- **Feather**  **GND** &nbsp;to&nbsp; **SI7021**** &nbsp;GND**
- **Feather**  **SCL** &nbsp;to&nbsp; **SI7021**** &nbsp;SCL**
- **Feather**  **SDA** &nbsp;to&nbsp; **SI7021** &nbsp; **SDA**

&nbsp;

![wireless_wiring-rfm-feather_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/066/588/medium640/wireless_wiring-rfm-feather_bb.png?1543504529)

## Wiring with a Radio Featherwing
Make the following connections between the **Radio FeatherWing** and the **Si7021** :

- **Wing** &nbsp; **3V** &nbsp;to&nbsp; **SI7021**** &nbsp;VIN**
- **Wing** &nbsp; **GND** &nbsp;to&nbsp; **SI7021**** &nbsp;GND**
- **Wing**  **SCL** &nbsp;to&nbsp; **SI7021**** &nbsp;SCL**
- **Wing**  **SDA** &nbsp;to&nbsp; **SI7021** &nbsp; **SDA**

&nbsp;

The pins for **IRQ** (RFM9x's DIO0 Pin) and **CS** are configurable. We provide a few lettered pins. Solder them together like so with some short jumper wires:

- **Wing CS** to **Wing D**
- **Wing IRQ** &nbsp;to **Wing E**

![wireless_wing_wiring.png](https://cdn-learn.adafruit.com/assets/assets/000/067/101/medium640/wireless_wing_wiring.png?1544042066)

![wireless_feather_wiring.jpg](https://cdn-learn.adafruit.com/assets/assets/000/067/102/medium640/wireless_feather_wiring.jpg?1544042211)

## Wiring a LoRa Radio Transceiver Breakout
### Attaching an Antenna
These radio breakouts do not have a built-in antenna. Instead, you have three options for attaching an antenna. For most low cost radio nodes, a&nbsp;[Wire antenna](https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/assembly#wire-antenna-3-7)&nbsp;works great. If you need to put the radio into an enclosure, soldering in a&nbsp;[UFL connector](https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/assembly#ufl-connector-3-11). and using a uFL to SMA adapter will let you attach an external antenna. You can also solder an SMA edge-mount connector directly.

![wireless_adafruit_products_wiredone.jpg](https://cdn-learn.adafruit.com/assets/assets/000/066/601/medium640/wireless_adafruit_products_wiredone.jpg?1543511633)

## Wiring a CircuitPython-Compatible Board with a LoRa Breakout
Make the following connections between the **RFM Breakout** and the **board** :

- **Board 3V** &nbsp;to **Radio VIN**
- **Board GND** &nbsp;to **Radio GND**
- **Board SCK** &nbsp;to **Radio SCK**
- **Board MOSI** &nbsp;to **Radio MOSI**
- **Board MISO&nbsp;** to **Radio MISO**
- **Board D5&nbsp;** to **Radio G0**
- **Board D6** &nbsp;to&nbsp; **Radio CS**

Make the following connections between the **Si7021** and the **board** :

- **Board**  **3V** &nbsp;to&nbsp; **Si7021**** &nbsp;VIN**
- **Board**  **GND** &nbsp;to&nbsp; **Si7021**** &nbsp;GND**
- **Board**  **SCL** &nbsp;to&nbsp; **Si7021**** &nbsp;SCL**
- **Board**  **SDA** &nbsp;to&nbsp; **Si7021**  **SDA**

![wireless_wiring-breakout-feather.png](https://cdn-learn.adafruit.com/assets/assets/000/066/587/medium640/wireless_wiring-breakout-feather.png?1543503499)

## Python Computer Wiring with a LoRa Breakout

Since there's&nbsp;_dozens_&nbsp;of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms,&nbsp;[please visit the guide for CircuitPython on Linux to see whether your platform is supported](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux).&nbsp;

Here's the Raspberry Pi wired with a RFM9x Breakout and a SI7021:

Connect the Raspberry Pi to the SI7021 Sensor

- **Pi 3V3** &nbsp;to&nbsp; **SI7021**** &nbsp;VIN**
- **Pi GND** &nbsp;to&nbsp; **SI7021**** &nbsp;GND**
- **Pi SCL&nbsp;** to&nbsp; **SI7021**** &nbsp;SCL**
- **Pi SDA** &nbsp;to&nbsp; **SI7021**** &nbsp;SDA**

Make the following connections between the RFM breakout and the Raspberry Pi:

- **Pi 3V** &nbsp;to R **adio VIN&nbsp;**
- **Pi GND** &nbsp;to R **adio GND**
- **Pi SCK** &nbsp;to R **adio SCK**
- **Pi MOSI** &nbsp;to R **adio MOSI**
- **Pi MISO&nbsp;** to R **adio MISO**
- **Board D5&nbsp;** to R **adio G0**
- **Board D6** &nbsp;to&nbsp; **Radio CS**

![wireless_wiring-raspi.png](https://cdn-learn.adafruit.com/assets/assets/000/066/596/medium640/wireless_wiring-raspi.png?1543511274)

All wired up? Let's move on to setting up The Things Network for TinyLoRa.

# Using LoraWAN and The Things Network with CircuitPython

## TinyLoRa TTN Setup

Danger: 

Warning: 

Before your Feather can communicate with The Things Network, you'll need to create an application.

First, we're going to register an account with TTN. [Navigate to their account registration page](https://account.thethingsnetwork.org/register) to set up an account.

Once logged in,&nbsp;[navigate to the The Things Network Console](https://console.thethingsnetwork.org/). This page is where you can register applications and add new devices or gateways. Click&nbsp; **Applications** &nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/065/275/medium800/feather_console-application.png?1541611433)

Click **Add Application**.&nbsp;

Fill out an&nbsp; **Application ID** &nbsp;to identify the application, and a **description** of what the application is. We set our&nbsp; **Handler Registration&nbsp;** to match our region, _us-west_. If you're not located in the U.S., TTN provides multiple regions for handler registration.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/065/269/medium800/feather_The_Things_Network_Console.png?1541609514)

Once created, you'll be directed to the Application Overview. From here, you can add devices, view data coming into (and out of) the application, add integrations for external services, and more. We'll come back to this section later in the guide.

**Click&nbsp;Register Device**

![](https://cdn-learn.adafruit.com/assets/assets/000/065/276/medium800/feather_The_Things_Network_Console_2.png?1541611535)

On the **Register Device Page** ,&nbsp;The **Device ID** should be a unique string to identify the device.&nbsp;

The&nbsp; **Device EUI&nbsp;** is the unique identifier which came in the same bag as your Radiofruit Feather. We'll pad the middle of the string with four zeroes. Lost your key? No worries - you can also click the "mix" icon to switch it to auto-generate.

The&nbsp; **App Key&nbsp;** will be randomly generated for you by TTN. Select the **App EUI** (used to identify the application) from the list.

![](https://cdn-learn.adafruit.com/assets/assets/000/065/277/medium800/feather_The_Things_Network_Console_4.png?1541611564)

Next, we're going to switch the device settings from Over-the-Air-Activation to Activation-by-Personalization. From the Device Overview, **click Settings**

![](https://cdn-learn.adafruit.com/assets/assets/000/065/278/medium800/feather_The_Things_Network_Console_5.png?1541611643)

On the settings screen,&nbsp; **change the Activation Method from OTAA to ABP**.

&nbsp;

Then,&nbsp; **switch the Frame Counter Width from 32b to 16b** &nbsp;and&nbsp; **disable frame counter checks**. TTN will display a warning, ignore it, and&nbsp; **click Save**.

![feather_The_Things_Network_Console.png](https://cdn-learn.adafruit.com/assets/assets/000/065/281/medium640/feather_The_Things_Network_Console.png?1541611982)

![feather_The_Things_Network_Console_6.png](https://cdn-learn.adafruit.com/assets/assets/000/065/282/medium640/feather_The_Things_Network_Console_6.png?1541611997)

Warning: 

Now that the application is set up, and the device is registered to the application, let's move on to setting up Arduino with TinyLoRa.

### 

Disabling frame counter checks allows you to transmit data to The Things Network without requiring a match between your device's frame counter and the console's frame counter.

If you're making a project and doing a lot of prototyping/iteration to the code, disabling these checks is&nbsp;_okay_ as it'll let you reset the device and not re-register it to the application (it'll also prevent counter overflows).

If you're deploying a project, you'll want to re-activate the frame counter for security purposes. With the frame counter disabled, one could re-transmit the messages sent to TTN using a replay attack.&nbsp;

The Things Network's documentation page has&nbsp;[a full explanation about the role of the Frame Counter](https://www.thethingsnetwork.org/docs/lorawan/security.html#frame-counters).

# Using LoraWAN and The Things Network with CircuitPython

## CircuitPython Installation

## Installing CircuitPython on a Feather RFM9x
Some of the CircuitPython compatible boards come with CircuitPython installed. Others are&nbsp;_CircuitPython-ready_, but need to have it installed.&nbsp;

**If you're using a [Feather M0 RFM9x](https://www.adafruit.com/product/3178), you'll need to install CircuitPython on your board.**

- **If you're using a RFM9x breakout and a Feather _Express_ or a Python Linux board, you can ignore this page** and [continue to the library installation](https://learn.adafruit.com/using-lorawan-and-the-things-network-with-circuitpython/library-installation).

If you have [Arduino IDE downloaded and installed](https://learn.adafruit.com/ladyadas-learn-arduino-lesson-number-0/download-software), this process is as simple as uploading a sketch to your board then dragging and dropping a file.

First, we need to flash the UF2 bootloader onto the Feather.

Navigate to the latest release page for the UF2 bootloader on the Adafruit GitHub.

[Click here to see the latest UF2 bootloader releases. ](https://github.com/adafruit/uf2-samdx1/releases)
 **Click** &nbsp; **_update-bootloader-feather\_m0-v2.x.x-adafruit.7.ino_** &nbsp;to download the file.

**Double click&nbsp;** the file to open it in the Arduino IDE.

The&nbsp; **.ino** sketch should download to your computer. Open the file in the Arduino IDE by **double-clicking the file**. The Arduino IDE should load and the sketch should appear. The sketch will have a lot of hexadecimal numbers and might look daunting if you scroll down - _don't worry_, _we're not touching any of it._

![](https://cdn-learn.adafruit.com/assets/assets/000/066/580/medium800/wireless_update-bootloader-feather_m0-v2_0_0-adafruit_7___Arduino_1_8_7.png?1543447003)

From the Arduino IDE, select the **Port&nbsp;** associated with your Feather.&nbsp;

&nbsp;

_Not seeing a port displayed?_ Ensure your [Feather M0 RFM9x](https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module/setup) has been properly set up for the Arduino IDE.

![wireless_Port____dev_cu_usbmodem142241__and_Tools_and_Menubar.png](https://cdn-learn.adafruit.com/assets/assets/000/066/564/medium640/wireless_Port____dev_cu_usbmodem142241__and_Tools_and_Menubar.png?1544051187)

Click&nbsp; **Upload&nbsp;** ( **CTRL/CMD+U** ) to upload the bootloader to your Feather. The sketch will flash the bootloader onto the board.

![wireless_update-bootloader-feather_m0-v2_0_0-adafruit_7___Arduino_1_8_7.png](https://cdn-learn.adafruit.com/assets/assets/000/066/572/medium640/wireless_update-bootloader-feather_m0-v2_0_0-adafruit_7___Arduino_1_8_7.png?1544051205)

The board should reset. After resetting, the board should connect to your computer and appear as a volume on your computer named&nbsp; **FEATHERBOOT**. If you see this volume, you've successfully loaded the UF2 bootloader onto your Feather.

&nbsp;

We're almost done, but not yet - we still need to load CircuitPython on the board.

![wireless_featherboot.png](https://cdn-learn.adafruit.com/assets/assets/000/066/579/medium640/wireless_featherboot.png?1543446751)

## Download the latest CircuitPython version
Navigate to the [CircuitPython release page](https://github.com/adafruit/circuitpython/releases) and select the latest build for the **Feather M0 RFM9x**.&nbsp;

Click on the build for your region and Feather to download it to your computer. Put it somewhere you can remember, like your Desktop.

&nbsp;

**Make sure you select a .UF2 file, not a .BIN file.**

- For example, if I'm using a Feather M0 RFM9x in the United States, I'll select the build:&nbsp; **adafruit-circuitpython-feather\_m0\_rfm9x-en\_US-4.0.0.uf2**

![wireless_uf2.png](https://cdn-learn.adafruit.com/assets/assets/000/066/604/medium640/wireless_uf2.png?1543512015)

Next, we're going to load CircuitPython&nbsp;**(UF2 file)** onto our board.

## Start the UF2 Bootloader
If you see the board on your computer as a volume,&nbsp;`FEATHERBOOT`, you can proceed with these steps.&nbsp;

&nbsp;

Don't see&nbsp;`FEATHERBOOT`? **Tap the small, black, reset button on your board twice** to enter the bootloader.&nbsp;If it doesn't work on the first try, don't be discouraged. The rhythm of the taps needs to be correct and sometimes it takes a few tries.

![wireless_circuitpython_ResetButton.jpg](https://cdn-learn.adafruit.com/assets/assets/000/066/605/medium640/wireless_circuitpython_ResetButton.jpg?1543512065)

Now find the&nbsp; **UF2**  **file** you downloaded. Drag that file to the&nbsp;`FEATHERBOOT`&nbsp;drive on your computer.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/581/medium800/wireless_circuitpython_circuit_playground_drag.png?1543447312)

The lights should flash again,&nbsp;`FEATHERBOOT`&nbsp;will disappear and a&nbsp; **new** &nbsp;drive will show up on your computer called&nbsp;`CIRCUITPY`.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/582/medium800/wireless_CIRCUITPY.png?1543447513)

Congratulations! You've successfully installed CircuitPython!

# Using LoraWAN and The Things Network with CircuitPython

## Library Installation

## Bundle Installation
We're constantly building/updating/improving our libraries, so we don't ship all the CircuitPython libraries with your board.

You'll want to grab a copy of the [CircuitPython Library Bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle) - a .zip file containing a bunch of useful CircuitPython libraries.&nbsp; The [TinyLoRa library is separate repository](https://github.com/adafruit/Adafruit_CircuitPython_TinyLoRa), but it's easier to install everything at once using the bundle.

Grab the latest version of the library bundle by clicking this button and **make sure you download the version that matches your CircuitPython library version** :

[Click for the latest CircuitPython Library Bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest)
Unzip the library. You'll see a two folders:&nbsp;`lib`&nbsp;and `examples`. Double click the&nbsp;`lib`&nbsp;folder to see a listing of all the CircuitPython libraries.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/067/111/medium800/wireless_circuitpython_adafruit_gemma_libfol.png?1544052303)

## If you're using an Express board

On **Express** boards (the board will say 'EXPRESS' on it), the&nbsp;`lib`&nbsp;and&nbsp;`examples`&nbsp;directories can be copied directly to the CIRCUITPY drive.

Just drag the entire&nbsp;`lib`&nbsp;and&nbsp;`examples`&nbsp;(optional) folders into the CIRCUITPY drive, and 'replace' any old files if your operating system prompts you.

## If you're using a non-Express board

The [RFM9x Feather M0](https://www.adafruit.com/product/3178) (all-in-one) has less space available compared to express boards. To save space, we're only going to install the libraries&nbsp;required for this guide.&nbsp;

From the bundle folder, navigate to the `lib` folder and find the required folders:&nbsp;`adafruit_bus_device`,&nbsp;`adafruit_tinylora`&nbsp;and `adafruit_si7021`.

Copy these three folders/files over to the `CIRCUITPY` drive's `lib` directory.

Before continuing make sure your board's `lib` folder has at the `adafruit_tinylora`, `adafruit_bus_device`, and `adafruit_si7021`&nbsp;libraries copied.

![](https://cdn-learn.adafruit.com/assets/assets/000/067/094/medium800/wireless_directory_files.png?1544037437)

### 

If you find yourself running out of space on your non-express board and are a computer running MacOS - there's a chance that your mac is creating hidden files which are taking up space on the board.

Make sure you're running the latest version of CircuitPython for your board, and [follow the guide here for information&nbsp; on how to prevent these files from being created](https://learn.adafruit.com/welcome-to-circuitpython/troubleshooting#running-out-of-file-space-on-non-express-boards-20-38).

For further space savings- remove the TTN configurations for any country other than your own (you'll only need `ttn_usa.mpy` if you're in the United States).

## Installation on Python Linux Computers
![](https://cdn-learn.adafruit.com/assets/assets/000/067/110/medium800/wireless_blinkapi.gif?1544051381)

If you're following along with a Raspberry Pi, Beaglebone or any other supported small Linux computer, we'll use a special library called&nbsp;[**adafruit\_blinka**](https://pypi.org/project/Adafruit-Blinka/)&nbsp;([named after Blinka, the CircuitPython mascot](https://www.adafruit.com/?q=blinka)) to provide the layer that translates the CircuitPython hardware API to whatever library the Linux board provides. It's CircuitPython, on Pi!

If you haven't set up Blinka and the Adafruit IO Python Library yet on your Raspberry Pi, follow our guide:

- [Blinka and Adafruit IO Setup](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi#prerequisite-pi-setup-3-3)

### Enable I2C

We use two pins on the Pi (SDA/SCL) to communicate over I2C with the&nbsp;Si7021. You only have to do this step&nbsp;_once_ per Raspberry Pi, the I2C interface is disabled by default.

- [Enabling I2C](https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c)

Once you're done with this and have rebooted, verify you have the I2C devices with the command:

`sudo i2cdetect -y 1`

The output from running this command should look like the following:

![](https://cdn-learn.adafruit.com/assets/assets/000/067/093/medium800/wireless_1__pi_raspberrypi_____ssh_.png?1544037305)

### Enable SPI

You'll also need to enable SPI to communicate over SPI with the RFM breakout. You only have to do this step&nbsp;_once_&nbsp;per Raspberry Pi, the SPI interface is disabled by default.

- [Enabling SPI](https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-spi)

Once you're done enabling SPI and have rebooted, verify you have the SPI interface by typing the following command into the terminal:

`ls -l /dev/spidev*`

You should see the following output:

![](https://cdn-learn.adafruit.com/assets/assets/000/067/092/medium800/wireless_spidev.png?1544037269)

## Installing required CircuitPython&nbsp;Libraries

Next, you'll need to install libraries to communicate with the RFM9x breakout and the Si7021.&nbsp;Since we're using Adafruit Blinka (CircuitPython), we can install CircuitPython libraries straight to our Raspberry Pi, instead of installing from separate files.&nbsp;

Run the following command from your terminal to **install the [Adafruit\_CircuitPython\_Si7021 Library](https://github.com/adafruit/Adafruit_CircuitPython_SI7021)**:

`sudo pip3 install adafruit-circuitpython-si7021`

Then, **install the [Adafruit\_CircuitPython\_TinyLoRa](https://github.com/adafruit/Adafruit_CircuitPython_SGP30)&nbsp;library**

`sudo pip3 install adafruit-circuitpython-tinylora`

# Using LoraWAN and The Things Network with CircuitPython

## Using TinyLoRa

## Writing code With Mu

Adafruit recommends the Mu editor to type your code into and interact with your project. You can find out how to install Mu on mac, PC, and Linux in&nbsp;[this guide page](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor "Installing Mu")&nbsp;on the Adafruit Learning System.

The advantage to using Mu is it has an editor and added features like direct save to the board's REPL interactive command line and print output. Mu can even plot values for you.

## The Code
The code below will use the `adafruit_tinylora` library which provides high-level access to your radio transceiver's features.&nbsp;

The code for sending data using a Si7021 sensor to a Things Network Gateway is shown below:

https://github.com/adafruit/Adafruit_CircuitPython_TinyLoRa/blob/main/examples/tinylora_simpletest_si7021.py

Using Mu (or a text editor), copy this code and save it to your computer, naming it `code.py`.

Note: The code is configured to use a RFM9x breakout by default. If you are using a Feather M0 RFM9x, delete the following lines:

`# RFM9x Breakout Pinouts`

`cs = digitalio.DigitalInOut(board.D5)`

`irq = digitalio.DigitalInOut(board.D6)`

`rst = digitalio.DigitalInOut(board.D4)`

Then, uncomment (remove the `#`) the following lines to enable the RFM9x's builtin D0 and CS pins

`Feather M0 RFM9x Pinouts`

`irq = digitalio.DigitalInOut(board.RFM9X_D0)`

`cs = digitalio.DigitalInOut(board.RFM9X_CS)`

`rst = digitalio.DigitalInOut(board.RFM9X_RST)`

## Installing Code on CircuitPython

Navigate to where you saved your&nbsp; **code.py&nbsp;** file. Copy (by dragging the file and dropping it) the file to the **CIRCUITPY** drive.&nbsp;&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/066/623/medium800/wireless_express_files.png?1543528109)

While the code will appear to run, it is not yet set up for your Application or Device. We'll do that next.

## Setting up the code for The Things Network
While we can send data to The Things Network, and our gateway might notice it, it isn't registered to a device yet. To register your device with The Things Network **using**  **ABP** , you'll need to set three unique identifiers in the `code.py` file: the&nbsp;`Network Session Key`, the&nbsp;`Device Address`, and the&nbsp;`Application Session Key`.

Navigate to the&nbsp; **Device Overview&nbsp;** page for your Feather device.

&nbsp;

Make sure the&nbsp; **Activation Method** &nbsp;is set to&nbsp; **ABP**.&nbsp;

![wireless_feather_The_Things_Network_Console_7.png](https://cdn-learn.adafruit.com/assets/assets/000/066/616/medium640/wireless_feather_The_Things_Network_Console_7.png?1543526580)

Before adding the unique identifiers to our sketch, we'll need to first expand them by **clicking**  **the \<\>** icon.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/617/medium800thumb/wireless_feather_keyexpandconsole.jpg?1543526612)

These are your keys. We're going to enter them into our `code.py`, but we need to **be careful** - the keys on the Things Network console use&nbsp; **parentheses or curly&nbsp;**** braces _{ }&nbsp;_instead of brackets&nbsp; **_** []**.&nbsp;_

First, copy the&nbsp; **Device Address** &nbsp;from the TTN console to the&nbsp;`devaddr` **&nbsp;** variable in the code.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/066/620/medium800/wireless_device_Addr.png?1543527246)

Then, **remove the braces _{ }_** from the device address.

A device address copied from The Things Network console would look like:&nbsp;`{ 0x26, 0x02, 0x1F, 0x07 }`.&nbsp;In the code.py, it'd look like:&nbsp;`devaddr = bytearray([0x26, 0x02, 0x1F, 0x07])`.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/619/medium800/wireless_device_addr_python.png?1543527238)

Then, copy the&nbsp; **Network Session Key** &nbsp;from the TTN console to the&nbsp;`NwkSkey` **&nbsp;** variable in the code. Make sure to modify the code to remove the parentheses/curly braces { }.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/066/621/medium800/wireless_nwkey.png?1543527397)

Finally, copy the&nbsp; **Application Session Key** &nbsp;from the TTN console to the&nbsp;`AppSkey` **&nbsp;** variable in the code.&nbsp;Make sure to modify the code to remove the parentheses/curly braces { }.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/066/622/medium800/wireless_appskey.png?1543527401)

That's all for now - we're ready to run our code!&nbsp;

## Running the Code using Mu Editor
Upon saving ( **ctrl/cmd +s** ) your code, the board will refresh.&nbsp;

_But where is the output?&nbsp;_The serial monitor is hidden by default in Mu Editor.

In the Mu Editor, click the **Serial&nbsp;** button on the top icon-bar to bring up the Serial REPL.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/624/medium800thumb/wireless_capture_mu.jpg?1543528446)

You should see the temperature and humidity values printed to the console. The packet's status (_sending_, or _timed out and unable to send_) should appear shortly after. The LED on your Feather should also blink the onboard LED when it successfully sends a packet to The Things Network.

If you see&nbsp;_Packet Sent!,&nbsp;_rejoice - your packet has sent to the Things Network. But, while it's been sent, we want to check and make sure it's been received.&nbsp;

 **If you're using a Raspberry Pi:** The Pi does not have an onboard LED located at pin D13, so it will not blink when the packet is sent. In the code, comment out every line which uses the LED, like the following:

`led = digitalio.DigitalInOut(board.D13)` **to** `# led = digitalio.DigitalInOut(board.D13)`

## Checking Data on The Things Network Console

We want to make sure the data has been received on the other end. To do this, we'll navigate to the The Things Network Console and select the&nbsp; **application**. From the menu on the right hand side of the page,&nbsp; **Click&nbsp;Data**.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/625/medium800/wireless_feather_Pasted_Image_11_7_18__3_46_PM.png?1543528652)

If everything worked correctly, you'll see the payload from your device streaming into the page, in real time.&nbsp;

&nbsp;

Neat,&nbsp; **right**? But while we received a payload, we still don't understand what it means. It's been sent to The Things Network and _decoded_&nbsp;on the client (Gateway) side, so it's not an AES-encrypted payload anymore. It's just not read-able by humans.

## &nbsp;
![wireless_feather_The_Things_Network_Console_data.png](https://cdn-learn.adafruit.com/assets/assets/000/066/626/medium640/wireless_feather_The_Things_Network_Console_data.png?1543528702)

## Decoding the Payload
If you're sending packets in strange formats or encodings (like we are!), The Things Network Console has a&nbsp;[programmable data decoder](https://www.thethingsnetwork.org/docs/devices/bytes.html)&nbsp;to decode the packets, and assign useful labels to the data.

**Copy and paste the decoder script** &nbsp;below into the decoder's integrated text editor and&nbsp; **click save**.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/066/627/medium800thumb/wireless_feather_add_decoder.jpg?1543528865)

Then,&nbsp; **click the data tab**. Next to the raw payload data, you should see the decoded data for humidity and temperature.

![](https://cdn-learn.adafruit.com/assets/assets/000/066/628/medium800/wireless_feather_The_Things_Network_Console_decoded.png?1543528883)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/TheThingsNetwork_Feather/si7021_decoder.js

# Using LoraWAN and The Things Network with CircuitPython

## TinyLoRa CircuitPython FAQ

## I'm located in a region other than the United States

All the software modifications you'd need to make are within one line of **code.py**. The country defaults to the&nbsp; **US&nbsp;** (adafruit is located in this region), but you can change it to any of the four supported regions:

- **US** - USA, Canada, and South America
- **EU** - Europe
- **AS** - Asia
- **AU** - Australia

If you wanted to switch to an European frequency plan, you'd configure the&nbsp;`ttn_config`&nbsp;object with the following parameters:

`ttn_config = TTN(devaddr, nwkey, app, country = 'EU')`

We've supported a subset of the major frequency plans in the initial release of TinyLoRa for CircuitPython. If you don't see [your region](https://www.thethingsnetwork.org/docs/lorawan/frequency-plans.html) listed here, [you can submit an issue](https://github.com/adafruit/Adafruit_CircuitPython_TinyLoRa/issues/new) and we'll add it to the library.

## If you'd like to use a specific channel...

By default, TinyLoRa for CircuitPython broadcasts on multiple channels, randomly hopping between them. Since most gateways only listen for a transmission on a few channels at a time, this is a way to increase the probability of the gateway _"seeing"&nbsp;_the packet.&nbsp;

You can specify a channel by feeding the LoRa object constructor a channel as a keyword argument. For example, **if you'd like to send data on channel 3,** the object would be created like the following:

`lora = TinyLoRa(spi, cs, irq, ttn_config, channel=3)`

_Want to change channels during the event loop, between sending different data packets?_&nbsp; We included a `set_channel` function which will set up the radio to use the specified channel:

`lora.set_channel(3)`

## If you'd like to use a specific data rate...

By default, TinyLoRa uses the datarate&nbsp; **SF7BW125**. That is, a spreading factor of 7 and a bandwidth of 125kHz. Similar to setting a channel, TinyLoRa can set the datarate given a specific bandwidth and spreading factor. If you'd like to set the transmission datarate to a spreading factor of 10 and a bandwidth of 125kHz, call `set_datarate()` like the following:&nbsp;

`lora.set_datarate("SF10BW125")`

TinyLoRa has the following datarates available for use by this method:

- SF7BW125,&nbsp;SF7BW250,&nbsp;SF8BW125,&nbsp;SF9BW125,&nbsp;SF10BW125,&nbsp;SF11BW125,&nbsp;SF12BW125

Want to learn more about datarates and LoRa? [Check out this blog post here..](https://docs.exploratory.engineering/lora/dr_sf/)

## My packet never successfully sends

If you're hitting an error, `RuntimeError: Timeout during packet send`&nbsp;, it's likely a gateway is not in range, or connected properly. Ensure that there are gateways near you and in-range ([click here for a map of all the registered gateways](https://www.thethingsnetwork.org/map)).

If you're a Things Network Gateway operator, check from the Things Network Console if the gateway has been seen recently. If the&nbsp;_Last Seen_ value is greater than a few minutes, reset your gateway.&nbsp;

## My project has disconnected/been reset and I don't see any data in my application

If you haven't disabled frame counter checks from within your device (instructions on how do this are on the [TinyLoRa TTN Setup page](https://learn.adafruit.com/using-lorawan-and-the-things-network-with-circuitpython/tinylora-ttn-setup)), you'll encounter this issue when the device is reset/loses power.

_Why would this happen?_&nbsp;There's a mismatch between the frame counter on your device and the frame counter on The Things Network. Most likely, the frame counter on your device is reset to zero, and the frame counter on your device's console is set to the last known value.&nbsp;

There are ways around this issue, such as using a different activation method such as OTAA (currently unsupported by TinyLoRa).

However, we can still reset both the node and the frame counter on the application.

To do this, From your Things Network Console, navigate to your device ( **Applications-\>Application-\>Device** ).

&nbsp;

Click the&nbsp; **reset frame counters** button next to the **Frames up&nbsp;** label. This will reset the frame counter of the device (on The Things Network's Console) to zero.&nbsp;

&nbsp;

We'll also need to reset the frame counter on our device to zero. Press the&nbsp; **RST** button on the board.

![wireless_reset_Frame.png](https://cdn-learn.adafruit.com/assets/assets/000/066/629/medium640/wireless_reset_Frame.png?1543530499)

## What's the deal with the frame counter? Do I need it in my code?

Disabling frame counter checks allows you to transmit data to The Things Network without requiring a match between your device's frame counter and the console's frame counter.

If you're making a project and doing a lot of prototyping/iteration to the code, disabling these checks is&nbsp;_okay_ as it'll let you reset the device and not re-register it to the application (it'll also prevent counter overflows).

If you're deploying a project, you'll want to re-activate the frame counter for security purposes. With the frame counter disabled, one could re-transmit the messages sent to TTN using a replay attack.&nbsp;

The Things Network's documentation page has&nbsp;[a full explanation about the role of the Frame Counter](https://www.thethingsnetwork.org/docs/lorawan/security.html#frame-counters).


## Guide Products

### Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz

[Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz](https://www.adafruit.com/product/3178)
This is the **Adafruit Feather M0 RFM95 LoRa Radio (900MHz)****. **We call these _RadioFruits** ,**_ our take on an microcontroller with a "[Long Range (LoRa)](https://www.lora-alliance.org/)" packet radio transceiver with built...

In Stock
[Buy Now](https://www.adafruit.com/product/3178)
[Related Guides to the Product](https://learn.adafruit.com/products/3178/guides)
### Adafruit RFM95W LoRa Radio Transceiver Breakout - 868 or 915 MHz

[Adafruit RFM95W LoRa Radio Transceiver Breakout - 868 or 915 MHz](https://www.adafruit.com/product/3072)
_"You see, wire telegraph is a kind of a very, very long cat.&nbsp; You pull his tail in New York and his head is meowing in Los Angeles.&nbsp; Do you understand this? And radio operates exactly the same way: you send signals here, they receive them there.&nbsp; The only difference is..._

In Stock
[Buy Now](https://www.adafruit.com/product/3072)
[Related Guides to the Product](https://learn.adafruit.com/products/3072/guides)
### Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz

[Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz](https://www.adafruit.com/product/3231)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3231)
[Related Guides to the Product](https://learn.adafruit.com/products/3231/guides)
### Adafruit Si7021 Temperature & Humidity Sensor Breakout Board

[Adafruit Si7021 Temperature & Humidity Sensor Breakout Board](https://www.adafruit.com/product/3251)
It's summer and you're sweating and your hair's all frizzy and all you really want to know is why the weatherman said this morning that today's relative humidity would max out at a perfectly reasonable 42% when it feels more like 77%. Enter the&nbsp; **Si7021 Temperature +...**

In Stock
[Buy Now](https://www.adafruit.com/product/3251)
[Related Guides to the Product](https://learn.adafruit.com/products/3251/guides)
### Half Sized Premium Breadboard - 400 Tie Points

[Half Sized Premium Breadboard - 400 Tie Points](https://www.adafruit.com/product/64)
This is a cute, half-size breadboard with&nbsp;400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm&nbsp;x 5.5cm&nbsp;with a standard double-strip in the middle and two power rails on both sides.&nbsp;You can pull the power rails off easily to make the breadboard as...

In Stock
[Buy Now](https://www.adafruit.com/product/64)
[Related Guides to the Product](https://learn.adafruit.com/products/64/guides)
### Breadboarding wire bundle

[Breadboarding wire bundle](https://www.adafruit.com/product/153)
75 flexible stranded core wires with stiff ends molded on in red, orange, yellow, green, blue, brown, black and white. These are a major improvement over the "box of bent wires" that are sometimes sold with breadboards, and faster than stripping your own solid core wires. Makes...

In Stock
[Buy Now](https://www.adafruit.com/product/153)
[Related Guides to the Product](https://learn.adafruit.com/products/153/guides)
### Lithium Ion Battery - 3.7V 2000mAh

[Lithium Ion Battery - 3.7V 2000mAh](https://www.adafruit.com/product/2011)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 2000mAh. If you need a larger (or smaller!) battery,&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/2011)
[Related Guides to the Product](https://learn.adafruit.com/products/2011/guides)

## Related Guides

- [Adafruit Si7021 Temperature + Humidity Sensor](https://learn.adafruit.com/adafruit-si7021-temperature-plus-humidity-sensor.md)
- [Adafruit HUZZAH32 - ESP32 Feather](https://learn.adafruit.com/adafruit-huzzah32-esp32-feather.md)
- [Using QMK on RP2040 Microcontrollers](https://learn.adafruit.com/using-qmk-on-rp2040-microcontrollers.md)
- [Quickstart IoT - Raspberry Pi Pico RP2040 with WiFi ](https://learn.adafruit.com/quickstart-rp2040-pico-with-wifi-and-circuitpython.md)
- [Storage humidity and temperature monitor](https://learn.adafruit.com/storage-humidity-and-temperature-monitor.md)
- [Trellis Feather DSP-G1 Synthesizer](https://learn.adafruit.com/feather-trellis-dsp-g1-synthesizer.md)
- [Comparison and Experimentation with Flammable Gas Sensors](https://learn.adafruit.com/gas-sensor-comparison.md)
- [Feather ESP32-S3 TFT CircuitPython Day 2024 Countdown Clock](https://learn.adafruit.com/feather-esp32-s3-tft-circuitpython-day-2024-countdown-clock.md)
- [Integrating Home Assistant with Adafruit IO](https://learn.adafruit.com/integrating-adafruit-io-with-home-assistant.md)
- [Light-Up Costumes in Harsh Environments](https://learn.adafruit.com/light-up-costumes-in-harsh-environments.md)
- [Feather + Raspberry Pi Weather Monitoring Network with LoRa or LoRaWAN](https://learn.adafruit.com/multi-device-lora-temperature-network.md)
- [Getting Started with Raspberry Pi Pico and CircuitPython](https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython.md)
- [Schluff - The Sleep Monitor](https://learn.adafruit.com/schluff-the-oshw-sleep-monitor.md)
- [Adafruit IO Basics: Digital Input](https://learn.adafruit.com/adafruit-io-basics-digital-input.md)
- [Animatronic Fizzgig MonsterM4sk Puppet](https://learn.adafruit.com/animatronic-fizzgig-monsterm4sk-puppet.md)
- [MIDI for Makers](https://learn.adafruit.com/midi-for-makers.md)
