Sleep mode + pin change interrupt + Trigger

My Project: I want my Arduino sleep, if I trigger a button, my Arduino should wake up, send a massage to TTN and then go back to sleep.

Sending Data works fantastic, without any Problems, i also found sleep mode topics and implemented them and they also work. I don’t know if this is important for my Problem but I use Arduino Pro MINI and OTAA.

Idea: I want to use another Pin (in my case A5) as interrupt and not the standard one ( I think it was INT0 and INT1)

Solution: Pin change interrupt (or if you have a better solution)

Problem: I have Coding Problems

Implementation:

I) Button Code (pin change interrupt)

  1. Turn on Pin Change Interrupts

PCICR = B00100000; // enable PCIE1 group

  1. Chose which pins to interrupt on

PCMSK1 = B00000001; //enable PCINT13 (A5)

  1. Write an ISR for those pins

ISR(PCINT1_vect)

II) Sleepmode Code

Lowpower.h

I am not a professional coder, but i tried to combine the low power library with the pin change interrup settings. Well in the end it doesnt work. Have somebody experience with sleepmode + pin change interrup? i appreciate your help.

// **** INCLUDES *****
#include "LowPower.h"

// Use pin 2 as wake up pin
const int wakeUpPin = A5;

void wakeUp()
{
    // Just a handler for the pin interrupt.
}

void setup()
{
    // Configure wake up pin as input.
    // This will consumes few uA of current.
    
   pinMode(wakeUpPin, INPUT_PULLUP); // internal Resistor 
   PCMSK1 = B00000001; //enable PCINT13 (A5)
   PCIFR = B00000000; // clear all interrupt flags
   PCICR = B00100000; // enable PCIE1 group

}

void loop() 
{
    // Allow wake up pin to trigger interrupt on low.
    attachInterrupt(0, wakeUp, LOW);
    
    // Enter power down state with ADC and BOD module disabled.
    // Wake up when wake up pin is low.
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
    
    // Disable external pin interrupt on wake up pin.
    detachInterrupt(0); 
    
    // Do something here
    // Example: Read sensor, data logging, data transmission.
}
   ISR(PCINT1_vect) {
   state = !state;
}

Pins A6,A7 on an ATmega328P (Pro Mini) are analog only, they are not digital pins.

Sry, its A5, in the code its corect

This lot, from your code, does not look correct;

// Use pin 2 as wake up pin
const int wakeUpPin = A5;
attachInterrupt(0, wakeUp, LOW)

the low power library that i found used pin 2 as interupt. I cant use pin 2 so i tried pin change interrupt feature. The question is, whether my A5 is the new interrupter instead of Pin 2 or is it the case that if i trigger A5, it will trigger Pin2 which will trigger my sleep mode feature? I will post the code later, cause i want to try something out.

If you want to use pins other than D2 and D3, you can use the EnableInterrupt library.

