Looking for a cheap gateway i did find the LoRa Go Dock.
You can use it as a gateway for your own testing because of the single channel.
it is based on arduino code and you can find the code here GIT LoRa Go Code - The guys did a great job ;o)
I did find the hardware on Ebay link and here you can find the schematic
I did draw a 3D printet box so i could put it up outside my house.
The STL files for the 3D printet box you can find here STL 1 LORAGO DOCK STL 2 LORAGO DOCK
The box are not water proff so you have to use some kind of silicone if you put it outdoor.
You can have a config page you can hit via your browser - Really do not use it, because if you use the LoRaGo as gateway you can see packet an activity on TheThingsNetWork.
Because it is a singlechannel gateway you have to make sure that your end node do only send on one channel.
You can read about the LMIC and single channel gateway here LoRaGo single channel forum post
it means that if you use the my cheap and easy arduino sensor your code ON THE CHEAP AND EASY ARDUINO has to be modified
my code looks like
/*
* This code is a copy and a futher development
* from https://github.com/matthijskooijman/arduino-lmic
* a great guy which did a wonderfull job
* I did put on the powerdown etc
* have fun Hjalmar Skovholm Hansen
*/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include "LowPower.h"
// keys from TheThingsNetwork
// I do use ABP so have to put them in manually
// this because of LowPower
// update will come later when found a solution ;o)
static const PROGMEM u1_t NWKSKEY[16] = { 0x18, 0x21, 0xAF, 0xB4, 0x05, 0x2A, 0x10, 0x40, 0xE9, 0xE3, 0x54, 0xC0, 0xAF, 0xE9, 0x40, 0xE3 };
static const u1_t PROGMEM APPSKEY[16] = { 0xBE, 0xAA, 0x1B, 0xAB, 0xDF, 0x97, 0xD1, 0x08, 0xDF, 0xBD, 0x6B, 0x42, 0x61, 0x8E, 0xE4, 0x6E };
static const u4_t DEVADDR = 0x26011450 ;
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
// Our array to put data into
// The Things Network suggest max 10 byte
static uint8_t mydata[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
static osjob_t sendjob;
const lmic_pinmap lmic_pins = {
.nss = 6, // Digital pin connected to SS
.rxtx = LMIC_UNUSED_PIN, // we do not use these
.rst = 5, // Digital pin connected to RST
.dio = {2, 3, 4}, // Digital pin connected to 00,01,02
};
void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
break;
case EV_RFU1:
Serial.println(F("EV_RFU1"));
break;
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if(LMIC.dataLen) {
// data received in rx slot after tx
Serial.print(F("Data Received: "));
Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
Serial.println();
}
// Here we go to sleep ...
// watchdog can go max 8 sec
// so we make a loop 8 times 10 equal 80 sec between
// each time we do connetc to gateway
// think this only work for ABP
for (int i=0; i<=9; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
do_send(&sendjob);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
default:
Serial.println(F("Unknown event"));
break;
}
}
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
Serial.println(F("Packet queued"));
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("Starting"));
os_init();
LMIC_reset();
#ifdef PROGMEM
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
LMIC_setLinkCheckMode(0);
// Define the single channel and data rate (SF) to use
int channel = 0;
int dr = DR_SF7;
// Disable all channels, except for the one defined above. // FOR TESTING ONLY!
for(int i=0; i<9; i++)
{ // For EU; for US use i<71
if(i != channel)
{
LMIC_disableChannel(i);
}
}
// Set data rate (SF) and transmit power for uplink
LMIC_setDrTxpow(dr, 14);
do_send(&sendjob);
}
void loop() {
os_runloop_once(); // start your loop with calling LoRa statemachine
// From here you can read your sensors
// and update mydata array with results
// I just update for fun to have some data
// know overrun etc ..but just to see results
mydata[0]= mydata[0] + 0x01;
mydata[5]= mydata[5] + 0x01;
}