Viewing 2 posts - 1 through 2 (of 2 total)
-
AuthorPosts
-
December 29, 2019 at 5:30 AM #14437bpmcgeeParticipant
Hi,
I hope you can point out what I’m doing wrong. I’m using the ultra v3 with the LMIC library (MCCI LoraWAN LMIC Library) and ArduinoLowPower. I’ve scanned and rescanned every example I can find, but I can’t get the unit to go below 830 uA while in LowPower.sleep ().
What I need to do is to remain asleep until one of two switches is triggered, then wait to see if the other is also triggered, then send a message and go back to sleep.
Below is my code.
#include <ArduinoJson.h> /******************************************************************************* Copyright (c) 2020 Brian McGee Driveway sensor monitor. Do not forget to define the radio type correctly in config.h. *******************************************************************************/ #include <CayenneLPP.h> #include <ArduinoLowPower.h> #include <lmic.h> #include <hal/hal.h> #include <SerialFlash.h> #include <SPI.h> #include <Wire.h> #define EUI64_CHIP_ADDRESS 0x50 #define EUI64_MAC_ADDRESS 0xF8 #define EUI64_MAC_LENGTH 0x08 #define MAX_DATA_SIZE 51 #define Serial SerialUSB /* Local data. */ const float version = 1.3; const int SENSOR1_PIN = 7; const int SENSOR2_PIN = 8; volatile uint32_t trigger1 = 0; volatile uint32_t trigger2 = 0; volatile int programmingMode = 0; const int SFLASH_PIN = 4; int VEHICLE_DELAY = 2000; volatile int vehicle_detection = 1; #define VEHICLE_DETECTED 1 #define VEHICLE_ARRIVING 2 #define VEHICLE_LEAVING 3 const int LED_PIN = 13; // This EUI must be in little-endian format, so least-significant-byte // first. When copying an EUI from ttnctl output, this means to reverse // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, // 0x70. static const u1_t PROGMEM APPEUI[8] = { 0xFF, 0xFF, 0xFF, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8); } // This should also be in little endian format, see above. static u1_t PROGMEM DEVEUI[8]; void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8); } // This key should be in big endian format (or, since it is not really a // number but a block of memory, endianness does not really apply). In // practice, a key taken from ttnctl can be copied as-is. static const u1_t PROGMEM APPKEY[16] = { 0xFF, 0xFF, 0xFF, 0x50, 0x67, 0x14, 0xC7, 0x16, 0xD6, 0x5B, 0x45, 0xD3, 0xFD, 0xC2, 0xAD, 0x8E }; void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16); } //static uint8_t mydata[] = "Hello, world!"; //static uint8_t data[MAX_DATA_SIZE]; CayenneLPP lpp (MAX_DATA_SIZE); static osjob_t sendjob; // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 60; // Pin mapping const lmic_pinmap lmic_pins = { .nss = 5, .rxtx = LMIC_UNUSED_PIN, .rst = 3, .dio = {2, 6, LMIC_UNUSED_PIN}, }; void printHex2(unsigned v) { v &= 0xff; if (v < 16) Serial.print('0'); Serial.print(v, HEX); } 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")); { u4_t netid = 0; devaddr_t devaddr = 0; u1_t nwkKey[16]; u1_t artKey[16]; LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); Serial.print("netid: "); Serial.println(netid, DEC); Serial.print("devaddr: "); Serial.println(devaddr, HEX); Serial.print("AppSKey: "); for (size_t i = 0; i < sizeof(artKey); ++i) { if (i != 0) Serial.print("-"); printHex2(artKey[i]); } Serial.println(""); Serial.print("NwkSKey: "); for (size_t i = 0; i < sizeof(nwkKey); ++i) { if (i != 0) Serial.print("-"); printHex2(nwkKey[i]); } Serial.println(); } // Disable link check validation (automatically enabled // during join, but because slow data rates change max TX // size, we don't use it in this example. //os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(5), sendMessage); break; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_RFU1: || Serial.println(F("EV_RFU1")); || break; */ case EV_JOIN_FAILED: Serial.println(F("EV_JOIN_FAILED")); break; case EV_REJOIN_FAILED: Serial.println(F("EV_REJOIN_FAILED")); break; case EV_TXCOMPLETE: Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); if (LMIC.txrxFlags & TXRX_ACK) Serial.println(F("Received ack")); if (LMIC.dataLen) { Serial.print(F("Received ")); Serial.print(LMIC.dataLen); Serial.println(F(" bytes of payload")); } // Schedule next transmission //os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), sendMessage); 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; /* || This event is defined but not used in the code. No || point in wasting codespace on it. || || case EV_SCAN_FOUND: || Serial.println(F("EV_SCAN_FOUND")); || break; */ case EV_TXSTART: Serial.println(F("EV_TXSTART")); break; case EV_TXCANCELED: Serial.println(F("EV_TXCANCELED")); break; case EV_RXSTART: /* do not print anything -- it wrecks timing */ break; case EV_JOIN_TXCOMPLETE: Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept")); break; default: Serial.print(F("Unknown event: ")); Serial.println((unsigned) ev); break; } } void sendMessage (osjob_t *j) { int x; SerialUSB.print ("Vehicle Detected: "); SerialUSB.println (vehicle_detection); if (vehicle_detection != 0) { if (LMIC.opmode & OP_TXRXPEND) { Serial.println(F("OP_TXRXPEND, not sending")); } else { lpp.reset (); lpp.addDigitalOutput (1, vehicle_detection); LMIC_sendWithCallback(1, lpp.getBuffer(), lpp.getSize(), 0, txCompletionCallback, 0); Serial.println(F("Packet queued")); vehicle_detection = 0; } } } void txCompletionCallback(void *pUserData, int fSuccess) { Serial.print ("TX Completion Status:"); Serial.println (fSuccess); } void setup() { int count; unsigned char pinNumber; // ***** Put unused pins into known state ***** pinMode(0, INPUT_PULLUP); pinMode(1, INPUT_PULLUP); // D7-D13, A0(D14)-A5(D19), SDA(D20), SCL(D21), MISO(D22) for (pinNumber = 7; pinNumber <= 22; pinNumber++) { pinMode(pinNumber, INPUT_PULLUP); } // RX_LED (D25) & TX_LED (D26) (both LED not mounted on Mini Ultra Pro) pinMode(25, INPUT_PULLUP); pinMode(26, INPUT_PULLUP); // D30 (RX) & D31 (TX) of Serial pinMode(30, INPUT_PULLUP); pinMode(31, INPUT_PULLUP); // D34-D38 (EBDG Interface) for (pinNumber = 34; pinNumber <= 38; pinNumber++) { pinMode(pinNumber, INPUT_PULLUP); } // ***** End of unused pins state initialization ***** pinMode(LED_BUILTIN, OUTPUT); digitalWrite (LED_PIN, LOW); /* Enable the vehicle detector pins. */ pinMode(SENSOR1_PIN, INPUT_PULLUP); pinMode(SENSOR2_PIN, INPUT_PULLUP); LowPower.attachInterruptWakeup(digitalPinToInterrupt(SENSOR1_PIN), sensorChanged1, FALLING); LowPower.attachInterruptWakeup(digitalPinToInterrupt(SENSOR2_PIN), sensorChanged2, FALLING); // Initialize serial flash SerialFlash.begin(4); // Put serial flash in sleep SerialFlash.sleep(); setDevEui(&DEVEUI[EUI64_MAC_LENGTH - 1]); if (programmingMode) { while (!Serial && millis() < 10000); Serial.begin(115200); Serial.print("Starting Driveway v"); Serial.println(version, 1); Serial.print(F("DEVEUI: ")); for (count = EUI64_MAC_LENGTH; count > 0; count--) { Serial.print("0x"); if (DEVEUI[count - 1] <= 0x0F) Serial.print("0"); Serial.print(DEVEUI[count - 1], HEX); Serial.print(" "); } Serial.println(); } else { int count; SerialUSB.println("Entering standby mode in:"); for (count = 30; count > 0; count--) { SerialUSB.print(count); SerialUSB.println(" s"); programmingModeDelay (1000); USBDevice.detach (); } } // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); LMIC_setAdrMode (true); // Test if I'm not set up for TTN correctly. LMIC_setLinkCheckMode(0); LMIC_setDrTxpow(DR_SF7, 14); LMIC_selectSubBand(1); // End test // Start job (sending automatically starts OTAA too) sendMessage (&sendjob); } void loop() { os_runloop_once(); /* * If we're still trying to send a message, we don't want to sleep here. If we're NOT sending * a message, but one of the sensors has been triggered, we're going to delay. Otherwise we're * going to go into power saving mode. */ if (LMIC.opmode & OP_TXRXPEND) { // No sleep/delay. } else { if ((trigger1 !=0) || (trigger2 != 0) || (programmingMode)) { // No power saving. Flash the LED if we're waiting for a second trigger. if ((trigger1 !=0) || (trigger2 != 0)) programmingModeDelay (500); else { Serial.println ("Going to sleep."); } } else { // Go to sleep. programmingModeDelay (1000); programmingModeDelay (1000); LowPower.deepSleep (); } } /* endif */ /* If trigger1 is nonzero it means we haven't sent a notification yet. */ if ((trigger1 != 0) || (trigger2 != 0)) { int32_t now = millis (); int32_t offset1 = 0; int32_t offset2 = 0; if (trigger1) offset1 = abs(now - trigger1); if (trigger2) offset2 = abs(now - trigger2); /* We want to allow at least VEHICLE_DELAY milliseconds for the vehicle to travel from one sensor to the other. */ if (((offset1 > VEHICLE_DELAY) || (offset2 > VEHICLE_DELAY)) || ((trigger1 != 0) && (trigger2 != 0))) { SerialUSB.print (offset1); SerialUSB.print (" - "); SerialUSB.println (offset2); /* Okay, so we've waited. If we only have one sensor triggered, just send a "VEHICLE". If we have both triggered, send VEHICLE-UP or VEHICLE-DOWN as appropriate. */ if ((trigger1 == 0) || (trigger2 == 0)) { // VEHICLE //sendMessage (VEHICLE_DETECTED); vehicle_detection = VEHICLE_DETECTED; sendMessage (&sendjob); } else { if (trigger2 > trigger1) { vehicle_detection = VEHICLE_ARRIVING; sendMessage (&sendjob); } else { vehicle_detection = VEHICLE_LEAVING; sendMessage (&sendjob); } } trigger1 = trigger2 = 0; } } } void sensorChanged1() { trigger1 = millis(); } void sensorChanged2() { trigger2 = millis(); } void setDevEui(unsigned char* buf) { Wire.begin(); Wire.beginTransmission(EUI64_CHIP_ADDRESS); Wire.write(EUI64_MAC_ADDRESS); Wire.endTransmission(); Wire.requestFrom(EUI64_CHIP_ADDRESS, EUI64_MAC_LENGTH); // Format needs to be little endian (LSB...MSB) while (Wire.available()) { *buf-- = Wire.read(); } } void programmingModeDelay (int duration) { digitalWrite (LED_PIN, HIGH); delay (duration / 2); digitalWrite (LED_PIN, LOW); delay (duration / 2); }
December 29, 2019 at 9:54 PM #14445LIM PHANG MOHKeymasterIt’s most probably one of the pins are floating or contradicting with the state you have set them up with. Use a meter and check the pins for floating voltages.
And what sensor are you using? In most of the cases, the sensors are not low power enough.
-
AuthorPosts
Viewing 2 posts - 1 through 2 (of 2 total)
- You must be logged in to reply to this topic.