MQTT NodeMCU servo can react only on decimal array payload

I’m creating a fish feeder with SG90 servo and NodeMCU

I used this sketch:

```
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h>
// Update these with values suitable for your network.
const char* ssid = "your_wifi_hotspot";
const char* password = "your_wifi_password";
 const char* mqtt_server = "broker.mqttdashboard.com";
//const char* mqtt_server = "iot.eclipse.org";

Servo myservo;  // create servo object to control a servo
WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
   delay(100);
  // We start by connecting to a WiFi network
    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("Command from MQTT broker is : [");
  Serial.print(topic);
  for(int i=0;i<length;i++)
  {
    if((int)payload[i]>194||(int)payload[i]<0)
    break;
    myservo.write((int)payload[i]);              // tell servo to go to position in variable '(int)payload[i]'
  }
}//end callback

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) 
  {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    //if you MQTT broker has clientID,username and password
    //please change following line to    if (client.connect(clientId,userName,passWord))
    if (client.connect(clientId.c_str()))
    {
      Serial.println("connected");
     //once connected to MQTT broker, subscribe command if any
      client.subscribe("OsoyooCommand");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 6 seconds before retrying
      delay(6000);
    }
  }
} //end reconnect()

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  myservo.attach(D1);  // attaches the servo on pin D1 to the servo object
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

}
```

The servo is working when I use MQTTBox in order to send a payload as “Decimal Array”, it is however is giving me a hard time when I send payload as JSON string.

If I send “Decimal Array” 1 it does turn Servo to position 1, however if I simply send 1 as a payload as a string it moves Servo to position 49. If I send payload as 2 it moves to position 50. If I send payload as 10 then position is 4948 looks like position of 1 and position of 0 at the same time.

My ultimate goal is to send those payloads via HomeAssistant which are sent as string or JSON, however I don’t find a correct solution at the moment. I would highly appreciate any help or solution.

JSON is always sent as a string. The ascii code for “1” is 49.

Thank you @gpbenton, my goal if to turn servo from 180 to 0 and then again to 180. I’m still not sure how I could form my MQTT payload in Home Assistant in order to do so.

I found this converter: https://www.browserling.com/tools/text-to-ascii,and this https://www.browserling.com/tools/ascii-to-text but none of the values give correct result.

If you do the conversion from string to integer in your sketch, you just send the value you want from home assistant.

Hi, I feel that I could be closer to the solution, but still not there.

added this:

  i=Serial.parseInt();

with the hope that it will change string to integer, unfortunately it didn’t really help.

I used it here:

void callback(char* topic, byte* payload, unsigned int length) 
{
  Serial.print("Command from MQTT broker is : [");
  Serial.print(topic);
  Serial.print(" Rotation angle is:");
  Serial.print("   ");
 // for(int i=0;i<length;i++)
  {

//    if((int)payload[i]>194||(int)payload[i]<0)
  //  break;
  i=Serial.parseInt(); // Added this code to change variable to integer
    myservo.write((int)payload[i]);// tell servo to go to position in variable '(int)payload[i]'
    Serial.print((int)payload[i]);//print the rotation angle
    Serial.print("]");
    Serial.println();
  }
}//end callback

I fail to see how this would change the payload to an integer. You’re not using Serial.

Seems to me this should be
myservo.write(int(payload[i]));

@flamingm0e, your last suggestion is not returning any errors but I was not able to use string servo would move to 48 if I publish 0
and
495648 if I publish 180

So I’m still not sure how to convert string that I will be sending from Home Assistant and control servo.

You would probably need to convert all your code to use int() properly if you want it to work. I’ve never seen it written as (int)payload[i]. I’ve always used and seen it as int(payload[i])

Hi all, thank you for your response and help, I did manage to solve the problem.

I changed my sketch to this one:

It already accepts all strings.

1 Like