Page 1 of 1

Phone detection through WiFi

Posted: Mon Jun 26, 2023 11:49 am
by nikkio
Good mornig community, I am a beginner with DIY projects and I hope you can help me with the following...

Problem:
At the moment I have a garage light that is driven by an IR sensor, in some places the sensor does not detect me so the light goes out.
My idea:
I want the light to be switched on by an ESP32 that detects the presence of some phones
My solution, not so elegant, is derived by some standard sketch to set up an Access Point (AP):
1) I set up an AP and I give the password to who has to be detected
2) when someone connects to the network the ESP32 switches on the light
3) The ESP32 disconnects the AP (so that the phone is not trapped in an isolated network)
4) after a while, ESP32 restarts the AP to check if someone is still there, if not the light is swithed off.

The following code is working, but awkwardly

Code: Select all

#include <WiFi.h>

const char* ssid = "lightSwitcher";      // Name of the Wi-Fi network
const char* password = "turnOnTheLight";   // Password for the Wi-Fi network
const int channel = 1;               // Wi-Fi channel number
int loopCounter = 0;
const int ledPin = 13;               // Pin connected to the LED (This will become a realy for the 220V light)

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Initialize Wi-Fi as an access point
  WiFi.softAP(ssid, password, channel);

  IPAddress apIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(apIP);
}

void loop() {
  Serial.print("Loop: ");
  Serial.println(loopCounter++);
  
  // Check if a client is connected
  if (WiFi.softAPgetStationNum() > 0) {
    digitalWrite(ledPin, HIGH);  // Turn on the LED
    WiFi.softAPdisconnect(); // I switch off (?) the Access Point so that the phone disconnects
    Serial.println("Led ON and AP disconnected");
    //delay(10000); // don't know if it's necessary, I whant to ive time to the phone to realize that the AP is off
    Serial.println("restart AP");
    WiFi.softAP(ssid, password, channel);
    delay(10000);
  } else {
    digitalWrite(ledPin, LOW);   // Turn off the LED
    Serial.println("Led OFF");
    delay(5000);
  }
}
To avoid the light switching off every now and then I'll move the switch control to a Timer.
Because the time at which the phone will attempt to connect is quite random, I'd like to know if there is a more reliable way to detect the phone(s)

Re: Phone detection through WiFi

Posted: Wed Jun 28, 2023 8:46 am
by nikkio
I have now moved the off-switch in a timer so that AP managing can be done independently
this code will keep the led on for 20 seconds after last connection has been detected

Code: Select all

#include <WiFi.h>

const char* ssid = "lightSwitcher";      // Name of the Wi-Fi network
const char* password = "turnOnTheLight";   // Password for the Wi-Fi network
const int channel = 1;               // Wi-Fi channel number
int loopCounter = 0;
const int ledPin = 13;               // Pin connected to the LED
const int secON = 20;
hw_timer_t *My_timer = NULL;

void IRAM_ATTR onTimer(){
digitalWrite(ledPin, LOW);
Serial.println("***********************Led OFF**************************");
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Initialize Wi-Fi as an access point
  WiFi.softAP(ssid, password, channel);

  IPAddress apIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(apIP);
  My_timer = timerBegin(0, 8000, true); //1 tick every 1/10000s
    Serial.print(timerRead(My_timer));
    Serial.println(" - First Timer read");
    delay(100);
    Serial.print("A) Timer read: ");
    Serial.println(timerRead(My_timer));
  timerAttachInterrupt(My_timer, &onTimer, true);
    delay(100);
    Serial.print("B) Timer read: ");
    Serial.println(timerRead(My_timer));
  timerAlarmWrite(My_timer, secON*10000, true);
    delay(100);
    Serial.print("C) Timer read: ");
    Serial.println(timerRead(My_timer));
  timerAlarmEnable(My_timer);
    delay(100);
    Serial.print("D) Timer read: ");
    Serial.println(timerRead(My_timer));
  timerStop(My_timer);
}

void loop() {
  Serial.print("Loop: ");
  Serial.print(loopCounter++);
  Serial.print(" - Timer read: ");
  Serial.println(timerRead(My_timer));
  if (WiFi.softAPgetStationNum() > 0) {    // Check if a client is connected
    if(timerStarted(My_timer)){
    Serial.println("Timer already started");
    timerWrite(My_timer, 0);
    }
    else{
      Serial.println("Timer start now");
      timerStart(My_timer);
    }
    digitalWrite(ledPin, HIGH);  // Turn on the LED
    Serial.println("++++++++++++++++++++++++LED ON++++++++++++++++++++++");
    WiFi.softAPdisconnect();
    Serial.println("AP disconnected");
    delay(5000);
    Serial.println("restart AP");
    WiFi.softAP(ssid, password, channel);
  } else {
    Serial.println("No connection");
  }
  delay(1000);
}
One thing I didn't expect is the following output:
AP IP address: 192.168.4.1
1 - First Timer read
A) Timer read: 995
B) Timer read: 1995
C) Timer read: 2995
D) Timer read: 3995
Loop: 0 - Timer read: 3996
No connection
Loop: 1 - Timer read: 3996
No connection
The timer was started at the timerBegin() statement, so I don't understand the point on making a timerStart()
also can't see the difference with timerRestart(). Can someone explain what are they intended for?

Re: Phone detection through WiFi

Posted: Sun Jul 09, 2023 9:52 pm
by italocjs
Hey there, looking at the code i didnt immediately found what is causing the issue, but i had a couple of ideas that i think it would also work. Personally i think it would be easier to work with tasks instead of interrupts. ESP32 has freertos embedded

Ex
task 1 control the wifi connection, this includes opening AP, checking if someone has connected, closing the AP and restarting after some time, if the wanted device has connected sends an queue containing the current "millis"(esp equivalent function) to the task2
task 2 control the output (receives an queue from task1, then run the output for some time and check again if no other queue data has been received.

I'm also not sure using AP's are the best way to do this. I've been working with BLE lately, is not easy to learn (to be honest was quite a pain, the documentation and examples only provide the very basic stuff) and i think it would work better, no need to change wifi, lose internet on the phone, and handle wifi library stuff. a plus to ble, you can use any market beacon and/or your own android phone (nrf connect app let you emulate ble adv and services).