MAC Address identification leading to a trigger

Hi,
First post here, I’ve been a long time lurker reading but have never actually posted before. I have hit a brick wall so here goes!

I am using an esp8266 and uploading using the Arduino software.
I am trying to create a mac address identifier, in the sketch the mac address I’m looking for (my phone for now) is stated and when it joins the wifi network the serial window confirms its there. Once this happens I want to send a trigger to ifttt using the maker channel. This is all set up already.

The trouble I’m having is, the serial window confirms that wifi has been connected then when I switch on the wifi on my phone and connec to my home wifi, the serial window prints “Name is here” as its supposed to, but then never runs the ifttt trigger.

I was hoping someone could take a look at the sketch and point me in the right direction, if I have done this correctly, the code should be below in code tags.
I have blanked out the wifi details and ifttt maker key and also randomised the mac address.

Thanks for your time and help that may be received.

#include "./esppl_functions.h"
#include "IFTTTMaker.h"
char ssid[] = "WIFINAME";       // your network SSID (name)
char password[] = "PASS";  // your network key
#define KEY "IFTTTKEY"  // Get it from this page https://ifttt.com/services/maker/settings
#define EVENT_NAME "mac_arrive" // Name of your event name, set when you are creating the applet
WiFiClientSecure client;
IFTTTMaker ifttt(KEY, client);

/*  How many MAC addresses are we looking for?
*/
#define LIST_SIZE 1
/*
   Device mac address here
  Format it by taking the mac address aa:bb:cc:dd:ee:ff
  and converting it to 0xaa,0xbb,0xcc,0xdd,0xee,0xff
*/
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0x50, 0xcc, 0xc1, 0x3a, 0x53, 0xfg}
};
/*
   Name of person owning mac address
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Name"
};


void setup() {
  delay(500);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  esppl_init(cb);
}

int cooldown = 0; /* 

bool maccmp(uint8_t *mac1, uint8_t *mac2) {
  for (int i = 0; i < ESPPL_MAC_LEN; i++) {
    if (mac1[i] != mac2[i]) {
      return false;
    }
  }
  return true;
}

void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      cooldown = 1000; // here we set it to 1000 if we detect a packet that matches our list
      if (i == 1) {
        if (ifttt.triggerEvent(EVENT_NAME) {
         Serial.println("Successfully sent");
      } else
        {
          Serial.println("Failed!");
       }
       
    }
  }

void loop() {
 esppl_sniffing_start();
  while (true) {
    for (int i = ESPPL_CHANNEL_MIN; i <= ESPPL_CHANNEL_MAX; i++ ) {
      esppl_set_channel(i);
      while (esppl_process_frames()) {
       
      }
    }
  }
  }
      if (i == 1) {

The for will never reach 1 with a LISTSIZE of 1.

Ah I see!! I’ll amend and try.

Thankyou for your reply

      if (i == 1) {
        if (ifttt.triggerEvent(EVENT_NAME) {
         Serial.println("Successfully sent");
      } else
        {
          Serial.println("Failed!");
       }

Why are you comparing i to 1? We can't tell you the appropriate value to compare to without knowing what you are trying to do here. You've already determined that the MAC id of the connector is a known value, so it seems that you want to call the ifttt method without another if test in the way.

It’s a part of the code I’ve been trying to adapt to suit the needs of this project.

The basic outline of what I am trying to do is: ESP8266 connects to my WiFi network and scans for a specific MAC address. When it finds that MAC address it sends a trigger to ifttt, then it goes back to scanning for the MAC address again. A delay between sending the trigger and start scanning again would be useful now I think about it. The code I posted is showing me the MAC address is here, but doesn’t send the trigger. I moved the ifttt code up to the I == 0 and now I get a serial monitor full of numbers when the MAC address connects, then a reset. I’ve also tried adding a second MAC address and the same happens.

You should probably only send an event when the MAC connects or disconnects to the network, not all the time while it is connected.

Yes, when it connects would be the perfect solution. I’ve hit a wall with this at the moment and I’m unsure of the next steps in regard to getting the trigger to send to ifttt and only sending the trigger once when the device connects.

I've hit a wall with this at the moment and I'm unsure of the next steps in regard to getting the trigger to send to ifttt and only sending the trigger once when the device connects.

The nest steps would involve writing the code correctly. If you are unsure how, POST YOUR CODE as it is now.

This is how the code is looking right now…

#include "./esppl_functions.h"
#include "IFTTTMaker.h"
char ssid[] = "SSID";       // your network SSID (name)
char password[] = "PASS";  // your network key
#define KEY "KEY"  // Get it from this page https://ifttt.com/services/maker/settings
#define EVENT_NAME "mac1" // Name of your event name, set when you are creating the applet
WiFiClientSecure client;
IFTTTMaker ifttt(KEY, client);

/*  Define you friend's list size here
  How many MAC addresses are you tracking?
*/
#define LIST_SIZE 1
/*
   This is your friend's MAC address list
  Format it by taking the mac address aa:bb:cc:dd:ee:ff
  and converting it to 0xaa,0xbb,0xcc,0xdd,0xee,0xff
*/
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
  {0xfd, 0x29, 0x2d, 0xea, 0x72, 0x88}
};
/*
   This is your friend's name list
   put them in the same order as the MAC addresses
*/
String friendname[LIST_SIZE] = {
  "Name1"
};


