NodeMCU, MQTT and parsing payloads.

I'm just getting started with programming in the Arduino IDE beyond loading pre-existing sketches. What I've done below is basically a cobble together of items to try and get where I want and it almost works. I am using a NodeMCU V1.0 and have no issues writing to it.

My goal is to connect to WiFI (done), Connect to MQTT and subscribe (done) and when a message is posted, convert it to Morse Code (almost done) and flash the onboard LED with that message (done).

My issue is in the for loop. If I send the word "Hello" it only goes through the first three characters. If I then send a single letter "a" it will send the "a" then the "el" from Hello. I believe the problem is in using sizeof(payload) as it appears to give me the byte size rather than the number of characters. I just don't know what to use in it's place. Any help with understanding the correct way to do it is appreciated.

Here is just the line in question.

for (int i = 0; i < sizeof(payload) - 1; i++)

My full code is below (be gentle, I know it's ugly and I'm working on the practice of notating) I also removed the morse code letters b through y to keep it under 9000 for the forum post.

/* A program for an NodeMCU to connect to WiFi, Connect to an MQTT Broker,
 *  Subscribe to a topic and when a message is posted to that topic, 
 *  flash the message on the onboard LED in morse code. 
 *  
 *  Code chart https://morsecode.scphillips.com/morse2.html
 *  
 *  TODO 
 *  Add controlling a relay for Telegraph sounder 
 *  Add Full Punctuation
 *  Add ability to publish message back to MQTT from hand keyer.
 *  Clean up and better notate code.
 *  
 *  Troubleshooting
 *  Currently dropping last character of message.
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#define LED_PIN D0

//Set ssid and password for WiFi

char ssid[] = "SkyNet";
char pass[] = "***********";
// Define MQTT Server
char mqtt_server[] = "192.168.1.200";

WiFiClient espClient;
PubSubClient client(espClient);

//Set Timings. Adjust dotLen to change wpm

int dotLen = 200;     // length of the morse code 'dot'
int dashLen = dotLen * 3;    // length of the morse code 'dash'
int elemPause = dotLen;  // length of the pause between elements of a character
int Spaces = dotLen * 3;     // length of the spaces between characters
int wordPause = dotLen * 7;  // length of the pause between words

// Define what a dot, dash, and space are

// DOT
void MorseDot()
{
  digitalWrite(LED_PIN, LOW);    // turn the LED on
  delay(dotLen);              // hold in this position
}

// DASH
void MorseDash()
{
  digitalWrite(LED_PIN, LOW);    // turn the LED on
  delay(dashLen);               // hold in this position
}

// Turn Off
void LightsOff(int delayTime)
{
  digitalWrite(LED_PIN, HIGH);     // turn the LED off
  delay(delayTime);             // hold in this position
}

//define each character

void GetChar(char tmpChar)
{
  // Take the passed character and use a switch case to find the morse code for that character
  switch (tmpChar) {
    case 'a':
      MorseDot();
      LightsOff(elemPause);
      MorseDash();
      LightsOff(elemPause);
      Serial.print("a");
      break;
    
/* letters b through y retracted for forum to stay under 9000 */


    case 'z':
      MorseDash();
      LightsOff(elemPause);
      MorseDash();
      LightsOff(elemPause);
      MorseDot();
      LightsOff(elemPause);
      MorseDot();
      LightsOff(elemPause);
      Serial.print("z");
      break;
    case '.':
      MorseDot();
      LightsOff(elemPause);
      MorseDash();
      LightsOff(elemPause);
      MorseDot();
      LightsOff(elemPause);
      MorseDash();
      LightsOff(elemPause);
      MorseDot();
      LightsOff(elemPause);
      MorseDash();
      LightsOff(elemPause);
      Serial.print(".");
      break;
      
      default:
      // If a matching character was not found it will default to a blank space
      LightsOff(Spaces);
  }

}


void mqttCallback(char* topic, byte* payload, unsigned int length)
{
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
  }
  // Loop through the string and get each character one at a time until the end is reached
  for (int i = 0; i < sizeof(payload) - 1; i++)
  {
    // Get the character in the current position
    char tmpChar = payload[i];
    Serial.print(payload[i]);
    // Set the case to lower case
    tmpChar = toLowerCase(tmpChar);
    // Call the subroutine to get the morse code equivalent for this character
    GetChar(tmpChar);
  }

}
  void mqttConnect() {
    while (!client.connected())
    {
      Serial.print("Attempting MQTT connection...");
      String clientId = "ESP8266Client-";

      clientId += String(random(0xffff), HEX);

      if (client.connect(clientId.c_str()))
      {
        Serial.println("connected");
        client.subscribe("testing");
        Serial.println("Subscribed to testing");
      } else
      {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        delay(5000);
      }
    }
  }
  void setup()
  {
    pinMode(LED_PIN, OUTPUT);
    Serial.begin(115200);
    WiFi.begin(ssid, pass);
    client.setServer(mqtt_server, 1883);
    client.setCallback(mqttCallback);
  }
  void loop()
  {
    if (!client.connected())
    {
      mqttConnect();
    }
    client.loop();

  }

In this line

for (int i = 0; i < sizeof(payload) - 1; i++)

payload is a pointer to byte, sizeof(payload) returns the variable size, not the payload length.
You can get (intuitively) in the variable length.

Try changing it to

for (int i = 0; i < length; i++)

giova014:
In this line

for (int i = 0; i < sizeof(payload) - 1; i++)

payload is a pointer to byte, sizeof(payload) returns the variable size, not the payload length.
You can get (intuitively) in the variable length.

Try changing it to

for (int i = 0; i < length; i++)

That took care of it perfectly. Now I understand the difference between the two as well. Thanks.