bring repo up-to-date
No files matched your search
@@ -0,0 +1,43 @@
|
||||
#include <HX711_ADC.h>
|
||||
|
||||
//HX711 constructor (dout pin, sck pin)
|
||||
HX711_ADC LoadCell_1(A3, A2); //HX711 1
|
||||
HX711_ADC LoadCell_2(A1, A0); //HX711 2
|
||||
|
||||
long t;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); delay(10);
|
||||
Serial.println();
|
||||
Serial.println("Starting...");
|
||||
LoadCell_1.begin();
|
||||
LoadCell_2.begin();
|
||||
long stabilisingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilising time
|
||||
byte loadcell_1_rdy = 0;
|
||||
byte loadcell_2_rdy = 0;
|
||||
while ((loadcell_1_rdy + loadcell_2_rdy) < 2) { //run startup, stabilization and tare, both modules simultaniously
|
||||
if (!loadcell_1_rdy) loadcell_1_rdy = LoadCell_1.startMultiple(stabilisingtime);
|
||||
if (!loadcell_2_rdy) loadcell_2_rdy = LoadCell_2.startMultiple(stabilisingtime);
|
||||
}
|
||||
LoadCell_1.setCalFactor(100); // user set calibration value (float)
|
||||
LoadCell_2.setCalFactor(100); // user set calibration value (float)
|
||||
Serial.println("Startup + tare is complete");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//update() should be called at least as often as HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS
|
||||
//longer delay in scetch will reduce effective sample rate (be carefull with use of delay() in the loop)
|
||||
LoadCell_1.update();
|
||||
LoadCell_2.update();
|
||||
|
||||
//get smoothed value from data set + current calibration factor
|
||||
if (millis() > t + 250) {
|
||||
long a = LoadCell_1.getSingleConversionRaw();
|
||||
long b = LoadCell_2.getSingleConversionRaw();
|
||||
Serial.print("Load_cell 1 output val: ");
|
||||
Serial.print(a);
|
||||
Serial.print(" Load_cell 2 output val: ");
|
||||
Serial.println(b);
|
||||
t = millis();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <HX711_ADC.h>
|
||||
|
||||
//HX711 constructor (dout pin, sck pin)
|
||||
HX711_ADC LoadCell_1(A3, A2); //HX711 1
|
||||
HX711_ADC LoadCell_2(A1, A0); //HX711 2
|
||||
|
||||
long t;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); delay(10);
|
||||
Serial.println();
|
||||
Serial.println("Starting...");
|
||||
LoadCell_1.begin();
|
||||
LoadCell_2.begin();
|
||||
long stabilisingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilising time
|
||||
byte loadcell_1_rdy = 0;
|
||||
byte loadcell_2_rdy = 0;
|
||||
while ((loadcell_1_rdy + loadcell_2_rdy) < 2) { //run startup, stabilization and tare, both modules simultaniously
|
||||
if (!loadcell_1_rdy) loadcell_1_rdy = LoadCell_1.startMultiple(stabilisingtime);
|
||||
if (!loadcell_2_rdy) loadcell_2_rdy = LoadCell_2.startMultiple(stabilisingtime);
|
||||
}
|
||||
LoadCell_1.setCalFactor(100); // user set calibration value (float)
|
||||
LoadCell_2.setCalFactor(100); // user set calibration value (float)
|
||||
Serial.println("Startup + tare is complete");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//update() should be called at least as often as HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS
|
||||
//longer delay in scetch will reduce effective sample rate (be carefull with use of delay() in the loop)
|
||||
LoadCell_1.update();
|
||||
LoadCell_2.update();
|
||||
|
||||
//get smoothed value from data set + current calibration factor
|
||||
if (millis() > t + 250) {
|
||||
long a = LoadCell_1.getSingleConversionRaw();
|
||||
long b = LoadCell_2.getSingleConversionRaw();
|
||||
Serial.print("Load_cell 1 output val: ");
|
||||
Serial.print(a);
|
||||
Serial.print(" Load_cell 2 output val: ");
|
||||
Serial.println(b);
|
||||
t = millis();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <hal/hal.h>
|
||||
#include <SPI.h>
|
||||
#include "HX711.h"
|
||||
#include "Adafruit_Si7021.h"
|
||||
//#include "Adafruit_Si7021.h"
|
||||
#include "Adafruit_FRAM_SPI.h"
|
||||
|
||||
// Defines
|
||||
|
||||
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_TxBuffer.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD
|
||||
;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t *pSendJob);
|
||||
static void warmupDoneCb(osjob_t *pSendJob);
|
||||
static void txFailedDoneCb(osjob_t *pSendJob);
|
||||
static void sleepDoneCb(osjob_t *pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 4;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Versionierung des Paketformats
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Zehntels-Prozent
|
||||
uint8_t pressure; // Luftdruck in XXXX
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der Messung in Sekunden, erster Wert ist 0
|
||||
int16_t weight_raw1[MAX_VALUES_TO_SEND]; // Reading (raw) der ersten Waegzelle
|
||||
int16_t weight_raw2[MAX_VALUES_TO_SEND]; // Reading (raw) der zweiten Waegzelle
|
||||
int16_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/10 Grad Celsius
|
||||
} LORA_data;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed (Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK
|
||||
);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t *pJob);
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (! (gCatena.GetOperatingFlags() &
|
||||
static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)))
|
||||
{
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion))
|
||||
);
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring)
|
||||
);
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena))
|
||||
{
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t *pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM * const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform)
|
||||
{
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i)
|
||||
{
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags
|
||||
);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep))
|
||||
{
|
||||
fBme = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
LoadCell_1.begin(A3, A2);
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS))
|
||||
{
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() &
|
||||
static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest)))
|
||||
{
|
||||
if (! gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else
|
||||
{
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
startSendingUplink();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
|
||||
gCatena.poll();
|
||||
|
||||
/* for mfg test, don't tx, just fill -- this causes output to Serial */
|
||||
if (gCatena.GetOperatingFlags() &
|
||||
static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))
|
||||
{
|
||||
TxBuffer_t b;
|
||||
fillBuffer(b);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReadSensors()
|
||||
{
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int) (vBat * 1000.0f));
|
||||
lora_data.vbat = (vBat * 1000 / 20);
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int) (vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
if (fBme)
|
||||
{
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int) m.Temperature,
|
||||
(int) m.Pressure,
|
||||
(int) m.Humidity
|
||||
);
|
||||
lora_data.temperature[0] = m.Temperature;
|
||||
lora_data.humidity = m.Temperature;
|
||||
lora_data.pressure = m.Pressure;
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.wait_ready_timeout(1000))
|
||||
{
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not found.");
|
||||
}
|
||||
if (LoadCell_2.wait_ready_timeout(1000))
|
||||
{
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not found.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void fillBuffer(TxBuffer_t &b)
|
||||
{
|
||||
b.begin();
|
||||
FlagsSensor2 flag;
|
||||
|
||||
flag = FlagsSensor2(0);
|
||||
|
||||
b.put(FormatSensor2); /* the flag for this record format */
|
||||
uint8_t * const pFlag = b.getp();
|
||||
b.put(0x00); /* will be set to the flags */
|
||||
|
||||
// vBat is sent as 5000 * v
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int) (vBat * 1000.0f));
|
||||
b.putV(vBat);
|
||||
flag |= FlagsSensor2::FlagVbat;
|
||||
|
||||
// vBus is sent as 5000 * v
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int) (vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
uint32_t bootCount;
|
||||
if (gCatena.getBootCount(bootCount))
|
||||
{
|
||||
b.putBootCountLsb(bootCount);
|
||||
flag |= FlagsSensor2::FlagBoot;
|
||||
}
|
||||
|
||||
if (fBme)
|
||||
{
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int) m.Temperature,
|
||||
(int) m.Pressure,
|
||||
(int) m.Humidity
|
||||
);
|
||||
b.putT(m.Temperature);
|
||||
b.putP(m.Pressure);
|
||||
b.putRH(m.Humidity);
|
||||
|
||||
flag |= FlagsSensor2::FlagTPH;
|
||||
}
|
||||
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.wait_ready_timeout(1000))
|
||||
{
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not found.");
|
||||
}
|
||||
if (LoadCell_2.wait_ready_timeout(1000))
|
||||
{
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not found.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
*pFlag = uint8_t(flag);
|
||||
}
|
||||
|
||||
void startSendingUplink(void)
|
||||
{
|
||||
TxBuffer_t b;
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
fillBuffer(b);
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16))
|
||||
{
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
//gLoRaWAN.SendBuffer(b.getbase(), b.getn(), sendBufferDoneCb, NULL, fConfirmed);
|
||||
gLoRaWAN.SendBuffer((uint8_t*) &lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void *pContext,
|
||||
bool fStatus
|
||||
)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (! fStatus)
|
||||
{
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime()+sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn
|
||||
);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t *pSendJob
|
||||
)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t *pSendJob
|
||||
)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (! g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest)
|
||||
{
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr())
|
||||
{
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17))
|
||||
{
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() &
|
||||
static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0)
|
||||
{
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay
|
||||
);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n)
|
||||
{
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000)
|
||||
{
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100)
|
||||
{
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t *pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
void doLightSleep(osjob_t *pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb
|
||||
);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(
|
||||
osjob_t *pJob
|
||||
)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb
|
||||
);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(
|
||||
osjob_t *pJob
|
||||
)
|
||||
{
|
||||
startSendingUplink();
|
||||
}
|
||||
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
||||
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
||||
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
||||
CATCFG_INTERVAL_COUNT = 30,
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// the cycle time to use
|
||||
unsigned gTxCycle;
|
||||
// remaining before we reset to default
|
||||
unsigned gTxCycleCount;
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
static Arduino_LoRaWAN::ReceivePortBufferCbFn receiveMessage;
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount);
|
||||
|
||||
// Additional Commands
|
||||
// forward reference to the command function
|
||||
cCommandStream::CommandFn cmdHello;
|
||||
cCommandStream::CommandFn cmdGetCalibrationSettings;
|
||||
cCommandStream::CommandFn cmdGetSensorReadings;
|
||||
cCommandStream::CommandFn cmdGetScale1;
|
||||
cCommandStream::CommandFn cmdGetScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateScale2;
|
||||
|
||||
// the individual commmands are put in this table
|
||||
static const cCommandStream::cEntry sMyExtraCommmands[] =
|
||||
{
|
||||
{ "hello", cmdHello },
|
||||
{ "get_calibration_settings", cmdGetCalibrationSettings },
|
||||
{ "get_sensor_readings", cmdGetSensorReadings },
|
||||
{ "calibrate_zero_scale1", cmdCalibrateZeroScale1 },
|
||||
{ "calibrate_zero_scale2", cmdCalibrateZeroScale2 },
|
||||
{ "calibrate_scale1", cmdCalibrateScale1 },
|
||||
{ "calibrate_scale2", cmdCalibrateScale2 },
|
||||
// other commands go here....
|
||||
};
|
||||
|
||||
/* a top-level structure wraps the above and connects to the system table */
|
||||
/* it optionally includes a "first word" so you can for sure avoid name clashes */
|
||||
static cCommandStream::cDispatch
|
||||
sMyExtraCommands_top(
|
||||
sMyExtraCommmands, /* this is the pointer to the table */
|
||||
sizeof(sMyExtraCommmands), /* this is the size of the table */
|
||||
"application" /* this is the "first word" for all the commands in this table*/
|
||||
);
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// must be 65 bytes long...
|
||||
typedef struct {
|
||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 2 ohne Gewicht
|
||||
float cal_w1_factor; // 4 Bytes,
|
||||
float cal_w2_factor;
|
||||
byte fill[49];
|
||||
} __attribute__((packed)) CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} SENSOR_data;
|
||||
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
SENSOR_data last_sensor_reading;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
// Use D10 to regulate power
|
||||
pinMode(D10, OUTPUT);
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
//setup_scales();
|
||||
|
||||
/* for 4451, we need wider tolerances, it seems */
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
LMIC_setClockError(10 * 65536 / 100);
|
||||
#endif
|
||||
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
/* add our application-specific commands */
|
||||
gCatena.addCommands(
|
||||
sMyExtraCommands_top,
|
||||
nullptr
|
||||
);
|
||||
|
||||
// read config_data from fram...
|
||||
gCatena.SafePrintf("Reading Calibration Config from FRAM...\n");
|
||||
gCatena.getFram()->getField(cFramStorage::kBme680Cal, (uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
gCatena.SafePrintf("cal_w1_0: %d\n", config_data.cal_w1_0);
|
||||
gCatena.SafePrintf("cal_w2_0: %d\n", config_data.cal_w2_0);
|
||||
gCatena.SafePrintf("cal_w1_factor: %d.%03d\n", (int)config_data.cal_w1_factor, (int)(config_data.cal_w1_factor * 1000) % 1000);
|
||||
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n", (int)config_data.cal_w2_factor, (int)(config_data.cal_w2_factor * 1000) % 1000);
|
||||
gCatena.SafePrintf("Size of config_data: %d\n", sizeof(config_data));
|
||||
|
||||
// im Moment statisch...
|
||||
//config_data.cal_w1_0 = 20000;
|
||||
//config_data.cal_w2_0 = 20000;
|
||||
//config_data.cal_w1_factor = 2.5;
|
||||
//config_data.cal_w2_factor = 2.5;
|
||||
|
||||
|
||||
// config_data speichern...
|
||||
//gCatena.SafePrintf("Writing Calibration Config to FRAM...\n");
|
||||
//gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gLoRaWAN.SetReceiveBufferBufferCb(receiveMessage);
|
||||
setTxCycleTime(CATCFG_T_CYCLE_INITIAL, CATCFG_INTERVAL_COUNT_INITIAL);
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Enable Power
|
||||
digitalWrite(D10, HIGH);
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
//LoadCell_1.power_down();
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(D12, A2);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
//LoadCell_2.power_down();
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.temperature = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
lora_data.temperature_change[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n", lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n", lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n", lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n", lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n", lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n", lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n", lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n", lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n", lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n", lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n", lora_data.temperature);
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld", lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature_change\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND - 1; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.temperature_change[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetVBatValue(int millivolts)
|
||||
{
|
||||
uint8_t res;
|
||||
if (millivolts <= 2510) {
|
||||
res = 0;
|
||||
|
||||
} else if (millivolts >= 4295) {
|
||||
res = 255;
|
||||
|
||||
} else {
|
||||
res = (millivolts - 2510) / 7;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime, bool readOnly)
|
||||
{
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_last;
|
||||
int16_t temp_change;
|
||||
int32_t weight_current32;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n", pressure_current);
|
||||
}
|
||||
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
// Setup Scales
|
||||
setup_scales();
|
||||
|
||||
// Read Scales
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_1.power_up();
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
//LoadCell_1.power_down();
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_2.power_up();
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
//LoadCell_2.power_down();
|
||||
|
||||
// Disable Power
|
||||
digitalWrite(D10, LOW);
|
||||
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current32 = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
if (weight_current32 < 0) {
|
||||
weight_current32 = 0;
|
||||
} else if (weight_current32 > UINT16_MAX) {
|
||||
weight_current32 = UINT16_MAX;
|
||||
}
|
||||
weight_current = (uint16_t)weight_current32;
|
||||
|
||||
if (not(readOnly)) {
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
temp_last = lora_data.temperature;
|
||||
|
||||
for (int i = 0; i < my_position; i++) {
|
||||
temp_last = temp_last + lora_data.temperature_change[i];
|
||||
}
|
||||
|
||||
if (my_position > 0) {
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - temp_last;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
gCatena.SafePrintf("now going to sleep for 6 minutes...\n");
|
||||
Serial.flush();
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL - 5);
|
||||
}
|
||||
}
|
||||
|
||||
last_sensor_reading.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
|
||||
last_sensor_reading.weight1 = weight1_current;
|
||||
last_sensor_reading.weight2 = weight2_current;
|
||||
last_sensor_reading.weight = weight_current;
|
||||
last_sensor_reading.temperature = temp_current;
|
||||
last_sensor_reading.humidity = humidity_current;
|
||||
last_sensor_reading.pressure = pressure_current;
|
||||
}
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gCatena.SafePrintf("SendBuffer firstTime\n");
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gCatena.SafePrintf("SendBuffer not firstTime\n");
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
gCatena.SafePrintf("sendBufferDoneCB before TimedCallback\n");
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
gCatena.SafePrintf("sendBufferDoneCB after TimedCallback\n");
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("settleDoneCb\n");
|
||||
sleepDoneCb(pSendJob);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false, false);
|
||||
}
|
||||
|
||||
static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage, size_t nMessage)
|
||||
{
|
||||
unsigned txCycle;
|
||||
unsigned txCount;
|
||||
|
||||
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
||||
|
||||
if (! (port == 1 && 2 <= nMessage && nMessage <= 3))
|
||||
{
|
||||
gCatena.SafePrintf("invalid message port(%02x)/length(%zx)\n",
|
||||
port, nMessage
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
txCycle = (pMessage[0] << 8) | pMessage[1];
|
||||
|
||||
if (txCycle < CATCFG_T_MIN || txCycle > CATCFG_T_MAX)
|
||||
{
|
||||
gCatena.SafePrintf("tx cycle time out of range: %u\n", txCycle);
|
||||
return;
|
||||
}
|
||||
|
||||
// byte [2], if present, is the repeat count.
|
||||
// explicitly sending zero causes it to stick.
|
||||
txCount = CATCFG_INTERVAL_COUNT;
|
||||
if (nMessage >= 3)
|
||||
{
|
||||
txCount = pMessage[2];
|
||||
}
|
||||
|
||||
// we print out the received message...
|
||||
gCatena.SafePrintf("Received Data (Payload): \n");
|
||||
for (byte i = 0; i < nMessage; i++) {
|
||||
gCatena.SafePrintf("%c", pMessage[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
setTxCycleTime(txCycle, txCount);
|
||||
}
|
||||
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount)
|
||||
{
|
||||
if (txCount > 0)
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds for %u messages\n",
|
||||
txCycle, txCount
|
||||
);
|
||||
else
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds indefinitely\n",
|
||||
txCycle
|
||||
);
|
||||
|
||||
gTxCycle = txCycle;
|
||||
gTxCycleCount = txCount;
|
||||
}
|
||||
|
||||
/* process "application hello" -- args are ignored */
|
||||
// argv[0] is "hello"
|
||||
// argv[1..argc-1] are the (ignored) arguments
|
||||
cCommandStream::CommandStatus cmdHello(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("Hello, world!\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
|
||||
cCommandStream::CommandStatus cmdGetCalibrationSettings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"cal_w1_0\": \"%d\",\n", config_data.cal_w1_0);
|
||||
pThis->printf(" \"cal_w2_0\": \"%d\",\n", config_data.cal_w2_0);
|
||||
pThis->printf(" \"cal_w1_factor\": \"%d.%03d\n", (int)config_data.cal_w1_factor, (int)abs(config_data.cal_w1_factor * 1000) % 1000);
|
||||
pThis->printf(" \"cal_w2_factor\": \"%d.%03d\n", (int)config_data.cal_w2_factor, (int)abs(config_data.cal_w2_factor * 1000) % 1000);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetSensorReadings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"weight\": \"%d\",\n", last_sensor_reading.weight);
|
||||
pThis->printf(" \"weight1_raw\": \"%d\",\n", last_sensor_reading.weight1);
|
||||
pThis->printf(" \"weight2_raw\": \"%d\",\n", last_sensor_reading.weight2);
|
||||
pThis->printf(" \"temperature\": \"%d\",\n", last_sensor_reading.temperature);
|
||||
pThis->printf(" \"humidity\": \"%d\",\n", last_sensor_reading.humidity);
|
||||
pThis->printf(" \"pressure\": \"%d\",\n", last_sensor_reading.pressure);
|
||||
pThis->printf(" \"batt\": \"%d\",\n", last_sensor_reading.vbat);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("getscale1\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("getscale2\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
|
||||
String w1_gramm(argv[1]);
|
||||
config_data.cal_w1_factor = (((float)last_sensor_reading.weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
|
||||
String w2_gramm(argv[1]);
|
||||
config_data.cal_w2_factor = (((float)last_sensor_reading.weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,988 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
||||
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
||||
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
||||
CATCFG_INTERVAL_COUNT = 30,
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// the cycle time to use
|
||||
unsigned gTxCycle;
|
||||
// remaining before we reset to default
|
||||
unsigned gTxCycleCount;
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
static Arduino_LoRaWAN::ReceivePortBufferCbFn receiveMessage;
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount);
|
||||
|
||||
// Additional Commands
|
||||
// forward reference to the command function
|
||||
cCommandStream::CommandFn cmdHello;
|
||||
cCommandStream::CommandFn cmdGetCalibrationSettings;
|
||||
cCommandStream::CommandFn cmdGetSensorReadings;
|
||||
cCommandStream::CommandFn cmdGetScale1;
|
||||
cCommandStream::CommandFn cmdGetScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateScale2;
|
||||
|
||||
// the individual commmands are put in this table
|
||||
static const cCommandStream::cEntry sMyExtraCommmands[] =
|
||||
{
|
||||
{ "hello", cmdHello },
|
||||
{ "get_calibration_settings", cmdGetCalibrationSettings },
|
||||
{ "get_sensor_readings", cmdGetSensorReadings },
|
||||
{ "calibrate_zero_scale1", cmdCalibrateZeroScale1 },
|
||||
{ "calibrate_zero_scale2", cmdCalibrateZeroScale2 },
|
||||
{ "calibrate_scale1", cmdCalibrateScale1 },
|
||||
{ "calibrate_scale2", cmdCalibrateScale2 },
|
||||
// other commands go here....
|
||||
};
|
||||
|
||||
/* a top-level structure wraps the above and connects to the system table */
|
||||
/* it optionally includes a "first word" so you can for sure avoid name clashes */
|
||||
static cCommandStream::cDispatch
|
||||
sMyExtraCommands_top(
|
||||
sMyExtraCommmands, /* this is the pointer to the table */
|
||||
sizeof(sMyExtraCommmands), /* this is the size of the table */
|
||||
"application" /* this is the "first word" for all the commands in this table*/
|
||||
);
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// must be 65 bytes long...
|
||||
typedef struct {
|
||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 2 ohne Gewicht
|
||||
float cal_w1_factor; // 4 Bytes,
|
||||
float cal_w2_factor;
|
||||
byte fill[123];
|
||||
} __attribute__((packed)) CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vbat; // Batteriespannung (0: <= 2510mV, 70: 3000mV, 170: 3700mV, 255: >= 4295mV [1 Einheit => 7mV])
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} SENSOR_data;
|
||||
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
SENSOR_data last_sensor_reading;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
// Use D10 to regulate power
|
||||
pinMode(D10, OUTPUT);
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
//setup_scales();
|
||||
|
||||
/* for 4451, we need wider tolerances, it seems */
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
LMIC_setClockError(10 * 65536 / 100);
|
||||
#endif
|
||||
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
/* add our application-specific commands */
|
||||
gCatena.addCommands(
|
||||
sMyExtraCommands_top,
|
||||
nullptr
|
||||
);
|
||||
|
||||
// read config_data from fram...
|
||||
gCatena.SafePrintf("Reading Calibration Config from FRAM...\n");
|
||||
gCatena.getFram()->getField(cFramStorage::kBme680Cal, (uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
gCatena.SafePrintf("cal_w1_0: %d\n", config_data.cal_w1_0);
|
||||
gCatena.SafePrintf("cal_w2_0: %d\n", config_data.cal_w2_0);
|
||||
gCatena.SafePrintf("cal_w1_factor: %d.%03d\n", (int)config_data.cal_w1_factor, (int)(config_data.cal_w1_factor * 1000) % 1000);
|
||||
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n", (int)config_data.cal_w2_factor, (int)(config_data.cal_w2_factor * 1000) % 1000);
|
||||
gCatena.SafePrintf("Size of config_data: %d\n", sizeof(config_data));
|
||||
|
||||
// im Moment statisch...
|
||||
//config_data.cal_w1_0 = 20000;
|
||||
//config_data.cal_w2_0 = 20000;
|
||||
//config_data.cal_w1_factor = 2.5;
|
||||
//config_data.cal_w2_factor = 2.5;
|
||||
|
||||
|
||||
// config_data speichern...
|
||||
//gCatena.SafePrintf("Writing Calibration Config to FRAM...\n");
|
||||
//gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gLoRaWAN.SetReceiveBufferBufferCb(receiveMessage);
|
||||
setTxCycleTime(CATCFG_T_CYCLE_INITIAL, CATCFG_INTERVAL_COUNT_INITIAL);
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Enable Power
|
||||
digitalWrite(D10, HIGH);
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
//LoadCell_1.power_down();
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(D12, A2);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
//LoadCell_2.power_down();
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.temperature = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
lora_data.temperature_change[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n", lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n", lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n", lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n", lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n", lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n", lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n", lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n", lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n", lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n", lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n", lora_data.temperature);
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld", lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature_change\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND - 1; i++) {
|
||||
gCatena.SafePrintf("%d", lora_data.temperature_change[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetVBatValue(int millivolts)
|
||||
{
|
||||
uint8_t res;
|
||||
if (millivolts <= 2510) {
|
||||
res = 0;
|
||||
|
||||
} else if (millivolts >= 4295) {
|
||||
res = 255;
|
||||
|
||||
} else {
|
||||
res = (millivolts - 2510) / 7;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime, bool readOnly)
|
||||
{
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_last;
|
||||
int16_t temp_change;
|
||||
int32_t weight_current32;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n", pressure_current);
|
||||
}
|
||||
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
// Setup Scales
|
||||
setup_scales();
|
||||
|
||||
// Read Scales
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_1.power_up();
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
gCatena.SafePrintf("Load_cell 1 weight1_current: %ld\n", weight1_current);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
//LoadCell_1.power_down();
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_2.power_up();
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
gCatena.SafePrintf("Load_cell 2 weight2_current: %ld\n", weight2_current);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
//LoadCell_2.power_down();
|
||||
|
||||
// Disable Power
|
||||
digitalWrite(D10, LOW);
|
||||
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current32 = (int32_t)((((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor)) / 5.0);
|
||||
if (weight_current32 < 0) {
|
||||
weight_current32 = 0;
|
||||
} else if (weight_current32 > UINT16_MAX) {
|
||||
weight_current32 = UINT16_MAX;
|
||||
}
|
||||
weight_current = (uint16_t)weight_current32;
|
||||
|
||||
if (not(readOnly)) {
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
temp_last = lora_data.temperature;
|
||||
|
||||
for (int i = 0; i < my_position; i++) {
|
||||
temp_last = temp_last + lora_data.temperature_change[i];
|
||||
}
|
||||
|
||||
if (my_position > 0) {
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - temp_last;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
gCatena.SafePrintf("now going to sleep for 6 minutes...\n");
|
||||
Serial.flush();
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
if (!fUsbPower) {
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL - 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_sensor_reading.vbat = GetVBatValue((int)(vBat * 1000.0f));
|
||||
|
||||
last_sensor_reading.weight1 = weight1_current;
|
||||
last_sensor_reading.weight2 = weight2_current;
|
||||
last_sensor_reading.weight = weight_current;
|
||||
last_sensor_reading.temperature = temp_current;
|
||||
last_sensor_reading.humidity = humidity_current;
|
||||
last_sensor_reading.pressure = pressure_current;
|
||||
}
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gCatena.SafePrintf("SendBuffer firstTime\n");
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gCatena.SafePrintf("SendBuffer not firstTime\n");
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
gCatena.SafePrintf("sendBufferDoneCB before TimedCallback\n");
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
gCatena.SafePrintf("sendBufferDoneCB after TimedCallback\n");
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("settleDoneCb\n");
|
||||
sleepDoneCb(pSendJob);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false, false);
|
||||
}
|
||||
|
||||
static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage, size_t nMessage)
|
||||
{
|
||||
unsigned txCycle;
|
||||
unsigned txCount;
|
||||
|
||||
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
||||
|
||||
if (! (port == 1 && 2 <= nMessage && nMessage <= 3))
|
||||
{
|
||||
gCatena.SafePrintf("invalid message port(%02x)/length(%zx)\n",
|
||||
port, nMessage
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
txCycle = (pMessage[0] << 8) | pMessage[1];
|
||||
|
||||
if (txCycle < CATCFG_T_MIN || txCycle > CATCFG_T_MAX)
|
||||
{
|
||||
gCatena.SafePrintf("tx cycle time out of range: %u\n", txCycle);
|
||||
return;
|
||||
}
|
||||
|
||||
// byte [2], if present, is the repeat count.
|
||||
// explicitly sending zero causes it to stick.
|
||||
txCount = CATCFG_INTERVAL_COUNT;
|
||||
if (nMessage >= 3)
|
||||
{
|
||||
txCount = pMessage[2];
|
||||
}
|
||||
|
||||
// we print out the received message...
|
||||
gCatena.SafePrintf("Received Data (Payload): \n");
|
||||
for (byte i = 0; i < nMessage; i++) {
|
||||
gCatena.SafePrintf("%c", pMessage[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
setTxCycleTime(txCycle, txCount);
|
||||
}
|
||||
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount)
|
||||
{
|
||||
if (txCount > 0)
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds for %u messages\n",
|
||||
txCycle, txCount
|
||||
);
|
||||
else
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds indefinitely\n",
|
||||
txCycle
|
||||
);
|
||||
|
||||
gTxCycle = txCycle;
|
||||
gTxCycleCount = txCount;
|
||||
}
|
||||
|
||||
/* process "application hello" -- args are ignored */
|
||||
// argv[0] is "hello"
|
||||
// argv[1..argc-1] are the (ignored) arguments
|
||||
cCommandStream::CommandStatus cmdHello(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("Hello, world!\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
|
||||
cCommandStream::CommandStatus cmdGetCalibrationSettings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"cal_w1_0\": \"%d\",\n", config_data.cal_w1_0);
|
||||
pThis->printf(" \"cal_w2_0\": \"%d\",\n", config_data.cal_w2_0);
|
||||
pThis->printf(" \"cal_w1_factor\": \"%d.%03d\n", (int)config_data.cal_w1_factor, (int)abs(config_data.cal_w1_factor * 1000) % 1000);
|
||||
pThis->printf(" \"cal_w2_factor\": \"%d.%03d\n", (int)config_data.cal_w2_factor, (int)abs(config_data.cal_w2_factor * 1000) % 1000);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetSensorReadings(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"weight\": \"%d\",\n", last_sensor_reading.weight);
|
||||
pThis->printf(" \"weight1_raw\": \"%d\",\n", last_sensor_reading.weight1);
|
||||
pThis->printf(" \"weight2_raw\": \"%d\",\n", last_sensor_reading.weight2);
|
||||
pThis->printf(" \"temperature\": \"%d\",\n", last_sensor_reading.temperature);
|
||||
pThis->printf(" \"humidity\": \"%d\",\n", last_sensor_reading.humidity);
|
||||
pThis->printf(" \"pressure\": \"%d\",\n", last_sensor_reading.pressure);
|
||||
pThis->printf(" \"batt\": \"%d\",\n", last_sensor_reading.vbat);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("getscale1\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
pThis->printf("getscale2\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale1(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
|
||||
String w1_gramm(argv[1]);
|
||||
config_data.cal_w1_factor = (((float)last_sensor_reading.weight1 - config_data.cal_w1_0) / w1_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
gCatena.SafePrintf("last_sensor_reading.weight1: %ld\n", last_sensor_reading.weight1);
|
||||
gCatena.SafePrintf("config_data.cal_w1_0: %ld\n", config_data.cal_w1_0);
|
||||
gCatena.SafePrintf("w1_gramm: %s\n", w1_gramm);
|
||||
gCatena.SafePrintf("w1_gramm (float): %d\n", (int)w1_gramm.toFloat());
|
||||
gCatena.SafePrintf("config_data.cal_w1_factor: %d\n", (int)config_data.cal_w1_factor);
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale2(cCommandStream *pThis, void *pContext, int argc, char **argv)
|
||||
{
|
||||
ReadSensors(false, true);
|
||||
|
||||
String w2_gramm(argv[1]);
|
||||
config_data.cal_w2_factor = (((float)last_sensor_reading.weight2 - config_data.cal_w2_0) / w2_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
||||
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
||||
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
||||
CATCFG_INTERVAL_COUNT = 30,
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// the cycle time to use
|
||||
unsigned gTxCycle;
|
||||
// remaining before we reset to default
|
||||
unsigned gTxCycleCount;
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
static Arduino_LoRaWAN::ReceivePortBufferCbFn receiveMessage;
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount);
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// must be 65 bytes long...
|
||||
typedef struct {
|
||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
float cal_w1_factor; // 4 Bytes,
|
||||
float cal_w2_factor;
|
||||
byte fill[49];
|
||||
} __attribute__((packed)) CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
|
||||
/* for 4451, we need wider tolerances, it seems */
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
LMIC_setClockError(10 * 65536 / 100);
|
||||
#endif
|
||||
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// read config_data from fram...
|
||||
gCatena.SafePrintf("Reading Calibration Config from FRAM...\n");
|
||||
gCatena.getFram()->getField(cFramStorage::kBme680Cal, (uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
gCatena.SafePrintf("cal_w1_0: %d\n",config_data.cal_w1_0);
|
||||
gCatena.SafePrintf("cal_w2_0: %d\n",config_data.cal_w2_0);
|
||||
gCatena.SafePrintf("cal_w1_factor: %d.%03d\n",(int)config_data.cal_w1_factor,(int)(config_data.cal_w1_factor*1000)%1000);
|
||||
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n",(int)config_data.cal_w2_factor,(int)(config_data.cal_w2_factor*1000)%1000);
|
||||
gCatena.SafePrintf("Size of config_data: %d\n",sizeof(config_data));
|
||||
|
||||
// im Moment statisch...
|
||||
//config_data.cal_w1_0 = 20000;
|
||||
//config_data.cal_w2_0 = 20000;
|
||||
//config_data.cal_w1_factor = 2.5;
|
||||
//config_data.cal_w2_factor = 2.5;
|
||||
|
||||
|
||||
// config_data speichern...
|
||||
gCatena.SafePrintf("Writing Calibration Config to FRAM...\n");
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gLoRaWAN.SetReceiveBufferBufferCb(receiveMessage);
|
||||
setTxCycleTime(CATCFG_T_CYCLE_INITIAL, CATCFG_INTERVAL_COUNT_INITIAL);
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
//LoadCell_1.begin(A3, A2);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
//LoadCell_2.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.temperature = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
if (i < (MAX_VALUES_TO_SEND -1)) {
|
||||
lora_data.temperature_change[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data.temperature);
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature_change\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND - 1; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature_change[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_1.power_up();
|
||||
LoadCell_1.power_up();
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_last;
|
||||
int16_t temp_change;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Power-Down HX711
|
||||
LoadCell_1.power_down();
|
||||
LoadCell_1.power_down();
|
||||
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
temp_last = lora_data.temperature;
|
||||
|
||||
for (int i = 0; i < my_position; i++) {
|
||||
temp_last = temp_last + lora_data.temperature_change[i];
|
||||
}
|
||||
|
||||
if (my_position > 0) {
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - temp_last;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
|
||||
static void receiveMessage(void *pContext, uint8_t port, const uint8_t *pMessage, size_t nMessage)
|
||||
{
|
||||
unsigned txCycle;
|
||||
unsigned txCount;
|
||||
|
||||
gCatena.SafePrintf("receiveMessage was called!!!\n");
|
||||
|
||||
if (! (port == 1 && 2 <= nMessage && nMessage <= 3))
|
||||
{
|
||||
gCatena.SafePrintf("invalid message port(%02x)/length(%zx)\n",
|
||||
port, nMessage
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
txCycle = (pMessage[0] << 8) | pMessage[1];
|
||||
|
||||
if (txCycle < CATCFG_T_MIN || txCycle > CATCFG_T_MAX)
|
||||
{
|
||||
gCatena.SafePrintf("tx cycle time out of range: %u\n", txCycle);
|
||||
return;
|
||||
}
|
||||
|
||||
// byte [2], if present, is the repeat count.
|
||||
// explicitly sending zero causes it to stick.
|
||||
txCount = CATCFG_INTERVAL_COUNT;
|
||||
if (nMessage >= 3)
|
||||
{
|
||||
txCount = pMessage[2];
|
||||
}
|
||||
|
||||
// we print out the received message...
|
||||
gCatena.SafePrintf("Received Data (Payload): \n");
|
||||
for (byte i = 0; i < nMessage; i++) {
|
||||
gCatena.SafePrintf("%c", pMessage[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
setTxCycleTime(txCycle, txCount);
|
||||
}
|
||||
|
||||
void setTxCycleTime(unsigned txCycle, unsigned txCount)
|
||||
{
|
||||
if (txCount > 0)
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds for %u messages\n",
|
||||
txCycle, txCount
|
||||
);
|
||||
else
|
||||
gCatena.SafePrintf(
|
||||
"message cycle time %u seconds indefinitely\n",
|
||||
txCycle
|
||||
);
|
||||
|
||||
gTxCycle = txCycle;
|
||||
gTxCycleCount = txCount;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,718 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
long cal_w1_0;
|
||||
long cal_w2_0;
|
||||
float cal_w1_factor;
|
||||
float cal_w2_factor;
|
||||
} CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading;
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// im Moment statisch...
|
||||
config_data.cal_w1_0 = 20000;
|
||||
config_data.cal_w2_0 = 20000;
|
||||
config_data.cal_w1_factor = 2.5;
|
||||
config_data.cal_w2_factor = 2.5;
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
uint8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
uint8_t temp_last;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (uint8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 4;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Versionierung des Paketformats
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Zehntels-Prozent
|
||||
uint8_t pressure; // Luftdruck in XXXX
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der Messung in Sekunden, erster Wert ist 0
|
||||
int16_t weight_raw1[MAX_VALUES_TO_SEND]; // Reading (raw) der ersten Waegzelle
|
||||
int16_t weight_raw2[MAX_VALUES_TO_SEND]; // Reading (raw) der zweiten Waegzelle
|
||||
int16_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/10 Grad Celsius
|
||||
} LORA_data;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position >= MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.humidity = 0;
|
||||
lora_data.pressure = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
lora_data.weight_raw1[i] = 0;
|
||||
lora_data.weight_raw2[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowLORAData(void)
|
||||
{
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%i\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%i\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%i\",\n",lora_data.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%i\",\n",lora_data.pressure);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%i",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight_raw1\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%i",lora_data.weight_raw1[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight_raw2\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%i",lora_data.weight_raw2[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%i",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int16_t w1_current;
|
||||
int16_t w2_current;
|
||||
int16_t temp_last;
|
||||
uint8_t humidity_last;
|
||||
uint8_t pressure_last;
|
||||
int16_t w1_last;
|
||||
int16_t w2_last;
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = m.Temperature;
|
||||
humidity_current = m.Humidity;
|
||||
pressure_current = m.Pressure;
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
w1_current = w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
w2_current = w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
|
||||
if (my_position > 0) {
|
||||
temp_last = lora_data.temperature[my_position - 1];
|
||||
w1_last = lora_data.weight_raw1[my_position - 1];
|
||||
w2_last = lora_data.weight_raw2[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 10 || abs(w1_current - w1_last) > 50 || abs(w2_current - w2_last) > 50) {
|
||||
lora_data.vbat = (vBat * 1000 / 20);
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position] = int((millis() - timer_pos0) / 1000);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
lora_data.weight_raw1[my_position] = w1_current;
|
||||
lora_data.weight_raw2[my_position] = w2_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity = humidity_current;
|
||||
lora_data.pressure = humidity_current;
|
||||
|
||||
ShowLORAData();
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(void)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 6;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint32_t PRESSURE_OFFSET = 80000;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
long cal_w1_0;
|
||||
long cal_w2_0;
|
||||
float cal_w1_factor;
|
||||
float cal_w2_factor;
|
||||
} FRAM_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Versionierung des Paketformats
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t pressure; // Luftdruck in Pascal (0 entspricht 80000 Pa)
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der weiteren Messung in Sekunden seit Start
|
||||
int16_t weight[MAX_VALUES_TO_SEND]; // Gewicht in 10-Gramm, Addition beider Waegzellen
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
} LORA_data;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
FRAM_data fram_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
// aktuell noch als Konstanten...
|
||||
fram_data.cal_w1_0 = -10000;
|
||||
fram_data.cal_w2_0 = -10000;
|
||||
fram_data.cal_w1_factor = 1;
|
||||
fram_data.cal_w2_factor = 1;
|
||||
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position > MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.humidity = 0;
|
||||
lora_data.pressure = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(void)
|
||||
{
|
||||
char str[10];
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%d\",\n",lora_data.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%d\",\n",lora_data.pressure);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%u",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
int16_t pressure_current;
|
||||
int32_t weight_current;
|
||||
int32_t w1_current;
|
||||
int32_t w2_current;
|
||||
int8_t temp_last;
|
||||
int32_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint16_t)(m.Pressure - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
w1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
w2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Calculate Weight
|
||||
weight_current = (((w1_current - fram_data.cal_w1_0) / fram_data.cal_w1_factor) + ((w2_current - fram_data.cal_w2_0) / fram_data.cal_w2_factor));
|
||||
|
||||
// calculate last value
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist, oder es die erste Messung ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 3 || abs(weight_current - weight_last) > 50) {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position] = (uint8_t)((millis() - timer_pos0) / 1000);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
lora_data.humidity = humidity_current;
|
||||
lora_data.pressure = pressure_current;
|
||||
}
|
||||
|
||||
ShowLORAData();
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(void)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 3;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint32_t PRESSURE_OFFSET = 80000;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Versionierung des Paketformats
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
int16_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Pascal (0 entspricht 80000 Pa)
|
||||
int32_t weight1[MAX_VALUES_TO_SEND]; // Waegezelle 1, Raw Value
|
||||
int32_t weight2[MAX_VALUES_TO_SEND]; // Waegezelle 2, Raw Value
|
||||
uint16_t reading_offset[MAX_VALUES_TO_SEND - 1]; // Zeit der weiteren Messungen in Sekunden seit Start
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position >= MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
}
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight1[i] = 0;
|
||||
lora_data.weight2[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(void)
|
||||
{
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < (MAX_VALUES_TO_SEND - 1); i++) {
|
||||
gCatena.SafePrintf("%u",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight1\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight1[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight2\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight2[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
int16_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int8_t temp_last;
|
||||
int32_t weight1_last;
|
||||
int32_t weight2_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (int16_t)(m.Pressure - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// calculate last value
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight1_last = lora_data.weight1[my_position - 1];
|
||||
weight2_last = lora_data.weight2[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist, oder es die erste Messung ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 3 || abs(weight1_current - weight1_last) > 500 || abs(weight2_current - weight2_last) > 500) {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight1[my_position] = weight1_current;
|
||||
lora_data.weight2[my_position] = weight2_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position - 1] = (uint16_t)((millis() - timer_pos0) / 1000);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData();
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink();
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(void)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,667 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 3;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint32_t PRESSURE_OFFSET = 80000;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Versionierung des Paketformats
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
int16_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Pascal (0 entspricht 80000 Pa)
|
||||
int32_t weight1[MAX_VALUES_TO_SEND]; // Waegezelle 1, Raw Value
|
||||
int32_t weight2[MAX_VALUES_TO_SEND]; // Waegezelle 2, Raw Value
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der weiteren Messungen in Minuten seit Start, letzter Wert: Offset beim Senden des Pakets
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position >= MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight1[i] = 0;
|
||||
lora_data.weight2[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(void)
|
||||
{
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < (MAX_VALUES_TO_SEND); i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight1\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight1[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight2\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight2[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
int16_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int8_t temp_last;
|
||||
int32_t weight1_last;
|
||||
int32_t weight2_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (int16_t)(m.Pressure - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// calculate last value
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight1_last = lora_data.weight1[my_position - 1];
|
||||
weight2_last = lora_data.weight2[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist, oder es die erste Messung ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 3 || abs(weight1_current - weight1_last) > 500 || abs(weight2_current - weight2_last) > 500) {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight1[my_position] = weight1_current;
|
||||
lora_data.weight2[my_position] = weight2_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position - 1] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData();
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
lora_data.reading_offset[my_position] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink();
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(void)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,923 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
//CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE = 10, // every 10 seconds
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
CATCFG_T_CYCLE_INITIAL = 30, // every 30 seconds initially
|
||||
CATCFG_INTERVAL_COUNT_INITIAL = 30, // repeat for 15 minutes
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
CATCFG_T_MIN = CATCFG_T_OVERHEAD,
|
||||
CATCFG_T_MAX = CATCFG_T_CYCLE < 60 * 60 ? 60 * 60 : CATCFG_T_CYCLE, // normally one hour max.
|
||||
CATCFG_INTERVAL_COUNT = 30,
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// the cycle time to use
|
||||
unsigned gTxCycle;
|
||||
// remaining before we reset to default
|
||||
unsigned gTxCycleCount;
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
// Additional Commands
|
||||
// forward reference to the command function
|
||||
cCommandStream::CommandFn cmdHello;
|
||||
cCommandStream::CommandFn cmdGetCalibrationSettings;
|
||||
cCommandStream::CommandFn cmdGetSensorReadings;
|
||||
cCommandStream::CommandFn cmdGetScale1;
|
||||
cCommandStream::CommandFn cmdGetScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateZeroScale2;
|
||||
cCommandStream::CommandFn cmdCalibrateScale1;
|
||||
cCommandStream::CommandFn cmdCalibrateScale2;
|
||||
|
||||
// the individual commmands are put in this table
|
||||
static const cCommandStream::cEntry sMyExtraCommmands[] =
|
||||
{
|
||||
{ "hello", cmdHello },
|
||||
{ "get_calibration_settings", cmdGetCalibrationSettings },
|
||||
{ "get_sensor_readings", cmdGetSensorReadings },
|
||||
{ "calibrate_zero_scale1", cmdCalibrateZeroScale1 },
|
||||
{ "calibrate_zero_scale2", cmdCalibrateZeroScale2 },
|
||||
{ "calibrate_scale1", cmdCalibrateScale1 },
|
||||
{ "calibrate_scale2", cmdCalibrateScale2 },
|
||||
// other commands go here....
|
||||
};
|
||||
|
||||
/* a top-level structure wraps the above and connects to the system table */
|
||||
/* it optionally includes a "first word" so you can for sure avoid name clashes */
|
||||
static cCommandStream::cDispatch
|
||||
sMyExtraCommands_top(
|
||||
sMyExtraCommmands, /* this is the pointer to the table */
|
||||
sizeof(sMyExtraCommmands), /* this is the size of the table */
|
||||
"application" /* this is the "first word" for all the commands in this table*/
|
||||
);
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// must be 65 bytes long...
|
||||
typedef struct {
|
||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 2 ohne Gewicht
|
||||
float cal_w1_factor; // 4 Bytes,
|
||||
float cal_w2_factor;
|
||||
byte fill[49];
|
||||
} __attribute__((packed)) CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} SENSOR_data;
|
||||
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
SENSOR_data last_sensor_reading;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
|
||||
/* for 4451, we need wider tolerances, it seems */
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
LMIC_setClockError(10 * 65536 / 100);
|
||||
#endif
|
||||
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// prepare external Power
|
||||
pinMode(D10, OUTPUT);
|
||||
digitalWrite(D10, HIGH);
|
||||
|
||||
/* add our application-specific commands */
|
||||
gCatena.addCommands(
|
||||
sMyExtraCommands_top,
|
||||
nullptr
|
||||
);
|
||||
|
||||
// read config_data from fram...
|
||||
//gCatena.SafePrintf("Reading Calibration Config from FRAM...\n");
|
||||
gCatena.getFram()->getField(cFramStorage::kBme680Cal, (uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
//gCatena.SafePrintf("cal_w1_0: %d\n",config_data.cal_w1_0);
|
||||
//gCatena.SafePrintf("cal_w2_0: %d\n",config_data.cal_w2_0);
|
||||
//gCatena.SafePrintf("cal_w1_factor: %d.%03d\n",(int)config_data.cal_w1_factor,(int)(config_data.cal_w1_factor*1000)%1000);
|
||||
//gCatena.SafePrintf("cal_w2_factor: %d.%03d\n",(int)config_data.cal_w2_factor,(int)(config_data.cal_w2_factor*1000)%1000);
|
||||
//gCatena.SafePrintf("Size of config_data: %d\n",sizeof(config_data));
|
||||
|
||||
// im Moment statisch...
|
||||
//config_data.cal_w1_0 = 20000;
|
||||
//config_data.cal_w2_0 = 20000;
|
||||
//config_data.cal_w1_factor = 2.5;
|
||||
//config_data.cal_w2_factor = 2.5;
|
||||
|
||||
|
||||
// config_data speichern...
|
||||
//gCatena.SafePrintf("Writing Calibration Config to FRAM...\n");
|
||||
//gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
//gCatena.SafePrintf("\n");
|
||||
//gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
//gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
//gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
// gLoRaWAN.GetNetworkName(),
|
||||
// gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
//gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
//gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
//gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
//gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
//gCatena.SafePrintf(
|
||||
// "CPU Unique ID: %s\n",
|
||||
// gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
//gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
//gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::On);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
//gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
// we only read vBus once, as there was a read error after deep sleep...
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
//gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(D12, A2);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.temperature = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
if (i < (MAX_VALUES_TO_SEND -1)) {
|
||||
lora_data.temperature_change[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data.temperature);
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature_change\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND - 1; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature_change[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime, bool readOnly)
|
||||
{
|
||||
gCatena.SafePrintf("start ReadSensors\n");
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_last;
|
||||
int16_t temp_change;
|
||||
int32_t weight_current32;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
//float vBus = gCatena.ReadVbus();
|
||||
//gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
//fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
// Read Scales
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_1.power_up();
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
LoadCell_1.power_down();
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_2.power_up();
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
|
||||
// Power-Down HX711
|
||||
LoadCell_2.power_down();
|
||||
|
||||
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current32 = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
if (weight_current32 < 0) {
|
||||
weight_current32 = 0;
|
||||
} else if (weight_current32 > UINT16_MAX) {
|
||||
weight_current32 = UINT16_MAX;
|
||||
}
|
||||
weight_current = (uint16_t)weight_current32;
|
||||
|
||||
if (not(readOnly)) {
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
temp_last = lora_data.temperature;
|
||||
|
||||
for (int i = 0; i < my_position; i++) {
|
||||
temp_last = temp_last + lora_data.temperature_change[i];
|
||||
}
|
||||
|
||||
if (my_position > 0) {
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - temp_last;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
Serial.flush();
|
||||
LoadCell_1.power_down();
|
||||
LoadCell_2.power_down();
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//gCatena.SafePrintf("set last_sensor_reading fields...\n");
|
||||
last_sensor_reading.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
last_sensor_reading.weight1 = weight1_current;
|
||||
last_sensor_reading.weight2 = weight2_current;
|
||||
last_sensor_reading.weight = weight_current;
|
||||
last_sensor_reading.temperature = temp_current;
|
||||
last_sensor_reading.humidity = humidity_current;
|
||||
last_sensor_reading.pressure = pressure_current;
|
||||
gCatena.SafePrintf("completed ReadSensors\n");
|
||||
}
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
//gCatena.SafePrintf("start startSendingUplink\n");
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
//gCatena.SafePrintf("completed startSendingUplink\n");
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
//gCatena.SafePrintf("start sendBufferDoneCb\n");
|
||||
osjobcb_t pFn;
|
||||
|
||||
pFn = settleDoneCb;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
//gCatena.SafePrintf("completed sendBufferDoneCb\n");
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
//gCatena.SafePrintf("start txFailedDoneCb\n");
|
||||
//gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
//gCatena.SafePrintf("completed txFailedDoneCb\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
//gCatena.SafePrintf("start settleDoneCb\n");
|
||||
if (fUsbPower) {
|
||||
//gCatena.SafePrintf("we are running on USB power, so we do not go to deep sleep...\n");
|
||||
//gCatena.SafePrintf("calling os_setTimedCallback in settleDoneCb...Interval=%d\n",CATCFG_T_INTERVAL);
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime()+sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb
|
||||
);
|
||||
gCatena.SafePrintf("returning from settleDoneCb\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* ok..., now it's time for a deep sleep */
|
||||
|
||||
|
||||
Serial.flush();
|
||||
LoadCell_1.power_down();
|
||||
LoadCell_2.power_down();
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
sleepDoneCb(pSendJob);
|
||||
gCatena.SafePrintf("completed settleDoneCb\n");
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
//gCatena.SafePrintf("start sleepDoneCb\n");
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
//gCatena.SafePrintf("completed sleepDoneCb\n");
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
//gCatena.SafePrintf("start warmupDoneCb\n");
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
ReadSensors(false,false);
|
||||
//gCatena.SafePrintf("completed warmupDoneCb\n");
|
||||
}
|
||||
|
||||
|
||||
/* process "application hello" -- args are ignored */
|
||||
// argv[0] is "hello"
|
||||
// argv[1..argc-1] are the (ignored) arguments
|
||||
cCommandStream::CommandStatus cmdHello(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
pThis->printf("Hello, world!\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
|
||||
cCommandStream::CommandStatus cmdGetCalibrationSettings(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"cal_w1_0\": \"%d\",\n",config_data.cal_w1_0);
|
||||
pThis->printf(" \"cal_w2_0\": \"%d\",\n",config_data.cal_w2_0);
|
||||
pThis->printf(" \"cal_w1_factor\": \"%d.%03d\n",(int)config_data.cal_w1_factor,(int)abs(config_data.cal_w1_factor*1000)%1000);
|
||||
pThis->printf(" \"cal_w2_factor\": \"%d.%03d\n",(int)config_data.cal_w2_factor,(int)abs(config_data.cal_w2_factor*1000)%1000);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetSensorReadings(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
ReadSensors(false,true);
|
||||
pThis->printf("{\n");
|
||||
pThis->printf(" \"weight\": \"%d\",\n",last_sensor_reading.weight);
|
||||
pThis->printf(" \"weight1_raw\": \"%d\",\n",last_sensor_reading.weight1);
|
||||
pThis->printf(" \"weight2_raw\": \"%d\",\n",last_sensor_reading.weight2);
|
||||
pThis->printf(" \"temperature\": \"%d\",\n",last_sensor_reading.temperature);
|
||||
pThis->printf(" \"humidity\": \"%d\",\n",last_sensor_reading.humidity);
|
||||
pThis->printf(" \"pressure\": \"%d\",\n",last_sensor_reading.pressure);
|
||||
pThis->printf(" \"batt\": \"%d\",\n", last_sensor_reading.vbat);
|
||||
pThis->printf("}\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale1(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
pThis->printf("getscale1\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdGetScale2(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
pThis->printf("getscale2\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale1(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
ReadSensors(false,true);
|
||||
config_data.cal_w1_0 = last_sensor_reading.weight1;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateZeroScale2(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
ReadSensors(false,true);
|
||||
config_data.cal_w2_0 = last_sensor_reading.weight2;
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_zero_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale1(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
ReadSensors(false,true);
|
||||
|
||||
String w1_gramm(argv[1]);
|
||||
config_data.cal_w1_factor = (((float)last_sensor_reading.weight1 - config_data.cal_w1_0)/ w1_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale1 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
cCommandStream::CommandStatus cmdCalibrateScale2(cCommandStream *pThis,void *pContext,int argc,char **argv)
|
||||
{
|
||||
ReadSensors(false,true);
|
||||
|
||||
String w2_gramm(argv[1]);
|
||||
config_data.cal_w2_factor = (((float)last_sensor_reading.weight2 - config_data.cal_w2_0)/ w2_gramm.toFloat());
|
||||
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
pThis->printf("{ \"msg\": \"calibrate_scale2 was successful\" }\n");
|
||||
|
||||
return cCommandStream::CommandStatus::kSuccess;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 6;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
long cal_w1_0;
|
||||
long cal_w2_0;
|
||||
float cal_w1_factor;
|
||||
float cal_w2_factor;
|
||||
} CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der weiteren Messungen in Minuten seit Start, letzter Wert: Offset beim Senden des Pakets
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// im Moment statisch...
|
||||
config_data.cal_w1_0 = 20000;
|
||||
config_data.cal_w2_0 = 20000;
|
||||
config_data.cal_w1_factor = 2.5;
|
||||
config_data.cal_w2_factor = 2.5;
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position >= MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < (MAX_VALUES_TO_SEND); i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
uint8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
uint8_t temp_last;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (uint8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
|
||||
// calculate last value
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist, oder es die erste Messung ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 3 || abs(weight_current - weight_last) > 10) {
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position - 1] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
lora_data.reading_offset[my_position] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 6;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
long cal_w1_0;
|
||||
long cal_w2_0;
|
||||
float cal_w1_factor;
|
||||
float cal_w2_factor;
|
||||
} CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature[MAX_VALUES_TO_SEND]; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t reading_offset[MAX_VALUES_TO_SEND]; // Zeit der weiteren Messungen in Minuten seit Start, letzter Wert: Offset beim Senden des Pakets
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
uint8_t temperature; // Temperatur in 1/2 Grad Celsius (0 => -40 C, 255 => 87.5 C)
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// im Moment statisch...
|
||||
config_data.cal_w1_0 = 20000;
|
||||
config_data.cal_w2_0 = 20000;
|
||||
config_data.cal_w1_factor = 2.5;
|
||||
config_data.cal_w2_factor = 2.5;
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
LoadCell_1.begin(A3, A2);
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
LoadCell_2.begin(A1, A0);
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
bool ShouldDataBeSent(void)
|
||||
{
|
||||
bool res = (my_position >= MAX_VALUES_TO_SEND) ||
|
||||
((millis() - timer_pos0) > 3600000);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.reading_offset[i] = 0;
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
lora_data.temperature[i] = 0;
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"reading_offset\": [");
|
||||
for (int i = 0; i < (MAX_VALUES_TO_SEND); i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.reading_offset[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
uint8_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
uint8_t temp_last;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (uint8_t)((m.Temperature + 40) * 2);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
|
||||
// calculate last value
|
||||
if (my_position > 0) {
|
||||
temp_last =lora_data.temperature[my_position -1];
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
// Wir registrieren die Werte nur, falls die Abweichung zur letzen Messung gross genug ist, oder es die erste Messung ist
|
||||
if (my_position == 0 || abs(temp_current - temp_last) > 3 || abs(weight_current - weight_last) > 10) {
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
lora_data.temperature[my_position] = temp_current;
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
if (my_position > 0) {
|
||||
lora_data.reading_offset[my_position - 1] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
} else {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("Too little difference, measurements are not stored...\n");
|
||||
}
|
||||
|
||||
// Should we send the Data?
|
||||
if (firstTime || ShouldDataBeSent()) {
|
||||
lora_data.reading_offset[MAX_VALUES_TO_SEND - 1] = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
|
||||
beescale_lora_mcci.ino
|
||||
|
||||
BeieliScale, see https://mini-beieli.ch
|
||||
|
||||
Joerg Lehmann, nbit Informatik GmbH
|
||||
|
||||
*/
|
||||
|
||||
#include <Catena.h>
|
||||
|
||||
#include <Catena_Led.h>
|
||||
#include <Catena_CommandStream.h>
|
||||
#include <Catena_Mx25v8035f.h>
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <Arduino_LoRaWAN.h>
|
||||
#include <lmic.h>
|
||||
#include <hal/hal.h>
|
||||
#include <mcciadk_baselib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
#include <HX711.h>
|
||||
|
||||
using namespace McciCatena;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| MANIFEST CONSTANTS & TYPEDEFS
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
/* how long do we wait between transmissions? (in seconds) */
|
||||
enum {
|
||||
// set this to interval between transmissions, in seconds
|
||||
// Actual time will be a little longer because have to
|
||||
// add measurement and broadcast time, but we attempt
|
||||
// to compensate for the gross effects below.
|
||||
//CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE = 6 * 60, // every 6 minutes
|
||||
CATCFG_T_CYCLE_TEST = 30, // every 10 seconds
|
||||
};
|
||||
|
||||
/* additional timing parameters; ususually you don't change these. */
|
||||
enum {
|
||||
CATCFG_T_WARMUP = 1,
|
||||
CATCFG_T_SETTLE = 5,
|
||||
CATCFG_T_OVERHEAD = (CATCFG_T_WARMUP + CATCFG_T_SETTLE),
|
||||
};
|
||||
|
||||
constexpr uint32_t CATCFG_GetInterval(uint32_t tCycle)
|
||||
{
|
||||
return (tCycle < CATCFG_T_OVERHEAD)
|
||||
? CATCFG_T_OVERHEAD
|
||||
: tCycle - CATCFG_T_OVERHEAD;
|
||||
}
|
||||
|
||||
enum {
|
||||
CATCFG_T_INTERVAL = CATCFG_GetInterval(CATCFG_T_CYCLE),
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ONE_WIRE = A2, // XSDA1 == A2
|
||||
PIN_SHT10_CLK = 8, // XSCL0 == D8
|
||||
PIN_SHT10_DATA = 12, // XSDA0 == D12
|
||||
};
|
||||
|
||||
// forwards
|
||||
static void settleDoneCb(osjob_t* pSendJob);
|
||||
static void warmupDoneCb(osjob_t* pSendJob);
|
||||
static void txFailedDoneCb(osjob_t* pSendJob);
|
||||
static void sleepDoneCb(osjob_t* pSendJob);
|
||||
static Arduino_LoRaWAN::SendBufferCbFn sendBufferDoneCb;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| READ-ONLY DATA
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
static const char sVersion[] = "0.1";
|
||||
static const byte MAX_VALUES_TO_SEND = 8;
|
||||
static const uint8_t LORA_DATA_VERSION = 1;
|
||||
static const uint8_t LORA_DATA_VERSION_FIRST_PACKAGE = 128;
|
||||
static const uint32_t PRESSURE_OFFSET = 825;
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| VARIABLES
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// must be 65 bytes long...
|
||||
typedef struct {
|
||||
long cal_w1_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
long cal_w2_0; // 4 Bytes, Wert Waegezelle 1 ohne Gewicht
|
||||
float cal_w1_factor; // 4 Bytes,
|
||||
float cal_w2_factor;
|
||||
byte fill[49];
|
||||
} __attribute__((packed)) CONFIG_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity[MAX_VALUES_TO_SEND]; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur (Startwert) in 1/10 Grad Celsius
|
||||
int8_t temperature_change[MAX_VALUES_TO_SEND - 1]; // Unterschied Temperatur seit letztem Messwert in 1/10 Grad Celsius
|
||||
uint8_t pressure[MAX_VALUES_TO_SEND]; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
uint16_t weight[MAX_VALUES_TO_SEND]; // Waegezelle Gesamtgewicht, in 5g
|
||||
uint8_t offset_last_reading; // Zeitunterschied letzte zu erste Messung (in Minuten)
|
||||
} __attribute__((packed)) LORA_data;
|
||||
|
||||
typedef struct {
|
||||
uint8_t version; // Version
|
||||
uint8_t vbat; // Batteriespannung (1 Einheit => 20 mV)
|
||||
uint8_t humidity; // Luftfeuchtigkeit in Prozent
|
||||
int16_t temperature; // Temperatur in 1/10 Grad Celsius
|
||||
uint8_t pressure; // Luftdruck in Hekto-Pascal (0 entspricht 825 hPa)
|
||||
int32_t weight1; // Waegezelle 1, Raw Value
|
||||
int32_t weight2; // Waegezelle 2, Raw Value
|
||||
uint16_t weight; // Waegezelle Gesamtgewicht, in 5g
|
||||
} __attribute__((packed)) LORA_data_first;
|
||||
|
||||
byte my_position = 0; // what is our actual measurement, starts with 0
|
||||
long timer_pos0;
|
||||
|
||||
// Global Variables
|
||||
LORA_data lora_data;
|
||||
LORA_data_first lora_data_first;
|
||||
CONFIG_data config_data;
|
||||
|
||||
// generic timer
|
||||
long t_cur;
|
||||
|
||||
// the primary object
|
||||
Catena gCatena;
|
||||
|
||||
//
|
||||
// the LoRaWAN backhaul. Note that we use the
|
||||
// Catena version so it can provide hardware-specific
|
||||
// information to the base class.
|
||||
//
|
||||
Catena::LoRaWAN gLoRaWAN;
|
||||
|
||||
//
|
||||
// the LED
|
||||
//
|
||||
StatusLed gLed(Catena::PIN_STATUS_LED);
|
||||
|
||||
// The temperature/humidity sensor
|
||||
Adafruit_BME280 gBME280; // The default initalizer creates an I2C connection
|
||||
bool fBme;
|
||||
|
||||
SPIClass gSPI2(
|
||||
Catena::PIN_SPI2_MOSI,
|
||||
Catena::PIN_SPI2_MISO,
|
||||
Catena::PIN_SPI2_SCK);
|
||||
|
||||
// The flash
|
||||
Catena_Mx25v8035f gFlash;
|
||||
bool fFlash;
|
||||
|
||||
// Scales
|
||||
HX711 LoadCell_1;
|
||||
HX711 LoadCell_2;
|
||||
|
||||
// USB power
|
||||
bool fUsbPower;
|
||||
|
||||
// have we printed the sleep info?
|
||||
bool g_fPrintedSleeping = false;
|
||||
|
||||
// the job that's used to synchronize us with the LMIC code
|
||||
static osjob_t sensorJob;
|
||||
void sensorJob_cb(osjob_t* pJob);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
gCatena.begin();
|
||||
ClearLoraData();
|
||||
|
||||
setup_platform();
|
||||
setup_bme280();
|
||||
setup_scales();
|
||||
setup_flash();
|
||||
setup_uplink();
|
||||
}
|
||||
|
||||
void setup_platform(void)
|
||||
{
|
||||
|
||||
// read config_data from fram...
|
||||
gCatena.SafePrintf("Reading Calibration Config from FRAM...\n");
|
||||
gCatena.getFram()->getField(cFramStorage::kBme680Cal, (uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
gCatena.SafePrintf("cal_w1_0: %d\n",config_data.cal_w1_0);
|
||||
gCatena.SafePrintf("cal_w2_0: %d\n",config_data.cal_w2_0);
|
||||
gCatena.SafePrintf("cal_w1_factor: %d.%03d\n",(int)config_data.cal_w1_factor,(int)(config_data.cal_w1_factor*1000)%1000);
|
||||
gCatena.SafePrintf("cal_w2_factor: %d.%03d\n",(int)config_data.cal_w2_factor,(int)(config_data.cal_w2_factor*1000)%1000);
|
||||
gCatena.SafePrintf("Size of config_data: %d\n",sizeof(config_data));
|
||||
|
||||
// im Moment statisch...
|
||||
//config_data.cal_w1_0 = 20000;
|
||||
//config_data.cal_w2_0 = 20000;
|
||||
//config_data.cal_w1_factor = 2.5;
|
||||
//config_data.cal_w2_factor = 2.5;
|
||||
|
||||
|
||||
// config_data speichern...
|
||||
gCatena.SafePrintf("Writing Calibration Config to FRAM...\n");
|
||||
gCatena.getFram()->saveField(cFramStorage::kBme680Cal, (const uint8_t *)&config_data, sizeof(config_data));
|
||||
|
||||
#ifdef USBCON
|
||||
// if running unattended, don't wait for USB connect.
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended))) {
|
||||
while (!Serial)
|
||||
/* wait for USB attach */
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
gCatena.SafePrintf("\n");
|
||||
gCatena.SafePrintf("-------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("BeieliScale Version %s.\n", sVersion);
|
||||
{
|
||||
char sRegion[16];
|
||||
gCatena.SafePrintf("Target network: %s / %s\n",
|
||||
gLoRaWAN.GetNetworkName(),
|
||||
gLoRaWAN.GetRegionString(sRegion, sizeof(sRegion)));
|
||||
}
|
||||
gCatena.SafePrintf("Enter 'help' for a list of commands.\n");
|
||||
|
||||
#ifdef CATENA_CFG_SYSCLK
|
||||
gCatena.SafePrintf("SYSCLK: %d MHz\n", CATENA_CFG_SYSCLK);
|
||||
#endif
|
||||
|
||||
#ifdef USBCON
|
||||
gCatena.SafePrintf("USB enabled\n");
|
||||
#else
|
||||
gCatena.SafePrintf("USB disabled\n");
|
||||
#endif
|
||||
|
||||
Catena::UniqueID_string_t CpuIDstring;
|
||||
|
||||
gCatena.SafePrintf(
|
||||
"CPU Unique ID: %s\n",
|
||||
gCatena.GetUniqueIDstring(&CpuIDstring));
|
||||
|
||||
gCatena.SafePrintf("--------------------------------------------------------------------------------\n");
|
||||
gCatena.SafePrintf("\n");
|
||||
|
||||
// set up the LED
|
||||
gLed.begin();
|
||||
gCatena.registerObject(&gLed);
|
||||
gLed.Set(LedPattern::FastFlash);
|
||||
|
||||
// set up LoRaWAN
|
||||
gCatena.SafePrintf("LoRaWAN init: ");
|
||||
if (!gLoRaWAN.begin(&gCatena)) {
|
||||
gCatena.SafePrintf("failed\n");
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("succeeded\n");
|
||||
}
|
||||
|
||||
gCatena.registerObject(&gLoRaWAN);
|
||||
|
||||
/* find the platform */
|
||||
const Catena::EUI64_buffer_t* pSysEUI = gCatena.GetSysEUI();
|
||||
|
||||
uint32_t flags;
|
||||
const CATENA_PLATFORM* const pPlatform = gCatena.GetPlatform();
|
||||
|
||||
if (pPlatform) {
|
||||
gCatena.SafePrintf("EUI64: ");
|
||||
for (unsigned i = 0; i < sizeof(pSysEUI->b); ++i) {
|
||||
gCatena.SafePrintf("%s%02x", i == 0 ? "" : "-", pSysEUI->b[i]);
|
||||
}
|
||||
gCatena.SafePrintf("\n");
|
||||
flags = gCatena.GetPlatformFlags();
|
||||
gCatena.SafePrintf(
|
||||
"Platform Flags: %#010x\n",
|
||||
flags);
|
||||
gCatena.SafePrintf(
|
||||
"Operating Flags: %#010x\n",
|
||||
gCatena.GetOperatingFlags());
|
||||
}
|
||||
else {
|
||||
gCatena.SafePrintf("**** no platform, check provisioning ****\n");
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setup_bme280(void)
|
||||
{
|
||||
if (gBME280.begin(BME280_ADDRESS, Adafruit_BME280::OPERATING_MODE::Sleep)) {
|
||||
fBme = true;
|
||||
}
|
||||
else {
|
||||
fBme = false;
|
||||
gCatena.SafePrintf("No BME280 found: check wiring\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_scales(void)
|
||||
{
|
||||
gCatena.SafePrintf("Setup Scales...\n");
|
||||
|
||||
// Initialize library with data output pin, clock input pin and gain factor.
|
||||
// Channel selection is made by passing the appropriate gain:
|
||||
// - With a gain factor of 64 or 128, channel A is selected
|
||||
// - With a gain factor of 32, channel B is selected
|
||||
// By omitting the gain factor parameter, the library
|
||||
// default "128" (Channel A) is used here.
|
||||
gCatena.SafePrintf("Setup Scale 1...\n");
|
||||
//LoadCell_1.begin(A3, A2);
|
||||
|
||||
if (!(LoadCell_1.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 1 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scale 2...\n");
|
||||
//LoadCell_2.begin(A1, A0);
|
||||
|
||||
if (!(LoadCell_2.wait_ready_timeout(1000))) {
|
||||
gCatena.SafePrintf("Scale 2 not ready.\n");
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Setup Scales is complete\n");
|
||||
}
|
||||
|
||||
void setup_flash(void)
|
||||
{
|
||||
if (gFlash.begin(&gSPI2, Catena::PIN_SPI2_FLASH_SS)) {
|
||||
fFlash = true;
|
||||
gFlash.powerDown();
|
||||
gCatena.SafePrintf("FLASH found, put power down\n");
|
||||
}
|
||||
else {
|
||||
fFlash = false;
|
||||
gFlash.end();
|
||||
gSPI2.end();
|
||||
gCatena.SafePrintf("No FLASH found: check hardware\n");
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uplink(void)
|
||||
{
|
||||
/* trigger a join by sending the first packet */
|
||||
if (!(gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fManufacturingTest))) {
|
||||
if (!gLoRaWAN.IsProvisioned())
|
||||
gCatena.SafePrintf("LoRaWAN not provisioned yet. Use the commands to set it up.\n");
|
||||
else {
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
/* warm up the BME280 by discarding a measurement */
|
||||
if (fBme)
|
||||
(void)gBME280.readTemperature();
|
||||
|
||||
/* trigger a join by sending the first packet */
|
||||
ReadSensors(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Arduino loop routine -- in our case, we just drive the other loops.
|
||||
// If we try to do too much, we can break the LMIC radio. So the work is
|
||||
// done by outcalls scheduled from the LMIC os loop.
|
||||
void loop()
|
||||
{
|
||||
gCatena.poll();
|
||||
}
|
||||
|
||||
void ClearLoraData(void)
|
||||
{
|
||||
lora_data.version = LORA_DATA_VERSION;
|
||||
lora_data.vbat = 0;
|
||||
lora_data.temperature = 0;
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
lora_data.humidity[i] = 0;
|
||||
lora_data.pressure[i] = 0;
|
||||
lora_data.weight[i] = 0;
|
||||
if (i < (MAX_VALUES_TO_SEND -1)) {
|
||||
lora_data.temperature_change[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lora_data_first.version = LORA_DATA_VERSION_FIRST_PACKAGE;
|
||||
lora_data_first.vbat = 0;
|
||||
lora_data_first.humidity = 0;
|
||||
lora_data_first.pressure = 0;
|
||||
lora_data_first.weight1 = 0;
|
||||
lora_data_first.weight2 = 0;
|
||||
lora_data_first.weight = 0;
|
||||
lora_data_first.temperature = 0;
|
||||
|
||||
my_position = 0;
|
||||
}
|
||||
|
||||
void ShowLORAData(bool firstTime)
|
||||
{
|
||||
if (firstTime) {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data_first.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data_first.vbat);
|
||||
gCatena.SafePrintf(" \"humidity\": \"%u\",\n",lora_data_first.humidity);
|
||||
gCatena.SafePrintf(" \"pressure\": \"%u\",\n",lora_data_first.pressure);
|
||||
gCatena.SafePrintf(" \"weight1\": \"%ld\",\n",lora_data_first.weight1);
|
||||
gCatena.SafePrintf(" \"weight2\": \"%ld\",\n",lora_data_first.weight2);
|
||||
gCatena.SafePrintf(" \"weight\": \"%u\",\n",lora_data_first.weight);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data_first.temperature);
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
} else {
|
||||
|
||||
gCatena.SafePrintf("{\n");
|
||||
gCatena.SafePrintf(" \"version\": \"%u\",\n",lora_data.version);
|
||||
gCatena.SafePrintf(" \"vbat\": \"%u\",\n",lora_data.vbat);
|
||||
gCatena.SafePrintf(" \"temperature\": \"%u\",\n",lora_data.temperature);
|
||||
gCatena.SafePrintf(" \"humidity\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.humidity[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"pressure\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.pressure[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"weight\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND; i++) {
|
||||
gCatena.SafePrintf("%ld",lora_data.weight[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 1)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("],\n");
|
||||
gCatena.SafePrintf(" \"temperature_change\": [");
|
||||
for (int i = 0; i < MAX_VALUES_TO_SEND - 1; i++) {
|
||||
gCatena.SafePrintf("%d",lora_data.temperature_change[i]);
|
||||
if (i < (MAX_VALUES_TO_SEND - 2)) {
|
||||
gCatena.SafePrintf(",");
|
||||
}
|
||||
}
|
||||
gCatena.SafePrintf("]\n");
|
||||
gCatena.SafePrintf("}\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSensors(bool firstTime)
|
||||
{
|
||||
|
||||
// Power-Up HX711
|
||||
LoadCell_1.power_up();
|
||||
LoadCell_1.power_up();
|
||||
|
||||
// vBat
|
||||
float vBat = gCatena.ReadVbat();
|
||||
gCatena.SafePrintf("vBat: %d mV\n", (int)(vBat * 1000.0f));
|
||||
|
||||
// vBus
|
||||
float vBus = gCatena.ReadVbus();
|
||||
gCatena.SafePrintf("vBus: %d mV\n", (int)(vBus * 1000.0f));
|
||||
fUsbPower = (vBus > 3.0) ? true : false;
|
||||
|
||||
int16_t temp_current;
|
||||
uint8_t humidity_current;
|
||||
uint8_t pressure_current;
|
||||
int32_t weight1_current;
|
||||
int32_t weight2_current;
|
||||
int16_t temp_last;
|
||||
int16_t temp_change;
|
||||
uint16_t weight_current;
|
||||
uint16_t weight_last;
|
||||
|
||||
|
||||
if (fBme) {
|
||||
Adafruit_BME280::Measurements m = gBME280.readTemperaturePressureHumidity();
|
||||
// temperature is 2 bytes from -0x80.00 to +0x7F.FF degrees C
|
||||
// pressure is 2 bytes, hPa * 10.
|
||||
// humidity is one byte, where 0 == 0/256 and 0xFF == 255/256.
|
||||
gCatena.SafePrintf(
|
||||
"BME280: T: %d P: %d RH: %d\n",
|
||||
(int)m.Temperature,
|
||||
(int)m.Pressure,
|
||||
(int)m.Humidity);
|
||||
temp_current = (int16_t)((m.Temperature) * 10);
|
||||
humidity_current = (uint8_t)m.Humidity;
|
||||
pressure_current = (uint8_t)((m.Pressure / 100) - PRESSURE_OFFSET);
|
||||
gCatena.SafePrintf("pressure_current: %d\n",pressure_current);
|
||||
}
|
||||
|
||||
gCatena.SafePrintf("Before Read Scales\n");
|
||||
if (LoadCell_1.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_1 is ready.");
|
||||
long w1 = LoadCell_1.read_average(5);
|
||||
weight1_current = (int32_t)w1;
|
||||
gCatena.SafePrintf("Load_cell 1 output val: %ld\n", w1);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_1 not ready.");
|
||||
}
|
||||
if (LoadCell_2.is_ready()) {
|
||||
Serial.println("HX711 LoadCell_2 is ready.");
|
||||
long w2 = LoadCell_2.read_average(5);
|
||||
weight2_current = (int32_t)w2;
|
||||
gCatena.SafePrintf("Load_cell 2 output val: %ld\n", w2);
|
||||
}
|
||||
else {
|
||||
Serial.println("HX711 LoadCell_2 not ready.");
|
||||
}
|
||||
gCatena.SafePrintf("After Read Scales\n");
|
||||
|
||||
// Power-Down HX711
|
||||
LoadCell_1.power_down();
|
||||
LoadCell_1.power_down();
|
||||
|
||||
|
||||
// Gewicht berechnen
|
||||
weight_current = ((weight1_current - config_data.cal_w1_0) / config_data.cal_w1_factor) + ((weight2_current - config_data.cal_w2_0) / config_data.cal_w2_factor);
|
||||
|
||||
// calculate last value
|
||||
weight_last = 0;
|
||||
temp_last = lora_data.temperature;
|
||||
|
||||
for (int i = 0; i < my_position; i++) {
|
||||
temp_last = temp_last + lora_data.temperature_change[i];
|
||||
}
|
||||
|
||||
if (my_position > 0) {
|
||||
weight_last = lora_data.weight[my_position - 1];
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
lora_data_first.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data_first.weight1 = weight1_current;
|
||||
lora_data_first.weight2 = weight2_current;
|
||||
lora_data_first.weight = weight_current;
|
||||
lora_data_first.temperature = temp_current;
|
||||
lora_data_first.humidity = humidity_current;
|
||||
lora_data_first.pressure = pressure_current;
|
||||
} else {
|
||||
lora_data.vbat = (uint8_t)(vBat * 1000.0f / 20);
|
||||
lora_data.weight[my_position] = weight_current;
|
||||
if (my_position == 0) {
|
||||
lora_data.temperature = temp_current;
|
||||
} else {
|
||||
temp_change = temp_current - temp_last;
|
||||
if (temp_change > 127) {
|
||||
temp_change = 127;
|
||||
}
|
||||
if (temp_change < -128) {
|
||||
temp_change = -128;
|
||||
}
|
||||
|
||||
lora_data.temperature_change[my_position - 1] = (uint8_t)temp_change;
|
||||
}
|
||||
lora_data.humidity[my_position] = humidity_current;
|
||||
lora_data.pressure[my_position] = pressure_current;
|
||||
}
|
||||
|
||||
if (my_position == 0) {
|
||||
timer_pos0 = millis();
|
||||
}
|
||||
|
||||
ShowLORAData(firstTime);
|
||||
my_position++;
|
||||
|
||||
// Should we send the Data?
|
||||
// we send data the first time the system is started, when the array is full
|
||||
// or when the weight has fallen more than 100g or the first measurement is
|
||||
// more than one hour old (which should not happen :-) )
|
||||
if (firstTime || (my_position >= MAX_VALUES_TO_SEND) || ((weight_last - weight_current) > 20) || ((millis() - timer_pos0) > 3600000)) {
|
||||
lora_data.offset_last_reading = (uint8_t)((millis() - timer_pos0) / 1000 / 60);
|
||||
gCatena.SafePrintf("startSendingUplink()\n");
|
||||
startSendingUplink(firstTime);
|
||||
} else {
|
||||
doLightSleep(&sensorJob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startSendingUplink(bool firstTime)
|
||||
{
|
||||
LedPattern savedLed = gLed.Set(LedPattern::Measuring);
|
||||
|
||||
if (savedLed != LedPattern::Joining)
|
||||
gLed.Set(LedPattern::Sending);
|
||||
else
|
||||
gLed.Set(LedPattern::Joining);
|
||||
|
||||
bool fConfirmed = false;
|
||||
if (gCatena.GetOperatingFlags() & (1 << 16)) {
|
||||
gCatena.SafePrintf("requesting confirmed tx\n");
|
||||
fConfirmed = true;
|
||||
}
|
||||
|
||||
if (firstTime) {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data_first, sizeof(LORA_data_first), sendBufferDoneCb, NULL, fConfirmed);
|
||||
} else {
|
||||
gLoRaWAN.SendBuffer((uint8_t*)&lora_data, sizeof(LORA_data), sendBufferDoneCb, NULL, fConfirmed);
|
||||
}
|
||||
ClearLoraData();
|
||||
}
|
||||
|
||||
static void sendBufferDoneCb(
|
||||
void* pContext,
|
||||
bool fStatus)
|
||||
{
|
||||
osjobcb_t pFn;
|
||||
|
||||
gLed.Set(LedPattern::Settling);
|
||||
if (!fStatus) {
|
||||
gCatena.SafePrintf("send buffer failed\n");
|
||||
pFn = txFailedDoneCb;
|
||||
}
|
||||
else {
|
||||
pFn = settleDoneCb;
|
||||
}
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_SETTLE),
|
||||
pFn);
|
||||
}
|
||||
|
||||
static void txFailedDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
gCatena.SafePrintf("not provisioned, idling\n");
|
||||
gLoRaWAN.Shutdown();
|
||||
gLed.Set(LedPattern::NotProvisioned);
|
||||
}
|
||||
|
||||
static void settleDoneCb(
|
||||
osjob_t* pSendJob)
|
||||
{
|
||||
const bool fDeepSleep = checkDeepSleep();
|
||||
|
||||
if (!g_fPrintedSleeping)
|
||||
doSleepAlert(fDeepSleep);
|
||||
|
||||
if (fDeepSleep)
|
||||
doDeepSleep(pSendJob);
|
||||
else
|
||||
doLightSleep(pSendJob);
|
||||
}
|
||||
|
||||
bool checkDeepSleep(void)
|
||||
{
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
bool fDeepSleep;
|
||||
|
||||
if (fDeepSleepTest) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
#ifdef USBCON
|
||||
else if (Serial.dtr()) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
#endif
|
||||
else if (gCatena.GetOperatingFlags() & (1 << 17)) {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
else if ((gCatena.GetOperatingFlags() & static_cast<uint32_t>(gCatena.OPERATING_FLAGS::fUnattended)) != 0) {
|
||||
fDeepSleep = true;
|
||||
}
|
||||
else {
|
||||
fDeepSleep = false;
|
||||
}
|
||||
|
||||
return fDeepSleep;
|
||||
}
|
||||
|
||||
void doSleepAlert(const bool fDeepSleep)
|
||||
{
|
||||
g_fPrintedSleeping = true;
|
||||
|
||||
if (fDeepSleep) {
|
||||
bool const fDeepSleepTest = gCatena.GetOperatingFlags() & (1 << 19);
|
||||
const uint32_t deepSleepDelay = fDeepSleepTest ? 10 : 30;
|
||||
|
||||
gCatena.SafePrintf("using deep sleep in %u secs"
|
||||
#ifdef USBCON
|
||||
" (USB will disconnect while asleep)"
|
||||
#endif
|
||||
": ",
|
||||
deepSleepDelay);
|
||||
|
||||
// sleep and print
|
||||
gLed.Set(LedPattern::TwoShort);
|
||||
|
||||
for (auto n = deepSleepDelay; n > 0; --n) {
|
||||
uint32_t tNow = millis();
|
||||
|
||||
while (uint32_t(millis() - tNow) < 1000) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
gCatena.SafePrintf(".");
|
||||
}
|
||||
gCatena.SafePrintf("\nStarting deep sleep.\n");
|
||||
uint32_t tNow = millis();
|
||||
while (uint32_t(millis() - tNow) < 100) {
|
||||
gCatena.poll();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
else
|
||||
gCatena.SafePrintf("using light sleep\n");
|
||||
}
|
||||
|
||||
void doDeepSleep(osjob_t* pJob)
|
||||
{
|
||||
/* ok... now it's time for a deep sleep */
|
||||
gLed.Set(LedPattern::Off);
|
||||
Serial.end();
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
if (fFlash)
|
||||
gSPI2.end();
|
||||
|
||||
gCatena.Sleep(CATCFG_T_INTERVAL);
|
||||
|
||||
/* and now... we're awake again. trigger another measurement */
|
||||
Serial.begin();
|
||||
Wire.begin();
|
||||
SPI.begin();
|
||||
if (fFlash)
|
||||
gSPI2.begin();
|
||||
sleepDoneCb(pJob);
|
||||
}
|
||||
|
||||
|
||||
void doLightSleep(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::Sleeping);
|
||||
os_setTimedCallback(
|
||||
pJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_INTERVAL),
|
||||
sleepDoneCb);
|
||||
}
|
||||
|
||||
static void sleepDoneCb(osjob_t* pJob)
|
||||
{
|
||||
gLed.Set(LedPattern::WarmingUp);
|
||||
|
||||
os_setTimedCallback(
|
||||
&sensorJob,
|
||||
os_getTime() + sec2osticks(CATCFG_T_WARMUP),
|
||||
warmupDoneCb);
|
||||
}
|
||||
|
||||
static void warmupDoneCb(osjob_t* pJob)
|
||||
{
|
||||
ReadSensors(false);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 33.866666 33.866668"
|
||||
version="1.1"
|
||||
id="svg96"
|
||||
inkscape:version="0.92.4 (unknown)"
|
||||
sodipodi:docname="bee-logo-128-cutout.svg">
|
||||
<defs
|
||||
id="defs90" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="6.4296875"
|
||||
inkscape:cx="64"
|
||||
inkscape:cy="63.780818"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata93">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-263.13332)">
|
||||
<path
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="M 64.605469,3.0644531 C 61.008105,3.0003949 57.29972,4.8041766 50.607422,8.6679688 L 36.943359,16.558594 23.277344,24.447266 C 10.780426,31.662384 9.6132812,32.661981 9.6132812,48.117188 v 15.779296 15.777344 c 1e-7,14.430161 0.2794604,15.942338 13.6640628,23.669922 l 13.666015,7.88867 13.664063,7.89063 c 12.49694,7.21511 13.945505,7.72762 27.330078,0 l 13.666016,-7.89063 13.664064,-7.88867 c 12.49694,-7.21508 13.66601,-8.214716 13.66601,-23.669922 V 63.896484 48.117188 c 0,-14.430237 -0.27948,-15.942338 -13.66406,-23.669922 L 91.603516,16.558594 77.9375,8.6679688 C 71.689043,5.0604097 68.202833,3.1285114 64.605469,3.0644531 Z M 63.529297,35.904297 c 11.421218,0 22.336405,2.321093 32.257812,6.517578 a 7.5378873,7.5378873 0 1 1 -5.86914,13.876953 C 81.811305,52.86989 72.913834,50.976562 63.529297,50.976562 c -9.384397,0 -18.283969,1.893328 -26.390625,5.322266 A 7.5378873,7.5378873 0 1 1 31.261719,42.421875 c 9.921402,-4.196485 20.846473,-6.517578 32.267578,-6.517578 z m 0,20.912109 c 8.53426,0 16.703271,1.734716 24.123047,4.873047 a 7.5378874,7.5378874 0 1 1 -5.875,13.876953 c -5.605111,-2.370784 -11.750487,-3.675781 -18.248047,-3.675781 -6.497443,0 -12.650715,1.304997 -18.255859,3.675781 A 7.5378874,7.5378874 0 1 1 39.404297,61.689453 c 7.419787,-3.138331 15.590827,-4.873047 24.125,-4.873047 z m 0,20.935547 c 5.643583,0 11.059704,1.145794 15.974609,3.224609 a 7.5395547,7.5395547 0 1 1 -5.876953,13.886719 c -3.100354,-1.311345 -6.490823,-2.037109 -10.097656,-2.037109 -3.606679,0 -7.006909,0.725727 -10.107422,2.037109 A 7.5378875,7.5378875 0 1 1 47.554688,80.976562 c 4.914946,-2.078777 10.331124,-3.224609 15.974609,-3.224609 z"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,0,263.13332)"
|
||||
id="path815"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:2.90305877;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10.674714,268.54246 8.8603022,264.91363"
|
||||
id="path899"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#483737;stroke-width:2.90305877;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 23.375595,268.54246 1.814411,-3.62883"
|
||||
id="path899-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="83.081947mm"
|
||||
height="52.319721mm"
|
||||
viewBox="0 0 83.081947 52.319721"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (unknown)"
|
||||
sodipodi:docname="mini-beieli-praegung-text-as-path.svg"
|
||||
inkscape:export-filename="/home/joerg/bee-logo-box.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
inkscape:stockid="DotL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path978"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,5.92,0.8)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1106813"
|
||||
inkscape:cx="3.5729304"
|
||||
inkscape:cy="42.625215"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2089"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid895"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
originx="15.558254"
|
||||
originy="-258.4087" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(15.558254,13.728425)">
|
||||
<path
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0.42512852;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 8.7393227,11.644791 -1.0589324,0.611374 -1.0589359,0.611374 c -1.0371974,0.598824 -1.1494606,0.559109 -2.1178708,0 L 3.4446478,12.256165 2.3857128,11.644791 C 1.3485151,11.045971 1.3267775,10.928889 1.3267775,9.8106715 V 8.5879237 7.3651789 c 0,-1.1976465 0.090525,-1.2750137 1.0589353,-1.8341225 L 3.4446478,4.9196842 4.5035836,4.3083089 c 1.0371978,-0.59882 1.1494596,-0.559106 2.1178708,0 l 1.0589359,0.6113753 1.0589324,0.6113722 c 1.0371922,0.5988236 1.058929,0.7159034 1.058929,1.8341225 v 1.2227448 1.2227478 c 0,1.1976435 -0.090524,1.2750145 -1.058929,1.8341195 z"
|
||||
id="path815"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scsscsscsscsscsscss"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.231964,7.4616379 c 0.6985148,-0.295449 1.4664939,-0.4588256 2.272625,-0.4588256 0.8061387,0 1.5741179,0.1633766 2.2726329,0.4588256"
|
||||
id="path846-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.8626628,8.9546319 c 0.5046637,-0.2134551 1.0595109,-0.331491 1.6419262,-0.331491 0.5824224,0 1.1372702,0.1180359 1.6419342,0.331491"
|
||||
id="path846-1-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 4.494172,10.44954 c 0.3105661,-0.131357 0.6520092,-0.203993 1.010417,-0.203993 0.3584154,0 0.699858,0.07264 1.0104178,0.203993"
|
||||
id="path846-8-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.7083008,5.2207965 3.1768908,4.1579827"
|
||||
id="path899"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:none;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 7.4281735,5.2207965 7.9595827,4.1579827"
|
||||
id="path899-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<g
|
||||
aria-label="mini-beieli.ch"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.44661283px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.11116531"
|
||||
id="text28">
|
||||
<path
|
||||
d="M 14.177507,10.866552 14.6736,6.7572427 h 0.533301 q 0.165365,0 0.260449,0.082682 0.09509,0.078548 0.09095,0.2563151 l -0.02067,0.434082 q 0.297657,-0.4216797 0.644922,-0.6242513 0.347266,-0.2067057 0.731738,-0.2067057 0.409278,0 0.644922,0.2563151 0.235645,0.2521809 0.272852,0.7317382 0.305924,-0.5084961 0.682129,-0.7482747 0.376204,-0.2397786 0.822688,-0.2397786 0.28112,0 0.49196,0.1033528 0.21084,0.1033529 0.343132,0.3017904 0.136425,0.1984375 0.181901,0.4878255 0.04961,0.289388 0.0041,0.6614583 l -0.305925,2.6127599 h -1.033528 l 0.305924,-2.6127599 q 0.04961,-0.3803385 -0.03307,-0.5374349 -0.07855,-0.1612305 -0.326595,-0.1612305 -0.16123,0 -0.322461,0.082682 -0.157096,0.078548 -0.297656,0.2315104 -0.14056,0.1529623 -0.260449,0.3762044 -0.119889,0.2191081 -0.206706,0.4960938 v 0.00413 l -0.243913,2.1208003 h -1.037662 l 0.305924,-2.6127599 q 0.04961,-0.3762044 -0.02481,-0.5374349 -0.07441,-0.1612305 -0.32246,-0.1612305 -0.173633,0 -0.338998,0.086816 -0.16123,0.086816 -0.30179,0.252181 -0.14056,0.1612305 -0.260449,0.3927409 -0.11989,0.2273763 -0.206706,0.5126302 l -0.239779,2.0670568 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path873" />
|
||||
<path
|
||||
d="m 22.565625,6.7613768 -0.49196,4.1051752 h -1.033528 l 0.491959,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.210839,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path875" />
|
||||
<path
|
||||
d="m 23.05345,10.866552 0.49196,-4.1093093 h 0.533301 q 0.169498,0 0.260449,0.082682 0.09508,0.078548 0.08682,0.2563151 l -0.02067,0.4919596 q 0.322461,-0.4506185 0.711067,-0.6697266 0.388607,-0.219108 0.802019,-0.219108 0.264583,0 0.475423,0.1033528 0.214974,0.1033529 0.351399,0.3017904 0.14056,0.1984375 0.194304,0.4878255 0.05788,0.289388 0.0124,0.6614583 l -0.305924,2.6127599 h -1.050065 l 0.310058,-2.6127599 q 0.04547,-0.3803385 -0.04961,-0.5374349 -0.09095,-0.1612305 -0.338998,-0.1612305 -0.169498,0 -0.347265,0.095085 -0.177767,0.095085 -0.343132,0.2687174 -0.16123,0.1736328 -0.297656,0.4216797 -0.132292,0.2439127 -0.21084,0.5457031 l -0.214974,1.9802404 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path877" />
|
||||
<path
|
||||
d="m 29.114062,6.7613768 -0.491959,4.1051752 h -1.033529 l 0.49196,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.119889,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.21084,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path879" />
|
||||
<path
|
||||
d="m 29.833398,8.034684 h 1.934765 l -0.107487,0.8433593 h -1.930631 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path881" />
|
||||
<path
|
||||
d="M 32.235318,10.866552 32.95052,4.92583 h 1.029394 l -0.32246,2.6251626 q 0.297656,-0.3927408 0.657324,-0.6201171 0.363802,-0.2315104 0.773079,-0.2315104 0.268718,0 0.483692,0.095085 0.219108,0.09095 0.37207,0.2811198 0.157096,0.1901692 0.239778,0.4836914 0.08682,0.289388 0.08682,0.6862629 0,0.5250326 -0.165365,1.0128581 -0.16123,0.4836913 -0.44235,0.8557621 -0.28112,0.37207 -0.657324,0.595312 -0.37207,0.219108 -0.79375,0.219108 -0.326595,0 -0.58291,-0.124023 -0.252181,-0.124024 -0.425814,-0.334864 l -0.03307,0.111621 q -0.04548,0.144694 -0.119889,0.214974 -0.07441,0.07028 -0.248047,0.07028 z m 2.447396,-3.3486323 q -0.165365,0 -0.338997,0.1116211 -0.169499,0.1116211 -0.33073,0.3059245 -0.157096,0.1901692 -0.293522,0.4506184 -0.136425,0.2604492 -0.23151,0.5581055 L 33.3722,9.8909014 q 0.14056,0.1322916 0.318326,0.1901696 0.177767,0.05374 0.3514,0.05374 0.264584,0 0.483692,-0.1570962 0.219108,-0.1570964 0.37207,-0.4092774 0.157096,-0.256315 0.239779,-0.5746419 0.08682,-0.3183268 0.08682,-0.6449218 0,-0.4258138 -0.144694,-0.6283854 -0.14056,-0.2025716 -0.396875,-0.2025716 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path883" />
|
||||
<path
|
||||
d="m 40.441535,7.7494301 q 0,0.2728516 -0.124023,0.5002279 -0.119889,0.2232421 -0.429948,0.4051432 -0.310058,0.1777669 -0.847493,0.3059244 -0.533301,0.1281576 -1.35599,0.2025716 0,0.4878255 0.227376,0.72347 0.231511,0.2315108 0.7028,0.2315108 0.297656,0 0.487825,-0.06615 0.194304,-0.066146 0.33073,-0.1446942 0.136425,-0.082682 0.239778,-0.1488281 0.107487,-0.066146 0.235645,-0.066146 0.111621,0 0.190169,0.09095 l 0.272852,0.3224606 q -0.231511,0.214974 -0.450619,0.372071 -0.219108,0.152962 -0.454753,0.256315 -0.23151,0.09922 -0.491959,0.144694 -0.256315,0.04961 -0.558106,0.04961 -0.396875,0 -0.72347,-0.124023 -0.32246,-0.124024 -0.553971,-0.3514 -0.227376,-0.23151 -0.355534,-0.5498373 -0.124023,-0.3224609 -0.124023,-0.7193359 0,-0.4836914 0.165364,-0.9301757 0.169499,-0.4506185 0.475424,-0.79375 0.310058,-0.3431315 0.74414,-0.5498372 0.438216,-0.2067057 0.979785,-0.2067057 0.355534,0 0.620117,0.095085 0.268718,0.09095 0.442351,0.2439128 0.177767,0.1488281 0.264583,0.3348632 0.09095,0.1860352 0.09095,0.3720703 z m -1.46761,-0.3183268 q -0.223242,0 -0.417546,0.078548 -0.190169,0.074414 -0.343131,0.2149739 -0.152962,0.1364258 -0.264583,0.3348633 -0.111622,0.1943034 -0.177767,0.4299479 0.553971,-0.066146 0.892968,-0.1405599 0.338998,-0.078548 0.525033,-0.1653646 0.186035,-0.09095 0.248047,-0.1901692 0.06201,-0.1033529 0.06201,-0.2191081 0,-0.062012 -0.02894,-0.1198893 -0.02894,-0.062012 -0.09508,-0.1116211 -0.06201,-0.049609 -0.16123,-0.078548 -0.09922,-0.033073 -0.239779,-0.033073 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path885" />
|
||||
<path
|
||||
d="m 42.42591,6.7613768 -0.49196,4.1051752 h -1.033528 l 0.491959,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115755,-0.053743 0.239779,-0.053743 0.124023,0 0.239778,0.053743 0.11989,0.049609 0.21084,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path887" />
|
||||
<path
|
||||
d="m 46.692317,7.7494301 q 0,0.2728516 -0.124023,0.5002279 -0.119889,0.2232421 -0.429948,0.4051432 -0.310058,0.1777669 -0.847493,0.3059244 -0.533301,0.1281576 -1.35599,0.2025716 0,0.4878255 0.227377,0.72347 0.23151,0.2315108 0.702799,0.2315108 0.297656,0 0.487825,-0.06615 0.194304,-0.066146 0.33073,-0.1446942 0.136425,-0.082682 0.239778,-0.1488281 0.107487,-0.066146 0.235645,-0.066146 0.111621,0 0.190169,0.09095 l 0.272852,0.3224606 q -0.231511,0.214974 -0.450619,0.372071 -0.219108,0.152962 -0.454752,0.256315 -0.231511,0.09922 -0.49196,0.144694 -0.256315,0.04961 -0.558106,0.04961 -0.396875,0 -0.72347,-0.124023 -0.32246,-0.124024 -0.553971,-0.3514 -0.227376,-0.23151 -0.355534,-0.5498373 -0.124023,-0.3224609 -0.124023,-0.7193359 0,-0.4836914 0.165364,-0.9301757 0.169499,-0.4506185 0.475424,-0.79375 0.310058,-0.3431315 0.74414,-0.5498372 0.438216,-0.2067057 0.979785,-0.2067057 0.355534,0 0.620117,0.095085 0.268718,0.09095 0.442351,0.2439128 0.177767,0.1488281 0.264583,0.3348632 0.09095,0.1860352 0.09095,0.3720703 z m -1.46761,-0.3183268 q -0.223242,0 -0.417546,0.078548 -0.190169,0.074414 -0.343131,0.2149739 -0.152962,0.1364258 -0.264583,0.3348633 -0.111622,0.1943034 -0.177767,0.4299479 0.553971,-0.066146 0.892968,-0.1405599 0.338998,-0.078548 0.525033,-0.1653646 0.186035,-0.09095 0.248047,-0.1901692 0.06201,-0.1033529 0.06201,-0.2191081 0,-0.062012 -0.02894,-0.1198893 -0.02894,-0.062012 -0.09509,-0.1116211 -0.06201,-0.049609 -0.16123,-0.078548 -0.09922,-0.033073 -0.239779,-0.033073 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path889" />
|
||||
<path
|
||||
d="M 47.134667,10.866552 47.849869,4.92583 h 1.037663 l -0.719336,5.940722 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path891" />
|
||||
<path
|
||||
d="m 50.760287,6.7613768 -0.491959,4.1051752 h -1.033529 l 0.49196,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.210839,0.1405599 0.09095,0.09095 0.144695,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path893" />
|
||||
<path
|
||||
d="m 51.38867,10.300179 q 0,-0.128158 0.04548,-0.243913 0.04961,-0.1157553 0.132291,-0.1984376 0.08682,-0.082682 0.202572,-0.1322916 0.115755,-0.049609 0.248047,-0.049609 0.132291,0 0.248047,0.049609 0.115755,0.049609 0.198437,0.1322916 0.08682,0.082682 0.136426,0.1984376 0.04961,0.115755 0.04961,0.243913 0,0.132291 -0.04961,0.248047 -0.04961,0.115755 -0.136426,0.198437 -0.08268,0.08268 -0.198437,0.128158 -0.115756,0.04961 -0.248047,0.04961 -0.132292,0 -0.248047,-0.04961 -0.115755,-0.04548 -0.202572,-0.128158 -0.08268,-0.08268 -0.132291,-0.198437 -0.04548,-0.115756 -0.04548,-0.248047 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path895" />
|
||||
<path
|
||||
d="m 56.672069,10.138948 q -0.202571,0.223242 -0.388607,0.376205 -0.181901,0.148828 -0.376204,0.243912 -0.194303,0.09095 -0.409277,0.128158 -0.21084,0.04134 -0.471289,0.04134 -0.359668,0 -0.644922,-0.119889 -0.28112,-0.124024 -0.479558,-0.347266 -0.194303,-0.227376 -0.30179,-0.5415688 -0.103353,-0.3183268 -0.103353,-0.7110677 0,-0.3348633 0.07028,-0.649056 0.07441,-0.3183268 0.21084,-0.5953124 0.136426,-0.2769857 0.330729,-0.5084961 0.194304,-0.2356445 0.434082,-0.4010091 0.243913,-0.1653646 0.525033,-0.2563151 0.285254,-0.095085 0.599446,-0.095085 0.413412,0 0.7028,0.144694 0.289388,0.1405599 0.51263,0.434082 l -0.338997,0.3927409 q -0.03307,0.045475 -0.08268,0.074414 -0.04961,0.028939 -0.107487,0.028939 -0.07028,0 -0.128157,-0.037207 -0.05374,-0.041341 -0.124024,-0.086816 -0.07028,-0.045475 -0.177767,-0.082682 -0.103352,-0.041341 -0.272851,-0.041341 -0.219108,0 -0.417546,0.1198893 -0.198437,0.1198893 -0.351399,0.3389974 -0.152963,0.219108 -0.243913,0.5291666 -0.09095,0.3100586 -0.09095,0.6945312 0,0.4382161 0.19017,0.6738606 0.194303,0.2315108 0.516764,0.2315108 0.223242,0 0.363802,-0.06201 0.14056,-0.062012 0.239779,-0.1364258 0.09922,-0.074414 0.177767,-0.1364258 0.08268,-0.062012 0.181901,-0.062012 0.05374,0 0.09922,0.024805 0.04961,0.024805 0.08682,0.07028 l 0.268717,0.3224607 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path897" />
|
||||
<path
|
||||
d="M 57.035872,10.866552 57.751073,4.92583 h 1.050065 l -0.305924,2.5052733 q 0.30179,-0.3720703 0.65319,-0.5498372 0.355534,-0.181901 0.727604,-0.181901 0.264584,0 0.475423,0.1033528 0.214974,0.1033529 0.3514,0.3017904 0.14056,0.1984375 0.194303,0.4878255 0.05788,0.289388 0.0124,0.6614583 l -0.310059,2.6127599 h -1.045931 l 0.305925,-2.6127599 q 0.04961,-0.3803385 -0.04134,-0.541569 -0.09095,-0.1653646 -0.338998,-0.1653646 -0.152962,0 -0.318327,0.086816 -0.16123,0.082682 -0.314192,0.2397787 -0.152963,0.1529622 -0.285254,0.3720702 -0.132292,0.214974 -0.223242,0.4836914 l -0.256315,2.1373368 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path900" />
|
||||
</g>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot844"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
|
||||
id="flowRegion846"><rect
|
||||
id="rect848"
|
||||
width="718.11023"
|
||||
height="548.03149"
|
||||
x="37.795277"
|
||||
y="404.40945" /></flowRegion><flowPara
|
||||
id="flowPara850" /></flowRoot> </g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="83.081947mm"
|
||||
height="52.319721mm"
|
||||
viewBox="0 0 83.081947 52.319721"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (unknown)"
|
||||
sodipodi:docname="mini-beieli-praegung-text.as-path.svg"
|
||||
inkscape:export-filename="/home/joerg/bee-logo-box.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
inkscape:stockid="DotL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path978"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,5.92,0.8)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1106813"
|
||||
inkscape:cx="3.5729304"
|
||||
inkscape:cy="42.625215"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2089"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid895"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
originx="15.558254"
|
||||
originy="-258.4087" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(15.558254,13.728425)">
|
||||
<path
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0.42512852;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 8.7393227,11.644791 -1.0589324,0.611374 -1.0589359,0.611374 c -1.0371974,0.598824 -1.1494606,0.559109 -2.1178708,0 L 3.4446478,12.256165 2.3857128,11.644791 C 1.3485151,11.045971 1.3267775,10.928889 1.3267775,9.8106715 V 8.5879237 7.3651789 c 0,-1.1976465 0.090525,-1.2750137 1.0589353,-1.8341225 L 3.4446478,4.9196842 4.5035836,4.3083089 c 1.0371978,-0.59882 1.1494596,-0.559106 2.1178708,0 l 1.0589359,0.6113753 1.0589324,0.6113722 c 1.0371922,0.5988236 1.058929,0.7159034 1.058929,1.8341225 v 1.2227448 1.2227478 c 0,1.1976435 -0.090524,1.2750145 -1.058929,1.8341195 z"
|
||||
id="path815"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scsscsscsscsscsscss"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.231964,7.4616379 c 0.6985148,-0.295449 1.4664939,-0.4588256 2.272625,-0.4588256 0.8061387,0 1.5741179,0.1633766 2.2726329,0.4588256"
|
||||
id="path846-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.8626628,8.9546319 c 0.5046637,-0.2134551 1.0595109,-0.331491 1.6419262,-0.331491 0.5824224,0 1.1372702,0.1180359 1.6419342,0.331491"
|
||||
id="path846-1-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 4.494172,10.44954 c 0.3105661,-0.131357 0.6520092,-0.203993 1.010417,-0.203993 0.3584154,0 0.699858,0.07264 1.0104178,0.203993"
|
||||
id="path846-8-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.7083008,5.2207965 3.1768908,4.1579827"
|
||||
id="path899"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:none;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 7.4281735,5.2207965 7.9595827,4.1579827"
|
||||
id="path899-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<g
|
||||
aria-label="mini-beieli.ch"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.44661283px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.11116531"
|
||||
id="text28">
|
||||
<path
|
||||
d="M 14.177507,10.866552 14.6736,6.7572427 h 0.533301 q 0.165365,0 0.260449,0.082682 0.09509,0.078548 0.09095,0.2563151 l -0.02067,0.434082 q 0.297657,-0.4216797 0.644922,-0.6242513 0.347266,-0.2067057 0.731738,-0.2067057 0.409278,0 0.644922,0.2563151 0.235645,0.2521809 0.272852,0.7317382 0.305924,-0.5084961 0.682129,-0.7482747 0.376204,-0.2397786 0.822688,-0.2397786 0.28112,0 0.49196,0.1033528 0.21084,0.1033529 0.343132,0.3017904 0.136425,0.1984375 0.181901,0.4878255 0.04961,0.289388 0.0041,0.6614583 l -0.305925,2.6127599 h -1.033528 l 0.305924,-2.6127599 q 0.04961,-0.3803385 -0.03307,-0.5374349 -0.07855,-0.1612305 -0.326595,-0.1612305 -0.16123,0 -0.322461,0.082682 -0.157096,0.078548 -0.297656,0.2315104 -0.14056,0.1529623 -0.260449,0.3762044 -0.119889,0.2191081 -0.206706,0.4960938 v 0.00413 l -0.243913,2.1208003 h -1.037662 l 0.305924,-2.6127599 q 0.04961,-0.3762044 -0.02481,-0.5374349 -0.07441,-0.1612305 -0.32246,-0.1612305 -0.173633,0 -0.338998,0.086816 -0.16123,0.086816 -0.30179,0.252181 -0.14056,0.1612305 -0.260449,0.3927409 -0.11989,0.2273763 -0.206706,0.5126302 l -0.239779,2.0670568 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path873" />
|
||||
<path
|
||||
d="m 22.565625,6.7613768 -0.49196,4.1051752 h -1.033528 l 0.491959,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.210839,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path875" />
|
||||
<path
|
||||
d="m 23.05345,10.866552 0.49196,-4.1093093 h 0.533301 q 0.169498,0 0.260449,0.082682 0.09508,0.078548 0.08682,0.2563151 l -0.02067,0.4919596 q 0.322461,-0.4506185 0.711067,-0.6697266 0.388607,-0.219108 0.802019,-0.219108 0.264583,0 0.475423,0.1033528 0.214974,0.1033529 0.351399,0.3017904 0.14056,0.1984375 0.194304,0.4878255 0.05788,0.289388 0.0124,0.6614583 l -0.305924,2.6127599 h -1.050065 l 0.310058,-2.6127599 q 0.04547,-0.3803385 -0.04961,-0.5374349 -0.09095,-0.1612305 -0.338998,-0.1612305 -0.169498,0 -0.347265,0.095085 -0.177767,0.095085 -0.343132,0.2687174 -0.16123,0.1736328 -0.297656,0.4216797 -0.132292,0.2439127 -0.21084,0.5457031 l -0.214974,1.9802404 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path877" />
|
||||
<path
|
||||
d="m 29.114062,6.7613768 -0.491959,4.1051752 h -1.033529 l 0.49196,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.119889,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.21084,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path879" />
|
||||
<path
|
||||
d="m 29.833398,8.034684 h 1.934765 l -0.107487,0.8433593 h -1.930631 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path881" />
|
||||
<path
|
||||
d="M 32.235318,10.866552 32.95052,4.92583 h 1.029394 l -0.32246,2.6251626 q 0.297656,-0.3927408 0.657324,-0.6201171 0.363802,-0.2315104 0.773079,-0.2315104 0.268718,0 0.483692,0.095085 0.219108,0.09095 0.37207,0.2811198 0.157096,0.1901692 0.239778,0.4836914 0.08682,0.289388 0.08682,0.6862629 0,0.5250326 -0.165365,1.0128581 -0.16123,0.4836913 -0.44235,0.8557621 -0.28112,0.37207 -0.657324,0.595312 -0.37207,0.219108 -0.79375,0.219108 -0.326595,0 -0.58291,-0.124023 -0.252181,-0.124024 -0.425814,-0.334864 l -0.03307,0.111621 q -0.04548,0.144694 -0.119889,0.214974 -0.07441,0.07028 -0.248047,0.07028 z m 2.447396,-3.3486323 q -0.165365,0 -0.338997,0.1116211 -0.169499,0.1116211 -0.33073,0.3059245 -0.157096,0.1901692 -0.293522,0.4506184 -0.136425,0.2604492 -0.23151,0.5581055 L 33.3722,9.8909014 q 0.14056,0.1322916 0.318326,0.1901696 0.177767,0.05374 0.3514,0.05374 0.264584,0 0.483692,-0.1570962 0.219108,-0.1570964 0.37207,-0.4092774 0.157096,-0.256315 0.239779,-0.5746419 0.08682,-0.3183268 0.08682,-0.6449218 0,-0.4258138 -0.144694,-0.6283854 -0.14056,-0.2025716 -0.396875,-0.2025716 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path883" />
|
||||
<path
|
||||
d="m 40.441535,7.7494301 q 0,0.2728516 -0.124023,0.5002279 -0.119889,0.2232421 -0.429948,0.4051432 -0.310058,0.1777669 -0.847493,0.3059244 -0.533301,0.1281576 -1.35599,0.2025716 0,0.4878255 0.227376,0.72347 0.231511,0.2315108 0.7028,0.2315108 0.297656,0 0.487825,-0.06615 0.194304,-0.066146 0.33073,-0.1446942 0.136425,-0.082682 0.239778,-0.1488281 0.107487,-0.066146 0.235645,-0.066146 0.111621,0 0.190169,0.09095 l 0.272852,0.3224606 q -0.231511,0.214974 -0.450619,0.372071 -0.219108,0.152962 -0.454753,0.256315 -0.23151,0.09922 -0.491959,0.144694 -0.256315,0.04961 -0.558106,0.04961 -0.396875,0 -0.72347,-0.124023 -0.32246,-0.124024 -0.553971,-0.3514 -0.227376,-0.23151 -0.355534,-0.5498373 -0.124023,-0.3224609 -0.124023,-0.7193359 0,-0.4836914 0.165364,-0.9301757 0.169499,-0.4506185 0.475424,-0.79375 0.310058,-0.3431315 0.74414,-0.5498372 0.438216,-0.2067057 0.979785,-0.2067057 0.355534,0 0.620117,0.095085 0.268718,0.09095 0.442351,0.2439128 0.177767,0.1488281 0.264583,0.3348632 0.09095,0.1860352 0.09095,0.3720703 z m -1.46761,-0.3183268 q -0.223242,0 -0.417546,0.078548 -0.190169,0.074414 -0.343131,0.2149739 -0.152962,0.1364258 -0.264583,0.3348633 -0.111622,0.1943034 -0.177767,0.4299479 0.553971,-0.066146 0.892968,-0.1405599 0.338998,-0.078548 0.525033,-0.1653646 0.186035,-0.09095 0.248047,-0.1901692 0.06201,-0.1033529 0.06201,-0.2191081 0,-0.062012 -0.02894,-0.1198893 -0.02894,-0.062012 -0.09508,-0.1116211 -0.06201,-0.049609 -0.16123,-0.078548 -0.09922,-0.033073 -0.239779,-0.033073 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path885" />
|
||||
<path
|
||||
d="m 42.42591,6.7613768 -0.49196,4.1051752 h -1.033528 l 0.491959,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115755,-0.053743 0.239779,-0.053743 0.124023,0 0.239778,0.053743 0.11989,0.049609 0.21084,0.1405599 0.09095,0.09095 0.144694,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path887" />
|
||||
<path
|
||||
d="m 46.692317,7.7494301 q 0,0.2728516 -0.124023,0.5002279 -0.119889,0.2232421 -0.429948,0.4051432 -0.310058,0.1777669 -0.847493,0.3059244 -0.533301,0.1281576 -1.35599,0.2025716 0,0.4878255 0.227377,0.72347 0.23151,0.2315108 0.702799,0.2315108 0.297656,0 0.487825,-0.06615 0.194304,-0.066146 0.33073,-0.1446942 0.136425,-0.082682 0.239778,-0.1488281 0.107487,-0.066146 0.235645,-0.066146 0.111621,0 0.190169,0.09095 l 0.272852,0.3224606 q -0.231511,0.214974 -0.450619,0.372071 -0.219108,0.152962 -0.454752,0.256315 -0.231511,0.09922 -0.49196,0.144694 -0.256315,0.04961 -0.558106,0.04961 -0.396875,0 -0.72347,-0.124023 -0.32246,-0.124024 -0.553971,-0.3514 -0.227376,-0.23151 -0.355534,-0.5498373 -0.124023,-0.3224609 -0.124023,-0.7193359 0,-0.4836914 0.165364,-0.9301757 0.169499,-0.4506185 0.475424,-0.79375 0.310058,-0.3431315 0.74414,-0.5498372 0.438216,-0.2067057 0.979785,-0.2067057 0.355534,0 0.620117,0.095085 0.268718,0.09095 0.442351,0.2439128 0.177767,0.1488281 0.264583,0.3348632 0.09095,0.1860352 0.09095,0.3720703 z m -1.46761,-0.3183268 q -0.223242,0 -0.417546,0.078548 -0.190169,0.074414 -0.343131,0.2149739 -0.152962,0.1364258 -0.264583,0.3348633 -0.111622,0.1943034 -0.177767,0.4299479 0.553971,-0.066146 0.892968,-0.1405599 0.338998,-0.078548 0.525033,-0.1653646 0.186035,-0.09095 0.248047,-0.1901692 0.06201,-0.1033529 0.06201,-0.2191081 0,-0.062012 -0.02894,-0.1198893 -0.02894,-0.062012 -0.09509,-0.1116211 -0.06201,-0.049609 -0.16123,-0.078548 -0.09922,-0.033073 -0.239779,-0.033073 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path889" />
|
||||
<path
|
||||
d="M 47.134667,10.866552 47.849869,4.92583 h 1.037663 l -0.719336,5.940722 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path891" />
|
||||
<path
|
||||
d="m 50.760287,6.7613768 -0.491959,4.1051752 h -1.033529 l 0.49196,-4.1051752 z m 0.248047,-1.1782226 q 0,0.1322917 -0.05788,0.252181 -0.05374,0.1157552 -0.148828,0.2067057 -0.09095,0.086816 -0.21084,0.1405599 -0.115755,0.049609 -0.239778,0.049609 -0.11989,0 -0.235645,-0.049609 -0.111621,-0.053744 -0.198437,-0.1405599 -0.08682,-0.09095 -0.14056,-0.2067057 -0.05374,-0.1198893 -0.05374,-0.252181 0,-0.1322917 0.05374,-0.252181 0.05374,-0.1198893 0.14056,-0.2067057 0.09095,-0.09095 0.202571,-0.144694 0.115756,-0.053743 0.239779,-0.053743 0.124023,0 0.239779,0.053743 0.119889,0.049609 0.210839,0.1405599 0.09095,0.09095 0.144695,0.2108398 0.05374,0.1157552 0.05374,0.252181 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path893" />
|
||||
<path
|
||||
d="m 51.38867,10.300179 q 0,-0.128158 0.04548,-0.243913 0.04961,-0.1157553 0.132291,-0.1984376 0.08682,-0.082682 0.202572,-0.1322916 0.115755,-0.049609 0.248047,-0.049609 0.132291,0 0.248047,0.049609 0.115755,0.049609 0.198437,0.1322916 0.08682,0.082682 0.136426,0.1984376 0.04961,0.115755 0.04961,0.243913 0,0.132291 -0.04961,0.248047 -0.04961,0.115755 -0.136426,0.198437 -0.08268,0.08268 -0.198437,0.128158 -0.115756,0.04961 -0.248047,0.04961 -0.132292,0 -0.248047,-0.04961 -0.115755,-0.04548 -0.202572,-0.128158 -0.08268,-0.08268 -0.132291,-0.198437 -0.04548,-0.115756 -0.04548,-0.248047 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path895" />
|
||||
<path
|
||||
d="m 56.672069,10.138948 q -0.202571,0.223242 -0.388607,0.376205 -0.181901,0.148828 -0.376204,0.243912 -0.194303,0.09095 -0.409277,0.128158 -0.21084,0.04134 -0.471289,0.04134 -0.359668,0 -0.644922,-0.119889 -0.28112,-0.124024 -0.479558,-0.347266 -0.194303,-0.227376 -0.30179,-0.5415688 -0.103353,-0.3183268 -0.103353,-0.7110677 0,-0.3348633 0.07028,-0.649056 0.07441,-0.3183268 0.21084,-0.5953124 0.136426,-0.2769857 0.330729,-0.5084961 0.194304,-0.2356445 0.434082,-0.4010091 0.243913,-0.1653646 0.525033,-0.2563151 0.285254,-0.095085 0.599446,-0.095085 0.413412,0 0.7028,0.144694 0.289388,0.1405599 0.51263,0.434082 l -0.338997,0.3927409 q -0.03307,0.045475 -0.08268,0.074414 -0.04961,0.028939 -0.107487,0.028939 -0.07028,0 -0.128157,-0.037207 -0.05374,-0.041341 -0.124024,-0.086816 -0.07028,-0.045475 -0.177767,-0.082682 -0.103352,-0.041341 -0.272851,-0.041341 -0.219108,0 -0.417546,0.1198893 -0.198437,0.1198893 -0.351399,0.3389974 -0.152963,0.219108 -0.243913,0.5291666 -0.09095,0.3100586 -0.09095,0.6945312 0,0.4382161 0.19017,0.6738606 0.194303,0.2315108 0.516764,0.2315108 0.223242,0 0.363802,-0.06201 0.14056,-0.062012 0.239779,-0.1364258 0.09922,-0.074414 0.177767,-0.1364258 0.08268,-0.062012 0.181901,-0.062012 0.05374,0 0.09922,0.024805 0.04961,0.024805 0.08682,0.07028 l 0.268717,0.3224607 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path897" />
|
||||
<path
|
||||
d="M 57.035872,10.866552 57.751073,4.92583 h 1.050065 l -0.305924,2.5052733 q 0.30179,-0.3720703 0.65319,-0.5498372 0.355534,-0.181901 0.727604,-0.181901 0.264584,0 0.475423,0.1033528 0.214974,0.1033529 0.3514,0.3017904 0.14056,0.1984375 0.194303,0.4878255 0.05788,0.289388 0.0124,0.6614583 l -0.310059,2.6127599 h -1.045931 l 0.305925,-2.6127599 q 0.04961,-0.3803385 -0.04134,-0.541569 -0.09095,-0.1653646 -0.338998,-0.1653646 -0.152962,0 -0.318327,0.086816 -0.16123,0.082682 -0.314192,0.2397787 -0.152963,0.1529622 -0.285254,0.3720702 -0.132292,0.214974 -0.223242,0.4836914 l -0.256315,2.1373368 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531"
|
||||
id="path900" />
|
||||
</g>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot844"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
|
||||
id="flowRegion846"><rect
|
||||
id="rect848"
|
||||
width="718.11023"
|
||||
height="548.03149"
|
||||
x="37.795277"
|
||||
y="404.40945" /></flowRegion><flowPara
|
||||
id="flowPara850" /></flowRoot> </g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,294 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: cairo 1.16.0 (https://cairographics.org)
|
||||
%%CreationDate: Wed Feb 20 19:23:49 2019
|
||||
%%Pages: 1
|
||||
%%DocumentData: Clean7Bit
|
||||
%%LanguageLevel: 2
|
||||
%%BoundingBox: 47 71 217 100
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
50 dict begin
|
||||
/q { gsave } bind def
|
||||
/Q { grestore } bind def
|
||||
/cm { 6 array astore concat } bind def
|
||||
/w { setlinewidth } bind def
|
||||
/J { setlinecap } bind def
|
||||
/j { setlinejoin } bind def
|
||||
/M { setmiterlimit } bind def
|
||||
/d { setdash } bind def
|
||||
/m { moveto } bind def
|
||||
/l { lineto } bind def
|
||||
/c { curveto } bind def
|
||||
/h { closepath } bind def
|
||||
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
|
||||
0 exch rlineto 0 rlineto closepath } bind def
|
||||
/S { stroke } bind def
|
||||
/f { fill } bind def
|
||||
/f* { eofill } bind def
|
||||
/n { newpath } bind def
|
||||
/W { clip } bind def
|
||||
/W* { eoclip } bind def
|
||||
/BT { } bind def
|
||||
/ET { } bind def
|
||||
/BDC { mark 3 1 roll /BDC pdfmark } bind def
|
||||
/EMC { mark /EMC pdfmark } bind def
|
||||
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
|
||||
/Tj { show currentpoint cairo_store_point } bind def
|
||||
/TJ {
|
||||
{
|
||||
dup
|
||||
type /stringtype eq
|
||||
{ show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
|
||||
} forall
|
||||
currentpoint cairo_store_point
|
||||
} bind def
|
||||
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
|
||||
cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
|
||||
/Tf { pop /cairo_font exch def /cairo_font_matrix where
|
||||
{ pop cairo_selectfont } if } bind def
|
||||
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
|
||||
/cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
|
||||
/cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
|
||||
cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/g { setgray } bind def
|
||||
/rg { setrgbcolor } bind def
|
||||
/d1 { setcachedevice } bind def
|
||||
/cairo_data_source {
|
||||
CairoDataIndex CairoData length lt
|
||||
{ CairoData CairoDataIndex get /CairoDataIndex CairoDataIndex 1 add def }
|
||||
{ () } ifelse
|
||||
} def
|
||||
/cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def
|
||||
/cairo_image { image cairo_flush_ascii85_file } def
|
||||
/cairo_imagemask { imagemask cairo_flush_ascii85_file } def
|
||||
%%EndProlog
|
||||
%%BeginSetup
|
||||
%%BeginResource: font Carlito-BoldItalic
|
||||
11 dict begin
|
||||
/FontType 42 def
|
||||
/FontName /Carlito-BoldItalic def
|
||||
/PaintType 0 def
|
||||
/FontMatrix [ 1 0 0 1 0 0 ] def
|
||||
/FontBBox [ 0 0 0 0 ] def
|
||||
/Encoding 256 array def
|
||||
0 1 255 { Encoding exch /.notdef put } for
|
||||
Encoding 45 /hyphen put
|
||||
Encoding 46 /period put
|
||||
Encoding 98 /b put
|
||||
Encoding 99 /c put
|
||||
Encoding 101 /e put
|
||||
Encoding 104 /h put
|
||||
Encoding 105 /i put
|
||||
Encoding 108 /l put
|
||||
Encoding 109 /m put
|
||||
Encoding 110 /n put
|
||||
/CharStrings 11 dict dup begin
|
||||
/.notdef 0 def
|
||||
/m 1 def
|
||||
/i 2 def
|
||||
/n 3 def
|
||||
/hyphen 4 def
|
||||
/b 5 def
|
||||
/e 6 def
|
||||
/l 7 def
|
||||
/period 8 def
|
||||
/c 9 def
|
||||
/h 10 def
|
||||
end readonly def
|
||||
/sfnts [
|
||||
<0001000000090080000300106376742026d7027600000828000000386670676ddbb62e8c0000
|
||||
086000000a75676c79667c62e8020000009c0000078c686561647d5a70d0000012d800000036
|
||||
686865610e6808980000131000000024686d747826e2028c000013340000002c6c6f63610000
|
||||
319400001360000000306d61787001bf0bc90000139000000020707265709a783a38000013b0
|
||||
0000008100040028000003ff057600230037003b003f0088b50001020001424bb01a50584034
|
||||
000302010203016800010402010466000000020300025b000400050804055b00090906510006
|
||||
060e4300080807510007070d07441b4032000302010203016800010402010466000600090006
|
||||
0959000000020300025b000400050804055b00080807510007070d074459400d3f3e11111428
|
||||
26232a1c220a182b133e0133321e0215140e040f012327263e0435342623220e022322271334
|
||||
3e0233321e0215140e0223222e020121112137211121e5388e61466e4c281a29302b220516ae
|
||||
12061527312b1d292a222d211a0f2410481525321e1c3225151525321c1e322515feb803d7fc
|
||||
2941034cfcb404552d3c25445f3a354c39292322155b6d24342a23272f211f260c0f0c1efd4a
|
||||
1c3225151525321c1d3125151525310460fa8a4504ec0000000100370000061903f0002c005b
|
||||
400c06010400201f0c03030402424bb0245058401606010404005302010200000f4308070503
|
||||
03030d03441b401a0000000f430601040401530201010117430807050303030d034459400f00
|
||||
00002c002c2316231524252109162b33133332160f013e01333216173e0133321e0207032313
|
||||
362623220e020715032313362623220e020703377881282e010548a85d6372094ab66c446641
|
||||
170b4afa4a0c273c274d443a153bfb4a0c243c2a4f443a153a03e2272b6966637b747b743260
|
||||
8c5afd8802785c4d274a6b4301fdff02785b4e2a4f6f45fe0c00000000020043000001f0059d
|
||||
000300170026402300020203530003030e43040101010f430000000d0044000014120a080003
|
||||
00031105102b0103231301140e0223222e0235343e0233321e0201b477fa7701361b2d391e1d
|
||||
372a1a1a2b371e1e392c1a03e1fc1f03e1011d20392b19192b3920203a2b1a192c3900010032
|
||||
000003ec03f0001a004bb50601020301424bb024505840130003030053010100000f43050402
|
||||
02020d02441b40170000000f430003030153000101174305040202020d024459400c0000001a
|
||||
001a2315252106132b33133332160f013e0133321e0207032313362623220e02070332778129
|
||||
2d02054ebc644067431b0b4afe4b0b2d3c29564f41133403e2272b776d6a32608c5afd880278
|
||||
5c4d2e547749fe210001005101e1023e02ad00030017401400000101004d0000000151000100
|
||||
0145111002112b132107216a01d41afe2d02adcc00000002003bfff1040b059d0017002800a6
|
||||
4bb0225058400b1e030205041301020502421b400b1e03020504130103050242594bb00f5058
|
||||
401d0000000e430701040401530001011743000505025406030202021502441b4bb022505840
|
||||
1d0000000e430701040401530001011743000505025406030202021802441b40210000000e43
|
||||
0701040401530001011743060103030d43000505025400020218024459594013191800002220
|
||||
182819280017001628231108122b331333033e0133321e0215140e0223222627070e01230122
|
||||
0e020f011e0133323e023534263badf94e48af6341694b294f88b5664f7b2a080b242a01c728
|
||||
534d42171c22562a406a4b2945059dfd855f6f2d5c8d607febb46b3c331b2322032a365d7e48
|
||||
e5201b4c7b9a4f67620000020031fff103c403ef002300320063400b29050201041001000102
|
||||
424bb00f5058401e000104000401006805010404035300030317430000000253000202150244
|
||||
1b401e00010400040100680501040403530003031743000000025300020218024459400c2524
|
||||
243225322826232706132b01140e010407141633323e0233321f010e0323222e0235343e0233
|
||||
321e0225220e02073e0335342e0203c43b96fefdc76f72485d42331f1b1342386a717d49609d
|
||||
6f3d5195d3835681552bfe9d365d4a361086a45a1e0e1f3002f2426d573e127671202720164e
|
||||
344b31173c6f9b6075d9a6642d495a2025435f3910252b311c0f1d180f000001003f000001e7
|
||||
059d0003001840150000000e43020101010d01440000000300031103102b331333033fadfbae
|
||||
059dfa63000000010054fff20185012000130012400f0000000153000101150144282402112b
|
||||
37343e0233321e0215140e0223222e025417293820203829181829382020382917891f382818
|
||||
1828381f203828171728380000000001002efff1036103ef002e0069400a1401030100010004
|
||||
02424bb00f505840240002030503020568000504030504660003030153000101174300040400
|
||||
530000001500441b402400020305030205680005040305046600030301530001011743000404
|
||||
005300000018004459b7232623252a2406152b250e0323222e0235343e0433321617070e0123
|
||||
222e0223220e0215141633323e023332161f01032e31595e673f57895f3323425e75894c648c
|
||||
365208180e111b22332935604a2c5d4e36443027180d170941b036492d133b6d995f51998671
|
||||
502d45475f0b0e1316133a6a965d6a711e241e0c0b4e0001003a000003ee059d0017002c4029
|
||||
0301030101420000000e430003030153000101174305040202020d0244000000170017231523
|
||||
1106132b331333033e0133321e0207032313362623220e0207033aadfe4a49ab5a4067431b0b
|
||||
4bfd4a0c2c3c254f4a40163e059dfda25a5732608c5afd8802785c4f294b6941fdfb00000000
|
||||
000000000000000000000000000000fe00c200fe00c205300000059d03e10000febe079efdda
|
||||
053ffff2059d03effff1febe079efddab0002cb02060662db0012c206420b0c050b004265ab0
|
||||
04455b582123211b8a5820b050505821b040591b20b038505821b038595920b00b456164b028
|
||||
505821b00b4520b030505821b030591b20b0c050582066208a8a6120b00a5058601b20b02050
|
||||
5821b00a601b20b036505821b036601b605959591bb0002b595923b00050586559592db0022c
|
||||
204520b00425616420b005435058b0052342b00623421b212159b001602db0032c2321232120
|
||||
64b105624220b0062342b20b01022a2120b00643208a208ab0002bb13005258a515860501b61
|
||||
52595823592120b0405358b0002b1b21b0405923b000505865592db0042cb007432bb2000200
|
||||
4360422db0052cb00723422320b000234261b0026266b00163b00160b0042a2db0062c202045
|
||||
20b0024563b804006220b0005058b040605966b001636044b001602db0072c20204520b0002b
|
||||
23b10804256020458a2361206420b020505821b0001bb0305058b0201bb040595923b0005058
|
||||
6559b0032523614444b001602db0082cb1050545b00161442db0092cb001602020b009434ab0
|
||||
00505820b009234259b00a434ab000525820b00a2342592db00a2c20b0106266b0016320b804
|
||||
00638a2361b00b4360208a6020b00b2342232db00b2c4b5458b10701445924b00d6523782db0
|
||||
0c2c4b51584b5358b1070144591b215924b0136523782db00d2cb1000c435558b10c0c43b001
|
||||
6142b00a2b59b00043b0022542b109022542b10a022542b001162320b003255058b101004360
|
||||
b00425428a8a208a2361b0092a2123b00161208a2361b0092a211bb101004360b0022542b002
|
||||
2561b0092a2159b0094347b00a434760b0026220b0005058b040605966b0016320b0024563b8
|
||||
04006220b0005058b040605966b0016360b10000132344b00143b0003eb20101014360422db0
|
||||
0e2cb1000545545800b00c23422060b00161b50d0d01000b0042428a60b10d052bb06d2b1b22
|
||||
592db00f2cb1000e2b2db0102cb1010e2b2db0112cb1020e2b2db0122cb1030e2b2db0132cb1
|
||||
040e2b2db0142cb1050e2b2db0152cb1060e2b2db0162cb1070e2b2db0172cb1080e2b2db018
|
||||
2cb1090e2b2db0192cb0082bb1000545545800b00c23422060b00161b50d0d01000b0042428a
|
||||
60b10d052bb06d2b1b22592db01a2cb100192b2db01b2cb101192b2db01c2cb102192b2db01d
|
||||
2cb103192b2db01e2cb104192b2db01f2cb105192b2db0202cb106192b2db0212cb107192b2d
|
||||
b0222cb108192b2db0232cb109192b2db0242c203cb001602db0252c2060b00d60204323b001
|
||||
6043b0022561b00160b0242a212db0262cb0252bb0252a2db0272c2020472020b0024563b804
|
||||
006220b0005058b040605966b001636023613823208a555820472020b0024563b804006220b0
|
||||
005058b040605966b00163602361381b21592db0282cb1000545545800b00116b0272ab00115
|
||||
301b22592db0292cb0082bb1000545545800b00116b0272ab00115301b22592db02a2c2035b0
|
||||
01602db02b2c00b0034563b804006220b0005058b040605966b00163b0002bb0024563b80400
|
||||
6220b0005058b040605966b00163b0002bb00016b40000000000443e2338b12a01152a2db02c
|
||||
2c203c204720b0024563b804006220b0005058b040605966b0016360b0004361382db02d2c2e
|
||||
173c2db02e2c203c204720b0024563b804006220b0005058b040605966b0016360b0004361b0
|
||||
014363382db02f2cb102001625202e2047b0002342b00225498a8a47234723612058621b2159
|
||||
b0012342b22e010115142a2db0302cb00016b00425b004254723472361b006452b658a2e2320
|
||||
203c8a382db0312cb00016b00425b00425202e472347236120b0042342b006452b20b0605058
|
||||
20b0405158b3022003201bb30226031a5942422320b00843208a234723472361234660b00443
|
||||
b0026220b0005058b040605966b001636020b0002b208a8a6120b00243606423b00343616450
|
||||
58b00243611bb003436059b00325b0026220b0005058b040605966b0016361232020b0042623
|
||||
4661381b23b0084346b00225b0084347234723616020b00443b0026220b0005058b040605966
|
||||
b00163602320b0002b23b0044360b0002bb0052561b00525b0026220b0005058b040605966b0
|
||||
0163b004266120b00425606423b0032560645058211b232159232020b0042623466138592db0
|
||||
322cb00016202020b00526202e4723472361233c382db0332cb0001620b00823422020204623
|
||||
47b0002b2361382db0342cb00016b00325b002254723472361b00054582e203c23211bb00225
|
||||
b00225472347236120b00525b004254723472361b00625b0052549b0022561b0014563232058
|
||||
621b215963b804006220b0005058b040605966b0016360232e2320203c8a382321592db0352c
|
||||
b0001620b00843202e47234723612060b0206066b0026220b0005058b040605966b001632320
|
||||
203c8a382db0362c23202e46b00225465258203c592eb12601142b2db0372c23202e46b00225
|
||||
465058203c592eb12601142b2db0382c23202e46b00225465258203c5923202e46b002254650
|
||||
58203c592eb12601142b2db0392cb0302b23202e46b00225465258203c592eb12601142b2db0
|
||||
3a2cb0312b8a20203cb00423428a3823202e46b00225465258203c592eb12601142bb004432e
|
||||
b0262b2db03b2cb00016b00425b00426202e4723472361b006452b23203c202e2338b1260114
|
||||
2b2db03c2cb108042542b00016b00425b00425202e472347236120b0042342b006452b20b060
|
||||
505820b0405158b3022003201bb30226031a594242232047b00443b0026220b0005058b04060
|
||||
5966b001636020b0002b208a8a6120b00243606423b0034361645058b00243611bb003436059
|
||||
b00325b0026220b0005058b040605966b0016361b0022546613823203c23381b212020462347
|
||||
b0002b2361382159b12601142b2db03d2cb0302b2eb12601142b2db03e2cb0312b212320203c
|
||||
b00423422338b12601142bb004432eb0262b2db03f2cb000152047b0002342b2000101151413
|
||||
2eb02c2a2db0402cb000152047b0002342b20001011514132eb02c2a2db0412cb100011413b0
|
||||
2d2a2db0422cb02f2a2db0432cb000164523202e20468a236138b12601142b2db0442cb00823
|
||||
42b0432b2db0452cb200003c2b2db0462cb200013c2b2db0472cb201003c2b2db0482cb20101
|
||||
3c2b2db0492cb200003d2b2db04a2cb200013d2b2db04b2cb201003d2b2db04c2cb201013d2b
|
||||
2db04d2cb20000392b2db04e2cb20001392b2db04f2cb20100392b2db0502cb20101392b2db0
|
||||
512cb200003b2b2db0522cb200013b2b2db0532cb201003b2b2db0542cb201013b2b2db0552c
|
||||
b200003e2b2db0562cb200013e2b2db0572cb201003e2b2db0582cb201013e2b2db0592cb200
|
||||
003a2b2db05a2cb200013a2b2db05b2cb201003a2b2db05c2cb201013a2b2db05d2cb0322b2e
|
||||
b12601142b2db05e2cb0322bb0362b2db05f2cb0322bb0372b2db0602cb00016b0322bb0382b
|
||||
2db0612cb0332b2eb12601142b2db0622cb0332bb0362b2db0632cb0332bb0372b2db0642cb0
|
||||
332bb0382b2db0652cb0342b2eb12601142b2db0662cb0342bb0362b2db0672cb0342bb0372b
|
||||
2db0682cb0342bb0382b2db0692cb0352b2eb12601142b2db06a2cb0352bb0362b2db06b2cb0
|
||||
352bb0372b2db06c2cb0352bb0382b2db06d2c2bb00865b003245078b00115302d0000000001
|
||||
000000011a5e61392c2f5f0f3cf5001b0800000000004a53db2600000000ce2e3052fc8dfdd6
|
||||
09190828000300060002000100000000000100000600fe0001c40aa0fc8df7ed0919080000fb
|
||||
000000000000000000000000000b040e0028066e003701f7004304380032027300510439003b
|
||||
03ee003101f7003f02230054034b002e0438003a00000000000001440000022c000002a40000
|
||||
03480000037c000004a000000598000005cc000006200000070c0000078c00010000000b00f5
|
||||
00100000000000020050005d006e000000e50a75000000004bb800c85258b101018e59b90800
|
||||
08006320b0012344b0032370b017452020b0286066208a5558b0022561b00145632362b00223
|
||||
44b20b01062ab20c06062ab21406062a59b2042809455244b20c08072ab1060144b124018851
|
||||
58b0408858b1060344b12601885158b804008858b106014459595959b801ff85b0048db10500
|
||||
4400000000>
|
||||
] def
|
||||
/f-0-0 currentdict end definefont pop
|
||||
%%EndResource
|
||||
%%EndSetup
|
||||
%%Page: 1 1
|
||||
%%BeginPageSetup
|
||||
%%PageBoundingBox: 47 71 217 100
|
||||
%%EndPageSetup
|
||||
q 47 71 170 29 rectclip
|
||||
1 0 0 -1 0 149 cm q
|
||||
0.282353 0.215686 0.215686 rg
|
||||
68.875 71.926 m 65.875 73.656 l 62.871 75.391 l 59.93 77.086 59.613 76.977
|
||||
56.867 75.391 c 53.867 73.656 l 50.863 71.926 l 47.926 70.227 47.863 69.895
|
||||
47.863 66.727 c 47.863 59.793 l 47.863 56.398 48.121 56.18 50.863 54.594
|
||||
c 53.867 52.859 l 56.867 51.129 l 59.809 49.43 60.125 49.543 62.871 51.129
|
||||
c 65.875 52.859 l 68.875 54.594 l 71.816 56.293 71.875 56.625 71.875 59.793
|
||||
c 71.875 66.727 l 71.875 70.121 71.621 70.34 68.875 71.926 c h
|
||||
68.875 71.926 m f
|
||||
1.205089 w
|
||||
1 J
|
||||
1 j
|
||||
[] 0.0 d
|
||||
4 M q 1 0 0 1 0 0 cm
|
||||
68.875 71.926 m 65.875 73.656 l 62.871 75.391 l 59.93 77.086 59.613 76.977
|
||||
56.867 75.391 c 53.867 73.656 l 50.863 71.926 l 47.926 70.227 47.863 69.895
|
||||
47.863 66.727 c 47.863 59.793 l 47.863 56.398 48.121 56.18 50.863 54.594
|
||||
c 53.867 52.859 l 56.867 51.129 l 59.809 49.43 60.125 49.543 62.871 51.129
|
||||
c 65.875 52.859 l 68.875 54.594 l 71.816 56.293 71.875 56.625 71.875 59.793
|
||||
c 71.875 66.727 l 71.875 70.121 71.621 70.34 68.875 71.926 c h
|
||||
68.875 71.926 m S Q
|
||||
1 0.8 0 rg
|
||||
3.31125 w
|
||||
q 1 0 0 1 0 0 cm
|
||||
53.262 60.066 m 55.242 59.23 57.422 58.766 59.707 58.766 c 61.992 58.766
|
||||
64.168 59.23 66.148 60.066 c S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
55.051 64.297 m 56.48 63.695 58.055 63.359 59.707 63.359 c 61.355 63.359
|
||||
62.93 63.695 64.359 64.297 c S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
56.84 68.535 m 57.723 68.164 58.691 67.957 59.707 67.957 c 60.723 67.957
|
||||
61.691 68.164 62.57 68.535 c S Q
|
||||
0.282353 0.215686 0.215686 rg
|
||||
2.410177 w
|
||||
0 j
|
||||
q 1 0 0 1 0 0 cm
|
||||
54.613 53.715 m 53.109 50.703 l S Q
|
||||
q 1 0 0 1 0 0 cm
|
||||
65.16 53.715 m 66.664 50.703 l S Q
|
||||
BT
|
||||
23.999999 0 0 -23.999999 83.645814 69.718046 Tm
|
||||
/f-0-0 1 Tf
|
||||
[(mini-be)-3(ieli.)-3(ch)]TJ
|
||||
ET
|
||||
Q Q
|
||||
showpage
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
||||
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="83.081947mm"
|
||||
height="52.319721mm"
|
||||
viewBox="0 0 83.081947 52.319721"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (unknown)"
|
||||
sodipodi:docname="mini-beieli-praegung.svg"
|
||||
inkscape:export-filename="/home/joerg/bee-logo-box.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
inkscape:stockid="DotL"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="DotL"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path978"
|
||||
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
|
||||
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,5.92,0.8)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1106813"
|
||||
inkscape:cx="10.645336"
|
||||
inkscape:cy="42.625215"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2089"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid895"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
originx="15.558254"
|
||||
originy="-258.4087" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(15.558254,13.728425)">
|
||||
<path
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0.42512852;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 8.7393227,11.644791 -1.0589324,0.611374 -1.0589359,0.611374 c -1.0371974,0.598824 -1.1494606,0.559109 -2.1178708,0 L 3.4446478,12.256165 2.3857128,11.644791 C 1.3485151,11.045971 1.3267775,10.928889 1.3267775,9.8106715 V 8.5879237 7.3651789 c 0,-1.1976465 0.090525,-1.2750137 1.0589353,-1.8341225 L 3.4446478,4.9196842 4.5035836,4.3083089 c 1.0371978,-0.59882 1.1494596,-0.559106 2.1178708,0 l 1.0589359,0.6113753 1.0589324,0.6113722 c 1.0371922,0.5988236 1.058929,0.7159034 1.058929,1.8341225 v 1.2227448 1.2227478 c 0,1.1976435 -0.090524,1.2750145 -1.058929,1.8341195 z"
|
||||
id="path815"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scsscsscsscsscsscss"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.231964,7.4616379 c 0.6985148,-0.295449 1.4664939,-0.4588256 2.272625,-0.4588256 0.8061387,0 1.5741179,0.1633766 2.2726329,0.4588256"
|
||||
id="path846-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 3.8626628,8.9546319 c 0.5046637,-0.2134551 1.0595109,-0.331491 1.6419262,-0.331491 0.5824224,0 1.1372702,0.1180359 1.6419342,0.331491"
|
||||
id="path846-1-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:#ffcc00;stroke-width:1.16813552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 4.494172,10.44954 c 0.3105661,-0.131357 0.6520092,-0.203993 1.010417,-0.203993 0.3584154,0 0.699858,0.07264 1.0104178,0.203993"
|
||||
id="path846-8-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.7083008,5.2207965 3.1768908,4.1579827"
|
||||
id="path899"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<path
|
||||
style="fill:none;stroke:#483737;stroke-width:0.85025704;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 7.4281735,5.2207965 7.9595827,4.1579827"
|
||||
id="path899-8"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:4.44661283px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.11116531"
|
||||
x="13.95013"
|
||||
y="10.866552"
|
||||
id="text28"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan26"
|
||||
x="13.95013"
|
||||
y="10.866552"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:8.46666622px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.11116531">mini-beieli.ch</tspan></text>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot844"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
|
||||
id="flowRegion846"><rect
|
||||
id="rect848"
|
||||
width="718.11023"
|
||||
height="548.03149"
|
||||
x="37.795277"
|
||||
y="404.40945" /></flowRegion><flowPara
|
||||
id="flowPara850" /></flowRoot> </g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.2 KiB |
@@ -0,0 +1,30 @@
|
||||
$fn = 100;
|
||||
|
||||
// Head
|
||||
head_length=57.13;
|
||||
head_width=26.13;
|
||||
head_thickness=2.4;
|
||||
head_radius_corners=(44.65 - 35.6) /2.0;
|
||||
offset_m12_holes = (10-2-1.6-0.1)-8.5;
|
||||
|
||||
module loch() {
|
||||
cylinder(r=(0.15*25.4/2), h=10, center=true);
|
||||
cylinder(r1=(0.23*25.4/2), r2=(0.15*25.4/2), h=((0.23-0.15)*25.4/2), center=true);
|
||||
}
|
||||
|
||||
module m12() {
|
||||
cylinder(d=12.2, h=10, center=true);
|
||||
}
|
||||
|
||||
color("red")
|
||||
difference() {
|
||||
minkowski() {
|
||||
cube([head_length - (2 * head_radius_corners),head_width - (2 * head_radius_corners),head_thickness], center=true);
|
||||
cylinder(r=head_radius_corners, h=0.1, center=true);
|
||||
};
|
||||
translate([-48.15/2,0,0-((0.23-0.15)*25.4/2)]) loch();
|
||||
translate([48.15/2,0,0-((0.23-0.15)*25.4/2)]) loch();
|
||||
translate([-20.95/2,offset_m12_holes,0]) m12();
|
||||
translate([20.95/2,offset_m12_holes,0]) m12();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
$fn = 100;
|
||||
|
||||
// Head
|
||||
head_length=57.13;
|
||||
head_width=26.13;
|
||||
head_thickness=2.4;
|
||||
head_radius_corners=(44.65 - 35.6) /2.0;
|
||||
|
||||
module loch() {
|
||||
cylinder(r=(0.15*25.4/2), h=10, center=true);
|
||||
cylinder(r1=(0.23*25.4/2), r2=(0.15*25.4/2), h=((0.23-0.15)*25.4/2), center=true);
|
||||
}
|
||||
|
||||
module switch() {
|
||||
cube([9.2,13.8,5],center = true);
|
||||
}
|
||||
|
||||
module usb() {
|
||||
cube([8,3.2,5],center = true);
|
||||
}
|
||||
|
||||
module antenne() {
|
||||
cylinder(d=6.5, h=10, center=true);
|
||||
}
|
||||
|
||||
color("red")
|
||||
difference() {
|
||||
minkowski() {
|
||||
cube([head_length - (2 * head_radius_corners),head_width - (2 * head_radius_corners),head_thickness], center=true);
|
||||
cylinder(r=head_radius_corners, h=0.1, center=true);
|
||||
};
|
||||
translate([-48.15/2,0,0-((0.23-0.15)*25.4/2)]) loch();
|
||||
translate([48.15/2,0,0-((0.23-0.15)*25.4/2)]) loch();
|
||||
translate([-11.4-0.3-(8.3/2),-2.5]) switch();
|
||||
translate([0,1,0]) usb();
|
||||
translate([16,0,0]) antenne();
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1,220 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg869"
|
||||
version="1.1"
|
||||
viewBox="-29 -14 793.7008 1122.5197"
|
||||
height="297mm"
|
||||
width="210mm"
|
||||
sodipodi:docname="froncap-silk-screening-only.svg"
|
||||
inkscape:version="0.92.4 (unknown)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2089"
|
||||
id="namedview915"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.678367"
|
||||
inkscape:cx="396.85039"
|
||||
inkscape:cy="561.25984"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer2" />
|
||||
<metadata
|
||||
id="metadata875">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>OpenSCAD Model</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs873" />
|
||||
<title
|
||||
id="title865">OpenSCAD Model</title>
|
||||
<g
|
||||
transform="translate(0,1094.5197)"
|
||||
style="display:none"
|
||||
id="layer1">
|
||||
<g
|
||||
transform="matrix(3.75,0,0,3.75,-567.45454,-477.12286)"
|
||||
id="g2635">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g2623"
|
||||
transform="translate(237.60469,-134.81117)">
|
||||
<path
|
||||
style="fill:#d3d3d3;stroke:#000000;stroke-width:0.5"
|
||||
d="m 24.339244,-13.109364 0.283,0.0268 0.2808,0.0445 0.2774,0.062 0.273,0.0793 0.2674,0.0963 0.2609,0.1129 0.2533,0.129 0.2447,0.1447 0.2351,0.1598 0.2246,0.1742 0.2133,0.188 0.201,0.201 0.188,0.2133 0.1742,0.2246 0.1598,0.2351 0.1447,0.2447 0.129,0.2533 0.1129,0.2609 0.0963,0.2674097 0.0793,0.27298 0.062,0.27742 0.0445,0.28076 0.0268,0.28302 0.0089,0.28412 V 8.4867259 l -0.0089,0.28412 -0.0268,0.28302 -0.0445,0.28076 -0.062,0.27742 -0.0793,0.27298 -0.0963,0.2674101 -0.1129,0.2609 -0.129,0.2533 -0.1447,0.2447 -0.1598,0.2351 -0.1742,0.2246 -0.188,0.2133 -0.201,0.201 -0.2133,0.188 -0.2246,0.1742 -0.2351,0.1598 -0.2447,0.1447 -0.2533,0.129 -0.2609,0.1129 -0.2674,0.0963 -0.273,0.0793 -0.2774,0.062 -0.2808,0.0445 -0.283,0.0268 -0.2841,0.0089 h -48.08 l -0.2841,-0.0089 -0.283,-0.0268 -0.2808,-0.0445 -0.2774,-0.062 -0.273,-0.0793 -0.2674,-0.0963 -0.2609,-0.1129 -0.2533,-0.129 -0.2447,-0.1447 -0.2351,-0.1598 -0.2246,-0.1742 -0.2133,-0.188 -0.201,-0.201 -0.188,-0.2133 -0.1742,-0.2246 -0.1598,-0.2351 -0.1447,-0.2447 -0.129,-0.2533 -0.1129,-0.2609 -0.0963,-0.2674101 -0.0793,-0.27298 -0.062,-0.27742 -0.0445,-0.28076 -0.0268,-0.28302 -0.0089,-0.28412 V -8.5932543 l 0.0089,-0.28412 0.0268,-0.28302 0.0445,-0.28076 0.062,-0.27742 0.0793,-0.27298 0.0963,-0.2674097 0.1129,-0.2609 0.129,-0.2533 0.1447,-0.2447 0.1598,-0.2351 0.1742,-0.2246 0.188,-0.2133 0.201,-0.201 0.2133,-0.188 0.2246,-0.1742 0.2351,-0.1598 0.2447,-0.1447 0.2533,-0.129 0.2609,-0.1129 0.2674,-0.0963 0.273,-0.0793 0.2774,-0.062 0.2808,-0.0445 0.283,-0.0268 0.2841,-0.0089 h 48.08 z m -44.7741,3.7561097 V 4.2467259 h 9.2 V -9.3532543 Z m 36.2459,6.05641 -0.2032,0.01921 -0.2017,0.03194 -0.1992,0.04454 -0.1961,0.05696 -0.1921,0.06917 -0.1874,0.08109 -0.1819,0.09268 -0.1757,0.10393 -0.1689,0.11476 -0.1613,0.12513 -0.1532,0.13503 -0.1444,0.14436 -0.135,0.15316 -0.1251,0.16133 -0.1148,0.16887 -0.1039,0.17573 -0.0927,0.18192 -0.0811,0.18737 -0.0691,0.1920999 -0.057,0.19607205 -0.0445,0.19925 -0.032,0.20166 -0.0192,0.203262 -0.0064,0.204056 0.0064,0.204056 0.0192,0.203262 0.032,0.20166 0.0445,0.19925 0.057,0.19607205 0.0691,0.1921002 0.0811,0.18737 0.0927,0.18192 0.1039,0.17573 0.1148,0.16887 0.1251,0.16133 0.135,0.15316 0.1444,0.14436 0.1532,0.13503 0.1613,0.12513 0.1689,0.11476 0.1757,0.10393 0.1819,0.09268 0.1874,0.08109 0.1921,0.06917 0.1961,0.05696 0.1992,0.04454 0.2017,0.03194 0.2032,0.01921 0.2041,0.00642 0.2041,-0.00642 0.2032,-0.01921 0.2017,-0.03194 0.1992,-0.04454 0.1961,-0.05696 0.1921,-0.06917 0.1874,-0.08109 0.1819,-0.09268 0.1757,-0.10393 0.1689,-0.11476 0.1613,-0.12513 0.1532,-0.13503 0.1443,-0.14436 0.1351,-0.15316 0.1251,-0.16133 0.1148,-0.16887 0.1039,-0.17573 0.0927,-0.18192 0.0811,-0.18737 0.0691,-0.1921002 0.057,-0.19607205 0.0445,-0.19925 0.032,-0.20166 0.0192,-0.203262 0.0064,-0.204056 -0.0064,-0.204056 -0.0192,-0.203262 -0.032,-0.20166 -0.0445,-0.19925 -0.057,-0.19607205 -0.0691,-0.1920999 -0.0811,-0.18737 -0.0927,-0.18192 -0.1039,-0.17573 -0.1148,-0.16887 -0.1251,-0.16133 -0.1351,-0.15316 -0.1443,-0.14436 -0.1532,-0.13503 -0.1613,-0.12513 -0.1689,-0.11476 -0.1757,-0.10393 -0.1819,-0.09268 -0.1874,-0.08109 -0.1921,-0.06917 -0.1961,-0.05696 -0.1992,-0.04454 -0.2017,-0.03194 -0.2032,-0.01921 -0.2041,-0.0064 z M -3.9848564,-0.65325535 V 2.5467259 h 8 v -3.19998125 z m -20.1945996,-1.30123895 -0.1192,0.01126 -0.1182,0.01872 -0.1168,0.02611 -0.1149,0.03339 -0.1126,0.04054 -0.1098,0.04752 -0.1066,0.05433 -0.103,0.06092 -0.099,0.06727 -0.0946,0.07335 -0.0898,0.07915 -0.0846,0.08461 -0.0791,0.08978 -0.0734,0.09456 -0.0672,0.09898 -0.061,0.103 -0.0543,0.106644 -0.0475,0.109833 -0.0405,0.112594 -0.0335,0.114929 -0.026,0.116791 -0.0188,0.118195 -0.0112,0.11914 -0.0038,0.119614 0.0038,0.119614 0.0112,0.11914 0.0188,0.118195 0.026,0.116791 0.0335,0.114929 0.0405,0.112594 0.0475,0.109833 0.0543,0.106644 0.061,0.10300005 0.0672,0.0989799 0.0734,0.09456 0.0791,0.08978 0.0846,0.08461 0.0898,0.07915 0.0946,0.07335 0.099,0.06727 0.103,0.06092 0.1066,0.05433 0.1098,0.04752 0.1126,0.04054 0.1149,0.03339 0.1168,0.02611 0.1182,0.01872 0.1192,0.01126 0.1196,0.00377 0.1196,-0.00377 0.1192,-0.01126 0.1182,-0.01872 0.1168,-0.02611 0.1149,-0.03339 0.1126,-0.04054 0.1098,-0.04752 0.1066,-0.05433 0.1031,-0.06092 0.0989,-0.06727 0.0946,-0.07335 0.0898,-0.07915 0.0846,-0.08461 0.0791,-0.08978 0.0734,-0.09456 0.0672,-0.0989799 0.061,-0.10300005 0.0543,-0.106644 0.0475,-0.109833 0.0406,-0.112594 0.0334,-0.114929 0.0261,-0.116791 0.0187,-0.118195 0.0112,-0.11914 0.0038,-0.119614 -0.0038,-0.119614 -0.0112,-0.11914 -0.0187,-0.118195 -0.0261,-0.116791 -0.0334,-0.114929 -0.0406,-0.112594 -0.0475,-0.109833 -0.0543,-0.106644 -0.061,-0.103 -0.0672,-0.09898 -0.0734,-0.09456 -0.0791,-0.08978 -0.0846,-0.08461 -0.0898,-0.07915 -0.0946,-0.07335 -0.0989,-0.06727 -0.1031,-0.06092 -0.1066,-0.05433 -0.1098,-0.04752 -0.1126,-0.04054 -0.1149,-0.03339 -0.1168,-0.02611 -0.1182,-0.01872 -0.1192,-0.01126 -0.1196,-0.0038 z m 48.15,0 -0.1192,0.01126 -0.1182,0.01872 -0.1168,0.02611 -0.1149,0Line truncated
|
||||
id="path2611"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
id="text826"
|
||||
y="-809.41943"
|
||||
x="85.396912"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
y="-809.41943"
|
||||
x="85.396912"
|
||||
id="tspan824">Logo and Text Color: </tspan><tspan
|
||||
style="font-size:96px;fill:#442f29;fill-opacity:1;stroke:#442f29;stroke-opacity:1"
|
||||
id="tspan828"
|
||||
y="-709.87256"
|
||||
x="85.396912">RAL 8017</tspan></text>
|
||||
<text
|
||||
id="text832"
|
||||
y="-716.47192"
|
||||
x="541.79291"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan834"
|
||||
y="-681.0813"
|
||||
x="541.79291" /></text>
|
||||
<flowRoot
|
||||
transform="translate(-29,-1108.5197)"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
id="flowRoot838"
|
||||
xml:space="preserve"><flowRegion
|
||||
id="flowRegion840"><rect
|
||||
y="589.85907"
|
||||
x="131.67561"
|
||||
height="215.68584"
|
||||
width="483.20779"
|
||||
id="rect842" /></flowRegion><flowPara
|
||||
style="font-size:32px"
|
||||
id="flowPara844">nbit Informatik GmbH</flowPara><flowPara
|
||||
style="font-size:32px"
|
||||
id="flowPara846">joerg.lehmann@nbit.ch</flowPara><flowPara
|
||||
style="font-size:32px"
|
||||
id="flowPara848">25.4.2019</flowPara></flowRoot> <flowRoot
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
id="flowRoot850"
|
||||
xml:space="preserve"><flowRegion
|
||||
id="flowRegion852"><rect
|
||||
y="604.75452"
|
||||
x="132.86725"
|
||||
height="85.201866"
|
||||
width="107.84292"
|
||||
id="rect854" /></flowRegion><flowPara
|
||||
id="flowPara856" /></flowRoot> </g>
|
||||
<g
|
||||
transform="translate(0,1094.5197)"
|
||||
style="display:inline"
|
||||
id="layer2">
|
||||
<g
|
||||
id="g2767"
|
||||
transform="matrix(3.0001287,0,0,2.999999,380.29972,-988.15178)"
|
||||
style="display:inline">
|
||||
<path
|
||||
id="path815"
|
||||
d="m -18.884842,-11.733974 c -0.287789,-0.0051 -0.58446,0.139178 -1.119844,0.448281 l -1.093125,0.63125 -1.093281,0.631094 c -0.999754,0.5772086 -1.093125,0.6571766 -1.093125,1.8935936 v 1.262343 1.262188 c 0,1.154413 0.02236,1.275387 1.093125,1.893593 l 1.093281,0.631094 1.093125,0.63125 c 0.999755,0.577209 1.11564,0.61821 2.186406,0 l 1.093281,-0.63125 1.093126,-0.631094 c 0.999755,-0.577206 1.09328,-0.657177 1.09328,-1.893593 v -1.262188 -1.262343 c 0,-1.154419 -0.02236,-1.275387 -1.093124,-1.8935936 l -1.093282,-0.631094 -1.093281,-0.63125 c -0.499876,-0.288605 -0.778773,-0.443156 -1.066562,-0.448281 z m -0.08609,2.6271866 c 0.913697,0 1.786912,0.185688 2.580625,0.521407 a 0.60303098,0.60303098 0 1 1 -0.469531,1.110156 c -0.648533,-0.274315 -1.360331,-0.425781 -2.111094,-0.425781 -0.750752,0 -1.462718,0.151466 -2.11125,0.425781 a 0.60303098,0.60303098 0 1 1 -0.470156,-1.110156 c 0.793712,-0.335719 1.667717,-0.521407 2.581406,-0.521407 z m 0,1.672969 c 0.682741,0 1.336262,0.138777 1.929844,0.389844 a 0.60303099,0.60303099 0 1 1 -0.47,1.110156 c -0.448409,-0.189663 -0.940039,-0.294062 -1.459844,-0.294062 -0.519796,0 -1.012057,0.104399 -1.460469,0.294062 a 0.60303099,0.60303099 0 1 1 -0.469531,-1.110156 c 0.593583,-0.251067 1.247266,-0.389844 1.93,-0.389844 z m 0,1.674844 c 0.451487,0 0.884776,0.09166 1.277969,0.257969 a 0.60316438,0.60316438 0 1 1 -0.470157,1.110937 c -0.248028,-0.104907 -0.519265,-0.162969 -0.807812,-0.162969 -0.288534,0 -0.560553,0.05806 -0.808594,0.162969 a 0.603031,0.603031 0 1 1 -0.469375,-1.110937 c 0.393196,-0.166303 0.82649,-0.257969 1.277969,-0.257969 z"
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path899"
|
||||
d="m -20.82565,-10.34361 -0.548609,-1.097221"
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:0.87777525;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path899-8"
|
||||
d="m -16.985383,-10.34361 0.548609,-1.097221"
|
||||
style="fill:none;stroke:#483737;stroke-width:0.87777525;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
aria-label="mini-beieli.ch"
|
||||
style="font-style:normal;font-weight:normal;font-size:11.3441143px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28360289"
|
||||
id="text28">
|
||||
<path
|
||||
d="m 263.92661,-940.82233 1.26562,-10.48359 h 1.36055 q 0.42187,0 0.66445,0.21094 0.24258,0.20039 0.23203,0.6539 l -0.0527,1.10743 q 0.75937,-1.07579 1.64531,-1.59258 0.88594,-0.52735 1.8668,-0.52735 1.04414,0 1.64531,0.65391 0.60117,0.64336 0.69609,1.8668 0.78047,-1.29727 1.74024,-1.90899 0.95976,-0.61172 2.09882,-0.61172 0.71719,0 1.25508,0.26368 0.53789,0.26367 0.87539,0.76992 0.34805,0.50625 0.46407,1.24453 0.12656,0.73828 0.0105,1.6875 l -0.78047,6.66562 h -2.63672 l 0.78047,-6.66562 q 0.12657,-0.97031 -0.0844,-1.37109 -0.20039,-0.41133 -0.8332,-0.41133 -0.41133,0 -0.82266,0.21093 -0.40078,0.2004 -0.75938,0.59063 -0.35859,0.39023 -0.66445,0.95977 -0.30586,0.55898 -0.52734,1.26562 v 0.0105 l -0.62227,5.41054 h -2.64726 l 0.78047,-6.66562 q 0.12656,-0.95977 -0.0633,-1.37109 -0.18984,-0.41133 -0.82265,-0.41133 -0.44297,0 -0.86485,0.22148 -0.41132,0.22149 -0.76992,0.64336 -0.35859,0.41133 -0.66445,1.00195 -0.30586,0.58008 -0.52734,1.30782 l -0.61172,5.27343 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path917"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 285.32621,-951.29537 -1.25508,10.47304 h -2.63671 l 1.25507,-10.47304 z m 0.63282,-3.00586 q 0,0.3375 -0.14766,0.64336 -0.13711,0.29531 -0.37969,0.52734 -0.23203,0.22149 -0.53789,0.35859 -0.29531,0.12657 -0.61172,0.12657 -0.30586,0 -0.60117,-0.12657 -0.28477,-0.1371 -0.50625,-0.35859 -0.22148,-0.23203 -0.35859,-0.52734 -0.13711,-0.30586 -0.13711,-0.64336 0,-0.3375 0.13711,-0.64336 0.13711,-0.30586 0.35859,-0.52735 0.23203,-0.23203 0.5168,-0.36914 0.29531,-0.1371 0.61172,-0.1371 0.3164,0 0.61171,0.1371 0.30586,0.12657 0.5379,0.3586 0.23203,0.23203 0.36914,0.53789 0.13711,0.29531 0.13711,0.64336 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path919"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 286.57074,-940.82233 1.25508,-10.48359 h 1.36055 q 0.43242,0 0.66445,0.21094 0.24258,0.20039 0.22149,0.6539 l -0.0527,1.25508 q 0.82266,-1.14961 1.81406,-1.70859 0.99141,-0.55899 2.0461,-0.55899 0.675,0 1.21289,0.26368 0.54844,0.26367 0.89648,0.76992 0.3586,0.50625 0.49571,1.24453 0.14765,0.73828 0.0316,1.6875 l -0.78047,6.66562 h -2.67891 l 0.79102,-6.66562 q 0.11601,-0.97031 -0.12657,-1.37109 -0.23203,-0.41133 -0.86484,-0.41133 -0.43242,0 -0.88594,0.24258 -0.45351,0.24257 -0.87539,0.68554 -0.41133,0.44297 -0.75937,1.07578 -0.3375,0.62227 -0.53789,1.39219 l -0.54844,5.05195 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path921"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 302.03246,-951.29537 -1.25508,10.47304 h -2.63671 l 1.25507,-10.47304 z m 0.63281,-3.00586 q 0,0.3375 -0.14765,0.64336 -0.13711,0.29531 -0.37969,0.52734 -0.23203,0.22149 -0.53789,0.35859 -0.29531,0.12657 -0.61172,0.12657 -0.30586,0 -0.60117,-0.12657 -0.28477,-0.1371 -0.50625,-0.35859 -0.22148,-0.23203 -0.35859,-0.52734 -0.13711,-0.30586 -0.13711,-0.64336 0,-0.3375 0.13711,-0.64336 0.13711,-0.30586 0.35859,-0.52735 0.23203,-0.23203 0.5168,-0.36914 0.29531,-0.1371 0.61172,-0.1371 0.3164,0 0.61171,0.1371 0.30586,0.12657 0.53789,0.3586 0.23204,0.23203 0.36915,0.53789 0.1371,0.29531 0.1371,0.64336 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path923"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 303.86762,-948.04694 h 4.93593 l -0.27421,2.15157 h -4.92539 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path925"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 309.99535,-940.82233 1.82461,-15.15585 h 2.62617 l -0.82265,6.69726 q 0.75937,-1.00195 1.67695,-1.58203 0.92812,-0.59063 1.97226,-0.59063 0.68555,0 1.23399,0.24258 0.55898,0.23203 0.94922,0.71719 0.40078,0.48516 0.61172,1.23398 0.22148,0.73829 0.22148,1.75079 0,1.33945 -0.42188,2.58398 -0.41132,1.23398 -1.12851,2.1832 -0.71719,0.94922 -1.67695,1.51875 -0.94922,0.55899 -2.025,0.55899 -0.83321,0 -1.48711,-0.31641 -0.64336,-0.31641 -1.08633,-0.8543 l -0.0844,0.28477 q -0.11601,0.36914 -0.30586,0.54844 -0.18984,0.17929 -0.63281,0.17929 z m 6.24375,-8.54296 q -0.42187,0 -0.86484,0.28476 -0.43243,0.28477 -0.84375,0.78047 -0.40078,0.48516 -0.74883,1.14961 -0.34805,0.66445 -0.59063,1.42383 l -0.29531,2.41523 q 0.35859,0.3375 0.81211,0.48516 0.45352,0.13711 0.89648,0.13711 0.675,0 1.23399,-0.40078 0.55898,-0.40079 0.94922,-1.04415 0.40078,-0.6539 0.61172,-1.46601 0.22148,-0.81211 0.22148,-1.64531 0,-1.08633 -0.36914,-1.60313 -0.35859,-0.51679 -1.0125,-0.51679 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path927"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 330.9309,-948.77467 q 0,0.69609 -0.31641,1.27617 -0.30586,0.56953 -1.09687,1.0336 -0.79102,0.45351 -2.16211,0.78046 -1.36055,0.32696 -3.45938,0.5168 0,1.24453 0.58008,1.8457 0.59062,0.59063 1.79297,0.59063 0.75937,0 1.24453,-0.16875 0.4957,-0.16875 0.84375,-0.36914 0.34805,-0.21094 0.61172,-0.37969 0.27422,-0.16875 0.60117,-0.16875 0.28477,0 0.48516,0.23203 l 0.69609,0.82266 q -0.59063,0.54844 -1.14961,0.94922 -0.55898,0.39023 -1.16016,0.6539 -0.59062,0.25313 -1.25507,0.36914 -0.65391,0.12657 -1.42383,0.12657 -1.0125,0 -1.8457,-0.31641 -0.82266,-0.31641 -1.41329,-0.89648 -0.58007,-0.59063 -0.90703,-1.40274 -0.3164,-0.82265 -0.3164,-1.83515 0,-1.23399 0.42187,-2.37305 0.43242,-1.14961 1.21289,-2.025 0.79102,-0.87539 1.89844,-1.40274 1.11797,-0.52734 2.49961,-0.52734 0.90703,0 1.58203,0.24258 0.68555,0.23203 1.12852,0.62226 0.45351,0.37969 0.675,0.8543 0.23203,0.47461 0.23203,0.94922 z m -3.74414,-0.81211 q -0.56953,0 -1.06524,0.20039 -0.48515,0.18985 -0.87539,0.54844 -0.39023,0.34805 -0.675,0.8543 -0.28476,0.4957 -0.45351,1.09687 1.41328,-0.16875 2.27812,-0.35859 0.86484,-0.20039 1.33945,-0.42188 0.47461,-0.23203 0.63282,-0.48515 0.1582,-0.26368 0.1582,-0.55899 0,-0.1582 -0.0738,-0.30586 -0.0738,-0.1582 -0.24258,-0.28476 -0.1582,-0.12657 -0.41132,-0.20039 -0.25313,-0.0844 -0.61172,-0.0844 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path929"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 335.9934,-951.29537 -1.25508,10.47304 h -2.63672 l 1.25508,-10.47304 z m 0.63281,-3.00586 q 0,0.3375 -0.14766,0.64336 -0.13711,0.29531 -0.37969,0.52734 -0.23203,0.22149 -0.53789,0.35859 -0.29531,0.12657 -0.61171,0.12657 -0.30586,0 -0.60118,-0.12657 -0.28476,-0.1371 -0.50625,-0.35859 -0.22148,-0.23203 -0.35859,-0.52734 -0.13711,-0.30586 -0.13711,-0.64336 0,-0.3375 0.13711,-0.64336 0.13711,-0.30586 0.35859,-0.52735 0.23203,-0.23203 0.5168,-0.36914 0.29531,-0.1371 0.61172,-0.1371 0.31641,0 0.61172,0.1371 0.30586,0.12657 0.53789,0.3586 0.23203,0.23203 0.36914,0.53789 0.13711,0.29531 0.13711,0.64336 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path931"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 346.87777,-948.77467 q 0,0.69609 -0.3164,1.27617 -0.30586,0.56953 -1.09688,1.0336 -0.79101,0.45351 -2.16211,0.78046 -1.36054,0.32696 -3.45937,0.5168 0,1.24453 0.58008,1.8457 0.59062,0.59063 1.79296,0.59063 0.75938,0 1.24454,-0.16875 0.4957,-0.16875 0.84375,-0.36914 0.34804,-0.21094 0.61171,-0.37969 0.27422,-0.16875 0.60118,-0.16875 0.28476,0 0.48515,0.23203 l 0.6961,0.82266 q -0.59063,0.54844 -1.14961,0.94922 -0.55899,0.39023 -1.16016,0.6539 -0.59062,0.25313 -1.25508,0.36914 -0.6539,0.12657 -1.42383,0.12657 -1.01249,0 -1.8457,-0.31641 -0.82265,-0.31641 -1.41328,-0.89648 -0.58008,-0.59063 -0.90703,-1.40274 -0.31641,-0.82265 -0.31641,-1.83515 0,-1.23399 0.42188,-2.37305 0.43242,-1.14961 1.21289,-2.025 0.79101,-0.87539 1.89844,-1.40274 1.11796,-0.52734 2.49961,-0.52734 0.90703,0 1.58203,0.24258 0.68554,0.23203 1.12851,0.62226 0.45352,0.37969 0.675,0.8543 0.23203,0.47461 0.23203,0.94922 z m -3.74414,-0.81211 q -0.56953,0 -1.06523,0.20039 -0.48516,0.18985 -0.87539,0.54844 -0.39024,0.34805 -0.675,0.8543 -0.28477,0.4957 -0.45352,1.09687 1.41328,-0.16875 2.27813,-0.35859 0.86484,-0.20039 1.33945,-0.42188 0.47461,-0.23203 0.63281,-0.48515 0.15821,-0.26368 0.15821,-0.55899 0,-0.1582 -0.0738,-0.30586 -0.0738,-0.1582 -0.24258,-0.28476 -0.1582,-0.12657 -0.41133,-0.20039 -0.25312,-0.0844 -0.61172,-0.0844 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path933"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 348.00629,-940.82233 1.82461,-15.15585 h 2.64726 l -1.83515,15.15585 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path935"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 357.25589,-951.29537 -1.25508,10.47304 h -2.63671 l 1.25507,-10.47304 z m 0.63282,-3.00586 q 0,0.3375 -0.14766,0.64336 -0.13711,0.29531 -0.37969,0.52734 -0.23203,0.22149 -0.53789,0.35859 -0.29531,0.12657 -0.61172,0.12657 -0.30586,0 -0.60117,-0.12657 -0.28477,-0.1371 -0.50625,-0.35859 -0.22148,-0.23203 -0.35859,-0.52734 -0.13711,-0.30586 -0.13711,-0.64336 0,-0.3375 0.13711,-0.64336 0.13711,-0.30586 0.35859,-0.52735 0.23203,-0.23203 0.5168,-0.36914 0.29531,-0.1371 0.61172,-0.1371 0.3164,0 0.61171,0.1371 0.30586,0.12657 0.5379,0.3586 0.23203,0.23203 0.36914,0.53789 0.13711,0.29531 0.13711,0.64336 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path937"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 358.85902,-942.26725 q 0,-0.32695 0.11602,-0.62226 0.12656,-0.29532 0.3375,-0.50625 0.22148,-0.21094 0.51679,-0.3375 0.29532,-0.12657 0.63282,-0.12657 0.3375,0 0.63281,0.12657 0.29531,0.12656 0.50625,0.3375 0.22148,0.21093 0.34805,0.50625 0.12656,0.29531 0.12656,0.62226 0,0.3375 -0.12656,0.63281 -0.12657,0.29532 -0.34805,0.50625 -0.21094,0.21094 -0.50625,0.32696 -0.29531,0.12656 -0.63281,0.12656 -0.3375,0 -0.63282,-0.12656 -0.29531,-0.11602 -0.51679,-0.32696 -0.21094,-0.21093 -0.3375,-0.50625 -0.11602,-0.29531 -0.11602,-0.63281 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path939"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 372.33793,-942.67858 q -0.5168,0.56953 -0.99141,0.95977 -0.46406,0.37969 -0.95977,0.62226 -0.4957,0.23204 -1.04414,0.32696 -0.53789,0.10547 -1.20234,0.10547 -0.91758,0 -1.64531,-0.30586 -0.71719,-0.31641 -1.22344,-0.88594 -0.4957,-0.58008 -0.76992,-1.38164 -0.26367,-0.81211 -0.26367,-1.81406 0,-0.8543 0.17929,-1.65586 0.18985,-0.81211 0.53789,-1.51875 0.34805,-0.70664 0.84375,-1.29727 0.49571,-0.60117 1.10742,-1.02304 0.62227,-0.42188 1.33946,-0.65391 0.72773,-0.24258 1.52929,-0.24258 1.05469,0 1.79297,0.36914 0.73828,0.3586 1.30782,1.10742 l -0.86485,1.00196 q -0.0844,0.11601 -0.21094,0.18984 -0.12656,0.0738 -0.27421,0.0738 -0.1793,0 -0.32696,-0.0949 -0.13711,-0.10547 -0.3164,-0.22149 -0.1793,-0.11601 -0.45352,-0.21094 -0.26367,-0.10546 -0.69609,-0.10546 -0.55899,0 -1.06524,0.30586 -0.50625,0.30585 -0.89648,0.86484 -0.39024,0.55898 -0.62227,1.35 -0.23203,0.79101 -0.23203,1.77187 0,1.11797 0.48516,1.71914 0.4957,0.59063 1.31836,0.59063 0.56953,0 0.92812,-0.1582 0.3586,-0.15821 0.61172,-0.34805 0.25313,-0.18984 0.45352,-0.34805 0.21093,-0.1582 0.46406,-0.1582 0.13711,0 0.25312,0.0633 0.12657,0.0633 0.22149,0.1793 l 0.68555,0.82265 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path941"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 373.26605,-940.82233 1.82461,-15.15585 h 2.67891 l -0.78047,6.3914 q 0.76992,-0.94922 1.66641,-1.40273 0.90703,-0.46407 1.85625,-0.46407 0.675,0 1.21289,0.26368 0.54843,0.26367 0.89648,0.76992 0.35859,0.50625 0.4957,1.24453 0.14766,0.73828 0.0316,1.6875 l -0.79101,6.66562 h -2.66836 l 0.78047,-6.66562 q 0.12656,-0.97031 -0.10547,-1.38164 -0.23203,-0.42188 -0.86484,-0.42188 -0.39024,0 -0.81211,0.22149 -0.41133,0.21094 -0.80157,0.61172 -0.39023,0.39023 -0.72773,0.94922 -0.3375,0.54843 -0.56953,1.23398 l -0.65391,5.45273 z"
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:21.59999847px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.28360289"
|
||||
id="path943"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="-29 -14 793.7008 1122.5197"
|
||||
version="1.1"
|
||||
id="svg869"
|
||||
sodipodi:docname="froncap-silk-screening.svg"
|
||||
inkscape:version="0.92.4 (unknown)">
|
||||
<metadata
|
||||
id="metadata875">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>OpenSCAD Model</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs873" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2089"
|
||||
id="namedview871"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.678367"
|
||||
inkscape:cx="396.85039"
|
||||
inkscape:cy="561.25984"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
units="mm">
|
||||
<sodipodi:guide
|
||||
position="13.227543,31.505603"
|
||||
orientation="0,1"
|
||||
id="guide1380"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<title
|
||||
id="title865">OpenSCAD Model</title>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Cut-Outs"
|
||||
style="display:inline"
|
||||
transform="translate(0,1094.5197)">
|
||||
<g
|
||||
id="g2635"
|
||||
transform="matrix(3.75,0,0,3.75,-567.45454,-477.12286)">
|
||||
<g
|
||||
transform="translate(237.60469,-134.81117)"
|
||||
id="g2623"
|
||||
style="display:inline">
|
||||
<path
|
||||
id="path2611"
|
||||
d="m 24.339244,-13.109364 0.283,0.0268 0.2808,0.0445 0.2774,0.062 0.273,0.0793 0.2674,0.0963 0.2609,0.1129 0.2533,0.129 0.2447,0.1447 0.2351,0.1598 0.2246,0.1742 0.2133,0.188 0.201,0.201 0.188,0.2133 0.1742,0.2246 0.1598,0.2351 0.1447,0.2447 0.129,0.2533 0.1129,0.2609 0.0963,0.2674097 0.0793,0.27298 0.062,0.27742 0.0445,0.28076 0.0268,0.28302 0.0089,0.28412 V 8.4867259 l -0.0089,0.28412 -0.0268,0.28302 -0.0445,0.28076 -0.062,0.27742 -0.0793,0.27298 -0.0963,0.2674101 -0.1129,0.2609 -0.129,0.2533 -0.1447,0.2447 -0.1598,0.2351 -0.1742,0.2246 -0.188,0.2133 -0.201,0.201 -0.2133,0.188 -0.2246,0.1742 -0.2351,0.1598 -0.2447,0.1447 -0.2533,0.129 -0.2609,0.1129 -0.2674,0.0963 -0.273,0.0793 -0.2774,0.062 -0.2808,0.0445 -0.283,0.0268 -0.2841,0.0089 h -48.08 l -0.2841,-0.0089 -0.283,-0.0268 -0.2808,-0.0445 -0.2774,-0.062 -0.273,-0.0793 -0.2674,-0.0963 -0.2609,-0.1129 -0.2533,-0.129 -0.2447,-0.1447 -0.2351,-0.1598 -0.2246,-0.1742 -0.2133,-0.188 -0.201,-0.201 -0.188,-0.2133 -0.1742,-0.2246 -0.1598,-0.2351 -0.1447,-0.2447 -0.129,-0.2533 -0.1129,-0.2609 -0.0963,-0.2674101 -0.0793,-0.27298 -0.062,-0.27742 -0.0445,-0.28076 -0.0268,-0.28302 -0.0089,-0.28412 V -8.5932543 l 0.0089,-0.28412 0.0268,-0.28302 0.0445,-0.28076 0.062,-0.27742 0.0793,-0.27298 0.0963,-0.2674097 0.1129,-0.2609 0.129,-0.2533 0.1447,-0.2447 0.1598,-0.2351 0.1742,-0.2246 0.188,-0.2133 0.201,-0.201 0.2133,-0.188 0.2246,-0.1742 0.2351,-0.1598 0.2447,-0.1447 0.2533,-0.129 0.2609,-0.1129 0.2674,-0.0963 0.273,-0.0793 0.2774,-0.062 0.2808,-0.0445 0.283,-0.0268 0.2841,-0.0089 h 48.08 z m -44.7741,3.7561097 V 4.2467259 h 9.2 V -9.3532543 Z m 36.2459,6.05641 -0.2032,0.01921 -0.2017,0.03194 -0.1992,0.04454 -0.1961,0.05696 -0.1921,0.06917 -0.1874,0.08109 -0.1819,0.09268 -0.1757,0.10393 -0.1689,0.11476 -0.1613,0.12513 -0.1532,0.13503 -0.1444,0.14436 -0.135,0.15316 -0.1251,0.16133 -0.1148,0.16887 -0.1039,0.17573 -0.0927,0.18192 -0.0811,0.18737 -0.0691,0.1920999 -0.057,0.19607205 -0.0445,0.19925 -0.032,0.20166 -0.0192,0.203262 -0.0064,0.204056 0.0064,0.204056 0.0192,0.203262 0.032,0.20166 0.0445,0.19925 0.057,0.19607205 0.0691,0.1921002 0.0811,0.18737 0.0927,0.18192 0.1039,0.17573 0.1148,0.16887 0.1251,0.16133 0.135,0.15316 0.1444,0.14436 0.1532,0.13503 0.1613,0.12513 0.1689,0.11476 0.1757,0.10393 0.1819,0.09268 0.1874,0.08109 0.1921,0.06917 0.1961,0.05696 0.1992,0.04454 0.2017,0.03194 0.2032,0.01921 0.2041,0.00642 0.2041,-0.00642 0.2032,-0.01921 0.2017,-0.03194 0.1992,-0.04454 0.1961,-0.05696 0.1921,-0.06917 0.1874,-0.08109 0.1819,-0.09268 0.1757,-0.10393 0.1689,-0.11476 0.1613,-0.12513 0.1532,-0.13503 0.1443,-0.14436 0.1351,-0.15316 0.1251,-0.16133 0.1148,-0.16887 0.1039,-0.17573 0.0927,-0.18192 0.0811,-0.18737 0.0691,-0.1921002 0.057,-0.19607205 0.0445,-0.19925 0.032,-0.20166 0.0192,-0.203262 0.0064,-0.204056 -0.0064,-0.204056 -0.0192,-0.203262 -0.032,-0.20166 -0.0445,-0.19925 -0.057,-0.19607205 -0.0691,-0.1920999 -0.0811,-0.18737 -0.0927,-0.18192 -0.1039,-0.17573 -0.1148,-0.16887 -0.1251,-0.16133 -0.1351,-0.15316 -0.1443,-0.14436 -0.1532,-0.13503 -0.1613,-0.12513 -0.1689,-0.11476 -0.1757,-0.10393 -0.1819,-0.09268 -0.1874,-0.08109 -0.1921,-0.06917 -0.1961,-0.05696 -0.1992,-0.04454 -0.2017,-0.03194 -0.2032,-0.01921 -0.2041,-0.0064 z M -3.9848564,-0.65325535 V 2.5467259 h 8 v -3.19998125 z m -20.1945996,-1.30123895 -0.1192,0.01126 -0.1182,0.01872 -0.1168,0.02611 -0.1149,0.03339 -0.1126,0.04054 -0.1098,0.04752 -0.1066,0.05433 -0.103,0.06092 -0.099,0.06727 -0.0946,0.07335 -0.0898,0.07915 -0.0846,0.08461 -0.0791,0.08978 -0.0734,0.09456 -0.0672,0.09898 -0.061,0.103 -0.0543,0.106644 -0.0475,0.109833 -0.0405,0.112594 -0.0335,0.114929 -0.026,0.116791 -0.0188,0.118195 -0.0112,0.11914 -0.0038,0.119614 0.0038,0.119614 0.0112,0.11914 0.0188,0.118195 0.026,0.116791 0.0335,0.114929 0.0405,0.112594 0.0475,0.109833 0.0543,0.106644 0.061,0.10300005 0.0672,0.0989799 0.0734,0.09456 0.0791,0.08978 0.0846,0.08461 0.0898,0.07915 0.0946,0.07335 0.099,0.06727 0.103,0.06092 0.1066,0.05433 0.1098,0.04752 0.1126,0.04054 0.1149,0.03339 0.1168,0.02611 0.1182,0.01872 0.1192,0.01126 0.1196,0.00377 0.1196,-0.00377 0.1192,-0.01126 0.1182,-0.01872 0.1168,-0.02611 0.1149,-0.03339 0.1126,-0.04054 0.1098,-0.04752 0.1066,-0.05433 0.1031,-0.06092 0.0989,-0.06727 0.0946,-0.07335 0.0898,-0.07915 0.0846,-0.08461 0.0791,-0.08978 0.0734,-0.09456 0.0672,-0.0989799 0.061,-0.10300005 0.0543,-0.106644 0.0475,-0.109833 0.0406,-0.112594 0.0334,-0.114929 0.0261,-0.116791 0.0187,-0.118195 0.0112,-0.11914 0.0038,-0.119614 -0.0038,-0.119614 -0.0112,-0.11914 -0.0187,-0.118195 -0.0261,-0.116791 -0.0334,-0.114929 -0.0406,-0.112594 -0.0475,-0.109833 -0.0543,-0.106644 -0.061,-0.103 -0.0672,-0.09898 -0.0734,-0.09456 -0.0791,-0.08978 -0.0846,-0.08461 -0.0898,-0.07915 -0.0946,-0.07335 -0.0989,-0.06727 -0.1031,-0.06092 -0.1066,-0.05433 -0.1098,-0.04752 -0.1126,-0.04054 -0.1149,-0.03339 -0.1168,-0.02611 -0.1182,-0.01872 -0.1192,-0.01126 -0.1196,-0.0038 z m 48.15,0 -0.1192,0.01126 -0.1182,0.01872 -0.1168,0.02611 -0.1149,0Line truncated
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#d3d3d3;stroke:#000000;stroke-width:0.5" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="85.396912"
|
||||
y="-809.41943"
|
||||
id="text826"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan824"
|
||||
x="85.396912"
|
||||
y="-809.41943">Logo and Text Color: </tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="85.396912"
|
||||
y="-709.87256"
|
||||
id="tspan828"
|
||||
style="font-size:96px;fill:#442f29;fill-opacity:1;stroke:#442f29;stroke-opacity:1">RAL 8017</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="541.79291"
|
||||
y="-716.47192"
|
||||
id="text832"><tspan
|
||||
sodipodi:role="line"
|
||||
x="541.79291"
|
||||
y="-681.0813"
|
||||
id="tspan834" /></text>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot838"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
transform="translate(-29,-1108.5197)"><flowRegion
|
||||
id="flowRegion840"><rect
|
||||
id="rect842"
|
||||
width="483.20779"
|
||||
height="215.68584"
|
||||
x="131.67561"
|
||||
y="589.85907" /></flowRegion><flowPara
|
||||
id="flowPara844"
|
||||
style="font-size:32px">nbit Informatik GmbH</flowPara><flowPara
|
||||
id="flowPara846"
|
||||
style="font-size:32px">joerg.lehmann@nbit.ch</flowPara><flowPara
|
||||
id="flowPara848"
|
||||
style="font-size:32px">25.4.2019</flowPara></flowRoot> <flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot850"
|
||||
style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"><flowRegion
|
||||
id="flowRegion852"><rect
|
||||
id="rect854"
|
||||
width="107.84292"
|
||||
height="85.201866"
|
||||
x="132.86725"
|
||||
y="604.75452" /></flowRegion><flowPara
|
||||
id="flowPara856"></flowPara></flowRoot> </g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Silk-Screening"
|
||||
style="display:inline"
|
||||
transform="translate(0,1094.5197)">
|
||||
<text
|
||||
transform="matrix(3.75,0,0,3.75,-567.45454,-477.12286)"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:export-xdpi="96"
|
||||
id="text28"
|
||||
y="-124.18652"
|
||||
x="221.54695"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.02509713px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.07562744"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.75999975px;font-family:Carlito;-inkscape-font-specification:'Carlito Bold Italic';fill:#483737;fill-opacity:1;stroke-width:0.07562744"
|
||||
y="-124.18652"
|
||||
x="221.54695"
|
||||
id="tspan26"
|
||||
sodipodi:role="line">mini-beieli.ch</tspan></text>
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="matrix(3.0001287,0,0,2.999999,380.29972,-988.15178)"
|
||||
id="g2767">
|
||||
<path
|
||||
style="opacity:1;fill:#483737;fill-opacity:1;stroke:#483737;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m -18.884842,-11.733974 c -0.287789,-0.0051 -0.58446,0.139178 -1.119844,0.448281 l -1.093125,0.63125 -1.093281,0.631094 c -0.999754,0.5772086 -1.093125,0.6571766 -1.093125,1.8935936 v 1.262343 1.262188 c 0,1.154413 0.02236,1.275387 1.093125,1.893593 l 1.093281,0.631094 1.093125,0.63125 c 0.999755,0.577209 1.11564,0.61821 2.186406,0 l 1.093281,-0.63125 1.093126,-0.631094 c 0.999755,-0.577206 1.09328,-0.657177 1.09328,-1.893593 v -1.262188 -1.262343 c 0,-1.154419 -0.02236,-1.275387 -1.093124,-1.8935936 l -1.093282,-0.631094 -1.093281,-0.63125 c -0.499876,-0.288605 -0.778773,-0.443156 -1.066562,-0.448281 z m -0.08609,2.6271866 c 0.913697,0 1.786912,0.185688 2.580625,0.521407 a 0.60303098,0.60303098 0 1 1 -0.469531,1.110156 c -0.648533,-0.274315 -1.360331,-0.425781 -2.111094,-0.425781 -0.750752,0 -1.462718,0.151466 -2.11125,0.425781 a 0.60303098,0.60303098 0 1 1 -0.470156,-1.110156 c 0.793712,-0.335719 1.667717,-0.521407 2.581406,-0.521407 z m 0,1.672969 c 0.682741,0 1.336262,0.138777 1.929844,0.389844 a 0.60303099,0.60303099 0 1 1 -0.47,1.110156 c -0.448409,-0.189663 -0.940039,-0.294062 -1.459844,-0.294062 -0.519796,0 -1.012057,0.104399 -1.460469,0.294062 a 0.60303099,0.60303099 0 1 1 -0.469531,-1.110156 c 0.593583,-0.251067 1.247266,-0.389844 1.93,-0.389844 z m 0,1.674844 c 0.451487,0 0.884776,0.09166 1.277969,0.257969 a 0.60316438,0.60316438 0 1 1 -0.470157,1.110937 c -0.248028,-0.104907 -0.519265,-0.162969 -0.807812,-0.162969 -0.288534,0 -0.560553,0.05806 -0.808594,0.162969 a 0.603031,0.603031 0 1 1 -0.469375,-1.110937 c 0.393196,-0.166303 0.82649,-0.257969 1.277969,-0.257969 z"
|
||||
id="path815"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#fc0ff0;fill-opacity:0;stroke:#483737;stroke-width:0.87777525;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -20.82565,-10.34361 -0.548609,-1.097221"
|
||||
id="path899"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#483737;stroke-width:0.87777525;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -16.985383,-10.34361 0.548609,-1.097221"
|
||||
id="path899-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="58"
|
||||
height="28"
|
||||
viewBox="-29 -14 58 28"
|
||||
version="1.1"
|
||||
id="svg902"
|
||||
sodipodi:docname="endcap-front.svg"
|
||||
inkscape:version="0.92.4 (unknown)">
|
||||
<metadata
|
||||
id="metadata908">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>OpenSCAD Model</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs906" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
id="namedview904"
|
||||
showgrid="false"
|
||||
inkscape:zoom="33.051724"
|
||||
inkscape:cx="29"
|
||||
inkscape:cy="14"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg902" />
|
||||
<title
|
||||
id="title898">OpenSCAD Model</title>
|
||||
<path
|
||||
d="m -24.3241,-13.0561 -0.283,0.0268 -0.2808,0.0445 -0.2774,0.062 -0.273,0.0793 -0.2674,0.0963 -0.2609,0.1129 -0.2533,0.129 -0.2447,0.1447 -0.2351,0.1598 -0.2246,0.1742 -0.2133,0.188 -0.201,0.201 -0.188,0.2133 -0.1742,0.2246 -0.1598,0.2351 -0.1447,0.2447 -0.129,0.2533 -0.1129,0.2609 -0.0963,0.26741 -0.0793,0.27298 -0.062,0.27742 -0.0445,0.28076 -0.0268,0.28302 -0.0089,0.28412 V 8.53999 l 0.0089,0.28412 0.0268,0.28302 0.0445,0.28076 0.062,0.27742 0.0793,0.27298 0.0963,0.26741 0.1129,0.2609 0.129,0.2533 0.1447,0.2447 0.1598,0.2351 0.1742,0.2246 0.188,0.2133 0.201,0.201 0.2133,0.188 0.2246,0.1742 0.2351,0.1598 0.2447,0.1447 0.2533,0.129 0.2609,0.1129 0.2674,0.0963 0.273,0.0793 0.2774,0.062 0.2808,0.0445 0.283,0.0268 0.2841,0.0089 h 48.08 l 0.2841,-0.0089 0.283,-0.0268 0.2808,-0.0445 0.2774,-0.062 0.273,-0.0793 0.2674,-0.0963 0.2609,-0.1129 0.2533,-0.129 0.2447,-0.1447 0.2351,-0.1598 0.2246,-0.1742 0.2133,-0.188 0.201,-0.201 0.188,-0.2133 0.1742,-0.2246 0.1598,-0.2351 0.1447,-0.2447 0.129,-0.2533 0.1129,-0.2609 0.0963,-0.26741 0.0793,-0.27298 0.062,-0.27742 0.0445,-0.28076 0.0268,-0.28302 0.0089,-0.28412 V -8.53999 l -0.0089,-0.28412 -0.0268,-0.28302 -0.0445,-0.28076 -0.062,-0.27742 -0.0793,-0.27298 -0.0963,-0.26741 -0.1129,-0.2609 -0.129,-0.2533 -0.1447,-0.2447 -0.1598,-0.2351 -0.1742,-0.2246 -0.188,-0.2133 -0.201,-0.201 -0.2133,-0.188 -0.2246,-0.1742 -0.2351,-0.1598 -0.2447,-0.1447 -0.2533,-0.129 -0.2609,-0.1129 -0.2674,-0.0963 -0.273,-0.0793 -0.2774,-0.062 -0.2808,-0.0445 -0.283,-0.0268 L 24.04,-13.065 H -24.04 Z M 4.5,0.5 V 5 h -9 V 0.5 Z m -20.2959,-3.74358 0.2032,0.01921 0.2017,0.03194 0.1992,0.04454 0.1961,0.05696 0.1921,0.06917 0.1874,0.08109 0.1819,0.09268 0.1757,0.10393 0.1689,0.11476 0.1613,0.12513 0.1532,0.13503 0.1444,0.14436 0.135,0.15316 0.1251,0.16133 0.1148,0.16887 0.1039,0.17573 0.0927,0.18192 0.0811,0.18737 0.0691,0.1921 0.057,0.196072 0.0445,0.19925 0.032,0.20166 0.0192,0.203262 L -12.75,0 l -0.0064,0.204056 -0.0192,0.203262 -0.032,0.20166 -0.0445,0.19925 -0.057,0.196072 -0.0691,0.1921 -0.0811,0.18737 -0.0927,0.18192 -0.1039,0.17573 -0.1148,0.16887 -0.1251,0.16133 -0.135,0.15316 -0.1444,0.14436 -0.1532,0.13503 -0.1613,0.12513 -0.1689,0.11476 -0.1757,0.10393 -0.1819,0.09268 -0.1874,0.08109 -0.1921,0.06917 -0.1961,0.05696 -0.1992,0.04454 -0.2017,0.03194 -0.2032,0.01921 L -16,3.25 -16.2041,3.24358 -16.4073,3.22437 -16.609,3.19243 -16.8082,3.14789 -17.0043,3.09093 -17.1964,3.02176 -17.3838,2.94067 -17.5657,2.84799 -17.7414,2.74406 -17.9103,2.6293 -18.0716,2.50417 -18.2248,2.36914 -18.3691,2.22478 -18.5042,2.07162 -18.6293,1.91029 -18.7441,1.74142 -18.848,1.56569 -18.9407,1.38377 -19.0218,1.1964 -19.0909,1.0043 -19.1479,0.808228 -19.1924,0.608978 -19.2244,0.407318 -19.2436,0.204056 -19.25,0 l 0.0064,-0.204056 0.0192,-0.203262 0.032,-0.20166 0.0445,-0.19925 0.057,-0.196072 0.0691,-0.1921 0.0811,-0.18737 0.0927,-0.18192 0.1039,-0.17573 0.1148,-0.16887 0.1251,-0.16133 0.1351,-0.15316 0.1443,-0.14436 0.1532,-0.13503 0.1613,-0.12513 0.1689,-0.11476 0.1757,-0.10393 0.1819,-0.09268 0.1874,-0.08109 0.1921,-0.06917 0.1961,-0.05696 0.1992,-0.04454 0.2017,-0.03194 0.2032,-0.01921 L -16,-3.25 Z m 30.1501,2.346546 0.0938,0.008866 0.0931,0.01474 0.0919,0.020569 0.0905,0.026275 0.0887,0.031922 0.0865,0.037429 0.0839,0.042786 0.0811,0.047958 0.078,0.052964 0.0744,0.057769 0.0707,0.062317 0.0666,0.06662 0.0624,0.070694 0.0577,0.074448 0.053,0.077942 0.0479,0.081115 0.0428,0.0839542 0.0375,0.0864716 0.0319,0.0886692 0.0263,0.090484 0.0205,0.091965 0.0148,0.093063 0.0088,0.093827 0.003,0.094177 -0.003,0.094192 -0.0088,0.093811 -0.0148,0.093064 -0.0205,0.091964 -0.0263,0.090498 -0.0319,0.08866 -0.0375,0.08648 -0.0428,0.08396 -0.0479,0.08111 -0.053,0.07794 -0.0577,0.07445 -0.0624,0.0707 -0.0666,0.06663 -0.0707,0.06232 -0.0744,0.05775 -0.078,0.05297 L 14.9826,1.91446 14.8987,1.95723 14.8122,1.99466 14.7235,2.02658 14.633,2.05287 14.5411,2.07343 14.448,2.08817 14.3542,2.09703 14.26,2.09999 14.1658,2.09703 14.072,2.08817 13.9789,2.07343 13.887,2.05287 13.7965,2.02658 13.7078,1.99466 13.6213,1.95723 13.5374,1.91446 13.4563,1.86649 13.3783,1.81352 13.3039,1.75577 13.2332,1.69345 13.1665,1.62682 13.1042,1.55612 13.0465,1.48167 12.9935,1.40373 12.9455,1.32262 12.9028,1.23866 12.8653,1.15218 12.8334,1.06352 12.8071,0.973022 12.7866,0.881058 12.7718,0.787994 12.763,0.694183 12.76,0.599991 l 0.003,-0.094177 0.0088,-0.093827 0.0148,-0.093063 0.0205,-0.091965 0.0263,-0.090484 0.0319,-0.0886692 0.0375,-0.0864716 0.0427,-0.0839542 0.048,-0.081115 0.053,-0.077942 0.0577,-0.074448 0.0623,-0.070694 0.0667,-0.06662 0.0707,-0.062317 0.0744,-0.057769 0.078,-0.052964 0.0811,-0.047958 0.0839,-0.042786 0.0865,-0.037429 0.0887,-0.031922 0.0905,-0.026275 0.0919,-0.020569 0.0931,-0.01474 0.0938,-0.008866 0.0942,-0.00296 z m 9.8404,-1.004196 0.1192,0.01126 0.1182,0.01872 0.1168,0.02611 0.1149,0.03339 0.1126,0.04054 0.1098,0.04752 0.1066,0.05433 0.103,0.06092 0.099,0.06727 0.0946,0.07335 0.0898,0.07915 0.0846,0.08461 0.0791,0.08978 0.0734Line truncated
|
||||
id="path900"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#d3d3d3;stroke:#000000;stroke-width:0.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="58"
|
||||
height="28"
|
||||
viewBox="-29 -14 58 28"
|
||||
version="1.1"
|
||||
id="svg902"
|
||||
sodipodi:docname="endcap-front.svg"
|
||||
inkscape:version="0.92.4 (unknown)">
|
||||
<metadata
|
||||
id="metadata908">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>OpenSCAD Model</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs906" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
id="namedview904"
|
||||
showgrid="false"
|
||||
inkscape:zoom="33.051724"
|
||||
inkscape:cx="29"
|
||||
inkscape:cy="14"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg902" />
|
||||
<title
|
||||
id="title898">OpenSCAD Model</title>
|
||||
<path
|
||||
d="m -24.3241,-13.0561 -0.283,0.0268 -0.2808,0.0445 -0.2774,0.062 -0.273,0.0793 -0.2674,0.0963 -0.2609,0.1129 -0.2533,0.129 -0.2447,0.1447 -0.2351,0.1598 -0.2246,0.1742 -0.2133,0.188 -0.201,0.201 -0.188,0.2133 -0.1742,0.2246 -0.1598,0.2351 -0.1447,0.2447 -0.129,0.2533 -0.1129,0.2609 -0.0963,0.26741 -0.0793,0.27298 -0.062,0.27742 -0.0445,0.28076 -0.0268,0.28302 -0.0089,0.28412 V 8.53999 l 0.0089,0.28412 0.0268,0.28302 0.0445,0.28076 0.062,0.27742 0.0793,0.27298 0.0963,0.26741 0.1129,0.2609 0.129,0.2533 0.1447,0.2447 0.1598,0.2351 0.1742,0.2246 0.188,0.2133 0.201,0.201 0.2133,0.188 0.2246,0.1742 0.2351,0.1598 0.2447,0.1447 0.2533,0.129 0.2609,0.1129 0.2674,0.0963 0.273,0.0793 0.2774,0.062 0.2808,0.0445 0.283,0.0268 0.2841,0.0089 h 48.08 l 0.2841,-0.0089 0.283,-0.0268 0.2808,-0.0445 0.2774,-0.062 0.273,-0.0793 0.2674,-0.0963 0.2609,-0.1129 0.2533,-0.129 0.2447,-0.1447 0.2351,-0.1598 0.2246,-0.1742 0.2133,-0.188 0.201,-0.201 0.188,-0.2133 0.1742,-0.2246 0.1598,-0.2351 0.1447,-0.2447 0.129,-0.2533 0.1129,-0.2609 0.0963,-0.26741 0.0793,-0.27298 0.062,-0.27742 0.0445,-0.28076 0.0268,-0.28302 0.0089,-0.28412 V -8.53999 l -0.0089,-0.28412 -0.0268,-0.28302 -0.0445,-0.28076 -0.062,-0.27742 -0.0793,-0.27298 -0.0963,-0.26741 -0.1129,-0.2609 -0.129,-0.2533 -0.1447,-0.2447 -0.1598,-0.2351 -0.1742,-0.2246 -0.188,-0.2133 -0.201,-0.201 -0.2133,-0.188 -0.2246,-0.1742 -0.2351,-0.1598 -0.2447,-0.1447 -0.2533,-0.129 -0.2609,-0.1129 -0.2674,-0.0963 -0.273,-0.0793 -0.2774,-0.062 -0.2808,-0.0445 -0.283,-0.0268 L 24.04,-13.065 H -24.04 Z M 4.5,0.5 V 5 h -9 V 0.5 Z m -20.2959,-3.74358 0.2032,0.01921 0.2017,0.03194 0.1992,0.04454 0.1961,0.05696 0.1921,0.06917 0.1874,0.08109 0.1819,0.09268 0.1757,0.10393 0.1689,0.11476 0.1613,0.12513 0.1532,0.13503 0.1444,0.14436 0.135,0.15316 0.1251,0.16133 0.1148,0.16887 0.1039,0.17573 0.0927,0.18192 0.0811,0.18737 0.0691,0.1921 0.057,0.196072 0.0445,0.19925 0.032,0.20166 0.0192,0.203262 L -12.75,0 l -0.0064,0.204056 -0.0192,0.203262 -0.032,0.20166 -0.0445,0.19925 -0.057,0.196072 -0.0691,0.1921 -0.0811,0.18737 -0.0927,0.18192 -0.1039,0.17573 -0.1148,0.16887 -0.1251,0.16133 -0.135,0.15316 -0.1444,0.14436 -0.1532,0.13503 -0.1613,0.12513 -0.1689,0.11476 -0.1757,0.10393 -0.1819,0.09268 -0.1874,0.08109 -0.1921,0.06917 -0.1961,0.05696 -0.1992,0.04454 -0.2017,0.03194 -0.2032,0.01921 L -16,3.25 -16.2041,3.24358 -16.4073,3.22437 -16.609,3.19243 -16.8082,3.14789 -17.0043,3.09093 -17.1964,3.02176 -17.3838,2.94067 -17.5657,2.84799 -17.7414,2.74406 -17.9103,2.6293 -18.0716,2.50417 -18.2248,2.36914 -18.3691,2.22478 -18.5042,2.07162 -18.6293,1.91029 -18.7441,1.74142 -18.848,1.56569 -18.9407,1.38377 -19.0218,1.1964 -19.0909,1.0043 -19.1479,0.808228 -19.1924,0.608978 -19.2244,0.407318 -19.2436,0.204056 -19.25,0 l 0.0064,-0.204056 0.0192,-0.203262 0.032,-0.20166 0.0445,-0.19925 0.057,-0.196072 0.0691,-0.1921 0.0811,-0.18737 0.0927,-0.18192 0.1039,-0.17573 0.1148,-0.16887 0.1251,-0.16133 0.1351,-0.15316 0.1443,-0.14436 0.1532,-0.13503 0.1613,-0.12513 0.1689,-0.11476 0.1757,-0.10393 0.1819,-0.09268 0.1874,-0.08109 0.1921,-0.06917 0.1961,-0.05696 0.1992,-0.04454 0.2017,-0.03194 0.2032,-0.01921 L -16,-3.25 Z m 30.1501,2.346546 0.0938,0.008866 0.0931,0.01474 0.0919,0.020569 0.0905,0.026275 0.0887,0.031922 0.0865,0.037429 0.0839,0.042786 0.0811,0.047958 0.078,0.052964 0.0744,0.057769 0.0707,0.062317 0.0666,0.06662 0.0624,0.070694 0.0577,0.074448 0.053,0.077942 0.0479,0.081115 0.0428,0.0839542 0.0375,0.0864716 0.0319,0.0886692 0.0263,0.090484 0.0205,0.091965 0.0148,0.093063 0.0088,0.093827 0.003,0.094177 -0.003,0.094192 -0.0088,0.093811 -0.0148,0.093064 -0.0205,0.091964 -0.0263,0.090498 -0.0319,0.08866 -0.0375,0.08648 -0.0428,0.08396 -0.0479,0.08111 -0.053,0.07794 -0.0577,0.07445 -0.0624,0.0707 -0.0666,0.06663 -0.0707,0.06232 -0.0744,0.05775 -0.078,0.05297 L 14.9826,1.91446 14.8987,1.95723 14.8122,1.99466 14.7235,2.02658 14.633,2.05287 14.5411,2.07343 14.448,2.08817 14.3542,2.09703 14.26,2.09999 14.1658,2.09703 14.072,2.08817 13.9789,2.07343 13.887,2.05287 13.7965,2.02658 13.7078,1.99466 13.6213,1.95723 13.5374,1.91446 13.4563,1.86649 13.3783,1.81352 13.3039,1.75577 13.2332,1.69345 13.1665,1.62682 13.1042,1.55612 13.0465,1.48167 12.9935,1.40373 12.9455,1.32262 12.9028,1.23866 12.8653,1.15218 12.8334,1.06352 12.8071,0.973022 12.7866,0.881058 12.7718,0.787994 12.763,0.694183 12.76,0.599991 l 0.003,-0.094177 0.0088,-0.093827 0.0148,-0.093063 0.0205,-0.091965 0.0263,-0.090484 0.0319,-0.0886692 0.0375,-0.0864716 0.0427,-0.0839542 0.048,-0.081115 0.053,-0.077942 0.0577,-0.074448 0.0623,-0.070694 0.0667,-0.06662 0.0707,-0.062317 0.0744,-0.057769 0.078,-0.052964 0.0811,-0.047958 0.0839,-0.042786 0.0865,-0.037429 0.0887,-0.031922 0.0905,-0.026275 0.0919,-0.020569 0.0931,-0.01474 0.0938,-0.008866 0.0942,-0.00296 z m 9.8404,-1.004196 0.1192,0.01126 0.1182,0.01872 0.1168,0.02611 0.1149,0.03339 0.1126,0.04054 0.1098,0.04752 0.1066,0.05433 0.103,0.06092 0.099,0.06727 0.0946,0.07335 0.0898,0.07915 0.0846,0.08461 0.0791,0.08978 0.0734Line truncated
|
||||
id="path900"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#d3d3d3;stroke:#000000;stroke-width:0.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 470 KiB |
@@ -0,0 +1,4 @@
|
||||
|
||||
Uploaded
|
||||
|
||||
23 Apr 22:40
|
||||
@@ -0,0 +1,210 @@
|
||||
EESchema-LIBRARY Version 2.4
|
||||
#encoding utf-8
|
||||
#
|
||||
# Connector_Conn_01x02_Female
|
||||
#
|
||||
DEF Connector_Conn_01x02_Female J 0 40 Y N 1 F N
|
||||
F0 "J" 0 100 50 H V C CNN
|
||||
F1 "Connector_Conn_01x02_Female" 0 -200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
|
||||
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
|
||||
P 2 1 1 6 -50 -100 -20 -100 N
|
||||
P 2 1 1 6 -50 0 -20 0 N
|
||||
X Pin_1 1 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 -100 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Conn_01x03_Male
|
||||
#
|
||||
DEF Connector_Conn_01x03_Male J 0 40 Y N 1 F N
|
||||
F0 "J" 0 200 50 H V C CNN
|
||||
F1 "Connector_Conn_01x03_Male" 0 -200 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S 34 -95 0 -105 1 1 6 F
|
||||
S 34 5 0 -5 1 1 6 F
|
||||
S 34 105 0 95 1 1 6 F
|
||||
P 2 1 1 6 50 -100 34 -100 N
|
||||
P 2 1 1 6 50 0 34 0 N
|
||||
P 2 1 1 6 50 100 34 100 N
|
||||
X Pin_1 1 200 100 150 L 50 50 1 1 P
|
||||
X Pin_2 2 200 0 150 L 50 50 1 1 P
|
||||
X Pin_3 3 200 -100 150 L 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Conn_01x05_Female
|
||||
#
|
||||
DEF Connector_Conn_01x05_Female J 0 40 Y N 1 F N
|
||||
F0 "J" 0 300 50 H V C CNN
|
||||
F1 "Connector_Conn_01x05_Female" 0 -300 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*_1x??_*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
A 0 -200 20 901 -901 1 1 6 N 0 -180 0 -220
|
||||
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
|
||||
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
|
||||
A 0 100 20 901 -901 1 1 6 N 0 120 0 80
|
||||
A 0 200 20 901 -901 1 1 6 N 0 220 0 180
|
||||
P 2 1 1 6 -50 -200 -20 -200 N
|
||||
P 2 1 1 6 -50 -100 -20 -100 N
|
||||
P 2 1 1 6 -50 0 -20 0 N
|
||||
P 2 1 1 6 -50 100 -20 100 N
|
||||
P 2 1 1 6 -50 200 -20 200 N
|
||||
X Pin_1 1 -200 200 150 R 50 50 1 1 P
|
||||
X Pin_2 2 -200 100 150 R 50 50 1 1 P
|
||||
X Pin_3 3 -200 0 150 R 50 50 1 1 P
|
||||
X Pin_4 4 -200 -100 150 R 50 50 1 1 P
|
||||
X Pin_5 5 -200 -200 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# Connector_Generic_Conn_01x01
|
||||
#
|
||||
DEF Connector_Generic_Conn_01x01 J 0 40 Y N 1 F N
|
||||
F0 "J" 0 100 50 H V C CNN
|
||||
F1 "Connector_Generic_Conn_01x01" 0 -100 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
$FPLIST
|
||||
Connector*:*
|
||||
$ENDFPLIST
|
||||
DRAW
|
||||
S -50 5 0 -5 1 1 6 N
|
||||
S -50 50 50 -50 1 1 10 f
|
||||
X Pin_1 1 -200 0 150 R 50 50 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# MiscellaneousDevices_ADAFRUIT_FEATHER
|
||||
#
|
||||
DEF MiscellaneousDevices_ADAFRUIT_FEATHER U 0 40 Y Y 2 F N
|
||||
F0 "U" 200 -550 60 V V C CNN
|
||||
F1 "MiscellaneousDevices_ADAFRUIT_FEATHER" 200 250 60 V V C CNN
|
||||
F2 "" 150 -200 60 H V C CNN
|
||||
F3 "" 150 -200 60 H V C CNN
|
||||
DRAW
|
||||
S -150 650 150 -650 1 1 0 N
|
||||
S -150 800 150 -800 2 1 0 N
|
||||
X VBAT 17 -250 550 100 R 40 40 1 1 I
|
||||
X EN 18 -250 450 100 R 40 40 1 1 I
|
||||
X VBUS 19 -250 350 100 R 40 40 1 1 I
|
||||
X 13 20 -250 250 100 R 40 40 1 1 I
|
||||
X 12 21 -250 150 100 R 40 40 1 1 I
|
||||
X 11 22 -250 50 100 R 40 40 1 1 I
|
||||
X 10 23 -250 -50 100 R 40 40 1 1 I
|
||||
X 9 24 -250 -150 100 R 40 40 1 1 I
|
||||
X 6 25 -250 -250 100 R 40 40 1 1 I
|
||||
X 5 26 -250 -350 100 R 40 40 1 1 I
|
||||
X 3 27 -250 -450 100 R 40 40 1 1 I
|
||||
X 2 28 -250 -550 100 R 40 40 1 1 I
|
||||
X DIO1 1 -250 -750 100 R 40 40 2 1 I
|
||||
X A2 10 -250 150 100 R 40 40 2 1 I
|
||||
X A1 11 -250 250 100 R 40 40 2 1 I
|
||||
X A0 12 -250 350 100 R 40 40 2 1 I
|
||||
X GND 13 -250 450 100 R 40 40 2 1 I
|
||||
X AREF 14 -250 550 100 R 40 40 2 1 I
|
||||
X +3V3 15 -250 650 100 R 40 40 2 1 I
|
||||
X RST 16 -250 750 100 R 40 40 2 1 I
|
||||
X 1 2 -250 -650 100 R 40 40 2 1 I
|
||||
X 0 3 -250 -550 100 R 40 40 2 1 I
|
||||
X MISO 4 -250 -450 100 R 40 40 2 1 I
|
||||
X MOSI 5 -250 -350 100 R 40 40 2 1 I
|
||||
X SCK 6 -250 -250 100 R 40 40 2 1 I
|
||||
X A5 7 -250 -150 100 R 40 40 2 1 I
|
||||
X A4 8 -250 -50 100 R 40 40 2 1 I
|
||||
X A3 9 -250 50 100 R 40 40 2 1 I
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# SEN-13879_SEN-13879
|
||||
#
|
||||
DEF SEN-13879_SEN-13879 U 0 40 Y Y 1 L N
|
||||
F0 "U" -400 626 50 H V L BNN
|
||||
F1 "SEN-13879_SEN-13879" -400 -700 50 H V L BNN
|
||||
F2 "SPARKFUN_SEN-13879" 0 0 50 H I L BNN
|
||||
F3 "Load Cell Amp Hx711" 0 0 50 H I L BNN
|
||||
F4 "SparkFun" 0 0 50 H I L BNN
|
||||
F5 "Unavailable" 0 0 50 H I L BNN
|
||||
F6 "SEN-13879" 0 0 50 H I L BNN
|
||||
F7 "None" 0 0 50 H I L BNN
|
||||
F8 "None" 0 0 50 H I L BNN
|
||||
DRAW
|
||||
P 2 0 0 10 -400 -600 -400 600 N
|
||||
P 2 0 0 10 -400 600 400 600 N
|
||||
P 2 0 0 10 400 -600 -400 -600 N
|
||||
P 2 0 0 10 400 600 400 -600 N
|
||||
X RED 1 -500 300 100 R 40 40 0 0 B
|
||||
X VDD 10 500 500 100 L 40 40 0 0 W
|
||||
X B+ 11 -500 -300 100 R 40 40 0 0 I
|
||||
X B- 12 -500 -400 100 R 40 40 0 0 I
|
||||
X BLK 2 -500 200 100 R 40 40 0 0 B
|
||||
X WHT 3 -500 100 100 R 40 40 0 0 I
|
||||
X GRN 4 -500 0 100 R 40 40 0 0 I
|
||||
X YLW 5 -500 -100 100 R 40 40 0 0 B
|
||||
X GND 6 500 -500 100 L 40 40 0 0 W
|
||||
X CLK 7 500 -200 100 L 40 40 0 0 I C
|
||||
X DAT 8 500 -100 100 L 40 40 0 0 O
|
||||
X VCC 9 500 400 100 L 40 40 0 0 W
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# T4145015051-001_T4145015051-001
|
||||
#
|
||||
DEF T4145015051-001_T4145015051-001 J 0 40 N Y 1 L N
|
||||
F0 "J" -300 500 50 H V L BNN
|
||||
F1 "T4145015051-001_T4145015051-001" -300 -500 50 H V L BNN
|
||||
F2 "T4145015051-001" 0 0 50 H I L BNN
|
||||
F3 "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P" 0 0 50 H I L BNN
|
||||
F4 "https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493" 0 0 50 H I L BNN
|
||||
F5 "TE Connectivity" 0 0 50 H I L BNN
|
||||
F6 "Unavailable" 0 0 50 H I L BNN
|
||||
F7 "None" 0 0 50 H I L BNN
|
||||
F8 "T4145015051-001" 0 0 50 H I L BNN
|
||||
F9 "T4145015051-001" 0 0 50 H I L BNN
|
||||
F10 "None" 0 0 50 H I L BNN
|
||||
DRAW
|
||||
P 2 0 0 10 -300 -300 300 -300 N
|
||||
P 2 0 0 10 -300 400 -300 -300 N
|
||||
P 2 0 0 10 -300 400 -100 400 N
|
||||
P 2 0 0 10 -100 300 100 300 N
|
||||
P 2 0 0 10 -100 400 -100 300 N
|
||||
P 2 0 0 10 100 300 100 400 N
|
||||
P 2 0 0 10 100 400 300 400 N
|
||||
P 2 0 0 10 300 -300 300 400 N
|
||||
X 1 P$1 -200 400 200 D 40 40 0 0 B I
|
||||
X 2 P$2 200 400 200 D 40 40 0 0 B I
|
||||
X 3 P$3 200 -300 200 U 40 40 0 0 B I
|
||||
X 4 P$4 -200 -300 200 U 40 40 0 0 B I
|
||||
X 5 P$5 0 300 300 D 40 40 0 0 B I
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
# power_PWR_FLAG
|
||||
#
|
||||
DEF power_PWR_FLAG #FLG 0 0 N N 1 F P
|
||||
F0 "#FLG" 0 75 50 H I C CNN
|
||||
F1 "power_PWR_FLAG" 0 150 50 H V C CNN
|
||||
F2 "" 0 0 50 H I C CNN
|
||||
F3 "" 0 0 50 H I C CNN
|
||||
DRAW
|
||||
P 6 0 1 0 0 0 0 50 -40 75 0 100 40 75 0 50 N
|
||||
X pwr 1 0 0 0 U 50 50 0 0 w
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
||||
@@ -0,0 +1,3 @@
|
||||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
#End Doc Library
|
||||
@@ -0,0 +1,406 @@
|
||||
EESchema Schematic File Version 4
|
||||
LIBS:beieliscale-kicad-cache
|
||||
EELAYER 29 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
$Comp
|
||||
L SEN-13879:SEN-13879 HX711-1
|
||||
U 1 1 5C8AE7C5
|
||||
P 4550 3350
|
||||
F 0 "HX711-1" H 4550 4117 50 0000 C CNN
|
||||
F 1 "SEN-13879" H 4550 4026 50 0000 C CNN
|
||||
F 2 "SPARKFUN_SEN-13879" H 4550 3350 50 0001 L BNN
|
||||
F 3 "Load Cell Amp Hx711" H 4550 3350 50 0001 L BNN
|
||||
F 4 "SparkFun" H 4550 3350 50 0001 L BNN "Field4"
|
||||
F 5 "Unavailable" H 4550 3350 50 0001 L BNN "Field5"
|
||||
F 6 "SEN-13879" H 4550 3350 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 4550 3350 50 0001 L BNN "Field7"
|
||||
F 8 "None" H 4550 3350 50 0001 L BNN "Field8"
|
||||
1 4550 3350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6700 3550 6700 3150
|
||||
Wire Wire Line
|
||||
6700 3150 6850 3150
|
||||
Wire Wire Line
|
||||
5050 3550 6700 3550
|
||||
Wire Wire Line
|
||||
5050 3450 6750 3450
|
||||
Wire Wire Line
|
||||
6750 3450 6750 3250
|
||||
Wire Wire Line
|
||||
6750 3250 6850 3250
|
||||
NoConn ~ 6850 2950
|
||||
NoConn ~ 4050 3650
|
||||
NoConn ~ 4050 3750
|
||||
Wire Wire Line
|
||||
5050 2950 5600 2950
|
||||
Wire Wire Line
|
||||
5600 2950 5600 2850
|
||||
$Comp
|
||||
L power:PWR_FLAG #FLG0101
|
||||
U 1 1 5C8B848F
|
||||
P 6000 2850
|
||||
F 0 "#FLG0101" H 6000 2925 50 0001 C CNN
|
||||
F 1 "PWR_FLAG" H 6000 3024 50 0000 C CNN
|
||||
F 2 "" H 6000 2850 50 0001 C CNN
|
||||
F 3 "~" H 6000 2850 50 0001 C CNN
|
||||
1 6000 2850
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
5050 2850 5600 2850
|
||||
Connection ~ 5600 2850
|
||||
Wire Wire Line
|
||||
5600 2850 5700 2850
|
||||
Wire Wire Line
|
||||
5500 3850 5500 3050
|
||||
NoConn ~ 8700 3050
|
||||
NoConn ~ 8700 3250
|
||||
NoConn ~ 8700 3650
|
||||
NoConn ~ 8700 3750
|
||||
NoConn ~ 8700 3850
|
||||
$Comp
|
||||
L power:PWR_FLAG #FLG0102
|
||||
U 1 1 5C8C2453
|
||||
P 5250 3850
|
||||
F 0 "#FLG0102" H 5250 3925 50 0001 C CNN
|
||||
F 1 "PWR_FLAG" H 5250 4024 50 0000 C CNN
|
||||
F 2 "" H 5250 3850 50 0001 C CNN
|
||||
F 3 "~" H 5250 3850 50 0001 C CNN
|
||||
1 5250 3850
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Connection ~ 5250 3850
|
||||
$Comp
|
||||
L SEN-13879:SEN-13879 HX711-2
|
||||
U 1 1 5C8CD302
|
||||
P 4550 5100
|
||||
F 0 "HX711-2" H 4550 5867 50 0000 C CNN
|
||||
F 1 "SEN-13879" H 4550 5776 50 0000 C CNN
|
||||
F 2 "SPARKFUN_SEN-13879" H 4550 5100 50 0001 L BNN
|
||||
F 3 "Load Cell Amp Hx711" H 4550 5100 50 0001 L BNN
|
||||
F 4 "SparkFun" H 4550 5100 50 0001 L BNN "Field4"
|
||||
F 5 "Unavailable" H 4550 5100 50 0001 L BNN "Field5"
|
||||
F 6 "SEN-13879" H 4550 5100 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 4550 5100 50 0001 L BNN "Field7"
|
||||
F 8 "None" H 4550 5100 50 0001 L BNN "Field8"
|
||||
1 4550 5100
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 4050 5400
|
||||
NoConn ~ 4050 5500
|
||||
Wire Wire Line
|
||||
5050 4600 5600 4600
|
||||
Wire Wire Line
|
||||
5600 4600 5600 2950
|
||||
Connection ~ 5600 2950
|
||||
Wire Wire Line
|
||||
5050 4700 5600 4700
|
||||
Wire Wire Line
|
||||
5600 4700 5600 4600
|
||||
Connection ~ 5600 4600
|
||||
Wire Wire Line
|
||||
5050 5600 5250 5600
|
||||
Wire Wire Line
|
||||
5250 5600 5250 3850
|
||||
Wire Wire Line
|
||||
6650 5300 6650 3350
|
||||
Wire Wire Line
|
||||
6650 3350 6850 3350
|
||||
Wire Wire Line
|
||||
5050 5300 6650 5300
|
||||
$Comp
|
||||
L MiscellaneousDevices:ADAFRUIT_FEATHER U1
|
||||
U 1 1 5C8BFC62
|
||||
P 8950 3300
|
||||
F 0 "U1" H 9128 3353 60 0000 L CNN
|
||||
F 1 "MCCI 4610" H 9128 3247 60 0000 L CNN
|
||||
F 2 "" H 9100 3100 60 0000 C CNN
|
||||
F 3 "" H 9100 3100 60 0000 C CNN
|
||||
1 8950 3300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 8700 2850
|
||||
$Comp
|
||||
L Connector:Conn_01x02_Female BAT1
|
||||
U 1 1 5C92F7C2
|
||||
P 4350 1900
|
||||
F 0 "BAT1" H 4244 1575 50 0000 C CNN
|
||||
F 1 "Conn_01x02_Female" H 4244 1666 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical" H 4350 1900 50 0001 C CNN
|
||||
F 3 "~" H 4350 1900 50 0001 C CNN
|
||||
1 4350 1900
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
8150 1900 8150 2750
|
||||
Wire Wire Line
|
||||
8150 2750 8700 2750
|
||||
Wire Wire Line
|
||||
5250 3850 5500 3850
|
||||
$Comp
|
||||
L T4145015051-001:T4145015051-001 J2
|
||||
U 1 1 5CA65D1D
|
||||
P 2950 5000
|
||||
F 0 "J2" V 2483 5050 50 0000 C CNN
|
||||
F 1 "T4145015051-001" V 2574 5050 50 0000 C CNN
|
||||
F 2 "T4145015051-001" H 2950 5000 50 0001 L BNN
|
||||
F 3 "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P" H 2950 5000 50 0001 L BNN
|
||||
F 4 "https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493" H 2950 5000 50 0001 L BNN "Field4"
|
||||
F 5 "TE Connectivity" H 2950 5000 50 0001 L BNN "Field5"
|
||||
F 6 "Unavailable" H 2950 5000 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 2950 5000 50 0001 L BNN "Field7"
|
||||
F 8 "T4145015051-001" H 2950 5000 50 0001 L BNN "Field8"
|
||||
F 9 "T4145015051-001" H 2950 5000 50 0001 L BNN "Field9"
|
||||
F 10 "None" H 2950 5000 50 0001 L BNN "Field10"
|
||||
1 2950 5000
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L T4145015051-001:T4145015051-001 J1
|
||||
U 1 1 5CA66C31
|
||||
P 2950 3250
|
||||
F 0 "J1" V 2483 3300 50 0000 C CNN
|
||||
F 1 "T4145015051-001" V 2574 3300 50 0000 C CNN
|
||||
F 2 "T4145015051-001" H 2950 3250 50 0001 L BNN
|
||||
F 3 "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P" H 2950 3250 50 0001 L BNN
|
||||
F 4 "https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493" H 2950 3250 50 0001 L BNN "Field4"
|
||||
F 5 "TE Connectivity" H 2950 3250 50 0001 L BNN "Field5"
|
||||
F 6 "Unavailable" H 2950 3250 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 2950 3250 50 0001 L BNN "Field7"
|
||||
F 8 "T4145015051-001" H 2950 3250 50 0001 L BNN "Field8"
|
||||
F 9 "T4145015051-001" H 2950 3250 50 0001 L BNN "Field9"
|
||||
F 10 "None" H 2950 3250 50 0001 L BNN "Field10"
|
||||
1 2950 3250
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4050 3050 3350 3050
|
||||
Wire Wire Line
|
||||
4050 3150 3450 3150
|
||||
Wire Wire Line
|
||||
3450 3150 3450 3450
|
||||
Wire Wire Line
|
||||
3450 3450 3350 3450
|
||||
Wire Wire Line
|
||||
4050 3250 3650 3250
|
||||
Wire Wire Line
|
||||
3650 3250 3650 3650
|
||||
Wire Wire Line
|
||||
3650 3650 2650 3650
|
||||
Wire Wire Line
|
||||
2650 3650 2650 3450
|
||||
Wire Wire Line
|
||||
4050 3350 3750 3350
|
||||
Wire Wire Line
|
||||
3750 3350 3750 3800
|
||||
Wire Wire Line
|
||||
3750 3800 2450 3800
|
||||
Wire Wire Line
|
||||
2450 3800 2450 3050
|
||||
Wire Wire Line
|
||||
2450 3050 2650 3050
|
||||
Wire Wire Line
|
||||
4050 3450 3850 3450
|
||||
Wire Wire Line
|
||||
3850 3450 3850 3900
|
||||
Wire Wire Line
|
||||
3850 3900 3250 3900
|
||||
Wire Wire Line
|
||||
3250 3900 3250 3250
|
||||
Wire Wire Line
|
||||
4050 4800 3350 4800
|
||||
Wire Wire Line
|
||||
4050 4900 3500 4900
|
||||
Wire Wire Line
|
||||
3500 4900 3500 5200
|
||||
Wire Wire Line
|
||||
3500 5200 3350 5200
|
||||
Wire Wire Line
|
||||
4050 5000 3600 5000
|
||||
Wire Wire Line
|
||||
3600 5000 3600 5400
|
||||
Wire Wire Line
|
||||
3600 5400 2500 5400
|
||||
Wire Wire Line
|
||||
2500 5400 2500 5200
|
||||
Wire Wire Line
|
||||
2500 5200 2650 5200
|
||||
Wire Wire Line
|
||||
4050 5100 3700 5100
|
||||
Wire Wire Line
|
||||
3700 5100 3700 5550
|
||||
Wire Wire Line
|
||||
3700 5550 2400 5550
|
||||
Wire Wire Line
|
||||
2400 5550 2400 4800
|
||||
Wire Wire Line
|
||||
2400 4800 2650 4800
|
||||
Wire Wire Line
|
||||
3750 5200 3750 5600
|
||||
Wire Wire Line
|
||||
3750 5600 3250 5600
|
||||
Wire Wire Line
|
||||
3250 5600 3250 5000
|
||||
Wire Wire Line
|
||||
3750 5200 4050 5200
|
||||
Wire Wire Line
|
||||
4550 1800 5150 1800
|
||||
Wire Wire Line
|
||||
5050 3850 5150 3850
|
||||
Wire Wire Line
|
||||
5150 3850 5250 3850
|
||||
Connection ~ 5150 3850
|
||||
Wire Wire Line
|
||||
5150 1800 5150 3850
|
||||
$Comp
|
||||
L Connector:Conn_01x02_Female SWITCH1
|
||||
U 1 1 5CAD5AEF
|
||||
P 6300 1700
|
||||
F 0 "SWITCH1" H 6194 1375 50 0000 C CNN
|
||||
F 1 "Conn_01x02_Female" H 6194 1466 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical" H 6300 1700 50 0001 C CNN
|
||||
F 3 "~" H 6300 1700 50 0001 C CNN
|
||||
1 6300 1700
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6400 1900 8150 1900
|
||||
Wire Wire Line
|
||||
4550 1900 6300 1900
|
||||
NoConn ~ 8700 2950
|
||||
$Comp
|
||||
L Connector:Conn_01x05_Female J3
|
||||
U 1 1 5CBF85B5
|
||||
P 6000 3850
|
||||
F 0 "J3" H 6150 4050 50 0000 C CNN
|
||||
F 1 "Conn_01x05_Female" H 5950 4150 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B5B-PH-K_1x05_P2.00mm_Vertical" H 6000 3850 50 0001 C CNN
|
||||
F 3 "~" H 6000 3850 50 0001 C CNN
|
||||
1 6000 3850
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6600 4050 6600 2850
|
||||
Wire Wire Line
|
||||
6600 2850 6850 2850
|
||||
Wire Wire Line
|
||||
6200 4050 6600 4050
|
||||
Wire Wire Line
|
||||
6200 3950 6500 3950
|
||||
Wire Wire Line
|
||||
6500 3950 6500 3050
|
||||
Wire Wire Line
|
||||
5500 3050 6500 3050
|
||||
Connection ~ 6500 3050
|
||||
Wire Wire Line
|
||||
6500 3050 6850 3050
|
||||
Wire Wire Line
|
||||
6200 3650 6400 3650
|
||||
Wire Wire Line
|
||||
6400 3650 6400 2750
|
||||
Wire Wire Line
|
||||
6400 2750 6850 2750
|
||||
Wire Wire Line
|
||||
6200 3850 6400 3850
|
||||
Wire Wire Line
|
||||
6400 3850 6400 4450
|
||||
Wire Wire Line
|
||||
8500 4450 8500 3550
|
||||
Wire Wire Line
|
||||
8500 3550 8700 3550
|
||||
Wire Wire Line
|
||||
6200 3750 6550 3750
|
||||
Wire Wire Line
|
||||
6550 3750 6550 4350
|
||||
Wire Wire Line
|
||||
8400 4350 8400 3450
|
||||
Wire Wire Line
|
||||
8400 3450 8700 3450
|
||||
Wire Wire Line
|
||||
6550 4350 8400 4350
|
||||
Wire Wire Line
|
||||
6400 4450 8500 4450
|
||||
NoConn ~ 6850 3550
|
||||
$Comp
|
||||
L MiscellaneousDevices:ADAFRUIT_FEATHER U1
|
||||
U 2 1 5C8C025E
|
||||
P 7100 3500
|
||||
F 0 "U1" H 7278 3606 60 0000 L CNN
|
||||
F 1 "MCCI 4610" H 7278 3500 60 0000 L CNN
|
||||
F 2 "Modules:ADAFRUIT_FEATHER" H 7278 3394 60 0000 L CNN
|
||||
F 3 "" H 7250 3300 60 0000 C CNN
|
||||
2 7100 3500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 6850 4250
|
||||
NoConn ~ 6850 3950
|
||||
NoConn ~ 6850 3850
|
||||
NoConn ~ 6850 3750
|
||||
NoConn ~ 6850 3650
|
||||
NoConn ~ 6850 3450
|
||||
Wire Wire Line
|
||||
8600 5200 5050 5200
|
||||
Wire Wire Line
|
||||
8600 3150 8600 5200
|
||||
Wire Wire Line
|
||||
8600 3150 8700 3150
|
||||
$Comp
|
||||
L Connector:Conn_01x03_Male J4
|
||||
U 1 1 5CFBD036
|
||||
P 6000 4900
|
||||
F 0 "J4" H 6108 5181 50 0000 C CNN
|
||||
F 1 "Conn_01x03_Male" H 6108 5090 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" H 6000 4900 50 0001 C CNN
|
||||
F 3 "~" H 6000 4900 50 0001 C CNN
|
||||
1 6000 4900
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6200 5600 6200 5000
|
||||
Wire Wire Line
|
||||
6200 4800 6750 4800
|
||||
Wire Wire Line
|
||||
6750 4800 6750 4050
|
||||
Wire Wire Line
|
||||
6750 4050 6850 4050
|
||||
Wire Wire Line
|
||||
6200 4900 6800 4900
|
||||
Wire Wire Line
|
||||
6800 4900 6800 4150
|
||||
Wire Wire Line
|
||||
6800 4150 6850 4150
|
||||
NoConn ~ 8700 3350
|
||||
Wire Wire Line
|
||||
5250 5600 6200 5600
|
||||
Connection ~ 5250 5600
|
||||
$Comp
|
||||
L Connector:Conn_01x01_Male J5
|
||||
U 1 1 5CFE89F8
|
||||
P 5500 2350
|
||||
F 0 "J5" H 5608 2531 50 0000 C CNN
|
||||
F 1 "VOUT1" H 5608 2440 50 0000 C CNN
|
||||
F 2 "" H 5500 2350 50 0001 C CNN
|
||||
F 3 "~" H 5500 2350 50 0001 C CNN
|
||||
1 5500 2350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
5700 2350 5700 2850
|
||||
Connection ~ 5700 2850
|
||||
Wire Wire Line
|
||||
5700 2850 6000 2850
|
||||
$EndSCHEMATC
|
||||
@@ -0,0 +1,7 @@
|
||||
"Id";"Designator";"Package";"Quantity";"Designation";"Supplier and ref";
|
||||
1;"U2";"ADAFRUIT_FEATHER";1;"ADAFRUIT_FEATHER";;;
|
||||
2;"HX711-2,HX711-1";"SPARKFUN_SEN-13879";2;"SEN-13879";;;
|
||||
3;"J1,J2";"CUI_MD2-60ST";2;"Conn_01x05_Male";;;
|
||||
4;"J3";"AMPHENOL_MUSB-K152-30";1;"MUSB-K152-30";;;
|
||||
5;"J4";"JST_XH_B02B-XH-AM_1x02_P2.50mm_Vertical";1;"Conn_01x02_Female";;;
|
||||
6;"SW1";"SW_E-Switch_EG1224_SPDT_Angled";1;"SWITCH_SPST";;;
|
||||
|
@@ -0,0 +1,369 @@
|
||||
(export (version D)
|
||||
(design
|
||||
(source /home/joerg/git-repos/beieliscale/PCB/beieliscale-kicad/beieliscale-kicad.sch)
|
||||
(date "Fr 07 Jun 2019 16:19:25 CEST")
|
||||
(tool "Eeschema 5.1.2-1.fc30")
|
||||
(sheet (number 1) (name /) (tstamps /)
|
||||
(title_block
|
||||
(title)
|
||||
(company)
|
||||
(rev)
|
||||
(date)
|
||||
(source beieliscale-kicad.sch)
|
||||
(comment (number 1) (value ""))
|
||||
(comment (number 2) (value ""))
|
||||
(comment (number 3) (value ""))
|
||||
(comment (number 4) (value "")))))
|
||||
(components
|
||||
(comp (ref HX711-1)
|
||||
(value SEN-13879)
|
||||
(footprint SPARKFUN_SEN-13879)
|
||||
(datasheet "Load Cell Amp Hx711")
|
||||
(fields
|
||||
(field (name Field4) SparkFun)
|
||||
(field (name Field5) Unavailable)
|
||||
(field (name Field6) SEN-13879)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) None))
|
||||
(libsource (lib SEN-13879) (part SEN-13879) (description ""))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5C8AE7C5))
|
||||
(comp (ref HX711-2)
|
||||
(value SEN-13879)
|
||||
(footprint SPARKFUN_SEN-13879)
|
||||
(datasheet "Load Cell Amp Hx711")
|
||||
(fields
|
||||
(field (name Field4) SparkFun)
|
||||
(field (name Field5) Unavailable)
|
||||
(field (name Field6) SEN-13879)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) None))
|
||||
(libsource (lib SEN-13879) (part SEN-13879) (description ""))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5C8CD302))
|
||||
(comp (ref U1)
|
||||
(value "MCCI 4610")
|
||||
(footprint Modules:ADAFRUIT_FEATHER)
|
||||
(libsource (lib MiscellaneousDevices) (part ADAFRUIT_FEATHER) (description ""))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5C8BFC62))
|
||||
(comp (ref BAT1)
|
||||
(value Conn_01x02_Female)
|
||||
(footprint Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical)
|
||||
(datasheet ~)
|
||||
(libsource (lib Connector) (part Conn_01x02_Female) (description "Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)"))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5C92F7C2))
|
||||
(comp (ref J2)
|
||||
(value T4145015051-001)
|
||||
(footprint T4145015051-001)
|
||||
(datasheet "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P")
|
||||
(fields
|
||||
(field (name Field10) None)
|
||||
(field (name Field4) https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493)
|
||||
(field (name Field5) "TE Connectivity")
|
||||
(field (name Field6) Unavailable)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) T4145015051-001)
|
||||
(field (name Field9) T4145015051-001))
|
||||
(libsource (lib T4145015051-001) (part T4145015051-001) (description ""))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CA65D1D))
|
||||
(comp (ref J1)
|
||||
(value T4145015051-001)
|
||||
(footprint T4145015051-001)
|
||||
(datasheet "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P")
|
||||
(fields
|
||||
(field (name Field10) None)
|
||||
(field (name Field4) https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493)
|
||||
(field (name Field5) "TE Connectivity")
|
||||
(field (name Field6) Unavailable)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) T4145015051-001)
|
||||
(field (name Field9) T4145015051-001))
|
||||
(libsource (lib T4145015051-001) (part T4145015051-001) (description ""))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CA66C31))
|
||||
(comp (ref SWITCH1)
|
||||
(value Conn_01x02_Female)
|
||||
(footprint Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical)
|
||||
(datasheet ~)
|
||||
(libsource (lib Connector) (part Conn_01x02_Female) (description "Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)"))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CAD5AEF))
|
||||
(comp (ref J3)
|
||||
(value Conn_01x05_Female)
|
||||
(footprint Connector_JST:JST_PH_B5B-PH-K_1x05_P2.00mm_Vertical)
|
||||
(datasheet ~)
|
||||
(libsource (lib Connector) (part Conn_01x05_Female) (description "Generic connector, single row, 01x05, script generated (kicad-library-utils/schlib/autogen/connector/)"))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CBF85B5))
|
||||
(comp (ref J4)
|
||||
(value Conn_01x03_Male)
|
||||
(footprint Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical)
|
||||
(datasheet ~)
|
||||
(libsource (lib Connector) (part Conn_01x03_Male) (description "Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)"))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CFBD036))
|
||||
(comp (ref VOUT1)
|
||||
(value Conn_01x01)
|
||||
(footprint Connector_PinHeader_2.54mm:PinHeader_1x01_P2.54mm_Vertical)
|
||||
(datasheet ~)
|
||||
(libsource (lib Connector_Generic) (part Conn_01x01) (description "Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)"))
|
||||
(sheetpath (names /) (tstamps /))
|
||||
(tstamp 5CFF362B)))
|
||||
(libparts
|
||||
(libpart (lib Connector) (part Conn_01x02_Female)
|
||||
(description "Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)")
|
||||
(docs ~)
|
||||
(footprints
|
||||
(fp Connector*:*_1x??_*))
|
||||
(fields
|
||||
(field (name Reference) J)
|
||||
(field (name Value) Conn_01x02_Female))
|
||||
(pins
|
||||
(pin (num 1) (name Pin_1) (type passive))
|
||||
(pin (num 2) (name Pin_2) (type passive))))
|
||||
(libpart (lib Connector) (part Conn_01x03_Male)
|
||||
(description "Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)")
|
||||
(docs ~)
|
||||
(footprints
|
||||
(fp Connector*:*_1x??_*))
|
||||
(fields
|
||||
(field (name Reference) J)
|
||||
(field (name Value) Conn_01x03_Male))
|
||||
(pins
|
||||
(pin (num 1) (name Pin_1) (type passive))
|
||||
(pin (num 2) (name Pin_2) (type passive))
|
||||
(pin (num 3) (name Pin_3) (type passive))))
|
||||
(libpart (lib Connector) (part Conn_01x05_Female)
|
||||
(description "Generic connector, single row, 01x05, script generated (kicad-library-utils/schlib/autogen/connector/)")
|
||||
(docs ~)
|
||||
(footprints
|
||||
(fp Connector*:*_1x??_*))
|
||||
(fields
|
||||
(field (name Reference) J)
|
||||
(field (name Value) Conn_01x05_Female))
|
||||
(pins
|
||||
(pin (num 1) (name Pin_1) (type passive))
|
||||
(pin (num 2) (name Pin_2) (type passive))
|
||||
(pin (num 3) (name Pin_3) (type passive))
|
||||
(pin (num 4) (name Pin_4) (type passive))
|
||||
(pin (num 5) (name Pin_5) (type passive))))
|
||||
(libpart (lib Connector_Generic) (part Conn_01x01)
|
||||
(description "Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)")
|
||||
(docs ~)
|
||||
(footprints
|
||||
(fp Connector*:*))
|
||||
(fields
|
||||
(field (name Reference) J)
|
||||
(field (name Value) Conn_01x01))
|
||||
(pins
|
||||
(pin (num 1) (name Pin_1) (type passive))))
|
||||
(libpart (lib MiscellaneousDevices) (part ADAFRUIT_FEATHER)
|
||||
(fields
|
||||
(field (name Reference) U)
|
||||
(field (name Value) ADAFRUIT_FEATHER))
|
||||
(pins
|
||||
(pin (num 1) (name DIO1) (type input))
|
||||
(pin (num 2) (name 1) (type input))
|
||||
(pin (num 3) (name 0) (type input))
|
||||
(pin (num 4) (name MISO) (type input))
|
||||
(pin (num 5) (name MOSI) (type input))
|
||||
(pin (num 6) (name SCK) (type input))
|
||||
(pin (num 7) (name A5) (type input))
|
||||
(pin (num 8) (name A4) (type input))
|
||||
(pin (num 9) (name A3) (type input))
|
||||
(pin (num 10) (name A2) (type input))
|
||||
(pin (num 11) (name A1) (type input))
|
||||
(pin (num 12) (name A0) (type input))
|
||||
(pin (num 13) (name GND) (type input))
|
||||
(pin (num 14) (name AREF) (type input))
|
||||
(pin (num 15) (name +3V3) (type input))
|
||||
(pin (num 16) (name RST) (type input))
|
||||
(pin (num 17) (name VBAT) (type input))
|
||||
(pin (num 18) (name EN) (type input))
|
||||
(pin (num 19) (name VBUS) (type input))
|
||||
(pin (num 20) (name 13) (type input))
|
||||
(pin (num 21) (name 12) (type input))
|
||||
(pin (num 22) (name 11) (type input))
|
||||
(pin (num 23) (name 10) (type input))
|
||||
(pin (num 24) (name 9) (type input))
|
||||
(pin (num 25) (name 6) (type input))
|
||||
(pin (num 26) (name 5) (type input))
|
||||
(pin (num 27) (name 3) (type input))
|
||||
(pin (num 28) (name 2) (type input))))
|
||||
(libpart (lib SEN-13879) (part SEN-13879)
|
||||
(fields
|
||||
(field (name Reference) U)
|
||||
(field (name Value) SEN-13879)
|
||||
(field (name Footprint) SPARKFUN_SEN-13879)
|
||||
(field (name Datasheet) "Load Cell Amp Hx711")
|
||||
(field (name Field4) SparkFun)
|
||||
(field (name Field5) Unavailable)
|
||||
(field (name Field6) SEN-13879)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) None))
|
||||
(pins
|
||||
(pin (num 1) (name RED) (type BiDi))
|
||||
(pin (num 2) (name BLK) (type BiDi))
|
||||
(pin (num 3) (name WHT) (type input))
|
||||
(pin (num 4) (name GRN) (type input))
|
||||
(pin (num 5) (name YLW) (type BiDi))
|
||||
(pin (num 6) (name GND) (type power_in))
|
||||
(pin (num 7) (name CLK) (type input))
|
||||
(pin (num 8) (name DAT) (type output))
|
||||
(pin (num 9) (name VCC) (type power_in))
|
||||
(pin (num 10) (name VDD) (type power_in))
|
||||
(pin (num 11) (name B+) (type input))
|
||||
(pin (num 12) (name B-) (type input))))
|
||||
(libpart (lib T4145015051-001) (part T4145015051-001)
|
||||
(fields
|
||||
(field (name Reference) J)
|
||||
(field (name Value) T4145015051-001)
|
||||
(field (name Footprint) T4145015051-001)
|
||||
(field (name Datasheet) "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P")
|
||||
(field (name Field4) https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493)
|
||||
(field (name Field5) "TE Connectivity")
|
||||
(field (name Field6) Unavailable)
|
||||
(field (name Field7) None)
|
||||
(field (name Field8) T4145015051-001)
|
||||
(field (name Field9) T4145015051-001)
|
||||
(field (name Field10) None))
|
||||
(pins
|
||||
(pin (num P$1) (name 1) (type BiDi))
|
||||
(pin (num P$2) (name 2) (type BiDi))
|
||||
(pin (num P$3) (name 3) (type BiDi))
|
||||
(pin (num P$4) (name 4) (type BiDi))
|
||||
(pin (num P$5) (name 5) (type BiDi)))))
|
||||
(libraries
|
||||
(library (logical Connector)
|
||||
(uri /usr/share/kicad/library/Connector.lib))
|
||||
(library (logical Connector_Generic)
|
||||
(uri /usr/share/kicad/library/Connector_Generic.lib))
|
||||
(library (logical MiscellaneousDevices)
|
||||
(uri /home/joerg/git-repos/KiCad-Libraries/symbols/MiscellaneousDevices.lib))
|
||||
(library (logical SEN-13879)
|
||||
(uri /home/joerg/Downloads/SEN-13879.lib))
|
||||
(library (logical T4145015051-001)
|
||||
(uri /home/joerg/Downloads/T4145015051-001.lib)))
|
||||
(nets
|
||||
(net (code 1) (name "Net-(J3-Pad1)")
|
||||
(node (ref J3) (pin 1))
|
||||
(node (ref U1) (pin 15)))
|
||||
(net (code 2) (name "Net-(BAT1-Pad1)")
|
||||
(node (ref SWITCH1) (pin 1))
|
||||
(node (ref BAT1) (pin 1)))
|
||||
(net (code 3) (name "Net-(SWITCH1-Pad2)")
|
||||
(node (ref U1) (pin 17))
|
||||
(node (ref SWITCH1) (pin 2)))
|
||||
(net (code 4) (name "Net-(U1-Pad19)")
|
||||
(node (ref U1) (pin 19)))
|
||||
(net (code 5) (name "Net-(J3-Pad5)")
|
||||
(node (ref J3) (pin 5))
|
||||
(node (ref U1) (pin 16)))
|
||||
(net (code 6) (name "Net-(J3-Pad3)")
|
||||
(node (ref J3) (pin 3))
|
||||
(node (ref U1) (pin 25)))
|
||||
(net (code 7) (name "Net-(HX711-2-Pad4)")
|
||||
(node (ref HX711-2) (pin 4))
|
||||
(node (ref J2) (pin P$4)))
|
||||
(net (code 8) (name "Net-(HX711-2-Pad1)")
|
||||
(node (ref J2) (pin P$1))
|
||||
(node (ref HX711-2) (pin 1)))
|
||||
(net (code 9) (name "Net-(HX711-2-Pad2)")
|
||||
(node (ref J2) (pin P$2))
|
||||
(node (ref HX711-2) (pin 2)))
|
||||
(net (code 10) (name "Net-(HX711-2-Pad3)")
|
||||
(node (ref HX711-2) (pin 3))
|
||||
(node (ref J2) (pin P$3)))
|
||||
(net (code 11) (name "Net-(HX711-2-Pad5)")
|
||||
(node (ref HX711-2) (pin 5))
|
||||
(node (ref J2) (pin P$5)))
|
||||
(net (code 12) (name "Net-(U1-Pad6)")
|
||||
(node (ref U1) (pin 6)))
|
||||
(net (code 13) (name "Net-(U1-Pad7)")
|
||||
(node (ref U1) (pin 7)))
|
||||
(net (code 14) (name "Net-(U1-Pad9)")
|
||||
(node (ref U1) (pin 9)))
|
||||
(net (code 15) (name "Net-(HX711-2-Pad8)")
|
||||
(node (ref HX711-2) (pin 8))
|
||||
(node (ref U1) (pin 21)))
|
||||
(net (code 16) (name "Net-(J4-Pad1)")
|
||||
(node (ref J4) (pin 1))
|
||||
(node (ref U1) (pin 3)))
|
||||
(net (code 17) (name "Net-(J4-Pad2)")
|
||||
(node (ref J4) (pin 2))
|
||||
(node (ref U1) (pin 2)))
|
||||
(net (code 18) (name "Net-(U1-Pad5)")
|
||||
(node (ref U1) (pin 5)))
|
||||
(net (code 19) (name "Net-(U1-Pad23)")
|
||||
(node (ref U1) (pin 23)))
|
||||
(net (code 20) (name "Net-(J3-Pad4)")
|
||||
(node (ref U1) (pin 24))
|
||||
(node (ref J3) (pin 4)))
|
||||
(net (code 21) (name "Net-(U1-Pad8)")
|
||||
(node (ref U1) (pin 8)))
|
||||
(net (code 22) (name "Net-(U1-Pad1)")
|
||||
(node (ref U1) (pin 1)))
|
||||
(net (code 23) (name "Net-(U1-Pad4)")
|
||||
(node (ref U1) (pin 4)))
|
||||
(net (code 24) (name "Net-(HX711-1-Pad7)")
|
||||
(node (ref HX711-1) (pin 7))
|
||||
(node (ref U1) (pin 12)))
|
||||
(net (code 25) (name "Net-(U1-Pad14)")
|
||||
(node (ref U1) (pin 14)))
|
||||
(net (code 26) (name "Net-(U1-Pad20)")
|
||||
(node (ref U1) (pin 20)))
|
||||
(net (code 27) (name "Net-(U1-Pad22)")
|
||||
(node (ref U1) (pin 22)))
|
||||
(net (code 28) (name "Net-(U1-Pad26)")
|
||||
(node (ref U1) (pin 26)))
|
||||
(net (code 29) (name "Net-(U1-Pad27)")
|
||||
(node (ref U1) (pin 27)))
|
||||
(net (code 30) (name "Net-(U1-Pad28)")
|
||||
(node (ref U1) (pin 28)))
|
||||
(net (code 31) (name "Net-(BAT1-Pad2)")
|
||||
(node (ref HX711-1) (pin 6))
|
||||
(node (ref BAT1) (pin 2))
|
||||
(node (ref J3) (pin 2))
|
||||
(node (ref HX711-2) (pin 6))
|
||||
(node (ref U1) (pin 13))
|
||||
(node (ref J4) (pin 3)))
|
||||
(net (code 32) (name "Net-(HX711-1-Pad10)")
|
||||
(node (ref HX711-2) (pin 9))
|
||||
(node (ref HX711-2) (pin 10))
|
||||
(node (ref HX711-1) (pin 9))
|
||||
(node (ref HX711-1) (pin 10))
|
||||
(node (ref VOUT1) (pin 1)))
|
||||
(net (code 33) (name "Net-(HX711-2-Pad11)")
|
||||
(node (ref HX711-2) (pin 11)))
|
||||
(net (code 34) (name "Net-(HX711-2-Pad12)")
|
||||
(node (ref HX711-2) (pin 12)))
|
||||
(net (code 35) (name "Net-(HX711-1-Pad3)")
|
||||
(node (ref J1) (pin P$3))
|
||||
(node (ref HX711-1) (pin 3)))
|
||||
(net (code 36) (name "Net-(HX711-1-Pad4)")
|
||||
(node (ref J1) (pin P$4))
|
||||
(node (ref HX711-1) (pin 4)))
|
||||
(net (code 37) (name "Net-(HX711-1-Pad5)")
|
||||
(node (ref HX711-1) (pin 5))
|
||||
(node (ref J1) (pin P$5)))
|
||||
(net (code 38) (name "Net-(HX711-1-Pad8)")
|
||||
(node (ref U1) (pin 11))
|
||||
(node (ref HX711-1) (pin 8)))
|
||||
(net (code 39) (name "Net-(HX711-1-Pad11)")
|
||||
(node (ref HX711-1) (pin 11)))
|
||||
(net (code 40) (name "Net-(HX711-1-Pad12)")
|
||||
(node (ref HX711-1) (pin 12)))
|
||||
(net (code 41) (name "Net-(HX711-1-Pad2)")
|
||||
(node (ref HX711-1) (pin 2))
|
||||
(node (ref J1) (pin P$2)))
|
||||
(net (code 42) (name "Net-(HX711-1-Pad1)")
|
||||
(node (ref HX711-1) (pin 1))
|
||||
(node (ref J1) (pin P$1)))
|
||||
(net (code 43) (name "Net-(HX711-2-Pad7)")
|
||||
(node (ref HX711-2) (pin 7))
|
||||
(node (ref U1) (pin 10)))
|
||||
(net (code 44) (name "Net-(U1-Pad18)")
|
||||
(node (ref U1) (pin 18)))))
|
||||
@@ -0,0 +1,248 @@
|
||||
update=Mo 27 Mai 2019 17:30:58 CEST
|
||||
version=1
|
||||
last_client=kicad
|
||||
[general]
|
||||
version=1
|
||||
RootSch=
|
||||
BoardNm=
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
[eeschema/libraries]
|
||||
[schematic_editor]
|
||||
version=1
|
||||
PageLayoutDescrFile=empty.kicad_wks
|
||||
PlotDirectoryName=
|
||||
SubpartIdSeparator=0
|
||||
SubpartFirstId=65
|
||||
NetFmtName=Pcbnew
|
||||
SpiceAjustPassiveValues=0
|
||||
LabSize=50
|
||||
ERC_TestSimilarLabels=1
|
||||
[pcbnew]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
LastNetListRead=beieliscale-kicad.net
|
||||
CopperLayerCount=2
|
||||
BoardThickness=1.6
|
||||
AllowMicroVias=0
|
||||
AllowBlindVias=0
|
||||
RequireCourtyardDefinitions=0
|
||||
ProhibitOverlappingCourtyards=1
|
||||
MinTrackWidth=0.2
|
||||
MinViaDiameter=0.4
|
||||
MinViaDrill=0.3
|
||||
MinMicroViaDiameter=0.2
|
||||
MinMicroViaDrill=0.09999999999999999
|
||||
MinHoleToHole=0.25
|
||||
TrackWidth1=0.25
|
||||
ViaDiameter1=0.8
|
||||
ViaDrill1=0.4
|
||||
dPairWidth1=0.2
|
||||
dPairGap1=0.25
|
||||
dPairViaGap1=0.25
|
||||
SilkLineWidth=0.15
|
||||
SilkTextSizeV=1
|
||||
SilkTextSizeH=1
|
||||
SilkTextSizeThickness=0.15
|
||||
SilkTextItalic=0
|
||||
SilkTextUpright=1
|
||||
CopperLineWidth=0.2
|
||||
CopperTextSizeV=1.5
|
||||
CopperTextSizeH=1.5
|
||||
CopperTextThickness=0.3
|
||||
CopperTextItalic=0
|
||||
CopperTextUpright=1
|
||||
EdgeCutLineWidth=0.15
|
||||
CourtyardLineWidth=0.05
|
||||
OthersLineWidth=0.15
|
||||
OthersTextSizeV=1
|
||||
OthersTextSizeH=1
|
||||
OthersTextSizeThickness=0.15
|
||||
OthersTextItalic=0
|
||||
OthersTextUpright=1
|
||||
SolderMaskClearance=0.051
|
||||
SolderMaskMinWidth=0.25
|
||||
SolderPasteClearance=0
|
||||
SolderPasteRatio=0
|
||||
[pcbnew/Layer.F.Cu]
|
||||
Name=F.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.In1.Cu]
|
||||
Name=In1.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In2.Cu]
|
||||
Name=In2.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In3.Cu]
|
||||
Name=In3.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In4.Cu]
|
||||
Name=In4.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In5.Cu]
|
||||
Name=In5.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In6.Cu]
|
||||
Name=In6.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In7.Cu]
|
||||
Name=In7.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In8.Cu]
|
||||
Name=In8.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In9.Cu]
|
||||
Name=In9.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In10.Cu]
|
||||
Name=In10.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In11.Cu]
|
||||
Name=In11.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In12.Cu]
|
||||
Name=In12.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In13.Cu]
|
||||
Name=In13.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In14.Cu]
|
||||
Name=In14.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In15.Cu]
|
||||
Name=In15.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In16.Cu]
|
||||
Name=In16.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In17.Cu]
|
||||
Name=In17.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In18.Cu]
|
||||
Name=In18.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In19.Cu]
|
||||
Name=In19.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In20.Cu]
|
||||
Name=In20.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In21.Cu]
|
||||
Name=In21.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In22.Cu]
|
||||
Name=In22.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In23.Cu]
|
||||
Name=In23.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In24.Cu]
|
||||
Name=In24.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In25.Cu]
|
||||
Name=In25.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In26.Cu]
|
||||
Name=In26.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In27.Cu]
|
||||
Name=In27.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In28.Cu]
|
||||
Name=In28.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In29.Cu]
|
||||
Name=In29.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.In30.Cu]
|
||||
Name=In30.Cu
|
||||
Type=0
|
||||
Enabled=0
|
||||
[pcbnew/Layer.B.Cu]
|
||||
Name=B.Cu
|
||||
Type=0
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Adhes]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Paste]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.SilkS]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Mask]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Dwgs.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Cmts.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco1.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Eco2.User]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Edge.Cuts]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Margin]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.CrtYd]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.B.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.F.Fab]
|
||||
Enabled=1
|
||||
[pcbnew/Layer.Rescue]
|
||||
Enabled=0
|
||||
[pcbnew/Netclasses]
|
||||
[pcbnew/Netclasses/Default]
|
||||
Name=Default
|
||||
Clearance=0.2
|
||||
TrackWidth=0.25
|
||||
ViaDiameter=0.8
|
||||
ViaDrill=0.4
|
||||
uViaDiameter=0.3
|
||||
uViaDrill=0.1
|
||||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
@@ -0,0 +1,406 @@
|
||||
EESchema Schematic File Version 4
|
||||
LIBS:beieliscale-kicad-cache
|
||||
EELAYER 29 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date ""
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
$Comp
|
||||
L SEN-13879:SEN-13879 HX711-1
|
||||
U 1 1 5C8AE7C5
|
||||
P 4550 3350
|
||||
F 0 "HX711-1" H 4550 4117 50 0000 C CNN
|
||||
F 1 "SEN-13879" H 4550 4026 50 0000 C CNN
|
||||
F 2 "SPARKFUN_SEN-13879" H 4550 3350 50 0001 L BNN
|
||||
F 3 "Load Cell Amp Hx711" H 4550 3350 50 0001 L BNN
|
||||
F 4 "SparkFun" H 4550 3350 50 0001 L BNN "Field4"
|
||||
F 5 "Unavailable" H 4550 3350 50 0001 L BNN "Field5"
|
||||
F 6 "SEN-13879" H 4550 3350 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 4550 3350 50 0001 L BNN "Field7"
|
||||
F 8 "None" H 4550 3350 50 0001 L BNN "Field8"
|
||||
1 4550 3350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6700 3550 6700 3150
|
||||
Wire Wire Line
|
||||
6700 3150 6850 3150
|
||||
Wire Wire Line
|
||||
5050 3550 6700 3550
|
||||
Wire Wire Line
|
||||
5050 3450 6750 3450
|
||||
Wire Wire Line
|
||||
6750 3450 6750 3250
|
||||
Wire Wire Line
|
||||
6750 3250 6850 3250
|
||||
NoConn ~ 6850 2950
|
||||
NoConn ~ 4050 3650
|
||||
NoConn ~ 4050 3750
|
||||
Wire Wire Line
|
||||
5050 2950 5600 2950
|
||||
Wire Wire Line
|
||||
5600 2950 5600 2850
|
||||
$Comp
|
||||
L power:PWR_FLAG #FLG0101
|
||||
U 1 1 5C8B848F
|
||||
P 6000 2850
|
||||
F 0 "#FLG0101" H 6000 2925 50 0001 C CNN
|
||||
F 1 "PWR_FLAG" H 6000 3024 50 0000 C CNN
|
||||
F 2 "" H 6000 2850 50 0001 C CNN
|
||||
F 3 "~" H 6000 2850 50 0001 C CNN
|
||||
1 6000 2850
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
5050 2850 5550 2850
|
||||
Connection ~ 5600 2850
|
||||
Wire Wire Line
|
||||
5500 3850 5500 3050
|
||||
NoConn ~ 8700 3050
|
||||
NoConn ~ 8700 3250
|
||||
NoConn ~ 8700 3650
|
||||
NoConn ~ 8700 3750
|
||||
NoConn ~ 8700 3850
|
||||
$Comp
|
||||
L power:PWR_FLAG #FLG0102
|
||||
U 1 1 5C8C2453
|
||||
P 5250 3850
|
||||
F 0 "#FLG0102" H 5250 3925 50 0001 C CNN
|
||||
F 1 "PWR_FLAG" H 5250 4024 50 0000 C CNN
|
||||
F 2 "" H 5250 3850 50 0001 C CNN
|
||||
F 3 "~" H 5250 3850 50 0001 C CNN
|
||||
1 5250 3850
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Connection ~ 5250 3850
|
||||
$Comp
|
||||
L SEN-13879:SEN-13879 HX711-2
|
||||
U 1 1 5C8CD302
|
||||
P 4550 5100
|
||||
F 0 "HX711-2" H 4550 5867 50 0000 C CNN
|
||||
F 1 "SEN-13879" H 4550 5776 50 0000 C CNN
|
||||
F 2 "SPARKFUN_SEN-13879" H 4550 5100 50 0001 L BNN
|
||||
F 3 "Load Cell Amp Hx711" H 4550 5100 50 0001 L BNN
|
||||
F 4 "SparkFun" H 4550 5100 50 0001 L BNN "Field4"
|
||||
F 5 "Unavailable" H 4550 5100 50 0001 L BNN "Field5"
|
||||
F 6 "SEN-13879" H 4550 5100 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 4550 5100 50 0001 L BNN "Field7"
|
||||
F 8 "None" H 4550 5100 50 0001 L BNN "Field8"
|
||||
1 4550 5100
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 4050 5400
|
||||
NoConn ~ 4050 5500
|
||||
Wire Wire Line
|
||||
5050 4600 5600 4600
|
||||
Wire Wire Line
|
||||
5600 4600 5600 2950
|
||||
Connection ~ 5600 2950
|
||||
Wire Wire Line
|
||||
5050 4700 5600 4700
|
||||
Wire Wire Line
|
||||
5600 4700 5600 4600
|
||||
Connection ~ 5600 4600
|
||||
Wire Wire Line
|
||||
5050 5600 5250 5600
|
||||
Wire Wire Line
|
||||
5250 5600 5250 3850
|
||||
Wire Wire Line
|
||||
6650 5300 6650 3350
|
||||
Wire Wire Line
|
||||
6650 3350 6850 3350
|
||||
Wire Wire Line
|
||||
5050 5300 6650 5300
|
||||
$Comp
|
||||
L MiscellaneousDevices:ADAFRUIT_FEATHER U1
|
||||
U 1 1 5C8BFC62
|
||||
P 8950 3300
|
||||
F 0 "U1" H 9128 3353 60 0000 L CNN
|
||||
F 1 "MCCI 4610" H 9128 3247 60 0000 L CNN
|
||||
F 2 "" H 9100 3100 60 0000 C CNN
|
||||
F 3 "" H 9100 3100 60 0000 C CNN
|
||||
1 8950 3300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 8700 2850
|
||||
$Comp
|
||||
L Connector:Conn_01x02_Female BAT1
|
||||
U 1 1 5C92F7C2
|
||||
P 4350 1900
|
||||
F 0 "BAT1" H 4244 1575 50 0000 C CNN
|
||||
F 1 "Conn_01x02_Female" H 4244 1666 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical" H 4350 1900 50 0001 C CNN
|
||||
F 3 "~" H 4350 1900 50 0001 C CNN
|
||||
1 4350 1900
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
8150 1900 8150 2750
|
||||
Wire Wire Line
|
||||
8150 2750 8700 2750
|
||||
Wire Wire Line
|
||||
5250 3850 5500 3850
|
||||
$Comp
|
||||
L T4145015051-001:T4145015051-001 J2
|
||||
U 1 1 5CA65D1D
|
||||
P 2950 5000
|
||||
F 0 "J2" V 2483 5050 50 0000 C CNN
|
||||
F 1 "T4145015051-001" V 2574 5050 50 0000 C CNN
|
||||
F 2 "T4145015051-001" H 2950 5000 50 0001 L BNN
|
||||
F 3 "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P" H 2950 5000 50 0001 L BNN
|
||||
F 4 "https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493" H 2950 5000 50 0001 L BNN "Field4"
|
||||
F 5 "TE Connectivity" H 2950 5000 50 0001 L BNN "Field5"
|
||||
F 6 "Unavailable" H 2950 5000 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 2950 5000 50 0001 L BNN "Field7"
|
||||
F 8 "T4145015051-001" H 2950 5000 50 0001 L BNN "Field8"
|
||||
F 9 "T4145015051-001" H 2950 5000 50 0001 L BNN "Field9"
|
||||
F 10 "None" H 2950 5000 50 0001 L BNN "Field10"
|
||||
1 2950 5000
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L T4145015051-001:T4145015051-001 J1
|
||||
U 1 1 5CA66C31
|
||||
P 2950 3250
|
||||
F 0 "J1" V 2483 3300 50 0000 C CNN
|
||||
F 1 "T4145015051-001" V 2574 3300 50 0000 C CNN
|
||||
F 2 "T4145015051-001" H 2950 3250 50 0001 L BNN
|
||||
F 3 "Circular Metric Connectors; M12 R/A F PNLREAR STAMPED PIN A-CODE 5P" H 2950 3250 50 0001 L BNN
|
||||
F 4 "https://www.te.com/usa-en/product-T4145015051-001.html?te_bu=Cor&te_type=disp&te_campaign=seda_glo_cor-seda-global-disp-prtnr-fy19-seda-model-bom-cta_sma-317_1&elqCampaignId=32493" H 2950 3250 50 0001 L BNN "Field4"
|
||||
F 5 "TE Connectivity" H 2950 3250 50 0001 L BNN "Field5"
|
||||
F 6 "Unavailable" H 2950 3250 50 0001 L BNN "Field6"
|
||||
F 7 "None" H 2950 3250 50 0001 L BNN "Field7"
|
||||
F 8 "T4145015051-001" H 2950 3250 50 0001 L BNN "Field8"
|
||||
F 9 "T4145015051-001" H 2950 3250 50 0001 L BNN "Field9"
|
||||
F 10 "None" H 2950 3250 50 0001 L BNN "Field10"
|
||||
1 2950 3250
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
4050 3050 3350 3050
|
||||
Wire Wire Line
|
||||
4050 3150 3450 3150
|
||||
Wire Wire Line
|
||||
3450 3150 3450 3450
|
||||
Wire Wire Line
|
||||
3450 3450 3350 3450
|
||||
Wire Wire Line
|
||||
4050 3250 3650 3250
|
||||
Wire Wire Line
|
||||
3650 3250 3650 3650
|
||||
Wire Wire Line
|
||||
3650 3650 2650 3650
|
||||
Wire Wire Line
|
||||
2650 3650 2650 3450
|
||||
Wire Wire Line
|
||||
4050 3350 3750 3350
|
||||
Wire Wire Line
|
||||
3750 3350 3750 3800
|
||||
Wire Wire Line
|
||||
3750 3800 2450 3800
|
||||
Wire Wire Line
|
||||
2450 3800 2450 3050
|
||||
Wire Wire Line
|
||||
2450 3050 2650 3050
|
||||
Wire Wire Line
|
||||
4050 3450 3850 3450
|
||||
Wire Wire Line
|
||||
3850 3450 3850 3900
|
||||
Wire Wire Line
|
||||
3850 3900 3250 3900
|
||||
Wire Wire Line
|
||||
3250 3900 3250 3250
|
||||
Wire Wire Line
|
||||
4050 4800 3350 4800
|
||||
Wire Wire Line
|
||||
4050 4900 3500 4900
|
||||
Wire Wire Line
|
||||
3500 4900 3500 5200
|
||||
Wire Wire Line
|
||||
3500 5200 3350 5200
|
||||
Wire Wire Line
|
||||
4050 5000 3600 5000
|
||||
Wire Wire Line
|
||||
3600 5000 3600 5400
|
||||
Wire Wire Line
|
||||
3600 5400 2500 5400
|
||||
Wire Wire Line
|
||||
2500 5400 2500 5200
|
||||
Wire Wire Line
|
||||
2500 5200 2650 5200
|
||||
Wire Wire Line
|
||||
4050 5100 3700 5100
|
||||
Wire Wire Line
|
||||
3700 5100 3700 5550
|
||||
Wire Wire Line
|
||||
3700 5550 2400 5550
|
||||
Wire Wire Line
|
||||
2400 5550 2400 4800
|
||||
Wire Wire Line
|
||||
2400 4800 2650 4800
|
||||
Wire Wire Line
|
||||
3750 5200 3750 5600
|
||||
Wire Wire Line
|
||||
3750 5600 3250 5600
|
||||
Wire Wire Line
|
||||
3250 5600 3250 5000
|
||||
Wire Wire Line
|
||||
3750 5200 4050 5200
|
||||
Wire Wire Line
|
||||
4550 1800 5150 1800
|
||||
Wire Wire Line
|
||||
5050 3850 5150 3850
|
||||
Wire Wire Line
|
||||
5150 3850 5250 3850
|
||||
Connection ~ 5150 3850
|
||||
Wire Wire Line
|
||||
5150 1800 5150 3850
|
||||
$Comp
|
||||
L Connector:Conn_01x02_Female SWITCH1
|
||||
U 1 1 5CAD5AEF
|
||||
P 6300 1700
|
||||
F 0 "SWITCH1" H 6194 1375 50 0000 C CNN
|
||||
F 1 "Conn_01x02_Female" H 6194 1466 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B2B-PH-K_1x02_P2.00mm_Vertical" H 6300 1700 50 0001 C CNN
|
||||
F 3 "~" H 6300 1700 50 0001 C CNN
|
||||
1 6300 1700
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6400 1900 8150 1900
|
||||
Wire Wire Line
|
||||
4550 1900 6300 1900
|
||||
NoConn ~ 8700 2950
|
||||
$Comp
|
||||
L Connector:Conn_01x05_Female J3
|
||||
U 1 1 5CBF85B5
|
||||
P 6000 3850
|
||||
F 0 "J3" H 6150 4050 50 0000 C CNN
|
||||
F 1 "Conn_01x05_Female" H 5950 4150 50 0000 C CNN
|
||||
F 2 "Connector_JST:JST_PH_B5B-PH-K_1x05_P2.00mm_Vertical" H 6000 3850 50 0001 C CNN
|
||||
F 3 "~" H 6000 3850 50 0001 C CNN
|
||||
1 6000 3850
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6600 4050 6600 2850
|
||||
Wire Wire Line
|
||||
6600 2850 6850 2850
|
||||
Wire Wire Line
|
||||
6200 4050 6600 4050
|
||||
Wire Wire Line
|
||||
6200 3950 6500 3950
|
||||
Wire Wire Line
|
||||
6500 3950 6500 3050
|
||||
Wire Wire Line
|
||||
5500 3050 6500 3050
|
||||
Connection ~ 6500 3050
|
||||
Wire Wire Line
|
||||
6500 3050 6850 3050
|
||||
Wire Wire Line
|
||||
6200 3650 6400 3650
|
||||
Wire Wire Line
|
||||
6400 3650 6400 2750
|
||||
Wire Wire Line
|
||||
6400 2750 6850 2750
|
||||
Wire Wire Line
|
||||
6200 3850 6400 3850
|
||||
Wire Wire Line
|
||||
6400 3850 6400 4450
|
||||
Wire Wire Line
|
||||
8500 4450 8500 3550
|
||||
Wire Wire Line
|
||||
8500 3550 8700 3550
|
||||
Wire Wire Line
|
||||
6200 3750 6550 3750
|
||||
Wire Wire Line
|
||||
6550 3750 6550 4350
|
||||
Wire Wire Line
|
||||
8400 4350 8400 3450
|
||||
Wire Wire Line
|
||||
8400 3450 8700 3450
|
||||
Wire Wire Line
|
||||
6550 4350 8400 4350
|
||||
Wire Wire Line
|
||||
6400 4450 8500 4450
|
||||
NoConn ~ 6850 3550
|
||||
$Comp
|
||||
L MiscellaneousDevices:ADAFRUIT_FEATHER U1
|
||||
U 2 1 5C8C025E
|
||||
P 7100 3500
|
||||
F 0 "U1" H 7278 3606 60 0000 L CNN
|
||||
F 1 "MCCI 4610" H 7278 3500 60 0000 L CNN
|
||||
F 2 "Modules:ADAFRUIT_FEATHER" H 7278 3394 60 0000 L CNN
|
||||
F 3 "" H 7250 3300 60 0000 C CNN
|
||||
2 7100 3500
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
NoConn ~ 6850 4250
|
||||
NoConn ~ 6850 3950
|
||||
NoConn ~ 6850 3850
|
||||
NoConn ~ 6850 3750
|
||||
NoConn ~ 6850 3650
|
||||
NoConn ~ 6850 3450
|
||||
Wire Wire Line
|
||||
8600 5200 5050 5200
|
||||
Wire Wire Line
|
||||
8600 3150 8600 5200
|
||||
Wire Wire Line
|
||||
8600 3150 8700 3150
|
||||
$Comp
|
||||
L Connector:Conn_01x03_Male J4
|
||||
U 1 1 5CFBD036
|
||||
P 6000 4900
|
||||
F 0 "J4" H 6108 5181 50 0000 C CNN
|
||||
F 1 "Conn_01x03_Male" H 6108 5090 50 0000 C CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical" H 6000 4900 50 0001 C CNN
|
||||
F 3 "~" H 6000 4900 50 0001 C CNN
|
||||
1 6000 4900
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
6200 5600 6200 5000
|
||||
Wire Wire Line
|
||||
6200 4800 6750 4800
|
||||
Wire Wire Line
|
||||
6750 4800 6750 4050
|
||||
Wire Wire Line
|
||||
6750 4050 6850 4050
|
||||
Wire Wire Line
|
||||
6200 4900 6800 4900
|
||||
Wire Wire Line
|
||||
6800 4900 6800 4150
|
||||
Wire Wire Line
|
||||
6800 4150 6850 4150
|
||||
NoConn ~ 8700 3350
|
||||
Wire Wire Line
|
||||
5250 5600 6200 5600
|
||||
Connection ~ 5250 5600
|
||||
Wire Wire Line
|
||||
5600 2850 6000 2850
|
||||
$Comp
|
||||
L Connector_Generic:Conn_01x01 VOUT1
|
||||
U 1 1 5CFF362B
|
||||
P 5750 2300
|
||||
F 0 "VOUT1" H 5830 2342 50 0000 L CNN
|
||||
F 1 "Conn_01x01" H 5830 2251 50 0000 L CNN
|
||||
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x01_P2.54mm_Vertical" H 5750 2300 50 0001 C CNN
|
||||
F 3 "~" H 5750 2300 50 0001 C CNN
|
||||
1 5750 2300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Wire Wire Line
|
||||
5550 2300 5550 2850
|
||||
Connection ~ 5550 2850
|
||||
Wire Wire Line
|
||||
5550 2850 5600 2850
|
||||
$EndSCHEMATC
|
||||
@@ -0,0 +1,5 @@
|
||||
(page_layout
|
||||
(setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15)
|
||||
(left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10))
|
||||
(line (name segm1:Line) (start 0 0) (end 0 0))
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2-5.fc29*
|
||||
G04 #@! TF.CreationDate,2019-03-22T17:39:01+01:00*
|
||||
G04 #@! TF.ProjectId,beieliscale-kicad,62656965-6c69-4736-9361-6c652d6b6963,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Paste,Bot*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2-5.fc29) date Fr 22 Mär 2019 17:39:01 CET*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 APERTURE END LIST*
|
||||
M02*
|
||||
@@ -0,0 +1,15 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2-5.fc29*
|
||||
G04 #@! TF.CreationDate,2019-03-22T17:39:01+01:00*
|
||||
G04 #@! TF.ProjectId,beieliscale-kicad,62656965-6c69-4736-9361-6c652d6b6963,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Legend,Bot*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2-5.fc29) date Fr 22 Mär 2019 17:39:01 CET*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 APERTURE END LIST*
|
||||
M02*
|
||||
@@ -0,0 +1,112 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2-5.fc29*
|
||||
G04 #@! TF.CreationDate,2019-03-22T17:39:01+01:00*
|
||||
G04 #@! TF.ProjectId,beieliscale-kicad,62656965-6c69-4736-9361-6c652d6b6963,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Profile,NP*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2-5.fc29) date Fr 22 Mär 2019 17:39:01 CET*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.150000*%
|
||||
G04 #@! TA.AperFunction,NonConductor*
|
||||
%ADD11C,0.100000*%
|
||||
G04 #@! TD*
|
||||
G04 #@! TA.AperFunction,NonConductor*
|
||||
%ADD12C,0.000100*%
|
||||
G04 #@! TD*
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X74930000Y-49900000D02*
|
||||
X74930000Y-99900000D01*
|
||||
X194000000Y-49900000D02*
|
||||
X74930000Y-49900000D01*
|
||||
X194000000Y-99900000D02*
|
||||
X194000000Y-49900000D01*
|
||||
X74930000Y-99900000D02*
|
||||
X194000000Y-99900000D01*
|
||||
D11*
|
||||
G04 #@! TO.C,J1*
|
||||
X192765000Y-93180000D02*
|
||||
X192765000Y-92180000D01*
|
||||
X192765000Y-92180000D02*
|
||||
X190565000Y-92180000D01*
|
||||
X190565000Y-92180000D02*
|
||||
X190565000Y-93180000D01*
|
||||
X190565000Y-93180000D02*
|
||||
X192765000Y-93180000D01*
|
||||
X192765000Y-80380000D02*
|
||||
X192765000Y-79380000D01*
|
||||
X192765000Y-79380000D02*
|
||||
X190565000Y-79380000D01*
|
||||
X190565000Y-79380000D02*
|
||||
X190565000Y-80380000D01*
|
||||
X190565000Y-80380000D02*
|
||||
X192765000Y-80380000D01*
|
||||
G04 #@! TO.C,J2*
|
||||
X78240000Y-92180000D02*
|
||||
X76040000Y-92180000D01*
|
||||
X78240000Y-93180000D02*
|
||||
X78240000Y-92180000D01*
|
||||
X76040000Y-93180000D02*
|
||||
X78240000Y-93180000D01*
|
||||
X76040000Y-92180000D02*
|
||||
X76040000Y-93180000D01*
|
||||
X78240000Y-79380000D02*
|
||||
X76040000Y-79380000D01*
|
||||
X78240000Y-80380000D02*
|
||||
X78240000Y-79380000D01*
|
||||
X76040000Y-80380000D02*
|
||||
X78240000Y-80380000D01*
|
||||
X76040000Y-79380000D02*
|
||||
X76040000Y-80380000D01*
|
||||
G04 #@! TO.C,J3*
|
||||
X80090000Y-62685000D02*
|
||||
X77390000Y-62685000D01*
|
||||
X77390000Y-62685000D02*
|
||||
G75*
|
||||
G02X77390000Y-61685000I0J500000D01*
|
||||
G01*
|
||||
X77390000Y-61685000D02*
|
||||
X80090000Y-61685000D01*
|
||||
X80090000Y-61685000D02*
|
||||
G75*
|
||||
G02X80090000Y-62685000I0J-500000D01*
|
||||
G01*
|
||||
X80090000Y-71185000D02*
|
||||
X77390000Y-71185000D01*
|
||||
X77390000Y-71185000D02*
|
||||
G75*
|
||||
G02X77390000Y-70185000I0J500000D01*
|
||||
G01*
|
||||
X77390000Y-70185000D02*
|
||||
X80090000Y-70185000D01*
|
||||
X80090000Y-70185000D02*
|
||||
G75*
|
||||
G02X80090000Y-71185000I0J-500000D01*
|
||||
G01*
|
||||
D12*
|
||||
X79890000Y-66435000D02*
|
||||
G75*
|
||||
G03X79890000Y-66435000I-350000J0D01*
|
||||
G01*
|
||||
X79890000Y-65135000D02*
|
||||
G75*
|
||||
G03X79890000Y-65135000I-350000J0D01*
|
||||
G01*
|
||||
X79890000Y-67735000D02*
|
||||
G75*
|
||||
G03X79890000Y-67735000I-350000J0D01*
|
||||
G01*
|
||||
X78290000Y-67085000D02*
|
||||
G75*
|
||||
G03X78290000Y-67085000I-350000J0D01*
|
||||
G01*
|
||||
X78290000Y-65785000D02*
|
||||
G75*
|
||||
G03X78290000Y-65785000I-350000J0D01*
|
||||
G01*
|
||||
G04 #@! TD*
|
||||
M02*
|
||||
@@ -0,0 +1,15 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2-5.fc29*
|
||||
G04 #@! TF.CreationDate,2019-03-22T17:39:01+01:00*
|
||||
G04 #@! TF.ProjectId,beieliscale-kicad,62656965-6c69-4736-9361-6c652d6b6963,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Paste,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2-5.fc29) date Fr 22 Mär 2019 17:39:01 CET*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
G04 APERTURE END LIST*
|
||||
M02*
|
||||
@@ -0,0 +1,912 @@
|
||||
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,5.0.2-5.fc29*
|
||||
G04 #@! TF.CreationDate,2019-03-22T17:39:01+01:00*
|
||||
G04 #@! TF.ProjectId,beieliscale-kicad,62656965-6c69-4736-9361-6c652d6b6963,rev?*
|
||||
G04 #@! TF.SameCoordinates,Original*
|
||||
G04 #@! TF.FileFunction,Legend,Top*
|
||||
G04 #@! TF.FilePolarity,Positive*
|
||||
%FSLAX46Y46*%
|
||||
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
|
||||
G04 Created by KiCad (PCBNEW 5.0.2-5.fc29) date Fr 22 Mär 2019 17:39:01 CET*
|
||||
%MOMM*%
|
||||
%LPD*%
|
||||
G01*
|
||||
G04 APERTURE LIST*
|
||||
%ADD10C,0.200000*%
|
||||
%ADD11C,0.150000*%
|
||||
%ADD12C,0.127000*%
|
||||
%ADD13C,0.300000*%
|
||||
%ADD14C,0.100000*%
|
||||
%ADD15C,0.120000*%
|
||||
G04 APERTURE END LIST*
|
||||
D10*
|
||||
X123240952Y-54632380D02*
|
||||
X123240952Y-53965714D01*
|
||||
X123240952Y-54060952D02*
|
||||
X123288571Y-54013333D01*
|
||||
X123383809Y-53965714D01*
|
||||
X123526666Y-53965714D01*
|
||||
X123621904Y-54013333D01*
|
||||
X123669523Y-54108571D01*
|
||||
X123669523Y-54632380D01*
|
||||
X123669523Y-54108571D02*
|
||||
X123717142Y-54013333D01*
|
||||
X123812380Y-53965714D01*
|
||||
X123955238Y-53965714D01*
|
||||
X124050476Y-54013333D01*
|
||||
X124098095Y-54108571D01*
|
||||
X124098095Y-54632380D01*
|
||||
X124574285Y-54632380D02*
|
||||
X124574285Y-53965714D01*
|
||||
X124574285Y-53632380D02*
|
||||
X124526666Y-53680000D01*
|
||||
X124574285Y-53727619D01*
|
||||
X124621904Y-53680000D01*
|
||||
X124574285Y-53632380D01*
|
||||
X124574285Y-53727619D01*
|
||||
X125050476Y-53965714D02*
|
||||
X125050476Y-54632380D01*
|
||||
X125050476Y-54060952D02*
|
||||
X125098095Y-54013333D01*
|
||||
X125193333Y-53965714D01*
|
||||
X125336190Y-53965714D01*
|
||||
X125431428Y-54013333D01*
|
||||
X125479047Y-54108571D01*
|
||||
X125479047Y-54632380D01*
|
||||
X125955238Y-54632380D02*
|
||||
X125955238Y-53965714D01*
|
||||
X125955238Y-53632380D02*
|
||||
X125907619Y-53680000D01*
|
||||
X125955238Y-53727619D01*
|
||||
X126002857Y-53680000D01*
|
||||
X125955238Y-53632380D01*
|
||||
X125955238Y-53727619D01*
|
||||
X126431428Y-54251428D02*
|
||||
X127193333Y-54251428D01*
|
||||
X127669523Y-54632380D02*
|
||||
X127669523Y-53632380D01*
|
||||
X127669523Y-54013333D02*
|
||||
X127764761Y-53965714D01*
|
||||
X127955238Y-53965714D01*
|
||||
X128050476Y-54013333D01*
|
||||
X128098095Y-54060952D01*
|
||||
X128145714Y-54156190D01*
|
||||
X128145714Y-54441904D01*
|
||||
X128098095Y-54537142D01*
|
||||
X128050476Y-54584761D01*
|
||||
X127955238Y-54632380D01*
|
||||
X127764761Y-54632380D01*
|
||||
X127669523Y-54584761D01*
|
||||
X128955238Y-54584761D02*
|
||||
X128860000Y-54632380D01*
|
||||
X128669523Y-54632380D01*
|
||||
X128574285Y-54584761D01*
|
||||
X128526666Y-54489523D01*
|
||||
X128526666Y-54108571D01*
|
||||
X128574285Y-54013333D01*
|
||||
X128669523Y-53965714D01*
|
||||
X128860000Y-53965714D01*
|
||||
X128955238Y-54013333D01*
|
||||
X129002857Y-54108571D01*
|
||||
X129002857Y-54203809D01*
|
||||
X128526666Y-54299047D01*
|
||||
X129431428Y-54632380D02*
|
||||
X129431428Y-53965714D01*
|
||||
X129431428Y-53632380D02*
|
||||
X129383809Y-53680000D01*
|
||||
X129431428Y-53727619D01*
|
||||
X129479047Y-53680000D01*
|
||||
X129431428Y-53632380D01*
|
||||
X129431428Y-53727619D01*
|
||||
X130288571Y-54584761D02*
|
||||
X130193333Y-54632380D01*
|
||||
X130002857Y-54632380D01*
|
||||
X129907619Y-54584761D01*
|
||||
X129860000Y-54489523D01*
|
||||
X129860000Y-54108571D01*
|
||||
X129907619Y-54013333D01*
|
||||
X130002857Y-53965714D01*
|
||||
X130193333Y-53965714D01*
|
||||
X130288571Y-54013333D01*
|
||||
X130336190Y-54108571D01*
|
||||
X130336190Y-54203809D01*
|
||||
X129860000Y-54299047D01*
|
||||
X130907619Y-54632380D02*
|
||||
X130812380Y-54584761D01*
|
||||
X130764761Y-54489523D01*
|
||||
X130764761Y-53632380D01*
|
||||
X131288571Y-54632380D02*
|
||||
X131288571Y-53965714D01*
|
||||
X131288571Y-53632380D02*
|
||||
X131240952Y-53680000D01*
|
||||
X131288571Y-53727619D01*
|
||||
X131336190Y-53680000D01*
|
||||
X131288571Y-53632380D01*
|
||||
X131288571Y-53727619D01*
|
||||
X131764761Y-54537142D02*
|
||||
X131812380Y-54584761D01*
|
||||
X131764761Y-54632380D01*
|
||||
X131717142Y-54584761D01*
|
||||
X131764761Y-54537142D01*
|
||||
X131764761Y-54632380D01*
|
||||
X132669523Y-54584761D02*
|
||||
X132574285Y-54632380D01*
|
||||
X132383809Y-54632380D01*
|
||||
X132288571Y-54584761D01*
|
||||
X132240952Y-54537142D01*
|
||||
X132193333Y-54441904D01*
|
||||
X132193333Y-54156190D01*
|
||||
X132240952Y-54060952D01*
|
||||
X132288571Y-54013333D01*
|
||||
X132383809Y-53965714D01*
|
||||
X132574285Y-53965714D01*
|
||||
X132669523Y-54013333D01*
|
||||
X133098095Y-54632380D02*
|
||||
X133098095Y-53632380D01*
|
||||
X133526666Y-54632380D02*
|
||||
X133526666Y-54108571D01*
|
||||
X133479047Y-54013333D01*
|
||||
X133383809Y-53965714D01*
|
||||
X133240952Y-53965714D01*
|
||||
X133145714Y-54013333D01*
|
||||
X133098095Y-54060952D01*
|
||||
X134764761Y-54251428D02*
|
||||
X135526666Y-54251428D01*
|
||||
X137098095Y-54108571D02*
|
||||
X137240952Y-54156190D01*
|
||||
X137288571Y-54203809D01*
|
||||
X137336190Y-54299047D01*
|
||||
X137336190Y-54441904D01*
|
||||
X137288571Y-54537142D01*
|
||||
X137240952Y-54584761D01*
|
||||
X137145714Y-54632380D01*
|
||||
X136764761Y-54632380D01*
|
||||
X136764761Y-53632380D01*
|
||||
X137098095Y-53632380D01*
|
||||
X137193333Y-53680000D01*
|
||||
X137240952Y-53727619D01*
|
||||
X137288571Y-53822857D01*
|
||||
X137288571Y-53918095D01*
|
||||
X137240952Y-54013333D01*
|
||||
X137193333Y-54060952D01*
|
||||
X137098095Y-54108571D01*
|
||||
X136764761Y-54108571D01*
|
||||
X138145714Y-54584761D02*
|
||||
X138050476Y-54632380D01*
|
||||
X137860000Y-54632380D01*
|
||||
X137764761Y-54584761D01*
|
||||
X137717142Y-54489523D01*
|
||||
X137717142Y-54108571D01*
|
||||
X137764761Y-54013333D01*
|
||||
X137860000Y-53965714D01*
|
||||
X138050476Y-53965714D01*
|
||||
X138145714Y-54013333D01*
|
||||
X138193333Y-54108571D01*
|
||||
X138193333Y-54203809D01*
|
||||
X137717142Y-54299047D01*
|
||||
X138621904Y-54632380D02*
|
||||
X138621904Y-53965714D01*
|
||||
X138621904Y-53632380D02*
|
||||
X138574285Y-53680000D01*
|
||||
X138621904Y-53727619D01*
|
||||
X138669523Y-53680000D01*
|
||||
X138621904Y-53632380D01*
|
||||
X138621904Y-53727619D01*
|
||||
X139479047Y-54584761D02*
|
||||
X139383809Y-54632380D01*
|
||||
X139193333Y-54632380D01*
|
||||
X139098095Y-54584761D01*
|
||||
X139050476Y-54489523D01*
|
||||
X139050476Y-54108571D01*
|
||||
X139098095Y-54013333D01*
|
||||
X139193333Y-53965714D01*
|
||||
X139383809Y-53965714D01*
|
||||
X139479047Y-54013333D01*
|
||||
X139526666Y-54108571D01*
|
||||
X139526666Y-54203809D01*
|
||||
X139050476Y-54299047D01*
|
||||
X140098095Y-54632380D02*
|
||||
X140002857Y-54584761D01*
|
||||
X139955238Y-54489523D01*
|
||||
X139955238Y-53632380D01*
|
||||
X140479047Y-54632380D02*
|
||||
X140479047Y-53965714D01*
|
||||
X140479047Y-53632380D02*
|
||||
X140431428Y-53680000D01*
|
||||
X140479047Y-53727619D01*
|
||||
X140526666Y-53680000D01*
|
||||
X140479047Y-53632380D01*
|
||||
X140479047Y-53727619D01*
|
||||
X140907619Y-54584761D02*
|
||||
X141050476Y-54632380D01*
|
||||
X141288571Y-54632380D01*
|
||||
X141383809Y-54584761D01*
|
||||
X141431428Y-54537142D01*
|
||||
X141479047Y-54441904D01*
|
||||
X141479047Y-54346666D01*
|
||||
X141431428Y-54251428D01*
|
||||
X141383809Y-54203809D01*
|
||||
X141288571Y-54156190D01*
|
||||
X141098095Y-54108571D01*
|
||||
X141002857Y-54060952D01*
|
||||
X140955238Y-54013333D01*
|
||||
X140907619Y-53918095D01*
|
||||
X140907619Y-53822857D01*
|
||||
X140955238Y-53727619D01*
|
||||
X141002857Y-53680000D01*
|
||||
X141098095Y-53632380D01*
|
||||
X141336190Y-53632380D01*
|
||||
X141479047Y-53680000D01*
|
||||
X142336190Y-54584761D02*
|
||||
X142240952Y-54632380D01*
|
||||
X142050476Y-54632380D01*
|
||||
X141955238Y-54584761D01*
|
||||
X141907619Y-54537142D01*
|
||||
X141860000Y-54441904D01*
|
||||
X141860000Y-54156190D01*
|
||||
X141907619Y-54060952D01*
|
||||
X141955238Y-54013333D01*
|
||||
X142050476Y-53965714D01*
|
||||
X142240952Y-53965714D01*
|
||||
X142336190Y-54013333D01*
|
||||
X143193333Y-54632380D02*
|
||||
X143193333Y-54108571D01*
|
||||
X143145714Y-54013333D01*
|
||||
X143050476Y-53965714D01*
|
||||
X142860000Y-53965714D01*
|
||||
X142764761Y-54013333D01*
|
||||
X143193333Y-54584761D02*
|
||||
X143098095Y-54632380D01*
|
||||
X142860000Y-54632380D01*
|
||||
X142764761Y-54584761D01*
|
||||
X142717142Y-54489523D01*
|
||||
X142717142Y-54394285D01*
|
||||
X142764761Y-54299047D01*
|
||||
X142860000Y-54251428D01*
|
||||
X143098095Y-54251428D01*
|
||||
X143193333Y-54203809D01*
|
||||
X143812380Y-54632380D02*
|
||||
X143717142Y-54584761D01*
|
||||
X143669523Y-54489523D01*
|
||||
X143669523Y-53632380D01*
|
||||
X144574285Y-54584761D02*
|
||||
X144479047Y-54632380D01*
|
||||
X144288571Y-54632380D01*
|
||||
X144193333Y-54584761D01*
|
||||
X144145714Y-54489523D01*
|
||||
X144145714Y-54108571D01*
|
||||
X144193333Y-54013333D01*
|
||||
X144288571Y-53965714D01*
|
||||
X144479047Y-53965714D01*
|
||||
X144574285Y-54013333D01*
|
||||
X144621904Y-54108571D01*
|
||||
X144621904Y-54203809D01*
|
||||
X144145714Y-54299047D01*
|
||||
X145812380Y-54632380D02*
|
||||
X145812380Y-53632380D01*
|
||||
X145812380Y-54013333D02*
|
||||
X145907619Y-53965714D01*
|
||||
X146098095Y-53965714D01*
|
||||
X146193333Y-54013333D01*
|
||||
X146240952Y-54060952D01*
|
||||
X146288571Y-54156190D01*
|
||||
X146288571Y-54441904D01*
|
||||
X146240952Y-54537142D01*
|
||||
X146193333Y-54584761D01*
|
||||
X146098095Y-54632380D01*
|
||||
X145907619Y-54632380D01*
|
||||
X145812380Y-54584761D01*
|
||||
X146621904Y-53965714D02*
|
||||
X146860000Y-54632380D01*
|
||||
X147098095Y-53965714D02*
|
||||
X146860000Y-54632380D01*
|
||||
X146764761Y-54870476D01*
|
||||
X146717142Y-54918095D01*
|
||||
X146621904Y-54965714D01*
|
||||
X148240952Y-53965714D02*
|
||||
X148240952Y-54632380D01*
|
||||
X148240952Y-54060952D02*
|
||||
X148288571Y-54013333D01*
|
||||
X148383809Y-53965714D01*
|
||||
X148526666Y-53965714D01*
|
||||
X148621904Y-54013333D01*
|
||||
X148669523Y-54108571D01*
|
||||
X148669523Y-54632380D01*
|
||||
X149145714Y-54632380D02*
|
||||
X149145714Y-53632380D01*
|
||||
X149145714Y-54013333D02*
|
||||
X149240952Y-53965714D01*
|
||||
X149431428Y-53965714D01*
|
||||
X149526666Y-54013333D01*
|
||||
X149574285Y-54060952D01*
|
||||
X149621904Y-54156190D01*
|
||||
X149621904Y-54441904D01*
|
||||
X149574285Y-54537142D01*
|
||||
X149526666Y-54584761D01*
|
||||
X149431428Y-54632380D01*
|
||||
X149240952Y-54632380D01*
|
||||
X149145714Y-54584761D01*
|
||||
X150050476Y-54632380D02*
|
||||
X150050476Y-53965714D01*
|
||||
X150050476Y-53632380D02*
|
||||
X150002857Y-53680000D01*
|
||||
X150050476Y-53727619D01*
|
||||
X150098095Y-53680000D01*
|
||||
X150050476Y-53632380D01*
|
||||
X150050476Y-53727619D01*
|
||||
X150383809Y-53965714D02*
|
||||
X150764761Y-53965714D01*
|
||||
X150526666Y-53632380D02*
|
||||
X150526666Y-54489523D01*
|
||||
X150574285Y-54584761D01*
|
||||
X150669523Y-54632380D01*
|
||||
X150764761Y-54632380D01*
|
||||
X151860000Y-54632380D02*
|
||||
X151860000Y-53632380D01*
|
||||
X152336190Y-53965714D02*
|
||||
X152336190Y-54632380D01*
|
||||
X152336190Y-54060952D02*
|
||||
X152383809Y-54013333D01*
|
||||
X152479047Y-53965714D01*
|
||||
X152621904Y-53965714D01*
|
||||
X152717142Y-54013333D01*
|
||||
X152764761Y-54108571D01*
|
||||
X152764761Y-54632380D01*
|
||||
X153098095Y-53965714D02*
|
||||
X153479047Y-53965714D01*
|
||||
X153240952Y-54632380D02*
|
||||
X153240952Y-53775238D01*
|
||||
X153288571Y-53680000D01*
|
||||
X153383809Y-53632380D01*
|
||||
X153479047Y-53632380D01*
|
||||
X153955238Y-54632380D02*
|
||||
X153860000Y-54584761D01*
|
||||
X153812380Y-54537142D01*
|
||||
X153764761Y-54441904D01*
|
||||
X153764761Y-54156190D01*
|
||||
X153812380Y-54060952D01*
|
||||
X153860000Y-54013333D01*
|
||||
X153955238Y-53965714D01*
|
||||
X154098095Y-53965714D01*
|
||||
X154193333Y-54013333D01*
|
||||
X154240952Y-54060952D01*
|
||||
X154288571Y-54156190D01*
|
||||
X154288571Y-54441904D01*
|
||||
X154240952Y-54537142D01*
|
||||
X154193333Y-54584761D01*
|
||||
X154098095Y-54632380D01*
|
||||
X153955238Y-54632380D01*
|
||||
X154717142Y-54632380D02*
|
||||
X154717142Y-53965714D01*
|
||||
X154717142Y-54156190D02*
|
||||
X154764761Y-54060952D01*
|
||||
X154812380Y-54013333D01*
|
||||
X154907619Y-53965714D01*
|
||||
X155002857Y-53965714D01*
|
||||
X155336190Y-54632380D02*
|
||||
X155336190Y-53965714D01*
|
||||
X155336190Y-54060952D02*
|
||||
X155383809Y-54013333D01*
|
||||
X155479047Y-53965714D01*
|
||||
X155621904Y-53965714D01*
|
||||
X155717142Y-54013333D01*
|
||||
X155764761Y-54108571D01*
|
||||
X155764761Y-54632380D01*
|
||||
X155764761Y-54108571D02*
|
||||
X155812380Y-54013333D01*
|
||||
X155907619Y-53965714D01*
|
||||
X156050476Y-53965714D01*
|
||||
X156145714Y-54013333D01*
|
||||
X156193333Y-54108571D01*
|
||||
X156193333Y-54632380D01*
|
||||
X157098095Y-54632380D02*
|
||||
X157098095Y-54108571D01*
|
||||
X157050476Y-54013333D01*
|
||||
X156955238Y-53965714D01*
|
||||
X156764761Y-53965714D01*
|
||||
X156669523Y-54013333D01*
|
||||
X157098095Y-54584761D02*
|
||||
X157002857Y-54632380D01*
|
||||
X156764761Y-54632380D01*
|
||||
X156669523Y-54584761D01*
|
||||
X156621904Y-54489523D01*
|
||||
X156621904Y-54394285D01*
|
||||
X156669523Y-54299047D01*
|
||||
X156764761Y-54251428D01*
|
||||
X157002857Y-54251428D01*
|
||||
X157098095Y-54203809D01*
|
||||
X157431428Y-53965714D02*
|
||||
X157812380Y-53965714D01*
|
||||
X157574285Y-53632380D02*
|
||||
X157574285Y-54489523D01*
|
||||
X157621904Y-54584761D01*
|
||||
X157717142Y-54632380D01*
|
||||
X157812380Y-54632380D01*
|
||||
X158145714Y-54632380D02*
|
||||
X158145714Y-53965714D01*
|
||||
X158145714Y-53632380D02*
|
||||
X158098095Y-53680000D01*
|
||||
X158145714Y-53727619D01*
|
||||
X158193333Y-53680000D01*
|
||||
X158145714Y-53632380D01*
|
||||
X158145714Y-53727619D01*
|
||||
X158621904Y-54632380D02*
|
||||
X158621904Y-53632380D01*
|
||||
X158717142Y-54251428D02*
|
||||
X159002857Y-54632380D01*
|
||||
X159002857Y-53965714D02*
|
||||
X158621904Y-54346666D01*
|
||||
X160717142Y-53680000D02*
|
||||
X160621904Y-53632380D01*
|
||||
X160479047Y-53632380D01*
|
||||
X160336190Y-53680000D01*
|
||||
X160240952Y-53775238D01*
|
||||
X160193333Y-53870476D01*
|
||||
X160145714Y-54060952D01*
|
||||
X160145714Y-54203809D01*
|
||||
X160193333Y-54394285D01*
|
||||
X160240952Y-54489523D01*
|
||||
X160336190Y-54584761D01*
|
||||
X160479047Y-54632380D01*
|
||||
X160574285Y-54632380D01*
|
||||
X160717142Y-54584761D01*
|
||||
X160764761Y-54537142D01*
|
||||
X160764761Y-54203809D01*
|
||||
X160574285Y-54203809D01*
|
||||
X161193333Y-54632380D02*
|
||||
X161193333Y-53965714D01*
|
||||
X161193333Y-54060952D02*
|
||||
X161240952Y-54013333D01*
|
||||
X161336190Y-53965714D01*
|
||||
X161479047Y-53965714D01*
|
||||
X161574285Y-54013333D01*
|
||||
X161621904Y-54108571D01*
|
||||
X161621904Y-54632380D01*
|
||||
X161621904Y-54108571D02*
|
||||
X161669523Y-54013333D01*
|
||||
X161764761Y-53965714D01*
|
||||
X161907619Y-53965714D01*
|
||||
X162002857Y-54013333D01*
|
||||
X162050476Y-54108571D01*
|
||||
X162050476Y-54632380D01*
|
||||
X162526666Y-54632380D02*
|
||||
X162526666Y-53632380D01*
|
||||
X162526666Y-54013333D02*
|
||||
X162621904Y-53965714D01*
|
||||
X162812380Y-53965714D01*
|
||||
X162907619Y-54013333D01*
|
||||
X162955238Y-54060952D01*
|
||||
X163002857Y-54156190D01*
|
||||
X163002857Y-54441904D01*
|
||||
X162955238Y-54537142D01*
|
||||
X162907619Y-54584761D01*
|
||||
X162812380Y-54632380D01*
|
||||
X162621904Y-54632380D01*
|
||||
X162526666Y-54584761D01*
|
||||
X163431428Y-54632380D02*
|
||||
X163431428Y-53632380D01*
|
||||
X163431428Y-54108571D02*
|
||||
X164002857Y-54108571D01*
|
||||
X164002857Y-54632380D02*
|
||||
X164002857Y-53632380D01*
|
||||
X165240952Y-54251428D02*
|
||||
X166002857Y-54251428D01*
|
||||
X167145714Y-53965714D02*
|
||||
X167383809Y-54632380D01*
|
||||
X167621904Y-53965714D01*
|
||||
X168526666Y-54632380D02*
|
||||
X167955238Y-54632380D01*
|
||||
X168240952Y-54632380D02*
|
||||
X168240952Y-53632380D01*
|
||||
X168145714Y-53775238D01*
|
||||
X168050476Y-53870476D01*
|
||||
X167955238Y-53918095D01*
|
||||
X168955238Y-54537142D02*
|
||||
X169002857Y-54584761D01*
|
||||
X168955238Y-54632380D01*
|
||||
X168907619Y-54584761D01*
|
||||
X168955238Y-54537142D01*
|
||||
X168955238Y-54632380D01*
|
||||
X169955238Y-54632380D02*
|
||||
X169383809Y-54632380D01*
|
||||
X169669523Y-54632380D02*
|
||||
X169669523Y-53632380D01*
|
||||
X169574285Y-53775238D01*
|
||||
X169479047Y-53870476D01*
|
||||
X169383809Y-53918095D01*
|
||||
X171145714Y-54251428D02*
|
||||
X171907619Y-54251428D01*
|
||||
X173098095Y-53727619D02*
|
||||
X173145714Y-53680000D01*
|
||||
X173240952Y-53632380D01*
|
||||
X173479047Y-53632380D01*
|
||||
X173574285Y-53680000D01*
|
||||
X173621904Y-53727619D01*
|
||||
X173669523Y-53822857D01*
|
||||
X173669523Y-53918095D01*
|
||||
X173621904Y-54060952D01*
|
||||
X173050476Y-54632380D01*
|
||||
X173669523Y-54632380D01*
|
||||
X174288571Y-53632380D02*
|
||||
X174383809Y-53632380D01*
|
||||
X174479047Y-53680000D01*
|
||||
X174526666Y-53727619D01*
|
||||
X174574285Y-53822857D01*
|
||||
X174621904Y-54013333D01*
|
||||
X174621904Y-54251428D01*
|
||||
X174574285Y-54441904D01*
|
||||
X174526666Y-54537142D01*
|
||||
X174479047Y-54584761D01*
|
||||
X174383809Y-54632380D01*
|
||||
X174288571Y-54632380D01*
|
||||
X174193333Y-54584761D01*
|
||||
X174145714Y-54537142D01*
|
||||
X174098095Y-54441904D01*
|
||||
X174050476Y-54251428D01*
|
||||
X174050476Y-54013333D01*
|
||||
X174098095Y-53822857D01*
|
||||
X174145714Y-53727619D01*
|
||||
X174193333Y-53680000D01*
|
||||
X174288571Y-53632380D01*
|
||||
X175574285Y-54632380D02*
|
||||
X175002857Y-54632380D01*
|
||||
X175288571Y-54632380D02*
|
||||
X175288571Y-53632380D01*
|
||||
X175193333Y-53775238D01*
|
||||
X175098095Y-53870476D01*
|
||||
X175002857Y-53918095D01*
|
||||
X176050476Y-54632380D02*
|
||||
X176240952Y-54632380D01*
|
||||
X176336190Y-54584761D01*
|
||||
X176383809Y-54537142D01*
|
||||
X176479047Y-54394285D01*
|
||||
X176526666Y-54203809D01*
|
||||
X176526666Y-53822857D01*
|
||||
X176479047Y-53727619D01*
|
||||
X176431428Y-53680000D01*
|
||||
X176336190Y-53632380D01*
|
||||
X176145714Y-53632380D01*
|
||||
X176050476Y-53680000D01*
|
||||
X176002857Y-53727619D01*
|
||||
X175955238Y-53822857D01*
|
||||
X175955238Y-54060952D01*
|
||||
X176002857Y-54156190D01*
|
||||
X176050476Y-54203809D01*
|
||||
X176145714Y-54251428D01*
|
||||
X176336190Y-54251428D01*
|
||||
X176431428Y-54203809D01*
|
||||
X176479047Y-54156190D01*
|
||||
X176526666Y-54060952D01*
|
||||
D11*
|
||||
G04 #@! TO.C,U2*
|
||||
X135890000Y-63540000D02*
|
||||
X85090000Y-63540000D01*
|
||||
X135890000Y-86400000D02*
|
||||
X135890000Y-63540000D01*
|
||||
X85090000Y-86400000D02*
|
||||
X135890000Y-86400000D01*
|
||||
X85090000Y-63540000D02*
|
||||
X85090000Y-86400000D01*
|
||||
D12*
|
||||
G04 #@! TO.C,HX711-2*
|
||||
X160020000Y-90375000D02*
|
||||
X137160000Y-90375000D01*
|
||||
X137160000Y-90375000D02*
|
||||
X137160000Y-59895000D01*
|
||||
X137160000Y-59895000D02*
|
||||
X160020000Y-59895000D01*
|
||||
X160020000Y-59895000D02*
|
||||
X160020000Y-90375000D01*
|
||||
D13*
|
||||
X143406000Y-91391000D02*
|
||||
G75*
|
||||
G03X143406000Y-91391000I-150000J0D01*
|
||||
G01*
|
||||
D12*
|
||||
G04 #@! TO.C,HX711-1*
|
||||
X184150000Y-90375000D02*
|
||||
X161290000Y-90375000D01*
|
||||
X161290000Y-90375000D02*
|
||||
X161290000Y-59895000D01*
|
||||
X161290000Y-59895000D02*
|
||||
X184150000Y-59895000D01*
|
||||
X184150000Y-59895000D02*
|
||||
X184150000Y-90375000D01*
|
||||
D13*
|
||||
X167536000Y-91391000D02*
|
||||
G75*
|
||||
G03X167536000Y-91391000I-150000J0D01*
|
||||
G01*
|
||||
D12*
|
||||
G04 #@! TO.C,J1*
|
||||
X193965000Y-79730000D02*
|
||||
X193965000Y-92830000D01*
|
||||
X193965000Y-92830000D02*
|
||||
X193725000Y-92830000D01*
|
||||
X186165000Y-92830000D02*
|
||||
X189605000Y-92830000D01*
|
||||
X186165000Y-79730000D02*
|
||||
X189495000Y-79730000D01*
|
||||
X193965000Y-79730000D02*
|
||||
X193725000Y-79730000D01*
|
||||
D14*
|
||||
X185575000Y-85370000D02*
|
||||
G75*
|
||||
G03X185575000Y-85370000I-200000J0D01*
|
||||
G01*
|
||||
G04 #@! TO.C,J2*
|
||||
X83630000Y-87190000D02*
|
||||
G75*
|
||||
G03X83630000Y-87190000I-200000J0D01*
|
||||
G01*
|
||||
D12*
|
||||
X74840000Y-92830000D02*
|
||||
X75080000Y-92830000D01*
|
||||
X82640000Y-92830000D02*
|
||||
X79310000Y-92830000D01*
|
||||
X82640000Y-79730000D02*
|
||||
X79200000Y-79730000D01*
|
||||
X74840000Y-79730000D02*
|
||||
X75080000Y-79730000D01*
|
||||
X74840000Y-92830000D02*
|
||||
X74840000Y-79730000D01*
|
||||
G04 #@! TO.C,J3*
|
||||
X80540000Y-56935000D02*
|
||||
X80540000Y-60935000D01*
|
||||
X80540000Y-63535000D02*
|
||||
X80540000Y-69335000D01*
|
||||
X80540000Y-72035000D02*
|
||||
X80540000Y-75935000D01*
|
||||
X80540000Y-75935000D02*
|
||||
X74960000Y-75935000D01*
|
||||
X74960000Y-56935000D02*
|
||||
X80540000Y-56935000D01*
|
||||
D10*
|
||||
X81138000Y-65025000D02*
|
||||
G75*
|
||||
G03X81138000Y-65025000I-100000J0D01*
|
||||
G01*
|
||||
D12*
|
||||
X74960000Y-56935000D02*
|
||||
X74960000Y-75935000D01*
|
||||
D15*
|
||||
G04 #@! TO.C,J4*
|
||||
X108605000Y-61085000D02*
|
||||
X108605000Y-55115000D01*
|
||||
X108605000Y-55115000D02*
|
||||
X100985000Y-55115000D01*
|
||||
X100985000Y-55115000D02*
|
||||
X100985000Y-61085000D01*
|
||||
X100985000Y-61085000D02*
|
||||
X108605000Y-61085000D01*
|
||||
X105295000Y-61075000D02*
|
||||
X105295000Y-60325000D01*
|
||||
X105295000Y-60325000D02*
|
||||
X104295000Y-60325000D01*
|
||||
X104295000Y-60325000D02*
|
||||
X104295000Y-61075000D01*
|
||||
X104295000Y-61075000D02*
|
||||
X105295000Y-61075000D01*
|
||||
X108595000Y-61075000D02*
|
||||
X108595000Y-60325000D01*
|
||||
X108595000Y-60325000D02*
|
||||
X106795000Y-60325000D01*
|
||||
X106795000Y-60325000D02*
|
||||
X106795000Y-61075000D01*
|
||||
X106795000Y-61075000D02*
|
||||
X108595000Y-61075000D01*
|
||||
X102795000Y-61075000D02*
|
||||
X102795000Y-60325000D01*
|
||||
X102795000Y-60325000D02*
|
||||
X100995000Y-60325000D01*
|
||||
X100995000Y-60325000D02*
|
||||
X100995000Y-61075000D01*
|
||||
X100995000Y-61075000D02*
|
||||
X102795000Y-61075000D01*
|
||||
X108595000Y-58825000D02*
|
||||
X107845000Y-58825000D01*
|
||||
X107845000Y-58825000D02*
|
||||
X107845000Y-57485000D01*
|
||||
X104795000Y-55875000D02*
|
||||
X106785000Y-55875000D01*
|
||||
X100995000Y-58825000D02*
|
||||
X101745000Y-58825000D01*
|
||||
X101745000Y-58825000D02*
|
||||
X101745000Y-55875000D01*
|
||||
X101745000Y-55875000D02*
|
||||
X104795000Y-55875000D01*
|
||||
X107645000Y-61375000D02*
|
||||
X108895000Y-61375000D01*
|
||||
X108895000Y-61375000D02*
|
||||
X108895000Y-60125000D01*
|
||||
G04 #@! TO.C,SW1*
|
||||
X185545000Y-71465000D02*
|
||||
X185545000Y-70165000D01*
|
||||
X186845000Y-71465000D02*
|
||||
X185545000Y-71465000D01*
|
||||
X193195000Y-59215000D02*
|
||||
X193195000Y-69115000D01*
|
||||
X186495000Y-69115000D02*
|
||||
X186495000Y-59215000D01*
|
||||
X192445000Y-71165000D02*
|
||||
X187245000Y-71165000D01*
|
||||
X187245000Y-57165000D02*
|
||||
X192445000Y-57165000D01*
|
||||
G04 #@! TO.C,HX711-2*
|
||||
D14*
|
||||
X152924088Y-92607908D02*
|
||||
X152924088Y-91607848D01*
|
||||
X152924088Y-92084067D02*
|
||||
X153495551Y-92084067D01*
|
||||
X153495551Y-92607908D02*
|
||||
X153495551Y-91607848D01*
|
||||
X153876526Y-91607848D02*
|
||||
X154543233Y-92607908D01*
|
||||
X154543233Y-91607848D02*
|
||||
X153876526Y-92607908D01*
|
||||
X154828964Y-91607848D02*
|
||||
X155495671Y-91607848D01*
|
||||
X155067074Y-92607908D01*
|
||||
X156400487Y-92607908D02*
|
||||
X155829024Y-92607908D01*
|
||||
X156114756Y-92607908D02*
|
||||
X156114756Y-91607848D01*
|
||||
X156019512Y-91750713D01*
|
||||
X155924268Y-91845957D01*
|
||||
X155829024Y-91893579D01*
|
||||
X157352925Y-92607908D02*
|
||||
X156781462Y-92607908D01*
|
||||
X157067194Y-92607908D02*
|
||||
X157067194Y-91607848D01*
|
||||
X156971950Y-91750713D01*
|
||||
X156876706Y-91845957D01*
|
||||
X156781462Y-91893579D01*
|
||||
X157781522Y-92226932D02*
|
||||
X158543473Y-92226932D01*
|
||||
X158972070Y-91703091D02*
|
||||
X159019692Y-91655470D01*
|
||||
X159114936Y-91607848D01*
|
||||
X159353045Y-91607848D01*
|
||||
X159448289Y-91655470D01*
|
||||
X159495911Y-91703091D01*
|
||||
X159543533Y-91798335D01*
|
||||
X159543533Y-91893579D01*
|
||||
X159495911Y-92036445D01*
|
||||
X158924448Y-92607908D01*
|
||||
X159543533Y-92607908D01*
|
||||
G04 #@! TO.C,HX711-1*
|
||||
X161814088Y-92607908D02*
|
||||
X161814088Y-91607848D01*
|
||||
X161814088Y-92084067D02*
|
||||
X162385551Y-92084067D01*
|
||||
X162385551Y-92607908D02*
|
||||
X162385551Y-91607848D01*
|
||||
X162766526Y-91607848D02*
|
||||
X163433233Y-92607908D01*
|
||||
X163433233Y-91607848D02*
|
||||
X162766526Y-92607908D01*
|
||||
X163718964Y-91607848D02*
|
||||
X164385671Y-91607848D01*
|
||||
X163957074Y-92607908D01*
|
||||
X165290487Y-92607908D02*
|
||||
X164719024Y-92607908D01*
|
||||
X165004756Y-92607908D02*
|
||||
X165004756Y-91607848D01*
|
||||
X164909512Y-91750713D01*
|
||||
X164814268Y-91845957D01*
|
||||
X164719024Y-91893579D01*
|
||||
X166242925Y-92607908D02*
|
||||
X165671462Y-92607908D01*
|
||||
X165957194Y-92607908D02*
|
||||
X165957194Y-91607848D01*
|
||||
X165861950Y-91750713D01*
|
||||
X165766706Y-91845957D01*
|
||||
X165671462Y-91893579D01*
|
||||
X166671522Y-92226932D02*
|
||||
X167433473Y-92226932D01*
|
||||
X168433533Y-92607908D02*
|
||||
X167862070Y-92607908D01*
|
||||
X168147801Y-92607908D02*
|
||||
X168147801Y-91607848D01*
|
||||
X168052558Y-91750713D01*
|
||||
X167957314Y-91845957D01*
|
||||
X167862070Y-91893579D01*
|
||||
G04 #@! TO.C,J1*
|
||||
X186556296Y-93986773D02*
|
||||
X186556296Y-94701851D01*
|
||||
X186508624Y-94844867D01*
|
||||
X186413280Y-94940211D01*
|
||||
X186270265Y-94987883D01*
|
||||
X186174921Y-94987883D01*
|
||||
X187557406Y-94987883D02*
|
||||
X186985343Y-94987883D01*
|
||||
X187271375Y-94987883D02*
|
||||
X187271375Y-93986773D01*
|
||||
X187176031Y-94129788D01*
|
||||
X187080687Y-94225132D01*
|
||||
X186985343Y-94272804D01*
|
||||
G04 #@! TO.C,J2*
|
||||
X81581296Y-93986773D02*
|
||||
X81581296Y-94701851D01*
|
||||
X81533624Y-94844867D01*
|
||||
X81438280Y-94940211D01*
|
||||
X81295265Y-94987883D01*
|
||||
X81199921Y-94987883D01*
|
||||
X82010343Y-94082116D02*
|
||||
X82058015Y-94034445D01*
|
||||
X82153359Y-93986773D01*
|
||||
X82391719Y-93986773D01*
|
||||
X82487062Y-94034445D01*
|
||||
X82534734Y-94082116D01*
|
||||
X82582406Y-94177460D01*
|
||||
X82582406Y-94272804D01*
|
||||
X82534734Y-94415820D01*
|
||||
X81962671Y-94987883D01*
|
||||
X82582406Y-94987883D01*
|
||||
G04 #@! TO.C,J3*
|
||||
X79675383Y-54900272D02*
|
||||
X79675383Y-55617308D01*
|
||||
X79627580Y-55760715D01*
|
||||
X79531976Y-55856320D01*
|
||||
X79388569Y-55904122D01*
|
||||
X79292964Y-55904122D01*
|
||||
X80057802Y-54900272D02*
|
||||
X80679233Y-54900272D01*
|
||||
X80344616Y-55282691D01*
|
||||
X80488023Y-55282691D01*
|
||||
X80583628Y-55330494D01*
|
||||
X80631430Y-55378296D01*
|
||||
X80679233Y-55473901D01*
|
||||
X80679233Y-55712913D01*
|
||||
X80631430Y-55808517D01*
|
||||
X80583628Y-55856320D01*
|
||||
X80488023Y-55904122D01*
|
||||
X80201209Y-55904122D01*
|
||||
X80105604Y-55856320D01*
|
||||
X80057802Y-55808517D01*
|
||||
G04 #@! TO.C,J4*
|
||||
X98726666Y-59982380D02*
|
||||
X98726666Y-60696666D01*
|
||||
X98679047Y-60839523D01*
|
||||
X98583809Y-60934761D01*
|
||||
X98440952Y-60982380D01*
|
||||
X98345714Y-60982380D01*
|
||||
X99631428Y-60315714D02*
|
||||
X99631428Y-60982380D01*
|
||||
X99393333Y-59934761D02*
|
||||
X99155238Y-60649047D01*
|
||||
X99774285Y-60649047D01*
|
||||
G04 #@! TO.C,SW1*
|
||||
X185991666Y-56074761D02*
|
||||
X186134523Y-56122380D01*
|
||||
X186372619Y-56122380D01*
|
||||
X186467857Y-56074761D01*
|
||||
X186515476Y-56027142D01*
|
||||
X186563095Y-55931904D01*
|
||||
X186563095Y-55836666D01*
|
||||
X186515476Y-55741428D01*
|
||||
X186467857Y-55693809D01*
|
||||
X186372619Y-55646190D01*
|
||||
X186182142Y-55598571D01*
|
||||
X186086904Y-55550952D01*
|
||||
X186039285Y-55503333D01*
|
||||
X185991666Y-55408095D01*
|
||||
X185991666Y-55312857D01*
|
||||
X186039285Y-55217619D01*
|
||||
X186086904Y-55170000D01*
|
||||
X186182142Y-55122380D01*
|
||||
X186420238Y-55122380D01*
|
||||
X186563095Y-55170000D01*
|
||||
X186896428Y-55122380D02*
|
||||
X187134523Y-56122380D01*
|
||||
X187325000Y-55408095D01*
|
||||
X187515476Y-56122380D01*
|
||||
X187753571Y-55122380D01*
|
||||
X188658333Y-56122380D02*
|
||||
X188086904Y-56122380D01*
|
||||
X188372619Y-56122380D02*
|
||||
X188372619Y-55122380D01*
|
||||
X188277380Y-55265238D01*
|
||||
X188182142Y-55360476D01*
|
||||
X188086904Y-55408095D01*
|
||||
G04 #@! TD*
|
||||
M02*
|
||||
@@ -0,0 +1,122 @@
|
||||
M48
|
||||
;DRILL file {KiCad 5.0.2-5.fc29} date Fr 22 Mär 2019 17:51:56 CET
|
||||
;FORMAT={-:-/ absolute / inch / decimal}
|
||||
FMAT,2
|
||||
INCH,TZ
|
||||
T1C0.0157
|
||||
T2C0.0276
|
||||
T3C0.0354
|
||||
T4C0.0390
|
||||
T5C0.0394
|
||||
T6C0.0400
|
||||
T7C0.0472
|
||||
T8C0.0866
|
||||
T9C0.1000
|
||||
T10C0.0472
|
||||
%
|
||||
G90
|
||||
G05
|
||||
T1
|
||||
X4.425Y-3.1831
|
||||
T2
|
||||
X3.0685Y-2.59
|
||||
X3.0685Y-2.6411
|
||||
X3.1315Y-2.5644
|
||||
X3.1315Y-2.6156
|
||||
X3.1315Y-2.6667
|
||||
T3
|
||||
X7.425Y-2.3687
|
||||
X7.425Y-2.5262
|
||||
X7.425Y-2.6837
|
||||
X3.2299Y-3.2197
|
||||
X3.2299Y-3.2906
|
||||
X3.2299Y-3.3614
|
||||
X3.2299Y-3.4323
|
||||
X3.2299Y-3.5031
|
||||
X3.2299Y-3.574
|
||||
X7.353Y-3.2197
|
||||
X7.353Y-3.2906
|
||||
X7.353Y-3.3614
|
||||
X7.353Y-3.4323
|
||||
X7.353Y-3.5031
|
||||
X7.353Y-3.574
|
||||
T4
|
||||
X3.6Y-3.3516
|
||||
X3.7Y-3.3516
|
||||
X3.8Y-3.3516
|
||||
X3.9Y-3.3516
|
||||
X4.Y-2.5516
|
||||
X4.Y-3.3516
|
||||
X4.1Y-2.5516
|
||||
X4.1Y-3.3516
|
||||
X4.2Y-2.5516
|
||||
X4.2Y-3.3516
|
||||
X4.3Y-2.5516
|
||||
X4.3Y-3.3516
|
||||
X4.4Y-2.5516
|
||||
X4.4Y-3.3516
|
||||
X4.5Y-2.5516
|
||||
X4.5Y-3.3516
|
||||
X4.6Y-2.5516
|
||||
X4.6Y-3.3516
|
||||
X4.7Y-2.5516
|
||||
X4.7Y-3.3516
|
||||
X4.8Y-2.5516
|
||||
X4.8Y-3.3516
|
||||
X4.9Y-2.5516
|
||||
X4.9Y-3.3516
|
||||
X5.Y-2.5516
|
||||
X5.Y-3.3516
|
||||
X5.1Y-2.5516
|
||||
X5.1Y-3.3516
|
||||
T5
|
||||
X3.037Y-3.1449
|
||||
X3.037Y-3.6488
|
||||
X3.1Y-2.4482
|
||||
X3.1Y-2.7829
|
||||
X7.5459Y-3.1449
|
||||
X7.5459Y-3.6488
|
||||
X4.0766Y-2.3081
|
||||
X4.175Y-2.3081
|
||||
T6
|
||||
X6.6Y-2.4081
|
||||
X6.6Y-3.5081
|
||||
X6.7Y-2.4081
|
||||
X6.7Y-3.5081
|
||||
X6.8Y-2.4081
|
||||
X6.8Y-3.5081
|
||||
X6.9Y-2.4081
|
||||
X6.9Y-2.7081
|
||||
X6.9Y-3.5081
|
||||
X7.Y-2.4081
|
||||
X7.Y-2.7081
|
||||
X7.Y-3.5081
|
||||
X5.65Y-2.4081
|
||||
X5.65Y-3.5081
|
||||
X5.75Y-2.4081
|
||||
X5.75Y-3.5081
|
||||
X5.85Y-2.4081
|
||||
X5.85Y-3.5081
|
||||
X5.95Y-2.4081
|
||||
X5.95Y-2.7081
|
||||
X5.95Y-3.5081
|
||||
X6.05Y-2.4081
|
||||
X6.05Y-2.7081
|
||||
X6.05Y-3.5081
|
||||
T7
|
||||
X7.3561Y-2.29
|
||||
X7.3561Y-2.7624
|
||||
X7.5923Y-2.29
|
||||
X7.5923Y-2.7624
|
||||
T8
|
||||
X3.0646Y-3.3969
|
||||
X7.5183Y-3.3969
|
||||
T9
|
||||
X3.45Y-2.6016
|
||||
X3.45Y-3.3016
|
||||
X5.25Y-2.6016
|
||||
X5.25Y-3.3016
|
||||
T10
|
||||
X4.238Y-2.2293
|
||||
T0
|
||||
M30
|
||||
@@ -0,0 +1,3 @@
|
||||
(sym_lib_table
|
||||
(lib (name beieliscale-kicad-eagle-import)(type Legacy)(uri ${KIPRJMOD}/beieliscale-kicad-eagle-import.lib)(options "")(descr ""))
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python3
|
||||
from time import sleep
|
||||
import serial
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
while (True):
|
||||
serial_not_open = True
|
||||
while serial_not_open:
|
||||
try:
|
||||
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
|
||||
except:
|
||||
sleep(0.5)
|
||||
else:
|
||||
serial_not_open = False
|
||||
|
||||
no_exception = True
|
||||
while no_exception:
|
||||
try:
|
||||
while True:
|
||||
while ser.inWaiting():
|
||||
print(ser.read().decode('utf-8'), end='')
|
||||
sleep(0.1)
|
||||
except:
|
||||
print(datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")," - Serial Device disappeared...")
|
||||
ser.close()
|
||||
no_exception = False
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python3
|
||||
from time import sleep
|
||||
import serial
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
while (True):
|
||||
serial_not_open = True
|
||||
while serial_not_open:
|
||||
try:
|
||||
ser = serial.Serial('/dev/ttyUSB1', 115200, timeout=1)
|
||||
except:
|
||||
sleep(0.5)
|
||||
else:
|
||||
serial_not_open = False
|
||||
|
||||
no_exception = True
|
||||
while no_exception:
|
||||
try:
|
||||
while True:
|
||||
while ser.inWaiting():
|
||||
print(ser.read().decode('utf-8'), end='')
|
||||
sleep(0.1)
|
||||
except:
|
||||
print(datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")," - Serial Device disappeared...")
|
||||
ser.close()
|
||||
no_exception = False
|
||||