Lorawan uplink support and new lorawan 'basic-demo' example

This commit is contained in:
Olivier Fauchon
2023-01-10 23:15:39 +01:00
committed by Ron Evans
parent 301e6bc35b
commit 889536f7f0
15 changed files with 195 additions and 28 deletions
+4 -3
View File
@@ -4,6 +4,7 @@ import (
"encoding/hex"
"strings"
"tinygo.org/x/drivers/examples/lora/lorawan/common"
"tinygo.org/x/drivers/lora/lorawan"
)
@@ -14,7 +15,7 @@ func quicktest() {
// Check firmware version.
func version() {
writeCommandOutput("VER", currentVersion()+" ("+firmwareVersion()+")")
writeCommandOutput("VER", common.CurrentVersion()+" ("+common.FirmwareVersion()+")")
}
// Use to check the ID of the LoRaWAN module, or change the ID.
@@ -443,7 +444,7 @@ func sendhex(data string) error {
func recv(setting string) error {
cmd := "RECV"
data, err := lorarx()
data, err := common.Lorarx()
if err != nil {
writeCommandOutput(cmd, "ERROR "+err.Error())
return err
@@ -456,7 +457,7 @@ func recv(setting string) error {
func recvhex(setting string) error {
cmd := "RECVHEX"
data, err := lorarx()
data, err := common.Lorarx()
if err != nil {
writeCommandOutput(cmd, "ERROR "+err.Error())
return err
+2 -1
View File
@@ -12,6 +12,7 @@ import (
"machine"
"time"
"tinygo.org/x/drivers/examples/lora/lorawan/common"
"tinygo.org/x/drivers/lora"
"tinygo.org/x/drivers/lora/lorawan"
)
@@ -34,7 +35,7 @@ func main() {
uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
var err error
radio, err = setupLora()
radio, err = common.SetupLora()
if err != nil {
fail(err.Error())
}
-7
View File
@@ -1,7 +0,0 @@
package main
const VERSION = "0.0.1"
func currentVersion() string {
return VERSION
}
@@ -0,0 +1,35 @@
# Simple Lorawan example
This demo code will connect Lorawan network and send sample uplink message
You may change your Lorawan keys (AppEUI, DevEUI, AppKEY) in key-default.go
```
$ tinygo monitor
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
Lorawan Simple Demo
Start Lorawan Join sequence
loraConnect: Connected !
```
# Building
## Simulator
```
tinygo flash -target pico ./examples/lora/lorawan/basic-demo
```
## PyBadge with LoRa Featherwing
```
tinygo flash -target pybadge -tags featherwing ./examples/lora/lorawan/basic-demo
```
## LoRa-E5
```
tinygo flash -target lorae5 ./examples/lora/lorawan/basic-demo
```
@@ -0,0 +1,11 @@
//go:build !customkeys
package main
// These are sample keys, so the example builds
// Either change here, or create a new go file and use customkeys build tag
func setLorawanKeys() {
otaa.SetAppEUI([]uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
otaa.SetDevEUI([]uint8{0xB3, 0xD5, 0x41, 0x00, 0x0A, 0xF1, 0xA4, 0x45})
otaa.SetAppKey([]uint8{0x12, 0x22, 0xA3, 0xFF, 0x0C, 0x7B, 0x76, 0x7B, 0x8F, 0xD3, 0x12, 0x4F, 0xCE, 0x7A, 0x32, 0x16})
}
+107
View File
@@ -0,0 +1,107 @@
// Simple code for connecting to Lorawan network and uploading sample payload
package main
import (
"errors"
"strconv"
"time"
"tinygo.org/x/drivers/examples/lora/lorawan/common"
"tinygo.org/x/drivers/lora"
"tinygo.org/x/drivers/lora/lorawan"
)
const (
LORAWAN_JOIN_TIMEOUT_SEC = 180
LORAWAN_RECONNECT_DELAY_SEC = 15
LORAWAN_UPLINK_DELAY_SEC = 60
)
var (
radio lora.Radio
session *lorawan.Session
otaa *lorawan.Otaa
)
func loraConnect() error {
start := time.Now()
var err error
for time.Since(start) < LORAWAN_JOIN_TIMEOUT_SEC*time.Second {
println("Trying to join network")
err = lorawan.Join(otaa, session)
if err == nil {
println("Connected to network !")
return nil
}
println("Join error:", err, "retrying in", LORAWAN_RECONNECT_DELAY_SEC, "sec")
time.Sleep(time.Second * LORAWAN_RECONNECT_DELAY_SEC)
}
err = errors.New("Unable to join Lorawan network")
println(err.Error())
return err
}
func failMessage(err error) {
println("FATAL:", err)
for {
}
}
func main() {
println("*** Lorawan basic join and uplink demo ***")
// Board specific Lorawan initialization
var err error
radio, err = common.SetupLora()
if err != nil {
failMessage(err)
}
// Required for LoraWan operations
session = &lorawan.Session{}
otaa = &lorawan.Otaa{}
// Initial Lora modulation configuration
loraConf := lora.Config{
Freq: 868100000,
Bw: lora.Bandwidth_125_0,
Sf: lora.SpreadingFactor9,
Cr: lora.CodingRate4_7,
HeaderType: lora.HeaderExplicit,
Preamble: 12,
Ldr: lora.LowDataRateOptimizeOff,
Iq: lora.IQStandard,
Crc: lora.CRCOn,
SyncWord: lora.SyncPublic,
LoraTxPowerDBm: 20,
}
radio.LoraConfig(loraConf)
// Connect the lorawan with the Lora Radio device.
lorawan.UseRadio(radio)
// Configure AppEUI, DevEUI, APPKey
setLorawanKeys()
// Try to connect Lorawan network
if err := loraConnect(); err != nil {
failMessage(err)
}
// Try to periodicaly send an uplink sample message
upCount := 1
for {
payload := "Hello TinyGo #" + strconv.Itoa(upCount)
if err := lorawan.SendUplink([]byte(payload), session); err != nil {
println("Uplink error:", err)
} else {
println("Uplink success, msg=", payload)
}
println("Sleeping for", LORAWAN_UPLINK_DELAY_SEC, "sec")
time.Sleep(time.Second * LORAWAN_UPLINK_DELAY_SEC)
upCount++
}
}
@@ -1,4 +1,4 @@
package main
package common
import (
"errors"
@@ -1,11 +1,11 @@
//go:build !featherwing && !gnse && !lorae5 && !nucleowl55jc
package main
package common
import "tinygo.org/x/drivers/lora"
// do simulator setup here
func setupLora() (lora.Radio, error) {
func SetupLora() (lora.Radio, error) {
return &SimLoraRadio{}, nil
}
@@ -29,11 +29,12 @@ func (sr *SimLoraRadio) SetCodingRate(cr uint8) {}
func (sr *SimLoraRadio) SetBandwidth(bw uint8) {}
func (sr *SimLoraRadio) SetCrc(enable bool) {}
func (sr *SimLoraRadio) SetSpreadingFactor(sf uint8) {}
func (sr *SimLoraRadio) LoraConfig(cnf lora.Config) {}
func firmwareVersion() string {
return "simulator " + currentVersion()
func FirmwareVersion() string {
return "simulator " + CurrentVersion()
}
func lorarx() ([]byte, error) {
func Lorarx() ([]byte, error) {
return nil, nil
}
@@ -1,6 +1,6 @@
//go:build gnse || lorae5 || nucleowl55jc
package main
package common
import (
"device/stm32"
@@ -24,7 +24,7 @@ var (
)
// do sx126x setup here
func setupLora() (lora.Radio, error) {
func SetupLora() (lora.Radio, error) {
loraRadio = sx126x.New(machine.SPI3)
loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262)
@@ -64,10 +64,10 @@ func radioIntHandler(intr interrupt.Interrupt) {
loraRadio.HandleInterrupt()
}
func firmwareVersion() string {
func FirmwareVersion() string {
return "sx126x"
}
func lorarx() ([]byte, error) {
func Lorarx() ([]byte, error) {
return loraRadio.Rx(LORA_DEFAULT_RXTIMEOUT_MS)
}
@@ -1,6 +1,6 @@
//go:build featherwing
package main
package common
import (
"strconv"
@@ -28,7 +28,7 @@ var (
)
// do sx127x setup here
func setupLora() (lora.Radio, error) {
func SetupLora() (lora.Radio, error) {
rstPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
csPin.Configure(machine.PinConfig{Mode: machine.PinOutput})
dio0Pin.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
@@ -75,11 +75,11 @@ func dioIrqHandler(machine.Pin) {
loraRadio.HandleInterrupt()
}
func firmwareVersion() string {
func FirmwareVersion() string {
v := loraRadio.GetVersion()
return "sx127x v" + strconv.Itoa(int(v))
}
func lorarx() ([]byte, error) {
func Lorarx() ([]byte, error) {
return loraRadio.Rx(LORA_DEFAULT_RXTIMEOUT_MS)
}
+7
View File
@@ -0,0 +1,7 @@
package common
const VERSION = "0.0.1"
func CurrentVersion() string {
return VERSION
}
@@ -13,7 +13,7 @@
| RX | HIGH | LOW | HIGH |
+-----------+----------+-----------+------------+
*/
package main
package common
import (
"machine"
+11 -1
View File
@@ -71,7 +71,17 @@ func Join(otaa *Otaa, session *Session) error {
return nil
}
func SendUplink() error {
func SendUplink(data []uint8, session *Session) error {
payload, err := session.GenMessage(0, []byte(data))
if err != nil {
return err
}
ActiveRadio.SetCrc(true)
ActiveRadio.SetIqMode(0) // IQ Standard
ActiveRadio.Tx(payload, LORA_RXTX_TIMEOUT)
if err != nil {
return err
}
return nil
}
+1 -1
View File
@@ -87,7 +87,7 @@ func (o *Otaa) GenerateJoinRequest() ([]uint8, error) {
o.buf = append(o.buf, 0x00)
o.buf = append(o.buf, reverseBytes(o.AppEUI[:])...)
o.buf = append(o.buf, reverseBytes(o.DevEUI[:])...)
o.buf = append(o.buf, reverseBytes(o.DevNonce[:])...)
o.buf = append(o.buf, o.DevNonce[:]...)
mic := genPayloadMIC(o.buf, o.AppKey)
o.buf = append(o.buf, mic[:]...)
+1
View File
@@ -10,4 +10,5 @@ type Radio interface {
SetBandwidth(bw uint8)
SetCrc(enable bool)
SetSpreadingFactor(sf uint8)
LoraConfig(cnf Config)
}