krylr896

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2025 License: MIT Imports: 7 Imported by: 0

README

k-rylr896

Go library for RYLR896/RYLR40x LoRa radio modules using AT commands over serial.

Installation

go get github.com/1kharvey/k-rylr896

Quick Start

Creating a Connection

Create a connection by specifying the serial port, baud rate, configuration, and buffer length:

lora, err := krylr896.CreateConnection("/dev/ttyUSB0", krylr896.UartBaudRate_115200, config, 10)

For debug output with custom logging, use CreateConnectionDEBUG:

lora, err := krylr896.CreateConnectionDEBUG("/dev/ttyUSB0", krylr896.UartBaudRate_115200, config, 10, "MyRadio", func(name, msg string) {
    log.Printf("[DEBUG][%s] %s", name, msg)
})
Configuring the Radio

The Configuration struct allows you to set radio parameters. All fields are pointers and optional - any field set to nil will not be configured on the radio:

type Configuration struct {
    Address       *uint16     // Radio address (0-65535)
    NetworkID     *uint8      // Network ID (0-16), must match for communication
    Band          *uint32     // Frequency band in Hz (e.g., 915000000)
    Parameter     *Parameters // RF transmission parameters
    Mode          *uint8      // Operating mode (0=TRX, 1=SLEEP)
    UartBaudRate  *int        // UART baud rate (300-115200)
    EncryptionKey *[16]byte   // AES128 encryption key (16 bytes)
    RFOutputPower *uint8      // RF output power in dBm (0-15)
}

Example configuration setting only address and network:

address := uint16(1)
networkID := uint8(5)
config := krylr896.Configuration{
    Address:   &address,
    NetworkID: &networkID,
    // All other fields are nil and will not be configured
}

RF parameters can be configured with the Parameters struct:

params := krylr896.Parameters{
    SpreadingFactor:    7,
    Bandwidth:          krylr896.Bandwidth125KHz,
    CodingRate:         1,
    ProgrammedPreamble: 4,
}

Complete configuration example:

config := krylr896.Configuration{
    Address:       &address,
    NetworkID:     &networkID,
    Band:          &band,
    Parameter:     &params,
    RFOutputPower: &rfPower,
}

Apply configuration during connection or update anytime with SetConfig. Only non-nil fields will be sent to the radio:

err := lora.SetConfig(config)
Sending Messages

Send up to 240 bytes to another radio. The first argument is the destination radio's address. Both radios must have the same NetworkID to communicate:

err := lora.SendMessage(uint16(2), []byte("Hello!"))

This sends "Hello!" to the radio with address 2. The radios must share the same NetworkID (configured in Configuration.NetworkID).

Receiving Messages

Messages are delivered via the RecievedData channel. Set up a goroutine to listen:

go func() {
    for msg := range lora.RecievedData {
        data := string(msg.Data[:msg.Length])
        fmt.Printf("From %d: %s (RSSI: %d, SNR: %d)\n", msg.Address, data, msg.ReceivedSignalStrengthIndicator, msg.SignalToNoiseRatio)
    }
}()
Sending Raw AT Commands

For direct AT command access, send to the Commands channel:

responseChan := make(chan krylr896.CommandResponse, 1)
lora.Commands <- krylr896.Command{
    Text:         "AT+ADDRESS?",
    ResponseChan: responseChan,
}

Read the response:

response := <-responseChan
if response.Error != nil {
    // handle error
}
fmt.Println(response.Response)
Error Handling

The library distinguishes between two types of errors:

Radio Errors - Error codes from the LoRa module (e.g., +ERR=2):

  • Stored in ErrorEvent.Code as *int
  • nil if not a radio error

Go Errors - Runtime errors from the library:

  • Stored in ErrorEvent.Err as error
  • nil if not a Go error

Check both fields:

if errEvent.Code != nil {
    fmt.Printf("Radio error code: %d\n", *errEvent.Code)
}
if errEvent.Err != nil {
    fmt.Printf("Go error: %v\n", errEvent.Err)
}
Uncategorized Errors Channel

