Portenta H7 as Wireless Access Point Tutorial Very Slow

Hello folks,

I'm excited to get fully acquainted with the capabilities of the Portenta H7. I have noticed the very limited number of tutorials for it, so in the full spirit of commitment to learning this thing, I need to ensure that with the few examples on offer I should definitely get the tutorial examples fully-working on my device and tinker with those codes before anything else.

The basic blinking LED examples, despite their simplicity, I found very cool in sending instructions from the different M4 and M7 cores; these I have got working without a hitch.

When it came to the tutorial trying the turn the Portenta into a wireless access point in order to control the blinking LEDs via either a computer or iPhone using WiFi (https://www.arduino.cc/pro/tutorials/portenta-h7/por-ard-ap), I struggle to get this working at all. The code executes and compiles fine, but the connections are just crazy slow.

I can connect to it using my iPhone or Mac (curiously, I have found overriding the default IP address and instead using 10.0.0.1 much better for connection purposes, else it doesn't connect at all) however the connection that does form is so slow I can't send any instructions to the Portenta. Any tips for young players?

All the best,
Ryan

Hello thejerseychemist,

I ran through the tutorials and I didn't see any issues with the AP tutorial at the time that I ran it - I did that build on a win10 PC and the cell phone I used is one of the GOOG Pixel makes - I don't think that should have anything to do with what you're seeing other than I'm not doing this in a MAC environment.

Since the tutorials have been written there have been several 'pull' requests that affect WiFi performance and functionality but that wouldn't be the case (I think) for a basic IP-AP type of demo like in the tutorial and those pull requests hadn't been done yet when I ran the tutorial.

Make sure your iPhone or Mac isn't somehow doing 'statefull sniffing' of incoming packets from a new network or something similar a firewall could be doing when connecting to a new network. If you're connected to multiple network connections, all of which have a forwarding IP - meaning - you have more than one gateway set on your network connections, sometimes the routing can grind to a halt because the network doesn't know where to forward packets.

On the Mac you can start a shell (as poweruser/admin or root) and run ifconfig -a
to list the network interface settings - also - look at netstat -r

It's been a little while since I've been on a Mac but they run on top of BSD Unix. Make sure you don't have more than one active network connection with more than one active forwarding gateway - this can cause your network performance to slow to a crawl or not work at all.

HTH,
John W.

Many thanks for your comments.

If I disable my firewall it has no effect on the outcome. For me, the page loads when going to http://192.168.x.y where x and y I've played around with in the code. However, once I try and click on the buttons to send instructions, everything stops dead in its tracks.

I'm not sure whether this is a profound observation or not, but when things go awry, I'm finding that although the code comment refers to a default local IP address of 192.168.4.1, I find the default IP address differs from this and is instead 192.168.3.1 once I connect with my Mac and go to Network preferences and look at the Connection status, where the IP address is given.

If I bypass this and force it to have the IP address 192.168.4.1 by uncommenting WiFi.config(IPAddress(192, 168, 4, 1)), my Network preferences say that 'Wi-Fi is connected to PortentaAccessPoint and has the IP address 192.168.4.2.

Is this relevant to the problem?

Hello Ryan,

In the code:

#include <WiFi.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;             // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

WiFiServer server(80);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Access Point Web Server");

  pinMode(LEDR,OUTPUT);
  pinMode(LEDG,OUTPUT);
  pinMode(LEDB,OUTPUT); 

  // by default the local IP address of will be 192.168.4.1
  // you can override it with the following:
  // WiFi.config(IPAddress(10, 0, 0, 1));

  // print the network name (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);

  //Create the Access point
  status = WiFi.beginAP(ssid,pass);
  if(status != WL_AP_LISTENING){
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }

  // wait 10 seconds for connection:
  delay(10000);

  // start the web server on port 80
  server.begin();

  // you're connected now, so print out the status
  printWiFiStatus();

}

void loop() {

 // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // a device has connected to the AP
      Serial.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      Serial.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected()) {            // loop while the client's connected

      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("<html><head>");
            client.print("<style>");
            client.print("* { font-family: sans-serif;}");
            client.print("body { padding: 2em; font-size: 2em; text-align: center;}");            
            client.print("a { -webkit-appearance: button;-moz-appearance: button;appearance: button;text-decoration: none;color: initial; padding: 25px;} #red{color:red;} #green{color:green;} #blue{color:blue;}");
            client.print("</style></head>");
            client.print("<body><h1> LED CONTROLS </h1>");
            client.print("<h2><span id=\"red\">RED </span> LED </h2>");
            client.print("<a href=\"/Hr\">ON</a> <a href=\"/Lr\">OFF</a>");
            client.print("<h2> <span id=\"green\">GREEN</span> LED </h2>");
            client.print("<a href=\"/Hg\">ON</a> <a href=\"/Lg\">OFF</a>");
            client.print("<h2> <span id=\"blue\">BLUE</span> LED </h2>");
            client.print("<a href=\"/Hb\">ON</a> <a href=\"/Lb\">OFF</a>");
            client.print("</body></html>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /Hr")) {
          digitalWrite(LEDR, LOW);               // GET /Hr turns the Red LED on
        }
        if (currentLine.endsWith("GET /Lr")) {
          digitalWrite(LEDR, HIGH);                // GET /Lr turns the Red LED off
        }
        if (currentLine.endsWith("GET /Hg")){
          digitalWrite(LEDG, LOW);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Lg")){
          digitalWrite(LEDG, HIGH);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Hb")){
          digitalWrite(LEDB, LOW);                // GET /Hg turns the Green LED on
        }
        if (currentLine.endsWith("GET /Lb")){
          digitalWrite(LEDB, HIGH);                // GET /Hg turns the Green LED on
        } 

      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }

}

