title: Problem with RPC calls from Thingsboard to Arduino (ESP32)
body: <p>I created a simple Arduino program that receives a position value from a KnobControl Widget on my thingsboard dashboard and updates a servo position. The program is based on the <a href="https://thingsboard.io/docs/samples/esp32/gpio-control-pico-kit-dht22-sensor/#prepare-and-upload-sketch" rel="nofollow noreferrer">ESP32 Pico Kit GPIO control and DHT22 sensor monitor</a> example from the ThingsBoard website and is <em>mostly</em> working.</p>
  
  <p>So far, my code is able to connect to the dashboard and receive "setPos" and "getPos" RPC commands from the server, and so far, it is sucessfully running the associated RPC_Response function for the "setPos" call, and can move the servo.</p>
  
  <p>But, when I refresh the dashboard and it sends out a "getPos" call to the controller to get the current servo value, I get an SDK message in the serial output indicating that the controller received the command, but the associated RPC_Response function is never called. I'm not sure what I'm missing but here is the complete code example I wrote so far:</p>
  
  <pre><code>#include &lt;WiFi.h&gt;
  #include &lt;ESP32Servo.h&gt;
  #include &lt;ThingsBoard.h&gt;
  
  // Constants
  #define SERVO_PIN               19      // Servo Output Pin
  #define SERVO_UPDATE_INTERVAL   20      // Speed of servo position updates
  
  // Helper macro to calculate array size
  #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
  
  // WiFi Login Info
  #define ssid                "IoT"
  #define password            "password"
  
  // MQTT Broker IP address:
  #define THINGSBOARD_SERVER  "10.10.0.30"
  
  // MQTT Client Info
  #define ACCESS_TOKEN "ESP32_DEMO_TOKEN"
  
  // Servo Variables
  int minUs = 500;
  int maxUs = 2400;
  int SetPosition = 0; // ServoMotor Position Setpoint
  int Position = 0;    // ServoMotor current position
  
  // Control/Timing Variables
  long lastServoTime = 0;       // keeps track of timestamp since the last servo update occured
  
  // Objects
  Servo ServoMotor;
  WiFiClient espClient;
  ThingsBoard client(espClient);
  
  // RPC Callbacks
  RPC_Callback callbacks[] = {
    { "setPos", setPosition },
    { "getPos", getPosition },
  };
  
  void setup() {
    Serial.begin(115200);
  
    // Initialize Servo
    ServoMotor.setPeriodHertz(50);                  // Standard 50hz servo
    ServoMotor.attach(SERVO_PIN, minUs, maxUs);
  
    // Initialize the WiFi and MQTT connections
    setup_wifi();
  }
  
  void loop() {
    // Update/refresh the Wifi/MQTT connection
    updateWirelessConnection();
  
    // Update Servo Positions
    updateServo();
  }
  
  void updateWirelessConnection()
  {
    if (!client.connected()) {
      reconnect();
    }
  
    client.loop();
  }
  
  // Processes function for RPC call "getPos"
  // RPC_Data is a JSON variant, that can be queried using operator[]
  // See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
  RPC_Response getPosition(const RPC_Data &amp;data)
  {
    Serial.println("Received the get Position Method");
    return RPC_Response(NULL, SetPosition);
  }
  
  // Processes function for RPC call "setPos"
  // RPC_Data is a JSON variant, that can be queried using operator[]
  // See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
  RPC_Response setPosition(const RPC_Data &amp;data)
  {
    Serial.print("Received the Set Position method: ");
    SetPosition = data;
    Serial.println(SetPosition);
    return RPC_Response(NULL, SetPosition);
  }
  
  void updateServo()
  {
    long currentTime = millis();
  
    if (currentTime - lastServoTime &gt; SERVO_UPDATE_INTERVAL) {
      lastServoTime = currentTime;
  
      // Approach the Horizontal set point incrementally and update the servo if applicable
      if (Position != SetPosition) {
        Position = SetPosition;
        ServoMotor.write(Position);
      }
    }
  }
  
  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(".");
    }
  
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
  
  void reconnect() {
    // Loop until we're reconnected
    while (!client.connected())
    {
      Serial.print("Attempting MQTT connection...");
  
      // Attempt to connect
      if (client.connect(THINGSBOARD_SERVER, ACCESS_TOKEN)) {
        Serial.println("connected");
  
        // Perform a subscription. All consequent data processing will happen in
        // callbacks as denoted by callbacks[] array.
        if (!client.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
          Serial.println("Failed to subscribe for RPC");
          return;
        }
  
        Serial.println("Subscribe done");
      } else {
        Serial.println("Failed to connect. Trying again in 5 seconds...");
        // Wait 5 seconds before retrying
        delay(5000);
      }
    }
  }
  </code></pre>
  
  <p>Also, here's the response I see in the Serial Monitor when I refresh the dashboard:</p>
  
  <pre><code>{"method":"getPos"}
  [SDK] received RPC getPos
  [SDK] response {}
  </code></pre>
  
  <p>When I update the position of the knob control on the dashboard, here is what I receive in the Serial Monitor:</p>
  
  <pre><code>{"method":"setPos","params":"135"}
  [SDK] received RPC setPos
  [SDK] calling RPC setPos
  Received the Set Position method: 135
  [SDK] response 135
  </code></pre>
  
  <p>NOTE: I'm not having any problems with the setPos call, this calls the RPC function properly.</p>
  
  <p>As one final note, when I refresh the dashboard, an error message that says, "Unable to parse response: [object Object]" appears on the top of the knob control widget.</p>
  
  <p>So the main issue is that the right RPC function is not being called. What do you think the problem is here?</p>