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();
}