Hi Guys,
I have an unusual problem. At Cayenne I created a new trigger with email and SMS. This function has always been flawless. But yesterday and today I did tests. And now neither SMS nor email arrive. I’ve had the problem before and had to switch to another email address. Say at Cayenne I already have 3 email addresses and a cell phone number that is stored, but despite executing the triggers, I will not receive any SMS or an email. Is there a limit per email per day or month and also for SMS?
The application is a digital input that is sent to Cayenne on the Arduino board and is supposed to trigger a trigger there … At the beginning it worked great now but never: - / … I have already reset the dashboard, the trigger new created, even the node is still registered as a new node … but nothing. With TTN and also with Cayenne the entrance is registered … I don’t know any further because it was created for an alarm forwarding, but it doesn’t work :-(.
thank you in advance
Lg Bernd
Have a look at this Sending MQTT messages within notification limit
There is interest. So at the moment it is the first email that I have used so far no longer works. As if it was locked. I sent some 20 SMS and 20 emails today, suddenly there was no more email and no SMS either. The first email I used is still not working today: _ (… what I don’t know about.
That means when I can send a maximum of 90 SMS or 90 emails a day or 45 sms and 45 emails at the same time? and the next day everything should work again? or do I have to reset that via Arduino code? What if it shouldn’t work tomorrow? then my mobile number would no longer be active in the event of an alarm and the node would be useless with cayenne: _ (
Since I am more of a programmer in terms of programming, and I tried to insert the code as unsuccessful in the link, the question now is whether cayenne will automatically reset itself every day or whether this will be locked forever without having to program anything here. I tried to trigger the trigger again earlier, but I did not receive an email or an SMS: - (… if I can no longer get it to work, the work was unfortunately free
I just posted a new email address. the alarm is passed on. cayenne blocks the email addresses that send the maximum emails within a certain period of time! my cell phone number also no longer works. that can not be the point of an alarm that if you never have the possibility to send anything again after the maximum number of sms and emails. Conclusion: a cell phone number and 3 email addresses can no longer be used. I therefore ask that you solve this problem or reset the counter daily.
Before adding a new email and number did you make the changes to the code from the link i posted above?
no i have not changed anything on the arduino mini pro or the code or on cayenne. currently it is so that the sms are sent again. however, the email addresses no longer work. the system probably blocks them. I already have the 3 email addresses and the current one that is still working. but only the one the three “blocked” were not sent. for me it would be very important that the email addresses go again. can’t cayenne reset them manually? or reset the counter to zero?
I cannot insert the code at the moment. I get error messages and I’m not really a programmer.
even if i can reset, they will be blocked again until an unless you modify the code to send the data only once for trigger.
OK. The problem is that it is a transient alarm message and I had to see how quickly the SMS and the email arrive at the recipient. since i had done the test often, because the system had to work properly, i came up with the high number of sms and emails. but why is the SMS going again and the emails are not due to the system and not the code or do I get it wrong?
such a frequent triggering will no longer take place. Unfortunately, I don’t know exactly where I have to use the code. currently the sms is working again and the new email.
/*******************************************************************************
* ToDo:
* - set NWKSKEY (value from staging.thethingsnetwork.com)
* - set APPKSKEY (value from staging.thethingsnetwork.com)
* - set DEVADDR (value from staging.thethingsnetwork.com)
* - optionally comment #define DEBUG
* - optionally comment #define SLEEP
* - set TX_INTERVAL in seconds Anzahl der Sendungen
* - set 1,5 kohm widerstand zwischen pin 8 und restet pin für software reset
* - set pin 7 Digital INPUT Störung
* - set pin 9 LED
* - set Tone() Pin 10
******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <Wire.h>
#include <CayenneLPP.h>
// BME280 I2C address is 0x76(108)
#define Addr 0x76
#define ledPIN 9 // LED
// Reset für das Node
#define rstPin 8 // -> Pin 8
// pin 10 Tone
// LoRaWAN NwkSKey, your network session key, 16 bytes (from staging.thethingsnetwork.org)
static const PROGMEM u1_t NWKSKEY[16] = {
// LoRaWAN AppSKey, application session key, 16 bytes (from staging.thethingsnetwork.org)
static const u1_t PROGMEM APPSKEY[16] = {
// LoRaWAN end-device address (DevAddr), (from staging.thethingsnetwork.org)
static const u4_t DEVADDR = 0x26011707; // <-- Change this address for every node!
// show debug statements; comment next line to disable debug statements
#define DEBUG
// use low power sleep; comment next line to not use low power sleep
// #define SLEEP
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 60*10;
CayenneLPP lpp(51);
double cTemp0;
double pressure;
//double humidity;
#ifdef SLEEP
#include "LowPower.h"
bool next = false;
#endif
//-------------------------------------------------------------------
//TODO Richy an Bernd: Pin, der für den Alarm genutzt wird. Variablen, um Alarmzustand zu speichern
int inPin = 7; // Input des Alarmsignals
int reading; // Wert des Eingangs
int previous = LOW; // Vorheiger Wert des Eingangs
// folgende Variablen müssen vom Typo unsigned long sein da millis() disen Variablentyp liefert.
unsigned long time = 0; // letzter Zeitwert bei dem der Ausgangzustand wechselte.
unsigned long debounce = 10; // Entprellzeit
//-------------------------------------------------------------------
// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
static osjob_t sendjob;
// Pin mapping Lora Modul
const lmic_pinmap lmic_pins = {
.nss = 6,
.rxtx = LMIC_UNUSED_PIN,
.rst = 5,
.dio = {2, 3, 4},
};
void getSensorData(){
unsigned int b1[24];
unsigned int data[8];
unsigned int dig_H1 = 0;
for(int i = 0; i < 24; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((136+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 24 bytes of data
if(Wire.available() == 1)
{
b1[i] = Wire.read();
}
}
// Convert the data
// temp coefficients
unsigned int dig_T1 = (b1[0] & 0xff) + ((b1[1] & 0xff) * 256);
int dig_T2 = b1[2] + (b1[3] * 256);
int dig_T3 = b1[4] + (b1[5] * 256);
////////// Reset per Software////////////////////*
digitalWrite(rstPin,HIGH);
delay(200);
pinMode(rstPin, OUTPUT);
////// PinModes Ausgang oder Eingang/////
pinMode(ledPIN, OUTPUT);
pinMode(inPin, INPUT);
noTone(10);
// pressure coefficients
unsigned int dig_P1 = (b1[6] & 0xff) + ((b1[7] & 0xff ) * 256);
int dig_P2 = b1[8] + (b1[9] * 256);
int dig_P3 = b1[10] + (b1[11] * 256);
int dig_P4 = b1[12] + (b1[13] * 256);
int dig_P5 = b1[14] + (b1[15] * 256);
int dig_P6 = b1[16] + (b1[17] * 256);
int dig_P7 = b1[18] + (b1[19] * 256);
int dig_P8 = b1[20] + (b1[21] * 256);
int dig_P9 = b1[22] + (b1[23] * 256);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write(161);
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 1 byte of data
if(Wire.available() == 1)
{
dig_H1 = Wire.read();
}
for(int i = 0; i < 7; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((225+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 7 bytes of data
if(Wire.available() == 1)
{
b1[i] = Wire.read();
}
}
// Convert the data
// humidity coefficients
int dig_H2 = b1[0] + (b1[1] * 256);
unsigned int dig_H3 = b1[2] & 0xFF ;
int dig_H4 = (b1[3] * 16) + (b1[4] & 0xF);
int dig_H5 = (b1[4] / 16) + (b1[5] * 16);
int dig_H6 = b1[6];
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control humidity register
Wire.write(0xF2);
// Humidity over sampling rate = 1
Wire.write(0x01);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select control measurement register
Wire.write(0xF4);
// Normal mode, temp and pressure over sampling rate = 1
Wire.write(0x27);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select config register
Wire.write(0xF5);
// Stand_by time = 1000ms
Wire.write(0xA0);
// Stop I2C Transmission
Wire.endTransmission();
for(int i = 0; i < 8; i++)
{
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select data register
Wire.write((247+i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr, 1);
// Read 8 bytes of data
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
}
// Convert pressure and temperature data to 19-bits
long adc_p = (((long)(data[0] & 0xFF) * 65536) + ((long)(data[1] & 0xFF) * 256) + (long)(data[2] & 0xF0)) / 16;
long adc_t = (((long)(data[3] & 0xFF) * 65536) + ((long)(data[4] & 0xFF) * 256) + (long)(data[5] & 0xF0)) / 16;
// Convert the humidity data
long adc_h = ((long)(data[6] & 0xFF) * 256 + (long)(data[7] & 0xFF));
// Temperature offset calculations
double var1 = (((double)adc_t) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
double var2 = ((((double)adc_t) / 131072.0 - ((double)dig_T1) / 8192.0) *
(((double)adc_t)/131072.0 - ((double)dig_T1)/8192.0)) * ((double)dig_T3);
double t_fine = (long)(var1 + var2);
cTemp0 = (var1 + var2) / 5120.0;
// Pressure offset calculations
var1 = ((double)t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
var2 = var2 + var1 * ((double)dig_P5) * 2.0;
var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
double p = 1048576.0 - (double)adc_p;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
var1 = ((double) dig_P9) * p * p / 2147483648.0;
var2 = p * ((double) dig_P8) / 32768.0;
pressure = (p + (var1 + var2 + ((double)dig_P7)) / 16.0) / 100;
}
void onEvent (ev_t ev) {
#ifdef DEBUG
Serial.println(F("Enter onEvent"));
Serial.print(os_getTime());
Serial.print(": ");
#endif
switch(ev) {
case EV_TXCOMPLETE:
#ifdef DEBUG
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
#endif
if(LMIC.dataLen) {
// data received in rx slot after tx
#ifdef DEBUG
Serial.print(F("Data Received: "));
Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
Serial.println();
#endif
}
// Schedule next transmission
#ifndef SLEEP
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
#else
next = true;
#endif
break;
default:
#ifdef DEBUG
Serial.println(F("Unknown event"));
Serial.println("Reset in 2 S");
delay(2000);
Reset();
#endif
break;
}
#ifdef DEBUG
Serial.println(F("Leave onEvent"));
#endif
}
void do_send(osjob_t* j){
#ifdef DEBUG
Serial.println(F("Enter do_send"));
#endif
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
getSensorData();
// Prepare upstream data transmission at the next possible time.
lpp.reset();
lpp.addTemperature(1, cTemp0);
//lpp.addTemperature(2, cTemp1);
lpp.addBarometricPressure(2, pressure);
// lpp.addRelativeHumidity(4, humidity);
//--------------------------------------------------------
//Für Bernd: Alarm in lpp
lpp.addDigitalInput(4, digitalRead(inPin));
//--------------------------------------------------------
LMIC.txChnl = 0; //was ist das?!
LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);
#ifdef DEBUG
Serial.println(F("Packet queued"));
Serial.println(LMIC.freq);
#endif
}
// Next TX is scheduled after TX_COMPLETE event.
#ifdef DEBUG
Serial.println(F("Leave do_send"));
#endif
}
//////////////////////////////////////////////////
// RESET Node
//////////////////////////////////////////////////
void Reset() {
digitalWrite (rstPin, LOW);
// Code sollte nie erscheinen
Serial.println("Reset faild mittels Pin 8");
}
//////////////////////////////////////////////////
// Abfrage Sammelalarm
//////////////////////////////////////////////////
void checkAlarm() {
reading = digitalRead(inPin);
// Beim Wechsel des Eingangs von LOW zu HIGH und nach der Entprellzeit:
if ( reading == HIGH && previous == LOW && millis() - time > debounce) {
time = millis();
Serial.println("Alarmpin ist HIGH");
do_send(&sendjob);
merker = true;
}
// Beim Wechsel des Eingangs von HIGH zu LOW und nach der Entprellzeit:
if (reading == LOW && previous == HIGH && millis() - time > debounce) {
time = millis();
Serial.println("Alarmpin ist LOW Quittiert");
do_send(&sendjob);
merker = false;
}
/* while(digitalRead(inPin)==1) {
digitalWrite(ledPIN,HIGH);
tone(10,2800);
delay (500);
noTone (10);
delay (500);
}
*/
previous = reading;
}
//////////////////////////////////////////////////
// loop() HAUPTPROGRAMM
//////////////////////////////////////////////////
int main(int argc, char const *argv[]) {
init();
noTone(10);
#ifdef DEBUG
Serial.begin(9600);
#endif
// Initialise I2C communication as MASTER
Wire.begin();
//LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
//-------------------------------------------------------
LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 100); //relax LMIC timing to 20% skew for alarm read cycle
//-------------------------------------------------------
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set.
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices' ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
// Disable link check validation
LMIC_setLinkCheckMode(0);
// Uncomment to use channel 868100000 only
// for(int i=0; i<9; i++) { // For EU; for US use i<71
// if(i != 0) {
// LMIC_disableChannel(i);
// }
// }
// Set data rate (SF) and transmit power for uplink
LMIC_setDrTxpow(DR_SF7, 16);
// Start job
do_send(&sendjob);
#ifdef DEBUG
Serial.println(F("Leave setup"));
Serial.println("Reset ist aktiv bei Fehler");
#endif
while(1) {
//------------------------------------------------------
//TODO: Bernd
checkAlarm();
//------------------------------------------------------
#ifndef SLEEP
os_runloop_once();
#else
extern volatile unsigned long timer0_overflow_count;
if (next == false) {
os_runloop_once();
} else {
int sleepcycles = TX_INTERVAL / 8; // calculate the number of sleepcycles (8s) given the TX_INTERVAL
#ifdef DEBUG
Serial.print(F("Enter sleeping for "));
Serial.print(sleepcycles);
Serial.println(F(" cycles of 8 seconds"));
#endif
Serial.flush(); // give the serial print chance to complete
for (int i=0; i<sleepcycles; i++) {
// Enter power down state for 8 s with ADC and BOD module disabled
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
//LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
// LMIC uses micros() to keep track of the duty cycle, so
// hack timer0_overflow for a rude adjustment:
cli();
timer0_overflow_count+= 8 * 64 * clockCyclesPerMicrosecond();
sei();
}
#ifdef DEBUG
Serial.println(F("Sleep complete"));
#endif
next = false;
// Start job
do_send(&sendjob);
}
#endif
}
return 0;
}
you will need to modify the code to work for your cayenne LPP code. the main part is this:
void sendTriggerValue(int channel, int value, int threshold, bool sendBelowThreshold) {
if (((value >= threshold) && !sendBelowThreshold) || ((value < threshold) && sendBelowThreshold)) {
if (!crossedThreshold) {
crossedThreshold = true;
// send data to trigger only once.
}
}
else
{
crossedThreshold = false;
}
}
Also. can you private message me your cayenne account email id.
OK thank you. but where exactly do I have to insert this code into my current code? and do I have to add a libary to make it work? or just the code is enough.
please excuse me i’m really not a programmer and i’m glad i got it running at all.
there is no external library needed. it just a code you are adding to send data only once. Go through the link i shared above. the code is explained over there. you just need to modify it for your code.