The Errors channel receives:

  • Unsolicited error codes from the radio (e.g., spontaneous +ERR=10)
  • Serial port errors
  • Unknown/unrecognizable output that doesn't match expected patterns

Monitor errors in a goroutine:

go func() {
    for errEvent := range lora.Errors {
        if errEvent.Code != nil {
            log.Printf("Unsolicited radio error: %d", *errEvent.Code)
        }
        if errEvent.Err != nil {
            log.Printf("System error: %v", errEvent.Err)
        }
    }
}()

Any data received from the radio that doesn't match known patterns (+OK, +ERR=, +RCV=) is sent to this channel as a Go error with the message "unknown unsolicited data".

Closing the Connection

Always close when finished:

defer lora.CloseConnection()

This closes the serial port and command channels gracefully.

Constants

Bandwidth
  • Bandwidth125KHz, Bandwidth250KHz, Bandwidth500KHz (recommended)
  • Bandwidth7_8KHz, Bandwidth10_4KHz (not recommended)
Frequency Bands
  • BandUSA (915 MHz)
  • BandEUROPE1 (868 MHz)
  • BandEUROPE2 (433 MHz)
  • BandCHINA, BandASIA, BandAUSTRALIA, BandINDIA, BandKOREA, BandBRAZIL, BandJAPAN
Operating Mode
  • MODE_TRX - Transmit and receive
  • MODE_SLEEP - Sleep mode
UART Baud Rates
  • UartBaudRate_9600, UartBaudRate_115200 (default), etc.
Error Codes
  • OK (0) - Success
  • NO_ENTER (1) - Missing \r\n after command
  • NO_AT (2) - Command doesn't start with AT
  • NO_EQ (3) - Missing = in command
  • UNK_CMD (4) - Unknown command
  • TX_OT (10) - Transmit timeout
  • RX_OT (11) - Receive timeout
  • CRC_ERR (12) - CRC error
  • TX_OR (13) - Transmit overrun (>240 bytes)
  • UNK_ERR (15) - Unknown error

Example

See lora_test.go for complete examples including:

  • Full radio configuration
  • Bidirectional communication
  • Error handling
  • Raw AT commands

Further Reading

License

MIT License - See LICENSE.txt

Documentation

Overview

Example (BasicUsage)

Example_basicUsage demonstrates basic library usage

// configure the radio
address := uint16(1)
networkID := uint8(5)
band := BandUSA

config := Configuration{
	Address:   &address,
	NetworkID: &networkID,
	Band:      &band,
}

// create connection
lora, err := CreateConnectionDEBUG(testSerialPort, UartBaudRate_115200, config, 10, "r1", func(name, msg string) {
	log.Printf("[DEBUG][%s] %s", name, msg)
})
if err != nil {
	fmt.Printf("Error: %v\n", err.Err)
	return
}
defer lora.CloseConnection()

// send a message
targetAddress := uint16(2)
message := []byte("Hello!")
if sendErr := lora.SendMessage(targetAddress, message); sendErr != nil {
	fmt.Printf("Send error: %v\n", sendErr.Err)
	return
}

// listen for incoming messages
go func() {
	for {
		select {
		case msg := <-lora.RecievedData:
			fmt.Printf("Received: %s from %d\n",
				string(msg.Data[:msg.Length]),
				msg.Address)

		case errEvent := <-lora.Errors:
			if errEvent.Err != nil {
				fmt.Printf("Error: %v\n", errEvent.Err)
			}
		}
	}
}()

// keep running
time.Sleep(60 * time.Second)

Index

Examples

Constants

View Source
const (
	Bandwidth7_8KHz   uint8 = 0 // NOT RECCOMENDED
	Bandwidth10_4KHz  uint8 = 1 // NOT RECCOMENDED
	Bandwidth15_6KHz  uint8 = 2
	Bandwidth20_8KHz  uint8 = 3
	Bandwidth31_25KHz uint8 = 4
	Bandwidth41_7KHz  uint8 = 5
	Bandwidth62_5KHz  uint8 = 6
	Bandwidth125KHz   uint8 = 7
	Bandwidth250KHz   uint8 = 8
	Bandwidth500KHz   uint8 = 9
)

