ESP32 can't connect to iPhone Personal Hotspot - arduino

This is my code
#include <WiFi.h>
const char* ssid = "wifiname";
const char* password = "12345678";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // SETS TO STATION MODE!
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("IP is ");
Serial.println(WiFi.localIP());
}
void loop() {
}
I can found my iPhone's personal hotspot using the WiFiscan routine, but I can't connect to it.

I tested your code and I was able to connect my ESP32 to my iPhone 8+. Since you were able to scan your iPhone's hotspot, you could try the following:
Make sure that you are using the 2.4GHz hotspot and NOT the 5GHz. If you have a iPhone 12, which now supports 5GHz hotspot, disable 5GHz by going to Settings -> Personal Hotspot -> enable(!) "Maximize compatibility"
Try to connect with an other wifi (in the 2.4GHz range)
(sounds stupid but): did you try to change the SSID and PW on your iPhone? Are you sure that your "ssid" and "password"-variable are both correct (no spelling mistakes)? For testing purposes you could even try to exclude special characters and only use letters and numbers.
If all fails it might be a HW issue. Did you try to use a different ESP32?

FWIW: I have apparently been able to connect the ESP32 chip's Wifi to my iPhone13 pro running IOS 15.3.1. The line of code:
WiFi.mode(WIFI_STA); // SETS TO STATION MODE!
was the break thru allowing me to make this connection. Note that I can make the connection even with settings->personal hotspot->Maximize Compatibility DISABLED.

