Push notifications based on sensor feedback

Hey guys,

I’m trying to make an Arduino based notifier. It uses audio sensor, magnetic hall sensor and PIR sensor and connected to an ethernet card. I’m using ethercard library for it. To be more precise, I’m using notify “notify my android” example in that library.

The code runs smoothly as is, but the problem starts the moment i try to edit it. Firstly i don’t want it to run single time. I’d like to make push notifications based on sensor feedback.

But when I introduce IFs in the code the notifier stops working.

Another problem I’m having is my sensors give me feedback for a few seconds and it causes my code to be executed several times. How can I make it run only once and then ignore the sensor output until it becomes LOW again?

Here’s my whole code:

// This demo shows how to send a notification to the Notify My Android service
//
// Warning: Due to the limitations of the Arduino, this demo uses insecure
// HTTP to interact with the nma api (not HTTPS). The API key WILL be sent
// accross the wire in plain text.
//
// 2015-04-10 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <EtherCard.h>
int status=0;
const char apihost[] PROGMEM = "www.notifymyandroid.com";

static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };

byte Ethernet::buffer[900];
Stash stash;
static byte session;



void setup () {

pinMode(6,INPUT); // PIR
pinMode(7,INPUT); // MAGNET
pinMode(9,INPUT); // SOUND
  
  Serial.begin(57600);
  Serial.println("\nStarting Notify My Android Example");


  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);

  if (!ether.dnsLookup(apihost))
    Serial.println(F("DNS lookup failed for the apihost"));
  ether.printIp("SRV: ", ether.hisip);

  
}

static void notifyMyAndroid () {
  byte sd = stash.create();

if (status == 1) {
 
  stash.print("apikey=");
  stash.print("######");

  stash.print("&application=");
  stash.print("arduino");

  stash.print("&event=");
  stash.print("Arduino Security System");

  stash.print("&description=");
  stash.print("PIR");

  stash.print("&priority=");
  stash.print("0");
}

if (status == 2) { 
  stash.print("apikey=");
  stash.print("######");

  stash.print("&application=");
  stash.print("arduino");

  stash.print("&event=");
  stash.print("Arduino Security System");

  stash.print("&description=");
  stash.print("Magnet");

  stash.print("&priority=");
  stash.print("0");
}

if (status == 3) {
  stash.print("apikey=");
  stash.print("######");

  stash.print("&application=");
  stash.print("arduino");

  stash.print("&event=");
  stash.print("Arduino Security System");

  stash.print("&description=");
  stash.print("Sound");

  stash.print("&priority=");
  stash.print("0");
}


  stash.save();
  int stash_size = stash.size();
  Stash::prepare(PSTR("POST /publicapi/notify HTTP/1.1" "\r\n"
                      "Host: $F" "\r\n"
                      "Content-Length: $D" "\r\n"
                      "Content-Type: application/x-www-form-urlencoded" "\r\n"
                      "\r\n"
                      "$H"),
                 apihost, stash_size, sd);
  session = ether.tcpSend();
status=0;
}


void loop () {
if (digitalRead(6) == HIGH) {
Serial.println("MOVEMENT"); 
status = 1;
}
if (digitalRead(7) == LOW) {
Serial.println("MAGNET"); 
status = 2;
}
if (digitalRead(9) == LOW) {
Serial.println("SOUND");
status = 3;
}

notifyMyAndroid();
  
  ether.packetLoop(ether.packetReceive());

  const char* reply = ether.tcpReply(session);
  if (reply != 0) {
    Serial.println("Got a response!");
    Serial.println(reply);
  }

}

And here’s the stock example code:

// This demo shows how to send a notification to the Notify My Android service
//
// Warning: Due to the limitations of the Arduino, this demo uses insecure
// HTTP to interact with the nma api (not HTTPS). The API key WILL be sent
// accross the wire in plain text.
//
// 2015-04-10 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <EtherCard.h>

const char apihost[] PROGMEM = "www.notifymyandroid.com";

static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };

byte Ethernet::buffer[900];
Stash stash;
static byte session;

static void notifyMyAndroid () {
  byte sd = stash.create();

  stash.print("apikey=");
  stash.print("ADD YOUR API KEY HERE");

  stash.print("&application=");
  stash.print("arduino");

  stash.print("&event=");
  stash.print("Ethercard Notify My Android Example");

  stash.print("&description=");
  stash.print("Test message from an Arduino!");

  stash.print("&priority=");
  stash.print("0");

  stash.save();
  int stash_size = stash.size();

  // Compose the http POST request, taking the headers below and appending
  // previously created stash in the sd holder.
  Stash::prepare(PSTR("POST /publicapi/notify HTTP/1.1" "\r\n"
                      "Host: $F" "\r\n"
                      "Content-Length: $D" "\r\n"
                      "Content-Type: application/x-www-form-urlencoded" "\r\n"
                      "\r\n"
                      "$H"),
                 apihost, stash_size, sd);

  // send the packet - this also releases all stash buffers once done
  // Save the session ID so we can watch for it in the main loop.
  session = ether.tcpSend();
}

void setup () {
  Serial.begin(57600);
  Serial.println("\nStarting Notify My Android Example");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);

  if (!ether.dnsLookup(apihost))
    Serial.println(F("DNS lookup failed for the apihost"));
  ether.printIp("SRV: ", ether.hisip);

  notifyMyAndroid();
}

void loop () {
  ether.packetLoop(ether.packetReceive());

  const char* reply = ether.tcpReply(session);
  if (reply != 0) {
    Serial.println("Got a response!");
    Serial.println(reply);
  }
}

But when I introduce IFs in the code the notifier stops working.

It does NOT. It might no longer do what you want, but you haven't told us what it actually does or how that differs from what you want, so we can't help you.

How can I make it run only once and then ignore the sensor output until it becomes LOW again?

Have you looked at any of the examples for inspiration? The state change detection example, perhaps?

PaulS: It does NOT. It might no longer do what you want, but you haven't told us what it actually does or how that differs from what you want, so we can't help you. Have you looked at any of the examples for inspiration? The state change detection example, perhaps?

I just checked it but couldn't imagined a way to embed it into my code. Maybe that's my inability to improvise.

The moment I open the door, (and place some distance between the magnet and hall effect sensor) hall effect sensor reports high.

But using any if based condition based on sensor output will cause repeated code executions, since i'm in void loop. So I keep getting hundreds of "The door is opened" messages until the door is closed.

What I want it to report me only once when the pin state changes from high to low or low to high.

The state change example is exactly what you need. If you detect a state change, set a boolean variable to true. Where you call notifyMyAndroid Use an if to test that variable, if it's true, call notifyMyAndroid and set the variable false. Otherwise, do nothing.