Initial upload
This commit is contained in:
1 parent
c2db6ee4b6
commit
f238dc3f0f
45 files changed
+10444
-201
No files matched your search
@@ -0,0 +1,162 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Matthijs Kooijman
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to anyone
|
||||
* obtaining a copy of this document and accompanying files,
|
||||
* to do whatever they want with them without any restriction,
|
||||
* including, but not limited to, copying, modification and redistribution.
|
||||
* NO WARRANTY OF ANY KIND IS PROVIDED.
|
||||
*
|
||||
* This example transmits data on hardcoded channel and receives data
|
||||
* when not transmitting. Running this sketch on two nodes should allow
|
||||
* them to communicate.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#if !defined(DISABLE_INVERT_IQ_ON_RX)
|
||||
#error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \
|
||||
config.h in the lmic library to set it.
|
||||
#endif
|
||||
|
||||
// How often to send a packet. Note that this sketch bypasses the normal
|
||||
// LMIC duty cycle limiting, so when you change anything in this sketch
|
||||
// (payload length, frequency, spreading factor), be sure to check if
|
||||
// this interval should not also be increased.
|
||||
// See this spreadsheet for an easy airtime and duty cycle calculator:
|
||||
// https://docs.google.com/spreadsheets/d/1voGAtQAjC1qBmaVuP1ApNKs1ekgUjavHuVQIXyYSvNc
|
||||
#define TX_INTERVAL 2000
|
||||
|
||||
// Pin mapping
|
||||
const lmic_pinmap lmic_pins = {
|
||||
.nss = 6,
|
||||
.rxtx = LMIC_UNUSED_PIN,
|
||||
.rst = 5,
|
||||
.dio = {2, 3, 4},
|
||||
};
|
||||
|
||||
|
||||
// These callbacks are only used in over-the-air activation, so they are
|
||||
// left empty here (we cannot leave them out completely unless
|
||||
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
|
||||
void os_getArtEui (u1_t* buf) { }
|
||||
void os_getDevEui (u1_t* buf) { }
|
||||
void os_getDevKey (u1_t* buf) { }
|
||||
|
||||
void onEvent (ev_t ev) {
|
||||
}
|
||||
|
||||
osjob_t txjob;
|
||||
osjob_t timeoutjob;
|
||||
static void tx_func (osjob_t* job);
|
||||
|
||||
// Transmit the given string and call the given function afterwards
|
||||
void tx(const char *str, osjobcb_t func) {
|
||||
os_radio(RADIO_RST); // Stop RX first
|
||||
delay(1); // Wait a bit, without this os_radio below asserts, apparently because the state hasn't changed yet
|
||||
LMIC.dataLen = 0;
|
||||
while (*str)
|
||||
LMIC.frame[LMIC.dataLen++] = *str++;
|
||||
LMIC.osjob.func = func;
|
||||
os_radio(RADIO_TX);
|
||||
Serial.println("TX");
|
||||
}
|
||||
|
||||
// Enable rx mode and call func when a packet is received
|
||||
void rx(osjobcb_t func) {
|
||||
LMIC.osjob.func = func;
|
||||
LMIC.rxtime = os_getTime(); // RX _now_
|
||||
// Enable "continuous" RX (e.g. without a timeout, still stops after
|
||||
// receiving a packet)
|
||||
os_radio(RADIO_RXON);
|
||||
Serial.println("RX");
|
||||
}
|
||||
|
||||
static void rxtimeout_func(osjob_t *job) {
|
||||
digitalWrite(LED_BUILTIN, LOW); // off
|
||||
}
|
||||
|
||||
static void rx_func (osjob_t* job) {
|
||||
// Blink once to confirm reception and then keep the led on
|
||||
digitalWrite(LED_BUILTIN, LOW); // off
|
||||
delay(10);
|
||||
digitalWrite(LED_BUILTIN, HIGH); // on
|
||||
|
||||
// Timeout RX (i.e. update led status) after 3 periods without RX
|
||||
os_setTimedCallback(&timeoutjob, os_getTime() + ms2osticks(3*TX_INTERVAL), rxtimeout_func);
|
||||
|
||||
// Reschedule TX so that it should not collide with the other side's
|
||||
// next TX
|
||||
os_setTimedCallback(&txjob, os_getTime() + ms2osticks(TX_INTERVAL/2), tx_func);
|
||||
|
||||
Serial.print("Got ");
|
||||
Serial.print(LMIC.dataLen);
|
||||
Serial.println(" bytes");
|
||||
Serial.write(LMIC.frame, LMIC.dataLen);
|
||||
Serial.println();
|
||||
|
||||
// Restart RX
|
||||
rx(rx_func);
|
||||
}
|
||||
|
||||
static void txdone_func (osjob_t* job) {
|
||||
rx(rx_func);
|
||||
}
|
||||
|
||||
// log text to USART and toggle LED
|
||||
static void tx_func (osjob_t* job) {
|
||||
// say hello
|
||||
tx("Hello, world!", txdone_func);
|
||||
// reschedule job every TX_INTERVAL (plus a bit of random to prevent
|
||||
// systematic collisions), unless packets are received, then rx_func
|
||||
// will reschedule at half this time.
|
||||
os_setTimedCallback(job, os_getTime() + ms2osticks(TX_INTERVAL + random(500)), tx_func);
|
||||
}
|
||||
|
||||
// application entry point
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("Starting");
|
||||
#ifdef VCC_ENABLE
|
||||
// For Pinoccio Scout boards
|
||||
pinMode(VCC_ENABLE, OUTPUT);
|
||||
digitalWrite(VCC_ENABLE, HIGH);
|
||||
delay(1000);
|
||||
#endif
|
||||
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
|
||||
// initialize runtime env
|
||||
os_init();
|
||||
|
||||
// Set up these settings once, and use them for both TX and RX
|
||||
|
||||
#if defined(CFG_eu868)
|
||||
// Use a frequency in the g3 which allows 10% duty cycling.
|
||||
LMIC.freq = 869525000;
|
||||
#elif defined(CFG_us915)
|
||||
LMIC.freq = 902300000;
|
||||
#endif
|
||||
|
||||
// Maximum TX power
|
||||
LMIC.txpow = 27;
|
||||
// Use a medium spread factor. This can be increased up to SF12 for
|
||||
// better range, but then the interval should be (significantly)
|
||||
// lowered to comply with duty cycle limits as well.
|
||||
LMIC.datarate = DR_SF9;
|
||||
// This sets CR 4/5, BW125 (except for DR_SF7B, which uses BW250)
|
||||
LMIC.rps = updr2rps(LMIC.datarate);
|
||||
|
||||
Serial.println("Started");
|
||||
Serial.flush();
|
||||
|
||||
// setup initial job
|
||||
os_setCallback(&txjob, tx_func);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// execute scheduled jobs and events
|
||||
os_runloop_once();
|
||||
}
|
||||
Reference in new issue
Block a user