Hey everyone, I am trying to get the number of characters that are in a String. The text is getting sent over from NodeRed to the public HiveMQ broker and to my Serial Monitor. However when I use the length function in Arduino it only prints out 1s and not the actual character numbers. I will paste the part of my code in here. Thanks in advance!
void callback(char* topic, byte* payload, unsigned int length) {
//Serial.print("Weergave payload=");
for (int i = 0; i < length; i++) {
playingsong = ((char)payload[i]);
int CharacterLength = Serial.print(playingsong.length());
}
Serial.println();
}
Oh yes my bad, I forgot to add that in. "playingsong" is indeed a String. That is for getting the song name out of the void callback. So if I would say "Serial.print(playingsong);" it would print the name.
I've checked many websites on how to do this and some use strnlen and others say Mystring.length(); but both versions don't work.
Yes "playingsong' is indeed a String, I forgot to put that in sorry. So if I would say "Serial.print(playingsong);" it would print out the song name. I've tried printing out the length veriable as you mentioned but still no luck. This is my code now
void callback(char* topic, byte* payload, unsigned int length) {
//Serial.print("Weergave payload=");
for (int i = 0; i < length; i++) {
playingsong = ((char)payload[i]);
Serial.print(length);
}
Serial.println();
}
Sure, so this stores the song name in the var "playingsong". This just makes it easier to read and understand. I receive the song name instantly so it's not one character at a time. And I'm sorry I thought the code would be a bit too long to post in here but I will add it in now. I appreciate your help and time.
#include <WiFi.h>
#include <PubSubClient.h>
#include <LiquidCrystal_I2C.h>
const char* ssid = "Sint-Rembert Techniek";
const char* password = "Dt16Mc6UJa35";
const char* mqtt_server = "broker.mqtt-dashboard.com";
LiquidCrystal_I2C lcd(0x3F, 16, 2);
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
String playingsong = "";
String nextsong = "";
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
//Serial.print("Weergave payload=");
for (int i = 0; i < length; i++) {
playingsong = ((char)payload[i]);
Serial.print(length);
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// ... and resubscribe
client.subscribe("ThiboSpotify");
}
else {
Serial.print("failed, rc=");
Serial.println(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
//int Clength = playingsong.length();
//Serial.print(Clength);
//for (int i = 0; i < Clength; i++) {
// scroll one position left:
//lcd.scrollDisplayLeft();
// wait a bit:
//delay(400);
}
The payload is not a String. Payload is an array of characters. The for loop in your callback is converting the character array to a String. After the for loop is done, then print the String length of playsong.
Though serial printing from a callback is not good practice.
If String is to be used. I'd declare the String and in setup(), set the String to a reserve() size. Say 100. Then I'd use playingsong.concat( String(((char)payload[i]) ) to put data into the String reserved space and use "" to empty the String reserved space. Otherwise using String may create memory holes and consume ram and cause a system crash.
I'm getting more confused as this thread goes on. Can you back away from the code and explain what you are trying to do, because every explanation seems slightly different. My understanding is that you are trying to put the payload into a String variable called playing song, in which case this:
playingsong= String((const char*)payload);
should be all you need, assuming payload is null-terminated. Or, if it's not null-terminated and you need to use the length variable,
Fair enough. I'm working with a similar application ATM where I'm getting the song & artist from a Bluetooth A2DP message, so I figured this might be doing the same thing.