Displaying WiFi SSID's on OLED: Converting from String to Char array

Hi all,

I’m working on a WiFi connected project using an ESP32 and the Arduino IDE. I have a small OLED for a display, and a rotary encoder for user input.

Currently I’m trying to display the list of available networks after a WiFi Scan.

I figured out the list control function:

The arrow on the left side, and the Menu Line Text print separately.

The function wifiMenu() goes through a series of if statements to see if the encoder is going up or down, what position the arrow is in, and based off that, which lines of the menu should be printed. The menu lines are stored in an array of strings, what the Arduino Reference calls a two dimensional array.

//Globally Declared 2D Array
char* mainMenuLine[] = {
  " Menu Line 0", " Menu Line 1", " Menu Line 2",
  " Menu Line 3", " Menu Line 4", " Menu Line 5",
  " Menu Line 6", " Menu Line 7", " Menu Line 8",
  " Menu Line 9", " Menu Line 10", " Menu Line 11",
};
void wifiMenu() {

  int8_t encoderValue = rotaryEncoder();
  buttonPress();
  
  display.clearDisplay();
  display.setCursor(0, 0);

  if (goingUp == true) {
    if (arrowStatus == 0) {
      for (int i = encoderValue; i <= encoderValue + 3; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 8) {
      for (int i = encoderValue - 1 ; i <= encoderValue + 2; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 16) {
      for (int i = encoderValue - 2 ; i <= encoderValue + 1; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 24) {
      for (int i = encoderValue - 3 ; i <= encoderValue; i++) {
        display.println(mainMenuLine[i]);
      }
    }
  } else if (goingUp == false) {
    if (arrowStatus == 0) {
      for (int i = encoderValue; i <= encoderValue + 3; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 8) {
      for (int i = encoderValue - 1 ; i <= encoderValue + 2; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 16) {
      for (int i = encoderValue - 2 ; i <= encoderValue + 1; i++) {
        display.println(mainMenuLine[i]);
      }
    } else if (arrowStatus == 24) {
      for (int i = encoderValue - 3 ; i <= encoderValue; i++) {
        display.println(mainMenuLine[i]);
      }
    }
  }
  display.setCursor(0, arrowStatus);
  display.println(">");
  display.display();
}

What I was hoping to do was create a “string of arrays” that would be populated by the WiFi Scan:

void wiFiScan() {
  Serial.println("WiFi Network Scan Start");

  // WiFi.scanNetworks will return the number of networks found
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
      delay(10);
    }
  }
  Serial.println("");

  // Wait a bit before scanning again
  delay(5000);
}

The scan itself is returning strings, but the compiler was returning errors that the strings needed to be converted to chars. I tried using string.toCharArray() to do this conversion, and putting it in the for loop for the networking name printing so they would index through the ‘n’ number of networks, but the ESP is getting error messages and restarting after the scan.

void wiFiScan() {
  Serial.println("WiFi Network Scan Start");
  // WiFi.scanNetworks will return the number of networks found
  int n = WiFi.scanNetworks();
  Serial.println("scan done");

  char* wifiNetworks[n];
  String wiFiNameConversion;
  
  if (n == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");

      wiFiNameConversion = WiFi.SSID(i);
      int str_len = str.length()+1;
      wiFiNameConversion.toCharArray(wifiNetworks[i], len);

      delay(10);
    }
  }
  Serial.println("");

  // Wait a bit before scanning again
  delay(5000);
}

I’m not sure if I’m approaching this the correct way. If anyone has a better idea, or knows a “more correct” way to populate the array of network names, please let me know.

Thanks for any input,

TBB


I’ll just add some other attempts I’ve tried:

  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  char* wifiNetworks[n];

  if (n == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i) {
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");

      wifiNetworks[i] = WiFi.SSID(i); // attempting to assign "slots" of the char array with WiFi.SSID(i);

      delay(10);
    }
  }
  Seri

This returned:

exit status 1
cannot convert 'String' to 'char*' in assignment

"What I was hoping to do was create a "string of arrays" that would be populated by the WiFi Scan:"

You can capture the SSID in a String variable like below, then work with that.

readString = (WiFi.SSID(i)); //String test

Something like this?

It’s been a while, but I wanted to respond to this with the solution I found in case some one is following this thread later on.

What wound up being (a very simple solution) was just putting the string value into the println() function.

While far from perfect, here is an example:

int mainMenu() {

  int8_t encoderValue = rotaryEncoder();

  int mainMenuArraySize = sizeof(mainMenuLines);          //sizeof returns a number that is 4x the number of lines in the array (4 bytes each entry)
  int mainMenuEncoderMax = (mainMenuArraySize / 4) - 1 ;  // this gives us a number max for the encoder, otherwise the ESP was overflowing

  if (encoderValue >= mainMenuEncoderMax) {               //if the encoder value goes over our max
    encoder.setValue(mainMenuEncoderMax);                 //this resets it to our max and prevents overflow
    encoderValue = mainMenuEncoderMax;
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.fillRoundRect(0, 0, 127, 8, 3, WHITE); //X, Y, Width, Height, Corner Fillet
  display.setCursor(0, 0);
  display.setTextColor(BLACK);
  display.println(" Status Bar Line");
  display.setTextColor(WHITE);
  display.setCursor(0, 8);

  if (goingUp == true) {
    if (arrowStatus == 0) {
      for (int i = encoderValue; i <= encoderValue + 2; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    } else if (arrowStatus == 8) {
      for (int i = encoderValue - 1; i <= encoderValue + 1; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    } else if (arrowStatus == 16) {
      for (int i = encoderValue - 2 ; i <= encoderValue; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    } else if (arrowStatus == 24) {
      arrowStatus = 16;
      for (int i = encoderValue - 2 ; i <= encoderValue; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    }
  } else if (goingUp == false) {
    if (arrowStatus == 0) {
      for (int i = encoderValue; i <= encoderValue + 2; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    } else if (arrowStatus == 8) {
      for (int i = encoderValue - 1 ; i <= encoderValue + 1; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    } else if (arrowStatus == 16) {
      for (int i = encoderValue - 1 ; i <= encoderValue + 1; i++) {
        display.print(" ");
        display.println(mainMenuLines[i]);
      }
    }

  }
  display.drawBitmap(0, arrowStatus + 8, arrowBitmap, 10, 8, WHITE); // display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, colo
  display.display();
  return (encoderValue);
}