diff --git a/i2c-scanner.ino b/i2c-scanner.ino new file mode 100644 index 0000000..e12af08 --- /dev/null +++ b/i2c-scanner.ino @@ -0,0 +1,61 @@ +/* I2C SCANNER + http://playground.arduino.cc/Main/I2cScanner + + This sketch tests the standard 7-bit addresses + Devices with higher bit address might not be seen properly. + */ + + +#include + + +void setup() +{ + Wire.begin(); + + Serial.begin(9600); + Serial.println("\nI2C Scanner"); +} + + +void loop() +{ + byte error, address; + int nDevices; + + Serial.println("Scanning..."); + + nDevices = 0; + for(address = 1; address < 127; address++ ) + { + // The i2c_scanner uses the return value of + // the Write.endTransmisstion to see if + // a device did acknowledge to the address. + Wire.beginTransmission(address); + error = Wire.endTransmission(); + + if (error == 0) + { + Serial.print("I2C device found at address 0x"); + if (address<16) + Serial.print("0"); + Serial.print(address,HEX); + Serial.println(" !"); + + nDevices++; + } + else if (error==4) + { + Serial.print("Unknow error at address 0x"); + if (address<16) + Serial.print("0"); + Serial.println(address,HEX); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found\n"); + else + Serial.println("done\n"); + + delay(5000); // wait 5 seconds for next scan +} diff --git a/lorawan-sensor.ino b/lorawan-sensor.ino new file mode 100644 index 0000000..628c87c --- /dev/null +++ b/lorawan-sensor.ino @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman + * + * Permission is hereby granted, free of charge, to anyone + * obtaining a copy of this document and accompanying files, + * to do whatever they want with them without any restriction, + * including, but not limited to, copying, modification and redistribution. + * NO WARRANTY OF ANY KIND IS PROVIDED. + * + * This example sends a valid LoRaWAN packet with payload "Hello, + * world!", using frequency and encryption settings matching those of + * the The Things Network. + * + * This uses OTAA (Over-the-air activation), where where a DevEUI and + * application key is configured, which are used in an over-the-air + * activation procedure where a DevAddr and session keys are + * assigned/generated for use with all further communication. + * + * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in + * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably + * violated by this sketch when left running for longer)! + * To use this sketch, first register your application and device with + * the things network, to set or generate an AppEUI, DevEUI and AppKey. + * Multiple devices can use the same AppEUI, but each device has its own + * DevEUI and AppKey. + * + * Do not forget to define the radio type correctly in config.h. + * + *******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} +void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} +void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} + +static uint8_t mydata[] = "ping"; +static osjob_t sendjob; + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 30; + +const lmic_pinmap lmic_pins = { + .nss = 10, + .rxtx = LMIC_UNUSED_PIN, + .rst = LMIC_UNUSED_PIN, // hardwired to AtMega RESET + .dio = {4,5,LMIC_UNUSED_PIN}// .dio = {4, 5, LMIC_UNUSED_PIN}, +}; + +CayenneLPP lpp(51); +BME280I2C bme; + +long readVcc() { + // Read 1.1V reference against AVcc + // set the reference to Vcc and the measurement to the internal 1.1V reference + #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); + #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) + ADMUX = _BV(MUX5) | _BV(MUX0); + #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) + ADMUX = _BV(MUX3) | _BV(MUX2); + #else + ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); + #endif + + delay(2); // Wait for Vref to settle + ADCSRA |= _BV(ADSC); // Start conversion + while (bit_is_set(ADCSRA,ADSC)); // measuring + + uint8_t low = ADCL; // must read ADCL first - it then locks ADCH + uint8_t high = ADCH; // unlocks both + + long result = (high<<8) | low; + + result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 + return result; // Vcc in millivolts +} + +void onEvent (ev_t ev) { + Serial.print(os_getTime()); + Serial.print(": "); + switch(ev) { + case EV_SCAN_TIMEOUT: + Serial.println(F("EV_SCAN_TIMEOUT")); + break; + case EV_BEACON_FOUND: + Serial.println(F("EV_BEACON_FOUND")); + break; + case EV_BEACON_MISSED: + Serial.println(F("EV_BEACON_MISSED")); + break; + case EV_BEACON_TRACKED: + Serial.println(F("EV_BEACON_TRACKED")); + break; + case EV_JOINING: + Serial.println(F("EV_JOINING")); + break; + case EV_JOINED: + Serial.println(F("EV_JOINED")); + + // Disable link check validation (automatically enabled + // during join, but not supported by TTN at this time). + LMIC_setLinkCheckMode(0); + break; + case EV_RFU1: + Serial.println(F("EV_RFU1")); + break; + case EV_JOIN_FAILED: + Serial.println(F("EV_JOIN_FAILED")); + break; + case EV_REJOIN_FAILED: + Serial.println(F("EV_REJOIN_FAILED")); + break; + break; + case EV_TXCOMPLETE: + Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); + if (LMIC.txrxFlags & TXRX_ACK) + Serial.println(F("Received ack")); + if (LMIC.dataLen) { + Serial.println(F("Received ")); + Serial.println(LMIC.dataLen); + Serial.println(F(" bytes of payload")); + } + /*Serial.print(F("Frequency: ")); + Serial.println(LMIC.freq); + Serial.print(F("RSSI: ")); + Serial.println(LMIC.rssi); + Serial.print(F("SNR: ")); + Serial.println(LMIC.snr); + Serial.print(F("txpow: ")); + Serial.println(LMIC.txpow);*/ + Serial.print(F("adrTxPow: ")); + Serial.println(LMIC.adrTxPow); + Serial.print(F("txChnl: ")); + Serial.println(LMIC.txChnl); + Serial.println(); + // Schedule next transmission + os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); + break; + case EV_LOST_TSYNC: + Serial.println(F("EV_LOST_TSYNC")); + break; + case EV_RESET: + Serial.println(F("EV_RESET")); + break; + case EV_RXCOMPLETE: + // data received in ping slot + Serial.println(F("EV_RXCOMPLETE")); + break; + case EV_LINK_DEAD: + Serial.println(F("EV_LINK_DEAD")); + break; + case EV_LINK_ALIVE: + Serial.println(F("EV_LINK_ALIVE")); + break; + default: + Serial.println(F("Unknown event")); + break; + } +} + +void do_send(osjob_t* j){ + // Check if there is not a current TX/RX job running + if (LMIC.opmode & OP_TXRXPEND) { + Serial.println(F("OP_TXRXPEND, not sending")); + } else { + float temp(NAN), hum(NAN), pres(NAN); + + BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); + BME280::PresUnit presUnit(BME280::PresUnit_hPa); + + bme.read(pres, temp, hum, tempUnit, presUnit); + + float voltage = readVcc() / 1000.0 ; + + lpp.reset(); + lpp.addTemperature(1, temp); + lpp.addRelativeHumidity(2, hum); + lpp.addBarometricPressure(3, pres); + lpp.addAnalogInput(4, voltage); + // Prepare upstream data transmission at the next possible time. + LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0); + Serial.println(F("Packet queued")); + } + // Next TX is scheduled after TX_COMPLETE event. +} + +void setup() { + Serial.begin(9600); + Serial.println(F("Starting TTN Muc Cayenne Sensor 1")); + + while(!bme.begin()) + { + Serial.println("Could not find BME280 sensor!"); + delay(1000); + } + + + + // LMIC init + os_init(); + + // Reset the MAC state. Session and pending data transfers will be discarded. + LMIC_reset(); + + // Let LMIC compensate for +/- 1% clock error + LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); + + // Start job (sending automatically starts OTAA too) + do_send(&sendjob); +} + +void loop() { + os_runloop_once(); +}