void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

Can you please print out the results of the printWiFiStatus() call in your serial monitor window?

The DHCP server running on the Portenta's AP just serves up addresses in sequential order - so I don't see any problem there. Note, you can still have multiple gateway issues if you haven't checked ifconfig -a and netstat -r also run route -n - should be pretty obvious after you look at those.

HTH,
John

Dear John,

When I plug the Portenta into the USC port, upload the code and connect to 'PortentaAccessPort' in my network list, the serial monitor output is as follows:

 13:47:13.270 -> Access Point Web Server
13:47:13.270 -> Creating access point named: PortentaAccessPoint
13:47:23.967 -> SSID: 
13:47:23.967 -> IP Address: 192.168.4.1
13:47:23.967 -> To see this page in action, open a browser to http://192.168.4.1
13:47:23.967 -> Device disconnected from AP

Then when I go to http://192.168.4.1 in Safari the serial monitor then outputs the following additional lines of code:

13:48:04.880 -> new client
13:48:04.914 -> GET / HTTP/1.1
13:48:04.914 -> Host: 192.168.4.1
13:48:04.914 -> Upgrade-Insecure-Requests: 1
13:48:04.914 -> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
13:48:04.914 -> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15
13:48:04.947 -> Accept-Language: en-us
13:48:04.947 -> Accept-Encoding: gzip, deflate
13:48:04.986 -> Connection: keep-alive
13:48:04.986 ->

At which point all communication with the Portenta stops when I try and press any buttons.

Using ifconfig -a in Terminal, I am presented with a list of network interfaces such as 'en0, en1, en1' of which en1 and en2 are inactive.

Using netstat -r, I am presented with the following:

Internet:
Destination        Gateway            Flags        Netif Expire
default            192.168.1.1        UGSc           en0       
127                localhost          UCS            lo0       
localhost          localhost          UH             lo0       
169.254            link#4             UCS            en0      !
192.168.1          link#4             UCS            en0      !
192.168.1.1/32     link#4             UCS            en0      !
192.168.1.1        f8:8:4f:d8:c2:32   UHLWIir        en0   1176
192.168.1.2        64:5a:ed:10:7b:91  UHLWIi         en0   1164
192.168.1.3/32     link#4             UCS            en0      !
192.168.1.3        4c:32:75:9c:35:eb  UHLWIi         lo0       
192.168.1.255      ff:ff:ff:ff:ff:ff  UHLWbI         en0      !
224.0.0/4          link#4             UmCS           en0      !
all-systems.mcast. 1:0:5e:0:0:1       UHmLWI         en0       
224.0.0.251        1:0:5e:0:0:fb      UHmLWI         en0       
225.255.255.255    1:0:5e:7f:ff:ff    UHmLWI         en0       
239.255.255.250    1:0:5e:7f:ff:fa    UHmLWI         en0       
255.255.255.255/32 link#4             UCS            en0      !
broadcasthost      ff:ff:ff:ff:ff:ff  UHLWbI         en0      !

