first commit
This commit is contained in:
@@ -0,0 +1,697 @@
|
||||
/*********************************************************************
|
||||
BeieliScale by nbit Informatik GmbH
|
||||
|
||||
*********************************************************************/
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <avr/dtostrf.h>
|
||||
#include "HX711.h"
|
||||
#include "Adafruit_Si7021.h"
|
||||
#include "Adafruit_FRAM_SPI.h"
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
|
||||
// Required for Serial on Zero based boards
|
||||
#define Serial SERIAL_PORT_USBVIRTUAL
|
||||
#endif
|
||||
|
||||
#define MAX_VALUES_TO_SEND 5
|
||||
|
||||
typedef struct {
|
||||
byte version; // Versionierung des Paketformats
|
||||
short weight[MAX_VALUES_TO_SEND]; // Gewicht in 10-Gramm
|
||||
short temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/10 Grad Celsius
|
||||
byte vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
} LORA_data;
|
||||
|
||||
LORA_data lora_data;
|
||||
|
||||
typedef struct {
|
||||
u1_t nwkskey[16];
|
||||
u1_t appskey[16];
|
||||
u4_t devaddr;
|
||||
u1_t framecounter;
|
||||
long cal_w1_0;
|
||||
long cal_w2_0;
|
||||
float cal_w1_factor;
|
||||
float cal_w2_factor;
|
||||
short weight[MAX_VALUES_TO_SEND];
|
||||
short temperature[MAX_VALUES_TO_SEND];
|
||||
byte my_position;
|
||||
} FRAM_data;
|
||||
|
||||
FRAM_data fram_data;
|
||||
bool usb_power_only;
|
||||
|
||||
// Im DEBUG-Modus werden Meldungen auf der seriellen Schnittstelle ausgegeben
|
||||
#define DEBUG 1
|
||||
|
||||
#define DONEPIN A5
|
||||
#define VBATPIN A7
|
||||
#define LONG_OFFSET 2147483648L
|
||||
#define MAX_CHARS 80
|
||||
#define MAX_SHORT 32767
|
||||
|
||||
#define NWKSKEY 1
|
||||
#define APPSKEY 2
|
||||
#define DEVADDR 3
|
||||
|
||||
uint8_t FRAM_CS = 10;
|
||||
|
||||
Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_CS); // use hardware SPI
|
||||
|
||||
// Temperatursensor
|
||||
Adafruit_Si7021 sensor = Adafruit_Si7021();
|
||||
|
||||
// die beiden Waagen
|
||||
HX711 scale1;
|
||||
HX711 scale2;
|
||||
|
||||
char charVal[MAX_CHARS];
|
||||
|
||||
// LORA
|
||||
// LoRaWAN NwkSKey, network session key
|
||||
// This is the default Semtech key, which is used by the early prototype TTN
|
||||
// network.
|
||||
//static const PROGMEM u1_t NWKSKEY[16] = { 0x5F, 0x33, 0x20, 0x8C, 0x13, 0x3A, 0x39, 0x3F, 0xA5, 0x6F, 0xE1, 0xC7, 0x9B, 0x78, 0x2B, 0xDF };
|
||||
|
||||
// LoRaWAN AppSKey, application session key
|
||||
// This is the default Semtech key, which is used by the early prototype TTN
|
||||
// network.
|
||||
//static const u1_t PROGMEM APPSKEY[16] = { 0x17, 0x57, 0x92, 0x91, 0x43, 0x9C, 0xC3, 0xFC, 0x34, 0x50, 0xCD, 0x64, 0x14, 0xC4, 0xC8, 0xAB };
|
||||
|
||||
// LoRaWAN end-device address (DevAddr)
|
||||
//static const u4_t DEVADDR = 0x260112C8 ; // <-- Change this address for every node!
|
||||
|
||||
// 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) { }
|
||||
|
||||
static uint8_t mydata[] = "Hello, world!";
|
||||
static osjob_t sendjob;
|
||||
|
||||
// Schedule TX every this many seconds (might become longer due to duty
|
||||
// cycle limitations).
|
||||
const unsigned TX_INTERVAL = 60;
|
||||
|
||||
// Pin mapping
|
||||
const lmic_pinmap lmic_pins = {
|
||||
.nss = 8,
|
||||
.rxtx = LMIC_UNUSED_PIN,
|
||||
.rst = 4,
|
||||
.dio = {3, 6, LMIC_UNUSED_PIN},
|
||||
};
|
||||
|
||||
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;
|
||||
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) {
|
||||
Serial.println(F("Received "));
|
||||
Serial.println(LMIC.dataLen);
|
||||
Serial.println(F(" bytes of payload"));
|
||||
}
|
||||
// Schedule next transmission
|
||||
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
|
||||
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 {
|
||||
// Prepare upstream data transmission at the next possible time.
|
||||
//#define VBATPIN A7
|
||||
// float measuredvbat = analogRead(VBATPIN);
|
||||
// measuredvbat *= 2; // we divided by 2, so multiply back
|
||||
// measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
|
||||
// measuredvbat /= 1024; // convert to voltage
|
||||
// char buffer[8];
|
||||
|
||||
// dtostrf(measuredvbat, 1, 2, buffer);
|
||||
//String res = buffer;
|
||||
//res.getBytes(buffer, res.length() + 1);
|
||||
// Serial.print("VBat: " ); Serial.println(measuredvbat);
|
||||
//LMIC_setTxData2(1, (uint8_t*) &lora_data, sizeof(lora_data), 0);
|
||||
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
|
||||
ShowLoraData();
|
||||
|
||||
Serial.println(F("Packet queued"));
|
||||
}
|
||||
// Next TX is scheduled after TX_COMPLETE event.
|
||||
}
|
||||
|
||||
// END LORA
|
||||
|
||||
|
||||
|
||||
// Error-Fuction
|
||||
void error(const __FlashStringHelper*err) {
|
||||
#if DEBUG
|
||||
Serial.println(err);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Print Function
|
||||
void print_debug(const char *InputString) {
|
||||
#if DEBUG
|
||||
//Serial.println(millis());
|
||||
Serial.println(InputString);
|
||||
#endif
|
||||
}
|
||||
|
||||
byte dehex(char c) { // Get nibble value 0...15 from character c
|
||||
// Treat digit if c<'A', else letter
|
||||
return c < 'A' ? c & 0xF : 9 + (c & 0xF);
|
||||
// Above assumes that c is a 'hex digit' in 0...9, A or a ... F or f.
|
||||
// It would make more sense to just use 16 consecutive characters,
|
||||
// like eg 0123456789:;<=>? or @ABCDEFGHIJKLMNO so the above
|
||||
// could just say `return c & 0xF;`
|
||||
}
|
||||
|
||||
void WriteKey (String input, int which) {
|
||||
const char *hin = input.c_str(); // Get character array
|
||||
int clen = input.length() / 2;
|
||||
// Next line invalid in C++, ok in C99. Probably need to
|
||||
// instead declare a fixed-length array, cmd[MAXCMDLEN], etc
|
||||
char cmd[clen + 1]; // Leave a byte for null terminator
|
||||
for (int i = 0; i < 2 * clen; i += 2) {
|
||||
cmd[i / 2] = dehex(hin[i]) << 4 | dehex(hin[i + 1]);
|
||||
}
|
||||
cmd[clen] = 0; // Null-byte terminator
|
||||
if (which == APPSKEY) {
|
||||
memcpy(&fram_data.appskey, &cmd, 16);
|
||||
} else if (which == NWKSKEY) {
|
||||
memcpy(&fram_data.nwkskey, &cmd, 16);
|
||||
} else if (which == DEVADDR) {
|
||||
memcpy(&fram_data.devaddr, &cmd, 4);
|
||||
} else {
|
||||
print_debug("Invalid which");
|
||||
}
|
||||
Save2FRAM();
|
||||
}
|
||||
|
||||
boolean isValidHexKey(String hk, int length) {
|
||||
if (hk.length() != length) {
|
||||
return false;
|
||||
}
|
||||
char mychar;
|
||||
for (int i = 0; i < hk.length(); i++) {
|
||||
mychar = hk.charAt(i);
|
||||
if (not(isHexadecimalDigit(mychar))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_byte_array(u1_t arr[], int n) {
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (arr[i] < 16) Serial.write('0');
|
||||
Serial.print(arr[i], HEX);
|
||||
}
|
||||
}
|
||||
|
||||
float GetWeight() {
|
||||
long raw_weight1 = scale1.read_average(3);
|
||||
long raw_weight2 = scale2.read_average(3);
|
||||
|
||||
return (((raw_weight1 - fram_data.cal_w1_0) * fram_data.cal_w1_factor) + ((raw_weight2 - fram_data.cal_w2_0) * fram_data.cal_w2_factor));
|
||||
}
|
||||
|
||||
float GetTemp() {
|
||||
return sensor.readTemperature();
|
||||
}
|
||||
|
||||
float GetBat() {
|
||||
float vb = analogRead(VBATPIN);
|
||||
vb *= 2; // we divided by 2, so multiply back
|
||||
vb *= 3.3; // Multiply by 3.3V, our reference voltage
|
||||
return vb;
|
||||
}
|
||||
|
||||
void ShowFRAMData() {
|
||||
Serial.println('{');
|
||||
Serial.print(" \"nwkskey\": \"");
|
||||
print_byte_array(fram_data.nwkskey, 16);
|
||||
Serial.println("\", ");
|
||||
Serial.print(" \"appskey\": \"");
|
||||
print_byte_array(fram_data.appskey, 16);
|
||||
Serial.println("\", ");
|
||||
Serial.print(" \"devaddr\": \"");
|
||||
u1_t barr[4];
|
||||
memcpy(&barr, &fram_data.devaddr, 4);
|
||||
print_byte_array(barr, 4);
|
||||
Serial.println("\",");
|
||||
Serial.print(" \"framecounter\": ");
|
||||
Serial.print(fram_data.framecounter);
|
||||
Serial.println(",");
|
||||
Serial.print(" \"cal_w1_0\": ");
|
||||
Serial.print(fram_data.cal_w1_0);
|
||||
Serial.println(",");
|
||||
Serial.print(" \"cal_w2_0\": ");
|
||||
Serial.print(fram_data.cal_w2_0);
|
||||
Serial.println(",");
|
||||
Serial.print(" \"cal_w1_factor\": ");
|
||||
Serial.print(fram_data.cal_w1_factor);
|
||||
Serial.println(",");
|
||||
Serial.print(" \"cal_w2_factor\": ");
|
||||
Serial.print(fram_data.cal_w2_factor);
|
||||
Serial.println(",");
|
||||
Serial.print(" \"weight\": [");
|
||||
for (int i=0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
Serial.print(fram_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
Serial.print(",");
|
||||
}
|
||||
}
|
||||
Serial.println("],");
|
||||
Serial.print(" \"temperature\": [");
|
||||
for (int i=0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
Serial.print(fram_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
Serial.print(",");
|
||||
}
|
||||
}
|
||||
Serial.println("],");
|
||||
Serial.print(" \"my_position\": ");
|
||||
Serial.print(fram_data.my_position);
|
||||
Serial.println("");
|
||||
Serial.println("}");
|
||||
}
|
||||
|
||||
void Setup() {
|
||||
Serial.println("{ \"msg\": \"Entering setup mode\" }");
|
||||
String s = Serial.readStringUntil('\n');
|
||||
s.trim();
|
||||
while (s != "exit") {
|
||||
|
||||
if (s == "") {
|
||||
//Serial.println("Leerzeile wird ignoriert...");
|
||||
}
|
||||
else if (s.startsWith("setnwkskey")) {
|
||||
String key;
|
||||
key = s.substring(11);
|
||||
if (isValidHexKey(key, 32)) {
|
||||
WriteKey(key, NWKSKEY);
|
||||
Serial.println("{ \"msg\": \"setnwkskey was successful\" }");
|
||||
}
|
||||
else {
|
||||
Serial.println("{ \"msg\": \"Ist kein gueltiger Hex Key mit 32 Zeichen\" }");
|
||||
}
|
||||
}
|
||||
else if (s.startsWith("setappskey")) {
|
||||
String key;
|
||||
key = s.substring(11);
|
||||
if (isValidHexKey(key, 32)) {
|
||||
WriteKey(key, APPSKEY);
|
||||
Serial.println("{ \"msg\": \"setappskey was successful\" }");
|
||||
}
|
||||
else {
|
||||
Serial.println("{ \"msg\": \"Ist kein gueltiger Hex Key mit 32 Zeichen\" }");
|
||||
}
|
||||
}
|
||||
else if (s.startsWith("setdevaddr")) {
|
||||
String key;
|
||||
key = s.substring(11);
|
||||
if (isValidHexKey(key, 8)) {
|
||||
WriteKey(key, DEVADDR);
|
||||
Serial.println("{ \"msg\": \"setdevaddr was successful\" }");
|
||||
}
|
||||
else {
|
||||
Serial.println("{ \"msg\": \"Ist kein gueltiger Hex Key mit 32 Zeichen\" }");
|
||||
}
|
||||
}
|
||||
else if (s == "getvalues") {
|
||||
Serial.println('{');
|
||||
Serial.print(" \"weight\": ");
|
||||
Serial.print(GetWeight());
|
||||
Serial.println(", ");
|
||||
Serial.print(" \"temperature\": ");
|
||||
Serial.print(GetTemp());
|
||||
Serial.println(", ");
|
||||
Serial.print(" \"batt\": ");
|
||||
Serial.println(GetBat());
|
||||
Serial.println("}");
|
||||
}
|
||||
else if (s == "getrawvalues") {
|
||||
Serial.println("getrawvalues...");
|
||||
long raw_weight1 = scale1.read_average(3);
|
||||
long raw_weight2 = scale2.read_average(3);
|
||||
Serial.println("getrawvalues after read scales..");
|
||||
Serial.println('{');
|
||||
Serial.print(" \"w1_raw\": ");
|
||||
Serial.print(raw_weight1);
|
||||
Serial.println(", ");
|
||||
Serial.print(" \"w2_raw\": ");
|
||||
Serial.print(raw_weight2);
|
||||
Serial.println("");
|
||||
Serial.println("}");
|
||||
}
|
||||
else if (s == "getframdata") {
|
||||
ShowFRAMData();
|
||||
}
|
||||
else if (s == "initvalues") {
|
||||
for (int i=0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
fram_data.weight[i]=MAX_SHORT;
|
||||
fram_data.temperature[i]=MAX_SHORT;
|
||||
}
|
||||
fram_data.my_position = 0;
|
||||
Serial.println("{ \"msg\": \"initvalues was successful\" }");
|
||||
}
|
||||
else if (s == "calibrate_zero_1") {
|
||||
long raw_weight1 = scale1.read_average(3);
|
||||
fram_data.cal_w1_0 = raw_weight1;
|
||||
Serial.println("{ \"msg\": \"calibrate_zero_1 was successful\" }");
|
||||
}
|
||||
else if (s == "calibrate_zero_2") {
|
||||
long raw_weight2 = scale2.read_average(3);
|
||||
fram_data.cal_w2_0 = raw_weight2;
|
||||
Serial.println("{ \"msg\": \"calibrate_zero_2 was successful\" }");
|
||||
}
|
||||
else if (s.startsWith("calibrate_1")) {
|
||||
String w1_gramm;
|
||||
w1_gramm = s.substring(12);
|
||||
long raw_weight1 = scale1.read_average(3);
|
||||
fram_data.cal_w1_factor = (w1_gramm.toFloat() / (float)raw_weight1);
|
||||
Serial.println("{ \"msg\": \"calibrate_1 was successful\" }");
|
||||
}
|
||||
else if (s.startsWith("calibrate_2")) {
|
||||
String w2_gramm;
|
||||
w2_gramm = s.substring(12);
|
||||
long raw_weight2 = scale2.read_average(3);
|
||||
fram_data.cal_w2_factor = (w2_gramm.toFloat() / (float)raw_weight2);
|
||||
Serial.println("{ \"msg\": \"calibrate_2 was successful\" }");
|
||||
}
|
||||
else {
|
||||
Serial.println("{ \"msg\": \"You sent me an unknown command (exit to quit setup mode)\" }");
|
||||
}
|
||||
s = Serial.readStringUntil('\n');
|
||||
s.trim();
|
||||
}
|
||||
}
|
||||
|
||||
void Save2FRAM()
|
||||
{
|
||||
fram.writeEnable(true);
|
||||
fram.write(0x0, (uint8_t *) &fram_data, sizeof(FRAM_data) );
|
||||
fram.writeEnable(false);
|
||||
}
|
||||
|
||||
void ShowLoraData()
|
||||
{
|
||||
Serial.println("Lora Packet:");
|
||||
Serial.println(lora_data.version);
|
||||
Serial.println(lora_data.weight[0]);
|
||||
Serial.println(lora_data.weight[1]);
|
||||
Serial.println(lora_data.weight[2]);
|
||||
Serial.println(lora_data.weight[3]);
|
||||
Serial.println(lora_data.weight[4]);
|
||||
Serial.println(lora_data.temperature[0]);
|
||||
Serial.println(lora_data.temperature[1]);
|
||||
Serial.println(lora_data.temperature[2]);
|
||||
Serial.println(lora_data.temperature[3]);
|
||||
Serial.println(lora_data.temperature[4]);
|
||||
Serial.println(lora_data.vbat);
|
||||
Serial.print("Size of Lora Package: ");
|
||||
Serial.println(sizeof(LORA_data));
|
||||
}
|
||||
|
||||
// Alles wird im Setup erledigt...
|
||||
void setup(void)
|
||||
{
|
||||
// DONEPIN must be low...
|
||||
pinMode(DONEPIN, OUTPUT);
|
||||
digitalWrite(DONEPIN, LOW);
|
||||
|
||||
// Reading battery; Value is in Millivolts
|
||||
float vbat = GetBat();
|
||||
// Wir nehmen an, dass das USB-Kabel gesteckt ist, wenn die Batteriespannung
|
||||
// groesser als 4.4V ist (Schalter muss auf 0 sein!
|
||||
usb_power_only = (vbat >= 4400);
|
||||
|
||||
if (usb_power_only) {
|
||||
// Initialize serial and wait for port to open:
|
||||
Serial.begin(115200);
|
||||
Serial.setTimeout(6000);
|
||||
while (!Serial);
|
||||
print_debug("Serial Port initialized");
|
||||
}
|
||||
// fuer Debugzwecke
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
if (usb_power_only) {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
} else {
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
|
||||
// FRAM
|
||||
// we set #8 to High (CS of Lora Module), to be able to use FRAM
|
||||
pinMode(8, INPUT_PULLUP);
|
||||
digitalWrite(8, HIGH);
|
||||
|
||||
if (fram.begin()) {
|
||||
print_debug("Found SPI FRAM");
|
||||
} else {
|
||||
print_debug("No SPI FRAM found ... check your connections\r\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// wir lesen die FRAM-Werte
|
||||
fram.read(0x0, (uint8_t*) &fram_data, sizeof(FRAM_data));
|
||||
|
||||
//ShowFRAMData();
|
||||
// END FRAM
|
||||
|
||||
// zuerst wird der HX711 initialisiert
|
||||
print_debug("Initializing the scale");
|
||||
scale1.begin(A3, A2);
|
||||
scale2.begin(A1, A0);
|
||||
|
||||
// Jetzt initialisieren wir den Si7021
|
||||
if (!sensor.begin()) {
|
||||
print_debug("Did not find Si7021 sensor!");
|
||||
}
|
||||
|
||||
boolean success;
|
||||
|
||||
fram_data.weight[fram_data.my_position] = GetWeight();
|
||||
fram_data.temperature[fram_data.my_position] = (int)GetTemp() * 10;
|
||||
|
||||
// Wenn die Differenz des Gewichts zu gross ist oder alle Messplaetze belegt sind senden wir das Paket...
|
||||
bool send_lora_data = false;
|
||||
if (fram_data.my_position > 0) {
|
||||
if ((fram_data.weight[fram_data.my_position] - fram_data.weight[fram_data.my_position - 1]) >= 9999999) {
|
||||
Serial.print("CCC");
|
||||
Serial.print(fram_data.my_position);
|
||||
send_lora_data = true;
|
||||
}
|
||||
}
|
||||
fram_data.my_position++;
|
||||
|
||||
if (fram_data.my_position == MAX_VALUES_TO_SEND) {
|
||||
send_lora_data = true;
|
||||
}
|
||||
|
||||
Serial.print("send_lora_data:");
|
||||
Serial.print(send_lora_data);
|
||||
if (send_lora_data) {
|
||||
Serial.println("SendLoraPacket");
|
||||
lora_data.version = 1;
|
||||
for (int i=0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.weight[i] = fram_data.weight[i];
|
||||
lora_data.temperature[i] = fram_data.temperature[i];
|
||||
}
|
||||
lora_data.vbat = (byte)(vbat / 20);
|
||||
|
||||
|
||||
// LORA
|
||||
#ifdef VCC_ENABLE
|
||||
// For Pinoccio Scout boards
|
||||
pinMode(VCC_ENABLE, OUTPUT);
|
||||
digitalWrite(VCC_ENABLE, HIGH);
|
||||
delay(1000);
|
||||
#endif
|
||||
|
||||
// LMIC init
|
||||
os_init();
|
||||
// Reset the MAC state. Session and pending data transfers will be discarded.
|
||||
LMIC_reset();
|
||||
|
||||
// Set static session parameters. Instead of dynamically establishing a session
|
||||
// by joining the network, precomputed session parameters are be provided.
|
||||
|
||||
LMIC_setSession (0x1, fram_data.devaddr, fram_data.nwkskey, fram_data.appskey);
|
||||
|
||||
#if defined(CFG_eu868)
|
||||
// Set up the channels used by the Things Network, which corresponds
|
||||
// to the defaults of most gateways. Without this, only three base
|
||||
// channels from the LoRaWAN specification are used, which certainly
|
||||
// works, so it is good for debugging, but can overload those
|
||||
// frequencies, so be sure to configure the full frequency range of
|
||||
// your network here (unless your network autoconfigures them).
|
||||
// Setting up channels should happen after LMIC_setSession, as that
|
||||
// configures the minimal channel set.
|
||||
// NA-US channels 0-71 are configured automatically
|
||||
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
|
||||
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
|
||||
// devices' ping slots. LMIC does not have an easy way to define set this
|
||||
// frequency and support for class B is spotty and untested, so this
|
||||
// frequency is not configured here.
|
||||
#elif defined(CFG_us915)
|
||||
// NA-US channels 0-71 are configured automatically
|
||||
// but only one group of 8 should (a subband) should be active
|
||||
// TTN recommends the second sub band, 1 in a zero based count.
|
||||
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
|
||||
LMIC_selectSubBand(1);
|
||||
#endif
|
||||
|
||||
// Disable link check validation
|
||||
LMIC_setLinkCheckMode(0);
|
||||
|
||||
// TTN uses SF9 for its RX2 window.
|
||||
LMIC.dn2Dr = DR_SF9;
|
||||
|
||||
// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
|
||||
LMIC_setDrTxpow(DR_SF7, 14);
|
||||
|
||||
// Start job
|
||||
do_send(&sendjob);
|
||||
|
||||
// END LORA
|
||||
// Jetzt koennen wir die FRAM-Werte wieder initialisieren
|
||||
for (int i=0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
fram_data.weight[i] = MAX_SHORT;
|
||||
fram_data.temperature[i] = MAX_SHORT;
|
||||
}
|
||||
fram_data.my_position = 0;
|
||||
|
||||
|
||||
}
|
||||
delay(2000);
|
||||
Serial.println("BLABLA");
|
||||
// soll evtl. das Setup durchgefuehrt werden?
|
||||
if (usb_power_only && Serial.available()) {
|
||||
Serial.println("GGGGBLABLA");
|
||||
String s = Serial.readStringUntil('\n');
|
||||
if (s == "setup") {
|
||||
Serial.println("SETUPGGGGBLABLA");
|
||||
Setup();
|
||||
} else {
|
||||
Serial.println("{ \"msg\": \"Unknown command (only setup is allowed here)\"");
|
||||
}
|
||||
}
|
||||
|
||||
// dump the entire 8K of memory!
|
||||
if (usb_power_only) {
|
||||
uint8_t value;
|
||||
for (uint16_t a = 0; a < sizeof(FRAM_data); a++) {
|
||||
value = fram.read8(a);
|
||||
if ((a % 32) == 0) {
|
||||
Serial.print("\n 0x"); Serial.print(a, HEX); Serial.print(": ");
|
||||
}
|
||||
Serial.print("0x");
|
||||
if (value < 0x1)
|
||||
Serial.print('0');
|
||||
Serial.print(value, HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.print("\nsizeof(FRAM_data): " + String(sizeof(FRAM_data)));
|
||||
}
|
||||
|
||||
// Jetzt sichern wir die Werte
|
||||
Save2FRAM();
|
||||
|
||||
//ShowFRAMData();
|
||||
|
||||
/* Jetzt signalisieren wir, dass wir fertig sind... */
|
||||
delay(5000);
|
||||
print_debug("Jetzt senden wir das DONE Signal...");
|
||||
|
||||
|
||||
// while (1) {
|
||||
// print_debug("ENDLOS LOOP AM ENDE DES SETUPS");
|
||||
// delay(500);
|
||||
// }
|
||||
|
||||
#if DEBUG
|
||||
delay(3000);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
digitalWrite(DONEPIN, HIGH);
|
||||
delay(5);
|
||||
digitalWrite(DONEPIN, LOW);
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// Hier haben wir nichts zu tun, wir machen alles im Setup...
|
||||
}
|
||||
Reference in New Issue
Block a user