I believe the iPhone hotspot turns off (or at least stops broadcasting an SSID) shortly after leaving the "Personal Hotspot" screen in "Settings". Leaving the "Personal Hotspot" screen open with my iPhone unlocked allowed me to connect my ESP32.
This Apple support discussion from 2011 describes the behavior (assuming it hasn't changed in the last decade): https://discussions.apple.com/thread/2784174

For me, the apostrophe in the default hotspot SSID was problematic (ex: John Doe's iPhone). I changed the iPhone name (and therefore the SSID name) in Settings > General > About. Afterwards, my ESP32 was able to connect to the hotspot.
Potential caveat: instead of programming the firmware directly, I was using ESP Web Tools to configure the ESP32 with ESPHome, so my issue may have been specific to the ESPHome firmware (and how it handles character encodings).

I find a solution for that issue by trials and may be it could help :
1.You have to be in the iPhone hotspot settings when the ESP32 is trying to connect specially if there's no other device connected to the hotspot!
2.Hotspot works fine until the phone gets locked and ESP32 went to deep-sleep and after wake up the ESP32 cannot connect again in some cases until you go again to the hotspot page!

Related

ESP32 Switch Between Promiscuous and STA Mode

I'm working on a project based on the ESP32 platform. The aim is to count the number of MAC addresses in the area, and transmit this information over WiFi (using an http POST request).
The first task is achieved by sniffing WIFI packets and collecting the contained addresses, following this example: https://blog.podkalicki.com/esp32-wifi-sniffer/
I believe that the code which "sniffs" the packets sets the ESP to run in promiscuous mode, and therefore I cannot connect to any AP anymore.
I've tried several solutions, first starting with timer interrupts. However this approach always led to a Core Panic and reset of the chip.
I also learnt I could use RTOS to run different tasks in parallel on the two cores of the CPU, but that didn't help to solve the problem.
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type)
{
if (type != WIFI_PKT_MGMT)//aggiungere filtro su RSSI a questa altezza.
return;
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
//some analysis and then print the MAC address
}
void setup() {
Serial.begin(115200);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &chUpdate, true);
timerAlarmWrite(timer, 1000000, true);//timer, arr_val, reload=true
delay(4000);
wifi_sniffer_init();
timerAlarmEnable(timer);
}
// the loop function runs over and over again forever
void loop() {
//Serial.print("inside loop");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi..");
}
Serial.println("Connected to network");
}
I also noticed that the code in the loop gets stuck into the while, and is restarted every time the packet handler is run (I nevere get to see "Connected to network", but i see "Establishing connection to WiFi.." several times.
Anyone can explain me what's going on? Is there a different approach to achieve this result?
Thank you.
You may have two tasks and two cores, but the ESP32 still has only one wifi chip. The way your code is written (at least, the code you shared), you'll be trying to connect to a wifi network at the same time as you're trying to run promiscuous mode. You can do only one of those things at a time.
You'll need to stop promiscuous mode before you attempt to connect to an access point. Right now your code constantly attempt to connect to a wifi access point. Use a volatile variable to store the current mode - promiscuous or connected. Change it when you need to change states. Only attempt to connect to wifi when the variable says you want to be in connected mode.
There may be some code you need to run to turn off promiscuous mode when you change states, before you connect to a wifi access point.
If you're using wifi_sniffer_init() from the example you linked to, that code isn't meant to be run in an Arduino Core application. It does some network initialization that the Arduino Core will also do. It may not be safe to do that twice (it might work, it might not... but it's definitely not intended to be done that way).
You're setting an interrupt handle chUpdate() which you didn't share. I'd bet that's the cause of your Core Panics. You can do very little in an interrupt handler. You definitely can't call most Arduino Core functions or most ESP-IDF functions. Most code isn't protected against interrupts, so the timer interrupt can occur while data structures are in an inconsistent state. Re-entering code can corrupt the data structures and cause the kind of crash you described. You're best off setting a volatile variable and waking up a task that will do the work you need done while not in the interrupt handler.
Finally, you should call WiFi.mode(WIFI_STA); before you call WiFi.begin().
For anyone confused about why you can't connect to a wifi network while in promiscuous mode - what ESP8266 and ESP32 call "promiscuous mode" is really "wifi monitor mode", which lets you monitor a wifi radio channel and see all wifi frames sent on it. They use the term "promiscuous mode" differently from the rest of the industry. Usually "promiscuous mode" means seeing all the packets being sent on the network (wifi or hardwired) that you're connected to.
I know that it's been just over a year but THANKS to the info provided by romkey I think I solved this problem within my app by calling this routine before connecting to WiFi to upload MAC data.
void end_Scan_WiFi() {
esp_wifi_set_promiscuous(false);
esp_wifi_stop();
}
Followed by this ...
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,pass);

WebServer + AP not working? WebServer + STA does

I've been trying to set up an access point combined with a web server using the ESP8266WiFi libraries for Arduino. I am using an ESP8266 Huzzah module with NodeMCU firmware installed (newest master).
Setting up an AP using softAP works fine, I can also assert a PSK to it and choose which channel to use (I've chosen the one with the least traffic, in this case ch 11). The problem is when trying to access the web server from a connected device, it always ends up with a timeout exception. The ESP's IP is in this case 192.168.4.1 and the port is 80.
I've tried connecting the ESP to another AP (Home router) in STA mode and I am successfully able to connect to the ESP through the given IP Address.
To sum it all up:
ESP8266WebServer + WIFI_AP (Station) => Does not work!
ESP8266WebServer + WIFI_STA (Client) => Works!
This is how I set the web server up, together with AP:
In Setup:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
[...]
ESP8266WebServer server(80);
[...]
Serial.print("Setting soft-AP ... ");
WiFi.disconnect(true);
WiFi.mode(WIFI_AP);
delay(100);
boolean result = WiFi.softAP("TestAP", "0123456789", 11); // This does of course return true, and the access point shows up on my device
if(result == true)
{
Serial.println("Access Point Ready");
Serial.println(WiFi.softAPIP()); // Prints 192.168.4.1
}
else
{
Serial.println("Access Point Failed!");
}
[...]
server.on("/", [](){
server.send(200, "text/html", webPage);
delay(1000);
});
[...]
server.begin();
In Loop:
server.handleClient();
Has anyone else done this before and had it work? What am I actually doing wrong here?
Ok, so it seems that I figured it out partly...
All the time, I was using my smartphone to connect to the ESP AP and trying to access the web server. I tried connecting from my computer and by all the stupidness in this world, it works.
Why I can not connect via the phone is a mystery to me, maybe someone can tell me what is going on here...
Basically on certain android devices look out for a notification about staying connected as mentioned in the comments.
If you don't accept staying connected your phone will still show as "connected with out internet" and the page will not load, once you have accepted the notification about staying connected then you can load your wemos page.
On an android nvidia based tablet this was not required, but on my motorola smart phone it would not work until i accepted that box.

My Arduino Uno Wifi, stops responding to wifi

My new Arduino Uno Wifi, stops responding to wifi if left inactive. To be more specific, after 2-3 hours of no wifi usage:
I cannot access the build-in configuration page of the Arduino's wifi section
Loaded programs which use Wifi are not receiving any commands via my browser
loop() continues to run just fine
It somehow seems that the wifi section of my Uno Wifi "sleeps" after some arbitrary interval.
Using code to periodically reset the board (by sending HIGH to the reset pin of the board) did not solve the problem. As soon as the reset takes place, loop() starts executing just fine, but wifi connection is still impossible to obtain.
Things I usually do to gain access to my board AFTER wifi is lost:
Hard reset the board (unplug power and plug it again) -> almost always works
Try to access arduino from several different wifi devices hoping that the board somehow "wakes up" -> occasionally works but only after 4 or 5 minutes (sometimes hours) of failed attempts
My router seems to be fine. Another web server which I have set up in a wifi-connected laptop has had no hiccups (even after a long time of inactivity). Moreover I've never had any connection problems with my router so far.
This is giving me a hard time! Could anybody be of any help?
Is my Arduino Uno faulty?
Many thanks in advance
George
Here's my configuration:
Arduino Uno Wifi Developer edition (built-in wifi support)
Arduino IDE 1.8.0 (I'm using the Linux version installed on Ubuntu 12.04 )
I have already connected my arduino to my home network and gave it a static IP 192.168.2.50
WIFI mode: STA
Wifi channel: 1
SLIP status enabled
MQTT status disabled/disconnected
code:
int i=0;
void setup() {
pinMode(13,OUTPUT);
}
void loop() {
if (i==1){
digitalWrite(13, HIGH);
i=0;
}
else{
digitalWrite(13,LOW);
i=1;
}
delay(1000);
}
It seems that I have been a victim of an extreme ambiguity caused by the .org fork of arduino.
Arduino.cc and Arduino.org boards are NOT 100% compatible with each other.
To be more specific, the examples that come with the IDE (and are based on the the wifi shield of arduino.cc) DO NOT function with aruduino-uno-wifi (the one with the embedded wifi section)
Apart from that, it seems that arduino-uno-wifi has firmware that is way behind the arduino.cc (in terms of features as well as code quality). This has frustrated several users as you can see here:
Issue 2: Rename this fork and use less confusing versioning
Issue 10: Please stop doing this !
Issue 6: Remove old licenses from sample code comments and take credit for everything
If you are interested of an arduino.org view of things visit here:
The full story
All of the above is information which I wish I had when ordering my new ardnino-uno-wifi board.
Moreover it is relevant with the question I've asked, since it indicates that my problem is most probably a bug of the uno-wifi board, so I should file a bug report (and keep hoping) instead of trying to fix my code.

Interfacing a USB/serial device with Arduino USB/serial interface

On one side I have a device with a USB (FTDI chip) interface communicating in serial 9600bps,N,8,1 - the default configuration for the Arduino USB/serial interface.
On the other side I have a simple Arduino sketch that starts a serial session and transmits data.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600,SERIAL_8N1);
}
void loop() {
// put your main code here, to run repeatedly:
char* data_to_send="66";
SSEND(data_to_send);
delay(5000);
}
String SSEND(char* data){
String protocol="AT$SF=";
protocol+=(String)data;
// protocol+="\r";
Serial.println(String(protocol));
delay(1000);
return "OK";
}
The sketch works just fine when connected to the computer.
Then I try to connect to the device and I see the Tx LED that stops blinking so it doesn't send anything and of course the device doesn't work like expected. Besides, I tried sending serial commands directly from the computer to the device and it works just fine.
So my questions are:
Why does the serial interface between Arduino and my device doesn't work?
Why does Arduino stop sending data once the USB/serial interface switched from the computer to the device
What would be the solution to make the device work with the Arduino?
Should I switch the TX & RX with a splitted FTDI cable plugged to port 0 and 1?
Thanks for your help
I suspect that device is a USB device and not a USB host, and you plugged two USB devices together. That Arduino is not a USB host, and a USB connection always needs a host.
The plug adapter you're using is not even supposed to exist according to the USB spec, because the different shapes of plugs are specifically there to make it impossible to plug two devices into each other like you've done here.
The way to make it work would be to use another board that actually supports acting as a USB host.

Arduino: Incoming USB serial data when USB is disabled hoses the connection

I'm writing a sketch for an Arduino Leonardo that occasionally needs to communicate bidirectionally via USB serial, and also needs to be power efficient. To save power I'd like to disable the USB when it's not needed. I can successfully use power_usb_disable() and power_usb_enable() to do this, BUT only if no data is sent to the Arduino when USB is disabled.
Here's how to reproduce the problem: I run the following sketch on the Leonardo while it's connected to a serial comms program on my computer (I've tried the Arduino serial monitor and Minicom in Linux and PuTTY in Windows). It works as expected, printing out the messages, until I type something right after the "Disabling USB..." message. Once I do that, I will receive no further data from the Leo. The funny thing is, the TX and RX LEDs continue to blink as if everything is fine. The only way to get the connection working again is to reset the board.
Now, I don't really care about dropping the incoming data when USB is disabled, that's to be expected...but I would like the serial connection to continue to work correctly once USB is enabled again.
I don't know enough about how USB serial works to know how to troubleshoot this.
#include <avr/power.h>
void setup() {
Serial.begin(9600);
delay(3000);
}
void loop() {
Serial.println("USB is enabled!");
delay(1000);
// If I send characters here, everything is fine.
Serial.println("Disabling USB...");
delay(25);
power_usb_disable();
delay(1000);
// If I send characters here, it hoses the USB connection somehow.
power_usb_enable();
delay(25);
}
I guess for now the best answer to this problem is "don't do that." I can arrange not to disable the USB if the connection is open, using the "if (Serial)" thing. So if somebody has a serial monitor open and looks as if they're about to type something, I leave USB enabled. Seems to work OK, although it doesn't address the underlying general question of how to robustly disable and re-enable USB from any state it might be in. I would still love to hear expert advice on that.

Resources