Awesome, this library makes it a lot easier. That`s maybe embarrassing, so pls dont kill me right away :sweat_smile:. I installed the library and added this code. After that i changed the values and it gives me back on error if i try to compile: "expected primary-expression before ‘A5’ " . My goal is to make a trigger, which will tell me whether the door is open or not. i posted here also my code. I appreciate your help.

 enableInterrupt(uint8_t pinNumber, void (*userFunction)(void), uint8_t mode);

/*******************************************************************************
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 * Copyright (c) 2018 Terry Moore, MCCI
 *
 * 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
 * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt.
 *
 *******************************************************************************/

#include <lmic.h>  
#include <hal/hal.h>
#include <SPI.h> 

#include "LowPower.h" 
#include <EnableInterrupt.h>






// 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] = { };
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI, 8);
}

// This should also be in little endian format, see above.
static const 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.
// The key shown here is the semtech default key.
static const u1_t PROGMEM APPKEY[16] = {};
void os_getDevKey (u1_t* buf) {
  memcpy_P(buf, APPKEY, 16);
}

static osjob_t sendjob;




unsigned TX_INTERVAL = 20;         








const lmic_pinmap lmic_pins = {
  .nss = 10,                   
  .rxtx = LMIC_UNUSED_PIN,      
  .rst = LMIC_UNUSED_PIN,       
  .dio = {2, 7, 8},              // (DIO0,DIO1,DIO2)
};




int ledPin = 13;//LED



void onEvent (ev_t ev) {

  Serial.println("TX_Intervall lautet:");
  Serial.println(TX_INTERVAL);

    Serial.print((unsigned long)(os_getTime()/ OSTICKS_PER_SEC));
    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")); //The node has started joining the network
            break;
        case EV_JOINED:                     //The node has successfully joined the network and is now ready for dara exchange
            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("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                Serial.print(nwkKey[i], HEX);
              }
              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.
            LMIC_setLinkCheckMode(0);
            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"));  //The node could not join the network
            break;
        case EV_REJOIN_FAILED:
            Serial.println(F("EV_REJOIN_FAILED")); //The node did not join a new network but is still connected to the old network
            break;

    case EV_TXCOMPLETE:          //The dara prepared via LMIC-setTxData() has been sent, and the receive window for downstream data ist complete.
      
        Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));

        if (LMIC.txrxFlags & TXRX_ACK)
        Serial.println(F("Received ack"));

        Serial.println(F("sent"));

        Serial.print(F("Received "));


        

        Serial.println(LMIC.dataLen);
        Serial.println(F(" bytes of payload"));





      
 
      break;
    
        case EV_LOST_TSYNC: //Beacon was missed repeatedly and time synchronization has been lost. Tracking or pinging needs to be restarted
            Serial.println(F("EV_LOST_TSYNC"));
            break;
        case EV_RESET: // Session reset due to rollover of sequence counters. Network will be rejoined automatically to acquiere new session
            Serial.println(F("EV_RESET"));
            break;
        case EV_RXCOMPLETE:
            // data received in ping slot
            Serial.println(F("EV_RXCOMPLETE"));
            break;
        case EV_LINK_DEAD:  // NO confirmation has been received from the network server fpr an extended period of time. Transmissions are still possible but their 
                           //reception is uncertain
            Serial.println(F("EV_LINK_DEAD")); 
            break;
        case EV_LINK_ALIVE:
            Serial.println(F("EV_LINK_ALIVE"));  //Link was dead, but now is 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: //This event is reported just before telling the radio driver to start transmission.
            Serial.println(F("EV_TXSTART"));
            break;
        default:
            Serial.print(F("Unknown event: "));
            Serial.println((unsigned) ev);
            break;
    }
}

void do_send(osjob_t* j) {
 
 byte ON=1; 


  


static uint8_t mydata[1]; 
      mydata[0]= ON;   
  
      
      

      


  
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
       
        LMIC_setTxData2(1, mydata, sizeof(mydata), 0);  
        Serial.println(F("Packet queued"));
        
    }
    


}



void setup() {


enableInterrupt(uint8_t A5, void (*LowPower.powerDown)(void), uint8_t RISING); 


  pinMode(ledPin, OUTPUT); //LED
   digitalWrite(ledPin, HIGH); //LED
  Serial.begin(9600); 
  Serial.println(F("Starting"));

  // 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);  //Relax RX timing window

  // Start job (sending automatically starts OTAA too)
  


  os_setTimedCallback(&sendjob, os_getTime() + ms2osticks(10), do_send);
}

void loop() {

  extern volatile unsigned long timer0_overflow_count;
  os_runloop_once();  //check send status

  if (digitalRead(A5)==LOW) { //if the button is low, then enter sleepmode
    
    delay(1000);
    Serial.println(F("go to sleep ... "));
    Serial.flush();
     
   
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  //Sleepmode
  
    


  

    Serial.begin(9600);
    Serial.println(F("... done sleeping")); 
  
    delay(1000);
   
    
   
    os_setTimedCallback(&sendjob, os_getTime() + ms2osticks(10), do_send);  //do a send 
  }

} //loop

i managed to sent arduino to sleep if i press the button. If i let the button go, the arduino is awake. Now i have to solve the problem why i cant send data anymore:sweat_smile:




/*******************************************************************************
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 * Copyright (c) 2018 Terry Moore, MCCI
 *
 * 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
 * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt.
 *
 *******************************************************************************/

#include <lmic.h>  
#include <hal/hal.h> 
#include <SPI.h> 

#include "LowPower.h" 


// EnableInterrupt Simple example sketch. Demonstrates operation on a single pin of your choice.
// See https://github.com/GreyGnome/EnableInterrupt and the README.md for more information.
#include <EnableInterrupt.h>

// Modify this at your leisure. Refer to https://github.com/GreyGnome/EnableInterrupt/wiki/Usage#Summary
#if defined __AVR_ATmega640__ || defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || \
        defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__
#define ARDUINOPIN A5
#else
// Pin 7 is useful on Arduino Uno, Leonardo, Mighty1284, ATtiny84...
#define ARDUINOPIN A5
#endif




// 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] = {  };
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI, 8);
}

// This should also be in little endian format, see above.
static const u1_t PROGMEM DEVEUI[8] = {  0};
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.
// The key shown here is the semtech default key.
static const u1_t PROGMEM APPKEY[16] = {};
void os_getDevKey (u1_t* buf) {
  memcpy_P(buf, APPKEY, 16);
}

static osjob_t sendjob;




unsigned TX_INTERVAL = 20;         



volatile uint16_t interruptCount=0; // The count will go back to 0 after hitting 65535.




const lmic_pinmap lmic_pins = {
  .nss = 10,                     //Slave/Master
  .rxtx = LMIC_UNUSED_PIN,       //Antena
  .rst = LMIC_UNUSED_PIN,        //Reset
  .dio = {2, 7, 8},              // (DIO0,DIO1,DIO2)
};




int ledPin = 13;//LED



void onEvent (ev_t ev) {

  Serial.println("TX_Intervall :");
  Serial.println(TX_INTERVAL);

    Serial.print((unsigned long)(os_getTime()/ OSTICKS_PER_SEC));
    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")); //The node has started joining the network
            break;
        case EV_JOINED:                     //The node has successfully joined the network and is now ready for dara exchange
            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("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                Serial.print(nwkKey[i], HEX);
              }
              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.
            LMIC_setLinkCheckMode(0);
            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"));  //The node could not join the network
            break;
        case EV_REJOIN_FAILED:
            Serial.println(F("EV_REJOIN_FAILED")); //The node did not join a new network but is still connected to the old network
            break;

    case EV_TXCOMPLETE:          //The dara prepared via LMIC-setTxData() has been sent, and the receive window for downstream data ist complete.
      
        Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));

        if (LMIC.txrxFlags & TXRX_ACK)
        Serial.println(F("Received ack"));

        Serial.println(F("sent"));

        Serial.print(F("Received "));


        

        Serial.println(LMIC.dataLen);
        Serial.println(F(" bytes of payload"));





      
 
      break;
    
        case EV_LOST_TSYNC: //Beacon was missed repeatedly and time synchronization has been lost. Tracking or pinging needs to be restarted
            Serial.println(F("EV_LOST_TSYNC"));
            break;
        case EV_RESET: // Session reset due to rollover of sequence counters. Network will be rejoined automatically to acquiere new session
            Serial.println(F("EV_RESET"));
            break;
        case EV_RXCOMPLETE:
            // data received in ping slot
            Serial.println(F("EV_RXCOMPLETE"));
            break;
        case EV_LINK_DEAD:  // NO confirmation has been received from the network server fpr an extended period of time. Transmissions are still possible but their 
                           //reception is uncertain
            Serial.println(F("EV_LINK_DEAD")); 
            break;
        case EV_LINK_ALIVE:
            Serial.println(F("EV_LINK_ALIVE"));  //Link was dead, but now is 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: //This event is reported just before telling the radio driver to start transmission.
            Serial.println(F("EV_TXSTART"));
            break;
        default:
            Serial.print(F("Unknown event: "));
            Serial.println((unsigned) ev);
            break;
    }
}

void do_send(osjob_t* j) {

 
 byte ON=1; 


  


static uint8_t mydata[1]; 
      mydata[0]= ON;   
  
      
      

      


  
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
       
        LMIC_setTxData2(1, mydata, sizeof(mydata), 0);  
        Serial.println(F("Packet queued"));
        
    }
    


}



void setup() {


Serial.begin(9600);
#ifdef MIGHTY1284
  DDRA=0x0;    DDRB=0x0;   DDRC=0x0;   DDRD=0x0; // set all pins as inputs
  PORTA=0xFF; PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; // turn on all pullup resistors.
#else
  pinMode(ARDUINOPIN, INPUT_PULLUP);  // See http://arduino.cc/en/Tutorial/DigitalPins
#endif
  enableInterrupt(ARDUINOPIN, interruptFunction, CHANGE);


  pinMode(ledPin, OUTPUT); //LED
   digitalWrite(ledPin, HIGH); //LED
  Serial.begin(9600); 
  Serial.println(F("Starting"));

  // 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);  //Relax RX timing window

  // Start job (sending automatically starts OTAA too)
  


  os_setTimedCallback(&sendjob, os_getTime() + ms2osticks(10), do_send);
}

void loop() {
 Serial.println("---------------------------------------");
  delay(1000);
  Serial.print("Pin was interrupted: ");
  Serial.print(interruptCount, DEC);
  Serial.println(" times so far.");
  extern volatile unsigned long timer0_overflow_count;
  os_runloop_once();  //check send status

  if (digitalRead(A5)==LOW) { //if the button is low, then enter sleepmode
    
    delay(1000);
    Serial.println(F("go to sleep ... "));
    Serial.flush();
     
   
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  //Sleepmode
  
  


  

    Serial.begin(9600);
    Serial.println(F("... done sleeping")); 
  
    delay(1000);
   
    
   
    os_setTimedCallback(&sendjob, os_getTime() + ms2osticks(10), do_send);  //do a send // os_getTime() ist die Systemzeit in ticks
  }

} //loop

void interruptFunction() {
  interruptCount++;
}
1 Like

Ok now i can send data and if i press button then my arduino goes to sleep. If i let the button go then he wakes up. The last piece that now is missing is that i want to send data before he goes to sleep. It seems like the entire sending part is connected together. Is there a simple line that i can put there, so i can send data immediately before it goes to sleep?

  if (digitalRead(A5)==LOW) { //if the button is low, then enter sleepmode
   
//here i want send a data, for example ON=2 that the button was triggered.
   
    Serial.println(F("go to sleep ... "));
    Serial.flush();
     
   
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  //Sleepmode
  
  


  

    Serial.begin(9600);
    Serial.println(F("... done sleeping")); 
    delay(1000);
   //Sleepmode end
    
   
   
  }
/*******************************************************************************
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 * Copyright (c) 2018 Terry Moore, MCCI
 *
 * 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
 * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt.
 *
 *******************************************************************************/

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include "LowPower.h"
// PINchangeinterrupt von hier
// EnableInterrupt Simple example sketch. Demonstrates operation on a single pin of your choice.
// See https://github.com/GreyGnome/EnableInterrupt and the README.md for more information.
#include <EnableInterrupt.h>

// Modify this at your leisure. Refer to https://github.com/GreyGnome/EnableInterrupt/wiki/Usage#Summary
#if defined __AVR_ATmega640__ || defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || \
        defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__
#define ARDUINOPIN A5
#else
// Pin 7 is useful on Arduino Uno, Leonardo, Mighty1284, ATtiny84...
#define ARDUINOPIN A5
#endif
//
// For normal use, we require that you edit the sketch to replace FILLMEIN
// with values assigned by the TTN console. However, for regression tests,
// we want to be able to compile these scripts. The regression tests define
// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-
// working but innocuous value.
//
//bis hier


// 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]={  };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

// This should also be in little endian format, see above.
static const 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] = {  };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}


static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 5;

// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = LMIC_UNUSED_PIN,
    .dio = {2, 7, 8},
};
volatile uint16_t interruptCount=0; // The count will go back to 0 after hitting 65535.


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("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                Serial.print(nwkKey[i], HEX);
              }
              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.
            LMIC_setLinkCheckMode(0);
            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), 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;
        /*
        || 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;
        default:
            Serial.print(F("Unknown event: "));
            Serial.println((unsigned) ev);
            break;
    }
}

void do_send(osjob_t* j) {

 
 byte ON=1; 


  
//Payload part

static uint8_t mydata[1]; 
      mydata[0]= ON; 
        
  
      
      

      


  
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
       
        LMIC_setTxData2(1, mydata, sizeof(mydata), 0);  
        Serial.println(F("Packet queued"));
        
    }
    


}



void setup() {
  
//Pinchange interrupt von hier  
Serial.begin(9600);
#ifdef MIGHTY1284
  DDRA=0x0;    DDRB=0x0;   DDRC=0x0;   DDRD=0x0; // set all pins as inputs
  PORTA=0xFF; PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; // turn on all pullup resistors.
#else
  pinMode(ARDUINOPIN, INPUT_PULLUP);  // See http://arduino.cc/en/Tutorial/DigitalPins
#endif
  enableInterrupt(ARDUINOPIN, interruptFunction, CHANGE);
//bis hier

    Serial.begin(9600);
    Serial.println(F("Starting"));

    

    // 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);

    // Start job (sending automatically starts OTAA too)
    do_send(&sendjob);
  
}

void loop() {
    os_runloop_once();
  /*  Serial.println("---------------------------------------");
  delay(1000);
  Serial.print("Pin was interrupted: ");
  Serial.print(interruptCount, DEC);
  Serial.println(" times so far.");
  extern volatile unsigned long timer0_overflow_count;
  */
  if (digitalRead(A5)==LOW) { //if the button is low, then enter sleepmode
   
   
    Serial.println(F("go to sleep ... "));
    Serial.flush();
     
   
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  //Sleepmode
  
  


  

    Serial.begin(9600);
    Serial.println(F("... done sleeping")); 
    delay(1000);
   //Sleepmode end
    
   
   
  }
}
void interruptFunction() { //  Pinchangeinteruput part
  interruptCount++;
  
}

does somebody know how i can send data immediately when the button is pressed?
I tried it that way, but i just receive on serial monitor “Packed queued” but no data in the TNN console.

if (digitalRead(A5)==LOW) { //if the button is low, then enter sleepmode


    os_init();
    // Reset the MAC state. Session and pending data transfers will be discarded.
    LMIC_reset();
     LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100); 

    // Start job (sending automatically starts OTAA too)
    do_send(&sendjob);


  

    Serial.println(F("go to sleep ... "));
    Serial.flush();
     
   
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  //Sleepmode

    Serial.begin(9600);
    Serial.println(F("... done sleeping")); 
    delay(1000);

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.