A String object doubt...[Solved #8]

Refer the code snippet below :

  // Do a little work to get a unique-ish name. Append the
  // last two bytes of the MAC (HEX'd) to "Thing-":
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String AP_NameString = "ESP8266 Thing " + macID;

When compiled and executed the AP_NameString comes out as " ESP8266 Thing 1788 "

The operation is not obvious ( to me ). Help required to understand the logic. Thanks

The operation is not obvious

nor have you posted a complete program

Exactly what text were you expecting to be output?

So here we go with the code , if it helps :

#include <ESP8266WiFi.h>

//////////////////////
// WiFi Definitions //
//////////////////////
const char WiFiAPPSK[] = "sparkfun";  // This is the password string...

/////////////////////
// Pin Definitions //
/////////////////////
const int LED_PIN = 5; // Thing's onboard, green LED
const int ANALOG_PIN = A0; // The only analog pin on the Thing
const int DIGITAL_PIN = 12; // Digital pin to be read

WiFiServer server(80);

void setup() 
{
  initHardware();
  setupWiFi();
  server.begin();
}

void loop() 
{
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  // Match the request
  int val = -1; // We'll use 'val' to keep track of both the
                // request type (read/set) and value if set.
  if (req.indexOf("/led/0") != -1)
    val = 0; // Will write LED low
  else if (req.indexOf("/led/1") != -1)
    val = 1; // Will write LED high
  else if (req.indexOf("/read") != -1)
    val = -2; // Will print pin reads
  // Otherwise request will be invalid. We'll say as much in HTML

  // Set GPIO5 according to the request
  if (val >= 0)
    digitalWrite(LED_PIN, val);

  client.flush();

  // Prepare the response. Start with the common header:
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html>\r\n";
  // If we're setting the LED, print out a message saying we did
  if (val >= 0)
  {
    s += "LED is now ";
    s += (val)?"on":"off";
  }
  else if (val == -2)
  { // If we're reading pins, print out those values:
    s += "Analog Pin = ";
    s += String(analogRead(ANALOG_PIN));
    s += "
"; // Go to the next line.
    s += "Digital Pin 12 = ";
    s += String(digitalRead(DIGITAL_PIN));
  }
  else
  {
    s += "Invalid Request.
 Try /led/1, /led/0, or /read.";
  }
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}

void setupWiFi()
{
  WiFi.mode(WIFI_AP);

  // Do a little work to get a unique-ish name. Append the
  // last two bytes of the MAC (HEX'd) to "Thing-":
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
  String AP_NameString = "ESP8266 Thing " + macID;

  char AP_NameChar[AP_NameString.length() + 1];
  memset(AP_NameChar, 0, AP_NameString.length() + 1);

  for (int i=0; i<AP_NameString.length(); i++)
    AP_NameChar[i] = AP_NameString.charAt(i);

  WiFi.softAP(AP_NameChar, WiFiAPPSK);
}

void initHardware()
{
  Serial.begin(115200);
  pinMode(DIGITAL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // Don't need to set ANALOG_PIN as input, 
  // that's all it can be.
}

its all there in your first post, even comments are there

  // Do a little work to get a unique-ish name. Append the
  // last two bytes of the MAC (HEX'd) to "Thing-":

Mogaraghu:
When compiled and executed the AP_NameString comes out as " ESP8266 Thing 1788 "
The operation is not obvious ( to me ). Help required to understand the logic. Thanks

The "ESP8266 Thing " part comes from the string constant "ESP8266 Thing ". The "1788" part comes from the String variable 'macID'. The two are concatenated with the '+' operator which String defines as concatenation.

The "17" part of 'macID' comes from the

String(mac[WL_MAC_ADDR_LENGTH - 2], HEX)

. String objects can be printed into like Serial.print(). The defined constant "HEX" tells .print() to display the value of the byte in hexadecimal digits. Similarly for the "88" part.

NOTE: It is probable that the conversion to HEX will drop leading zeroes. If your MAC address ends in ".3.5" the 'macID' will be "35", not "0305".

Its almost clear now.. I could earlier itself make out the concatenation part but the factthat String object can be used akin to Serial print is news.

I still am wondering how does < mac[WL_MAC_ADDR_LENGTH - 2]> evaluate to 17 in HEX.

Thanks for your support John !

Mogaraghu:
I still am wondering how does < mac[WL_MAC_ADDR_LENGTH - 2]> evaluate to 17 in HEX.

'mac' is a byte array containing the MAC address.
Elements in an array of length 'N' are numbered 0 through N-1.

array[N-1] is the last element in the array (assuming N >= 1).  
array[N-2] is the second-to-last element in the array (assuming N >= 2).

In your case 'WL_MAC_ADDR_LENGTH' is 'N', the number of bytes in a MAC address (6?). The MAC address has 23 (0x17) as the second-to-last byte and 136 (0x88) as the last byte.

johnwasser:
'mac' is a byte array containing the MAC address.
Elements in an array of length 'N' are numbered 0 through N-1.

array[N-1] is the last element in the array (assuming N >= 1).  

array[N-2] is the second-to-last element in the array (assuming N >= 2).



In your case 'WL_MAC_ADDR_LENGTH' is 'N', the number of bytes in a MAC address (6?). The MAC address has 23 (0x17) as the second-to-last byte and 136 (0x88) as the last byte.

Hmmm.. being innovative is all fine to arrive at a unique-ish name for the AP. But this is convoluted to say the least. :slight_smile: Again maybe its me and for C or C++ experts out there, its basic stuff.

Anyway it was interesting read. Thanks for being so patient and explaining in detail.

C and C++ experts would have probably built the name into a character array using sprintf():sprintf(buffer, "ESP8266 Thing %02X%02X", mac[WL_MAC_ADDR_LENGTH - 2], mac[WL_MAC_ADDR_LENGTH - 1]);