void setup() {
  delay(500);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  esppl_init(cb);
}


int cooldown = 0;

bool maccmp(uint8_t *mac1, uint8_t *mac2) {
  for (int i = 0; i < ESPPL_MAC_LEN; i++) {
    if (mac1[i] != mac2[i]) {
      return false;
    }
  }
  return true;
}

void cb(esppl_frame_info *info) {
  for (int i = 0; i < LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      ifttt.triggerEvent(EVENT_NAME); {
        Serial.println("Successfully sent");
      }
         cooldown = 1000; // here we set it to 1000 if we detect a packet that matches our list
      if (i == 1) {

      }
    }


void loop() {
  esppl_sniffing_start();
  while (true) {
    for (int i = ESPPL_CHANNEL_MIN; i <= ESPPL_CHANNEL_MAX; i++ ) {
      esppl_set_channel(i);
      while (esppl_process_frames()) {

      }
    }
  }
}
void setup() {
  delay(500);

There is no excuse for starting with a delay().

You are handling far too much processing off to a library. You need to change the library if you want to be called only when a connection happens (if that is not what is happening now).

You can detect that a particular MAC address is present, many times, but only do something once, by keeping track of whether you've done it.

Add another array, of type bool, of the same size as the MAC address array. Call it something like eventTriggered.

    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i]))
    { // Down here, where it belongs
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      if(!eventTriggered[i]
      {
         ifttt.triggerEvent(EVENT_NAME);
         eventTriggered[i] = true;
      }
 {
        Serial.println("Successfully sent");
      }

Why is this statement in curly braces?

The original sketch was to control a multicolour LED when the MAC address is discovered. I have adapted it and inserted the parts to connect to my WiFi network and the ifttt details. I will post the original sketch up now that is to control the LED. In my mind it would be simple to remove the LED and use the ifttt instead, evidently I am mistaken.

I will take what you have posted and see if I can adapt the sketch to improve it. I really appreciate your time.

Original LED code is here. I stripped everything I didn’t need out of it to make it shorter to post on the forum. Only posting it in the hope it clears up where I’ve gone wrong.

/*
Friend Detector by Ricardo Oliveira, forked by Skickar 9/30/2018

A Node MCU microcontroller + mini bread board + 4 pin RGB LED to detect when devices belonging to a target are nearby.

The function of this code is to read nearby Wi-Fi traffic in the form of packets. These packets are compared
to a list of MAC addresses we wish to track, and if the MAC address of a packet matches one on the list, we turn
on a colored LED that is linked to the user owning the device. For example, when my roommate comes home, the
transmissions from his phone will be detected and cause the blue LED to turn on until his phone is no longer detected.
It can detect more than one phone at a time, meaning if my phone (red) and my roommate's phone (blue) are both home,
the LED will show purple. */

#include "./esppl_functions.h"

/*  Define you friend's list size here
 How many MAC addresses are you tracking?
 */
#define LIST_SIZE 2
/*
 * This is your friend's MAC address list
 Format it by taking the mac address aa:bb:cc:dd:ee:ff
 and converting it to 0xaa,0xbb,0xcc,0xdd,0xee,0xff
 */
uint8_t friendmac[LIST_SIZE][ESPPL_MAC_LEN] = {
   {0x12, 0x34, 0x56, 0x78, 0x90, 0x12}
  ,{0x34, 0x56, 0x78, 0x90, 0x12, 0x34}
  };
/*
 * This is your friend's name list
 * put them in the same order as the MAC addresses
 */
String friendname[LIST_SIZE] = {
   "Target 1"
  ,"Target 2"
  };

// start variables package - Skickar 2018 hardware LED for NodeMCU on mini breadboard //
void setup() {
  delay(500);
  pinMode(D5, OUTPUT); // sets the pins to output mode
  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
  Serial.begin(115200);
  esppl_init(cb);
}

/* You cannot use a time delay here to keep the LED on, so will need to use ratio of
detected packets to overall packets to keep LED on for longer. If you try to use a
delay to keep the light on for long enough to be useful, the watchdog timer kills the
process and it dies */
int cooldown = 0; /* This variable will be a cooldown timer to keep the LED on for longer, we'll set it to 1000 if we
detect a packet from a device with a MAC address on the list, and then keep the LED on till we get 1000 packets that
are NOT from any device on the list. */
void red() {
digitalWrite(D5, HIGH); }  // Turn ON the red LED
void blue() {
digitalWrite(D7, HIGH); } // Turn ON the blue LED
void green() {
digitalWrite(D6, HIGH); } // Turn ON the green LED
void turnoff() {
    digitalWrite(D7, LOW), digitalWrite(D5, LOW), digitalWrite(D6, LOW);
}

/* end exparimental variable package */

bool maccmp(uint8_t *mac1, uint8_t *mac2) {
  for (int i=0; i < ESPPL_MAC_LEN; i++) {
    if (mac1[i] != mac2[i]) {
      return false;
    }
  }
  return true;
}

void cb(esppl_frame_info *info) {
  for (int i=0; i<LIST_SIZE; i++) {
    if (maccmp(info->sourceaddr, friendmac[i]) || maccmp(info->receiveraddr, friendmac[i])) {
      Serial.printf("\n%s is here! :)", friendname[i].c_str());
      cooldown = 1000; // here we set it to 1000 if we detect a packet that matches our list
      if (i == 1){
        blue();} // Here we turn on the blue LED until turnoff() is called
        else {
          red();} // Here we turn on the RED LED until turnoff is called. We can also use if i == 0, or another index
    }

      else { // this is for if the packet does not match any we are tracking
        if (cooldown > 0) {
          cooldown--; } //subtract one from the cooldown timer if the value of "cooldown" is more than one
          else { // If the timer is at zero, then run the turnoff function to turn off any LED's that are on.

        turnoff(); } } } }

void loop() { // I didn't write this part but it sure looks fancy.
  esppl_sniffing_start();
  while (true) {
    for (int i = ESPPL_CHANNEL_MIN; i <= ESPPL_CHANNEL_MAX; i++ ) {
      esppl_set_channel(i);
      while (esppl_process_frames()) {
        //
      }
    }
  }
}

Whoever wrote that code was a moron. The structure of the application is just horrid.

That code lights up the blue LED if the MAC address is that of the second device and lights up the red LED if the MAC address is that of the first, third, fourth, etc. device. That makes no sense to me.

Triggering the same ifttt event every time you recognize a MAC address is easy. Triggering the event once, no matter how many times you see the MAC address is only slightly harder. I showed how to do that in reply #9.

Since triggering the event once for each device is your goal, or so I thought, I'm at a loss to understand why you posted this (crappy) code.

Well if the code is crappy that’s at least a start as to why I’m having so much trouble.
I want it to identify a MAC address (just one) and send the ifttt command once, then delay then start looking again until it sees it again.

I posted the code so you could see where I started from.

I’ll do some reading as to how to add a new array as you suggested and see if I can get it working that way. I copied your piece of code in to the sketch but obviously it gives an error as it isn’t mentioned anywhere before I pasted it in.

Again thanks for your help

I want it to identify a MAC address (just one)

You are doing that.

and send the ifttt command once

I showed you how to do that.

then delay

For how long, and why?

then start looking again until it sees it again.

The callback method will be called over and over, and the information passed to the callback will contain that MAC address each time. So, I don't understand, and I don't think you do, either, when you want to call the ifttt method again.

Only reason I wanted to delay was so that it wouldn’t send the trigger over and over. But I now see this isn’t needed.