Internet6:
Destination        Gateway            Flags         Netif Expire
default            fe80::fa08:4fff:fe UGc             en0       
default            fe80::%utun0       UGcI          utun0       
default            fe80::%utun1       UGcI          utun1       
localhost          localhost          UHL             lo0       
2600:6c50:7980:1af link#4             UC              en0       
2600:6c50:7980:1af 4c:32:75:9c:35:eb  UHL             lo0       
2600:6c50:7980:1af 4c:32:75:9c:35:eb  UHL             lo0       
2600:6c50:7980:1af 4c:32:75:9c:35:eb  UHL             lo0       
fe80::%lo0         ryans-macbook-pro- UcI             lo0       
ryans-macbook-pro- link#1             UHLI            lo0       
fe80::%en0         link#4             UCI             en0       
ryans-macbook-pro- 4c:32:75:9c:35:eb  UHLI            lo0       
fe80::fa08:4fff:fe f8:8:4f:d8:c2:32   UHLWIir         en0       
fe80::%awdl0       link#9             UCI           awdl0       
fe80::b401:85ff:fe b6:1:85:9:1:bf     UHLI            lo0       
fe80::%llw0        link#10            UCI            llw0       
fe80::b401:85ff:fe b6:1:85:9:1:bf     UHLI            lo0       
ryans-macbook-pro- link#11            UHLI            lo0       
ryans-macbook-pro- link#12            UHLI            lo0       
ff01::%lo0         localhost          UmCI            lo0       
ff01::%en0         link#4             UmCI            en0       
ff01::%awdl0       link#9             UmCI          awdl0       
ff01::%llw0        link#10            UmCI           llw0       
ff02::%lo0         localhost          UmCI            lo0       
ff02::%en0         link#4             UmCI            en0       
ff02::%awdl0       link#9             UmCI          awdl0       
ff02::%llw0        link#10            UmCI           llw0

From what I understood from your message, the germane part is to look for multiple Gateway addresses such as '192.168.1.1 ' which I do not see. Am I on the right track?

Thanks for all your help and patience.

Ryan

Hello Ryan,

Yes - that's very good - we're getting somewhere now.

Your ethernet connection - en0 - is probably causing the most grief right now - so you need to disable it when running the Portenta test.

The easiest thing to do is just unplug it.

So, why don't you try unplugging your ethernet connection, and try running again.

If it still doesn't work after you've unplugged en0 (your main ethernet connection) - please run netstat -r again and post those results.

Good job!

Regards,
John W.

Dear John,

Many thanks so far. I confess at this point I am now confused.

If I disable en0 using the Terminal command 'sudo ifconfig en0 down', this turns off my WiFi. So if en0 is actually my WiFi and I disable this, how do I connect to the Portenta as per the tutorial? I do not have any wired connections to any network.

All the best,
Ryan

Ryan,

Oops - I thought maybe you had an ethernet connection also.

Disable your WiFi AP connection that's got the 192.168.1.1 gateway. Disconnect from it.

Then - connect to the Portenta. Hopefully that will work. Not sure - but you may have to disable
auto reconnect to the 192.168.1.1 AP so you have a chance to open the web-browser to
192.168.4.1.

I suppose you know the password to your 192.168.1.1 AP/router - you'll probably have to reenter that
after this is done.

If you can isolate your network so that only the Portenta is your only network connection - you should be able to run the demo. The overall goal here is to just have one network path enabled so you can run the demo.

Please give that a try and let us know here how it is going.

Regards,
John W.

Dear John,

Disconnecting from my home WiFI, plus unchecking auto-join (and even deleting it from my list of connectable networks) still does not work. Again I'm nominally connected to the Portenta but no instructions can be sent over the webpage, same as before.

I ran netstar-r again and observe the following. Unlike before however, netstat -r took AGES to fully complete:

Internet:
Destination        Gateway            Flags        Netif Expire
default            192.168.4.1        UGSc           en0       
127                localhost          UCS            lo0       
localhost          localhost          UH             lo0       
169.254            link#4             UCS            en0      !
192.168.4          link#4             UCS            en0      !
192.168.4.1/32     link#4             UCS            en0      !
192.168.4.1        c6:ac:59:4d:bb:17  UHLWIir        en0   1068
192.168.4.2/32     link#4             UCS            en0      !
192.168.4.255      ff:ff:ff:ff:ff:ff  UHLWbI         en0      !
224.0.0/4          link#4             UmCS           en0      !
224.0.0.251        1:0:5e:0:0:fb      UHmLWI         en0       
239.255.255.250    1:0:5e:7f:ff:fa    UHmLWI         en0       
255.255.255.255/32 link#4             UCS            en0      !