bandwidth constants

View Source
const (
	BandUSA       uint32 = 915000000
	BandEUROPE1   uint32 = 868000000
	BandEUROPE2   uint32 = 433000000
	BandCHINA     uint32 = 470000000
	BandASIA      uint32 = 470000000
	BandAUSTRALIA uint32 = 923000000
	BandINDIA     uint32 = 865000000
	BandKOREA     uint32 = 920000000
	BandBRAZIL    uint32 = 915000000
	BandJAPAN     uint32 = 920000000
)

band constants, HZ

View Source
const (
	MODE_TRX   uint8 = 0 // transmit and recieve
	MODE_SLEEP uint8 = 1 // sleep
)

mode constants

View Source
const (
	UartBaudRate_300    int = 300
	UartBaudRate_1200   int = 1200
	UartBaudRate_4800   int = 4800
	UartBaudRate_9600   int = 9600
	UartBaudRate_28800  int = 19200
	UartBaudRate_38400  int = 38400
	UartBaudRate_57600  int = 57600
	UartBaudRate_115200 int = 115200 // default
)

UART baud rate constants

View Source
const (
	OK       = 0  // OK
	NO_ENTER = 1  // missing "\r\n" after command
	NO_AT    = 2  // head of command is not AT
	NO_EQ    = 3  // missing "=" in AT command
	UNK_CMD  = 4  // unknown command
	TX_OT    = 10 // transmit over time
	RX_OT    = 11 // receive over time
	CRC_ERR  = 12 // CRC error
	TX_OR    = 13 // transmit over run(over 240 bytes)
	UNK_ERR  = 15 // unknown error
)

result code constants

Variables

This section is empty.

Functions

This section is empty.

Types

type Command

type Command struct {
	Text         string
	ResponseChan chan CommandResponse // channel to receive response on
}

type CommandResponse

type CommandResponse struct {
	Response string
	Error    *ErrorEvent // nil if no error
}

type Configuration

type Configuration struct {
	Address       *uint16     // ADDRESS, 		0-65535,															ident of the transciever
	NetworkID     *uint8      // NETWORKID, 	0-16,																must be the same for radios to communicate
	Band          *uint32     // BAND(Hz), 		433000000-915000000,												center freq of wireless band
	Parameter     *Parameters // PARAMETER, 																		rf params
	Mode          *uint8      // MODE, 			0-1,																work mode
	UartBaudRate  *int        // IPR, 			300-115200, 														uart baud rate
	EncryptionKey *[16]byte   // CPIN, 			00000000000000000000000000000000-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,	AES128 network password
	RFOutputPower *uint8      // CRFOP(dBm),	0-15,																RF output power

}

complete configuration

type ErrorEvent

type ErrorEvent struct {
	Code *int  // LoRa error code (nil if not applicable)
	Err  error // Go error (nil if not applicable)
}

func CreateConnection

func CreateConnection(serialInterfaceName string, baudRate int, config Configuration, buffLen int) (Lora *lora, errEvent *ErrorEvent)

CreateConnection attaches to a uart serial port, and a desired buffer length and returns a lora object

func CreateConnectionDEBUG

func CreateConnectionDEBUG(serialInterfaceName string, baudRate int, config Configuration, buffLen int, debugName string, debugFunc func(string, string)) (Lora *lora, errEvent *ErrorEvent)

CreateConnectionDEBUG creates a connection with debug logging enabled

type Parameters

type Parameters struct {
	SpreadingFactor    uint8 // SF, 7-12
	Bandwidth          uint8 // BW, 0-9
	CodingRate         uint8 // CR, 1-4
	ProgrammedPreamble uint8 // PP, 4-7
}

rf transmission params,

type RecievedData

type RecievedData struct {
	Address                         uint16    // transmitter address
	Length                          uint8     // data length
	Data                            [240]byte // data
	ReceivedSignalStrengthIndicator int8      // RSSI(dBm)
	SignalToNoiseRatio              int8      // SNR
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL