Arduino MQTT topic value displayed is different to the same MQTT Explorer Topic value

Hi, Newby here
This is driving me nuts and I have not been able to figure it out.
I've been on and off this project for about 2 months now, I've got most of it up and running thanks to all yourcoding knowleadge out there but I have now hit a brick wall!!

I’m running a sketch on Arduino Nano33 IoT which is connected to a local Victron Energy Venus mqtt broker on a CerboGX by wifi and subsribes to the topic - N/XXXXXXXXXX/system/0/Dc/Pv/Power.
I send regular keepalive commands so the topic value is updated.

To check it's working, I am running MQTT Explorer connected to the same
local Victron Energy Venus mqtt broker on CerboGX by wifi and subsribes to the same topic - N/XXXXXXXXXX/system/0/Dc/Pv/Power.

The problem is that the subscribed Pv power topic values displayed on MQTT Explorer and my Arduino are always different. They vary considerably at times even though they are looking at the same Pv Power topic.
I've tried faster client.loop times but no improvement, plus the values displayed by my sketch seem to lag the values displayed by MQTT Explorer.

The Victron VRM app ( uses cloud mqtt broker) on my phone displays the same Pv topic value as MQTT Explorer so I am assumming there is something not right with the coding in my Arduino sketch which I can’t figure out.
Has anyone come across this before?
I don't know how to upload my setch if you want to see it.
cheers

Welcome to the forum

Please post your full sketch, using code tags when you do. This prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Hi HeliBob
Good to be on the forum now.
I think I understand what my problem is and I think it relates to client.loop() and / or void callback() functions.
The subscribed topic values I'm getting are actually correct but it takes around a 300 seconds for them to be displayed. Could this be related to a large buffer that is used by either of the functions above, quickly filling up with topic values as they are published by the mqtt broker and eventually get pushed out 300 seconds later?
If you could just point me in the right direction I'd like to try and work it out myself as I learn better that way.

I am using a 6 second delay in my main loop, code below
cheers


#include <BetterWiFiNINA.h>
#include "LocalVenus_secrets.h"
#include <PubSubClient.h>
#include <ArduinoJson.h>

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid1[] = SECRET_SSID1;
char pass1[] = SECRET_PW1;

int status = WL_IDLE_STATUS;     // the WiFi radio's status

WiFiClient wifiClient1;
PubSubClient client(wifiClient1);

const char mqttbroker1[] = "X.X.X.X.X";   // Local Venus mqtt Broker
int        mqttport1 = 1883;
const char InTopic[] = "N/XXXXXXXXXX/system/0/Dc/Pv/Power";


void callback(char* topic, byte* payload, unsigned int length) {

  char payloadBuffer1[25];                 //an array to hold the payload
  memcpy(payloadBuffer1, payload, length);  //copy the payload into the array
  payloadBuffer1[length] = '\0';            //turn the char array into a C string
  Serial.println(payloadBuffer1);
  parseMessage(payloadBuffer1);
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("WifiClient1")) {
      Serial.println("connected");
      delay(1000);
      //client.publish("XXXXXXXXXX/keepalive",NULL);
      //delay(1000);
      //Serial.println("Subscribing to Power topic: ");
      //client.subscribe(InTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(10000);
    }
  }
}

void setup()
{
  // Initialize "debug" serial port
  // The data rate must be much higher than the "link" serial port
  Serial.begin(115200);

  // Initialize the "link" serial port
  // Use a low data rate to reduce the error ratio
  Serial1.begin(9600);

  client.setServer(mqttbroker1, mqttport1);
  client.setCallback(callback);

  //delay(1000);
  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Venus SSID: ");
    Serial.println(ssid1);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid1, pass1);
    // wait 10 seconds for connection:
    delay(10000);
    Serial.println(WiFi.status());
  }
  // you're connected now, so print out the data:
  Serial.print("You're connected to the network : ");
  printCurrentNet();
  printWifiData();
  Serial.println();
  Serial.println();
}
void loop()  {

  if (!client.connected())
  {
    reconnect();
  }
  client.publish("XXXXXXXXXX/keepalive", NULL);
  delay(1000);
  client.subscribe(InTopic);
  client.loop();
  delay(6000);
}

void parseMessage(char* json) {
  JsonDocument doc;
  DeserializationError error = deserializeJson(doc, json);

  if (error)
  {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }
  int PVpower = doc["value"];

  Serial.print("PVpower= ");
  Serial.println(PVpower);

  // Send the JSON document over the "link" serial port
  serializeJson(doc, Serial1);

}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

Why ?

Hi UKHeliBob

Ha Ha, funny you should ask. Today I realised ( light bulb moment!! :blush:) this 6 second delay is the cause of my problem, I got rid of it and I’m now seeing my Pv solar topic value in real-time.

I’m sending this PV solar topic value via serial in a json doc to another Nano33IoT connected to a different wifi LAN, then to an OpenEVSE EV charger ( via mosquito broker).

This charger wants to see a Pv solar mqtt topic feed every 5 to 10 seconds to modulate the charge current, hence the 6 second delay…… just not the right way or place to implement it.

Can Nano33IoT be set up to swap between wifi LANs or do I have to still use two of them, one for each wifi LAN?

cheers

Sorry, but I don't know the answer to your question

OK, thanks UKHeliBob

Hi, for anyone thats interested.
I used millis() in my parseMessage function to set up a 7sec sample period to obtain the solar value from my local MQTT broker. This is then fed to my OpenEVSE charger. It is all working very well now.
cheers

void parseMessage(char* json) {
  JsonDocument doc;
  DeserializationError error = deserializeJson(doc, json);

  if (error)
  {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  unsigned long now = millis();
  if (now - lastsubscribe >= mqttinterval) {
    lastsubscribe = now;

    int PVpower = doc["value"];

    Serial.print("PVpower= ");
    Serial.println(PVpower);

    // Send the JSON document over the "link" serial port
    delay(500);
    serializeJson(doc, Serial1);
  }
}