Internet6:
Destination        Gateway            Flags         Netif Expire
default            fe80::%utun0       UGcI          utun0       
default            fe80::%utun1       UGcI          utun1       
localhost          localhost          UHL             lo0       
fe80::%lo0         ryans-macbook-pro- UcI             lo0       
ryans-macbook-pro- link#1             UHLI            lo0       
fe80::%en0         link#4             UCI             en0       
ryans-macbook-pro- 4c:32:75:9c:35:eb  UHLI            lo0       
fe80::%awdl0       link#9             UCI           awdl0       
fe80::1c3c:90ff:fe 1e:3c:90:53:57:86  UHLI            lo0       
fe80::%llw0        link#10            UCI            llw0       
fe80::1c3c:90ff:fe 1e:3c:90:53:57:86  UHLI            lo0       
ryans-macbook-pro- link#11            UHLI            lo0       
ryans-macbook-pro- link#12            UHLI            lo0       
ff01::%lo0         localhost          UmCI            lo0       
ff01::%en0         link#4             UmCSI           en0       
ff01::%awdl0       link#9             UmCSI         awdl0       
ff01::%llw0        link#10            UmCSI          llw0       
ff02::%lo0         localhost          UmCI            lo0       
ff02::%en0         link#4             UmCI            en0       
ff02::%awdl0       link#9             UmCI          awdl0       
ff02::%llw0        link#10            UmCI           llw0

If the results of netstat don't throw up any flags, I guess at this point I should just try it on a PC and see whether it's a Mac and also a PC problem. I'll keep this thread active with my findings in case I converge on whether the Murata chipset itself is being problematic.

All the best,
Ryan

Hello Ryan,

When you are connected to the Portenta - can you ping it?

Try a ping by typing in the shell:

ping 192.168.4.1 (this pings the gateway - in this case - the Portenta)

and can you post here what that returns?

Not a bad idea to try from a PC just to see if there's something up with the Mac. We have an old Mac here - I can try to boot that up maybe (it'll be a little while before I could get to that) - but I'm willing to look at that if this is still unresolved.

I'm assuming also that the IP you were given was 192.168.4.2, correct?

Another experiment to try quickly would be to have the PC just connect to the Portenta (the only active network) and try to ping from the PC to the Mac - if the ping doesn't make it that could indicate a possible firewall issue (in the Mac maybe) or some other network tool that could be doing 'stateful sniffing' or something similar.

That test is when the Mac and PC are both connected to the Portenta.

Regards,
John

Dear John,

Pinging the Portenta seems to work okay:

PING 192.168.4.1 (192.168.4.1): 56 data bytes
64 bytes from 192.168.4.1: icmp_seq=0 ttl=255 time=3.188 ms
64 bytes from 192.168.4.1: icmp_seq=1 ttl=255 time=2.331 ms
64 bytes from 192.168.4.1: icmp_seq=2 ttl=255 time=13.737 ms
64 bytes from 192.168.4.1: icmp_seq=3 ttl=255 time=4.394 ms
64 bytes from 192.168.4.1: icmp_seq=4 ttl=255 time=8.155 ms
64 bytes from 192.168.4.1: icmp_seq=5 ttl=255 time=4.660 ms
64 bytes from 192.168.4.1: icmp_seq=6 ttl=255 time=2.361 ms
64 bytes from 192.168.4.1: icmp_seq=7 ttl=255 time=13.813 ms
64 bytes from 192.168.4.1: icmp_seq=8 ttl=255 time=1.814 ms
64 bytes from 192.168.4.1: icmp_seq=9 ttl=255 time=4.388 ms
64 bytes from 192.168.4.1: icmp_seq=10 ttl=255 time=5.014 ms
64 bytes from 192.168.4.1: icmp_seq=11 ttl=255 time=2.439 ms
^C
--- 192.168.4.1 ping statistics ---
12 packets transmitted, 12 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.814/5.525/13.813/4.037 ms

I might be a bit delayed on the PC test; I thought I had an old laptop around but I don't. I'll have to take this to work and give it a bit of a test run.

All the best,
Ryan

Ryan,

Ping looks good. From a networking point of view - the demo should be good to go.

You can look up the specification for ping here: ICMP

The demo is using HTTP - but, it pings.

So, the demo should work.

Can you try firefox (mozilla) on the Mac maybe?

Regards,
John

Ryan,

Also - on cell phones - one of the reasons possibly the demo wasn't working is you have to make sure the connection will stay persistent if there's no internet connected to the AP. Since the Portenta is standalone - at least for this demo - you have to find the settings on your cell phone that will keep the connection or the phone may disconnect and find an alternate AP that it has connected to before with internet.

I'd forgotten I had to enable that on the android phone that I have - somewhat annoying and surprising really that the default setting is to disconnect from an AP the user selects if the running 'code' isn't satisfied with the status of the internet connection. This is why I don't like calling them smart phones at all - to me, at lot of this programming has taken huge steps backward. I'm not even sure if this gets QA'ed by a human anymore.

Anyway - if you're looking at this from your cell phone - make sure you aren't disconnecting due to the Portenta not have an internet connection (for this demo at least).

Something else I noticed on the tutorial pages - the demo has been changed to work with 192.168.3.1 vs. 192.168.4.1 .

Regards,
John

Dear John,

I've tried the tutorial now on Safari, Chrome and Firefox on my Macbook and also on an iPhone and Google Pixel and I always get the same error messages.

"For Firefox, the message is 'the connection has timed out: the server at 192.168.4.1 [or .3.1, the results are the same] is taking too long to respond."

For Chrome on an Google Pixel, the error message is "The site cannot be reached, the webpage at 192.168.3.1/Hg might be temporarily down or may have moved permanently to a new address ERR_CONNECTION_ABORTED"

I think I might be running out of troubleshooting options at this point!

All the best,
Ryan

I wonder if the problem may be in the subnetmask of your LAN? I mean, when a connection must be made with IP's like 192.168.1.1 and 192.168.4.1, the subnetmask should be (something like) 255.255.0.0 ! Just my 2 cts...

I recently found out what was the issue with WiFi. I have checked C++ code for WiFiClient, WiFiServer in new 1.2.2 version, and I would say that it is a disaster.=( For example, there is no check for null pointer, therefore program crashes in some cases...

Solution: Install old libraries (version 1.2.0) for Portenta and it will work.

Dear Erik_Baas,

I think your two cents might be worth more, my Subnet Mask (found by going to System Preferences > Network > Advanced > TCP/IP tab) is 255.255.255.0.

Now for the stupid question: can I change this address to 255.255.0.0? And if you have time, what causes my subnet mask to be different from the 'default'?

All the best,
Ryan

aderman96:
I recently found out what was the issue with WiFi. I have checked C++ code for WiFiClient, WiFiServer in new 1.2.2 version, and I would say that it is a disaster.=( For example, there is no check for null pointer, therefore program crashes in some cases...

Solution: Install old libraries (version 1.2.0) for Portenta and it will work.

I rolled back the version of my WiFi.h library to 1.2.0 (if this is what you mean), but I found this did not help my case. In fact, rolling it back meant that I could not connect to the Portenta in my list of networks at all, rather than it connecting but being very slow/dropping the connection.

All the best,
Ryan

Try to completely reinstall mbed library, not just one file.) In current version something wrong with server.available() function. It returns 0. I lost almost 3 hours debugging this issue, but still nothing..

Ryan,

A class C subnet mask is fine for this demo as long as you have the single gateway address as discussed previously.

I ran this demo originally on the mbed release 1.2.1 - are you running 1.2.1? Maybe go back to that and do a complete reinstall as suggested above?

I've patched my 1DX firmware to WHD 1.9.x - and this AP demo does fail. I'm running the wifi_on_qspi branch and it's not easy to back this out - but interesting (I guess) that as soon as I try to connect to the AP - I get the exception error with the 4 short red led blinks and the 4 long led blinks. But this is probably because not everything is compatible with what I've done.

I'm running multicast just fine, which is important for my immediate task.

If I had an extra Portenta H7, I'd go back to 1.2.1 and try the demo again.

I do get the web page with the LED controls on it before it fails - which is interesting also. But again, I'm running a non-standard build right now - and think it's worth trying everything with a clean (re)install of the mbed 1.2.1 tools.

Also - can you run the ping test continuously while trying this again? I think the -t option with ping will keep it running - so

ping -t 192.168.4.1 and see if that shows any issues while trying to run this.
(maybe just ping 192.168.4.1 will run continuously under BSD unix)

Also - some of the errors with the browsers you're seeing are the same that I saw with my cell phone when the AP was disconnected due to not having an Internet connection.

HTH,
John W.