MQTT ESP extra characters appearing?

Working with T-SIM7600 which has a ESP32 Rover onboard.

Want to publish to Hive and have it working but have some random characters appearing?

#define TINY_GSM_MODEM_SIM7600

// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial

// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// See all AT commands, if wanted
#define DUMP_AT_COMMANDS

// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon

// set GSM PIN, if any
#define GSM_PIN             ""

// Set phone numbers, if you want to test SMS and Calls
//#define SMS_TARGET  "+xxxxxx"
//#define CALL_TARGET "+xxxxxx"

// Your GPRS credentials, if any
//const char apn[] = "internet.xxx.xx";
const char apn[] = "";
const char gprsUser[] = "";
const char gprsPass[] = "";

//Your WiFi connection credentials, if applicable
const char wifiSSID[] = "xxxx";
const char wifiPass[] = "xxxx";

// MQTT details Private 8883
//const char* broker = "xxxxx"; 
//const char* mqttUsername = "xxxxx";  // MQTT username
//const char* mqttPassword = "xxxxx";  // MQTT password
// MQTT details Public 1883
const char* broker = "broker.xxx.com"; x
const char* mqttUsername = "xxxx";  // MQTT username
const char* mqttPassword = "xxxx";  // MQTT password

const char* topicOutput1 = "Protect/output1";
const char* topicOutput2 = "Protect/output2";
//const char* topicTemperature = "Protect/temperature";
const char* topicTemperature = "Protect/temperature";
const char* topicHumidity = "Protect/humidity";

//Trigger
unsigned long TriggerTimes[3];
unsigned TriggerCount = 0;

//All Functions libraries
#include <SPI.h>
#include <SD.h>
#include <Ticker.h>
#include <TinyGsmClient.h>
#include "utilities.h"
#include <WiFi.h>

//PIR HCSR501
int ledPin = 12;                // LED
int pirPin = 19;                 // PIR Out pin
int pirStat = 0;                   // PIR status

// Sensor state
boolean pirState, lastPirState;

//Interger countPIR
int countPIR = 0;
//Interger count Down
int countDown = 0;
//Interger timeInterval
int timeinterval = 51000; //51000 is 51secs allows it to count => than 50 remove equals
//Interger CPUTemp
//int temp = 0;
float temp = 0;
//Interger MQTTcount
int MQTTcount = 0;

//Debug
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

//MQTT
#include <PubSubClient.h>
TinyGsmClient client(modem);
PubSubClient mqtt(client);

#define OUTPUT_1             2
#define OUTPUT_2             15

uint32_t lastReconnectAttempt = 0;

// Static Wireless IP address
IPAddress local_IP(192, 168, x, x);
IPAddress gateway(192, 168, x, x);
IPAddress subnet(255, 255, 255, 255);
IPAddress primaryDNS(192, 168, x, x); //optional
IPAddress secondaryDNS(1, 1, 1, 1); //optional

//Libraries for OLED Display
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Graphics File
#include "graphics.h"

//OLED Display pins
#define OLED_SDA 21 //4
#define OLED_SCL 22 //15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

//OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);
RTC_DATA_ATTR int counter = 0;
#define Logo_BMPWIDTH 128
#define Logo_BMPHEIGHT 64
#define Logo2_BMPWIDTH 128
#define Logo2_BMPHEIGHT 64
#define Sleeping_BMPWIDTH 128
#define Sleeping_BMPHEIGHT 64
#define Sleeping2_BMPWIDTH 128
#define Sleeping2_BMPHEIGHT 64


//MQTT Setup
void mqttCallback(char* topic, byte* message, unsigned int len) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < len; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT
  // If a message is received on the topic Protect/output1, you check if the message is either "true" or "false".
  // Changes the output state according to the message
  if (String(topic) == "Protect/output1") {
    Serial.print("Changing output to ");
    if (messageTemp == "true") {
      Serial.println("true");
      digitalWrite(OUTPUT_1, HIGH);
    }
    else if (messageTemp == "false") {
      Serial.println("false");
      digitalWrite(OUTPUT_1, LOW);
    }
  }
  else if (String(topic) == "Protect/output2") {
    Serial.print("Changing output to ");
    if (messageTemp == "true") {
      Serial.println("true");
      digitalWrite(OUTPUT_2, HIGH);
    }
    else if (messageTemp == "false") {
      Serial.println("false");
      digitalWrite(OUTPUT_2, LOW);
    }
  }
}


boolean mqttConnect() {
  SerialMon.print("Connecting to ");

  // Connect to MQTT Broker without username and password
  boolean status = mqtt.connect("Protect");

  // Or, if you want to authenticate MQTT:
  //boolean status = mqtt.connect("Protect", mqttUsername, mqttPassword);
  //SerialMon.print(status);

  /*
    if (status == false) {
      SerialMon.println(" fail");
      //ESP.restart();
      return false;
    }
    SerialMon.println(" success");
    mqtt.subscribe(topicOutput1);
    mqtt.subscribe(topicOutput2);
  */
  return mqtt.connected();
  SerialMon.print("MQTT Connected ");

}


void setup()
{
  //PIR
  pinMode(ledPin, OUTPUT);
  pinMode(pirPin, INPUT);

  SerialMon.begin(115200);
  delay(10);

  //Reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  //Draw BitMap Logo
  display.clearDisplay();
  display.drawBitmap(0, 0, Logo, 128, 64, WHITE);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.drawBitmap(0, 0, Logo2, 128, 64, WHITE);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.drawBitmap(0, 0, Logo, 128, 64, WHITE);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.drawBitmap(0, 0, Logo2, 128, 64, WHITE);
  display.display();
  delay(1000);

  Serial.println("Booting");
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);  // draw box
  display.setCursor(2, 2);
  display.print("Booting...");
  display.display();
  delay(1000);

  //The indicator light of the board can be controlled
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  //MODEM_PWRKEY IO:4 The power-on signal of the modulator must be given to it,
  //otherwise the modulator will not reply when the command is sent
  pinMode(MODEM_PWRKEY, OUTPUT);
  digitalWrite(MODEM_PWRKEY, HIGH);
  delay(300); //Need delay
  digitalWrite(MODEM_PWRKEY, LOW);

  //MQTT
  pinMode(OUTPUT_1, OUTPUT);
  pinMode(OUTPUT_2, OUTPUT);

  //MODEM_FLIGHT IO:25 Modulator flight mode control,
  //need to enable modulator, this pin must be set to high
  pinMode(MODEM_FLIGHT, OUTPUT);
  digitalWrite(MODEM_FLIGHT, HIGH);

  SerialMon.println("Wait...");

  //Set GSM module baud rate
  SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
  //delay(6000);

  //Connect to a WiFi network
  WiFi.begin(wifiSSID, wifiPass);

  // Configures static IP address
  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(wifiSSID);
  WiFi.begin(wifiSSID, wifiPass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  bool res ;
  DBG("Initializing modem...");
  Serial.println("Initializing modem..");
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);  // draw box
  display.setCursor(3, 3);
  display.print("Initializing modem..");
  display.display();
  delay(1000);

  if (!modem.init()) {
    DBG("Failed to restart modem, delaying 10s and retrying");
    return;
  }

  //Print Wireless IP address and if connected
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);  // draw box
  display.setCursor(3, 3);
  display.print("Connecting ");
  display.println(wifiSSID);
  display.setCursor(3, 12);
  display.print(WiFi.localIP());
  display.display();
  delay(2000);

  /*
    SerialMon.print("Connecting to APN: ");
    SerialMon.print(apn);
    if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
      SerialMon.println(" fail");
      ESP.restart();
    }
    else {
      SerialMon.println(" OK");
    }

    if (modem.isGprsConnected()) {
      SerialMon.println("GPRS connected");
    }
  */

  // MQTT Broker setup
  mqtt.setServer(broker, 1883); //use TLS 8883 not Web Sockets not supported 8884
  //mqtt.setCallback(mqttCallback);

  DBG("Connecting to APN");
  Serial.println("Connecting to APN");
  delay(1000);

  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    light_sleep(10);
    return;
  }

  res = modem.isGprsConnected();
  DBG("GPRS status: ", res ? "connected" : "not connected");

  String ccid = modem.getSimCCID();
  DBG("CCID: ", ccid);
  Serial.println(ccid);

  String imei = modem.getIMEI();
  DBG("IMEI: ", imei);
  Serial.println(imei);

  String imsi = modem.getIMSI();
  DBG("IMSI: ", imsi);
  Serial.println(imsi);

  String cop = modem.getOperator();
  DBG("Operator: ", cop);
  Serial.println(cop);

  IPAddress local = modem.localIP();
  DBG("Local IP: ", local);
  Serial.println(local);

  int csq = modem.getSignalQuality();
  DBG("Signal quality: ", csq);
  Serial.println(csq);

  //Write to the display
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.drawRect(0, 0, 128, 64, SSD1306_WHITE);  // draw box
  // drawFastVLine(x, y, length, color)
  // Draw a verticle line starting at x,y for the length of pixels
  // L/R vPos, vLength
  display.drawFastVLine(30, 3, 58, WHITE);
  //display.setCursor(3, 3);
  //display.print("NTWK: ");
  display.drawBitmap(1, 1, Connected, 24, 16, SSD1306_WHITE);
  //left/right then down/up (l/r, u/d)
  display.setCursor(34, 3);
  display.print(cop);
  //display.setCursor(3, 15);
  //display.print("IP: ");
  display.drawBitmap(1, 14, IPAddressID, 24, 12, SSD1306_WHITE);
  display.setCursor(34, 17);
  display.print(local);
  //display.setCursor(3, 30);
  //display.print("SIG: ");
  display.drawBitmap(3, 28, Signalcellular, 24, 12, SSD1306_WHITE);
  display.setCursor(34, 31);
  display.print(csq);
  display.drawBitmap(3, 40, statusconnection, 24, 24, SSD1306_WHITE);
  //display.setCursor(3, 45);
  //display.print("Status: ");
  display.setCursor(34, 46);
  display.print(res ? + "Connected" : "Not connected");
  display.display();
  delay(5000);
  display.clearDisplay();

  /*
    mqttConnect();
    //mqtt.connect("Protect", mqttUsername, mqttPassword);
    mqtt.connect("Protect");
    SerialMon.print("MQTT Connected ");
    //mqtt.publish("Protect/temperature", "1332");
    temp = modem.getTemperature(); //get CPUtem
    // Convert the value to a char array
    char tempString[2];
    dtostrf(temp, 1, 1, tempString);
    mqtt.publish(topicTemperature, tempString);
    SerialMon.println("MQTT publish Protect/temperature value ");
    //Serial.println(topicTemperature, tempString);
    delay(2000); //wait to see on the serial monitor
  */
  //mqttConnect();
  //mqtt.connect("Protect");
  //SerialMon.print("MQTT Connected ");
  //mqtt.publish("Protect/temperature", "1332"); //manually enter the topic
    
  Serial.print("Status: ");
  Serial.println("Armed");

}

//Sleep Timer
void light_sleep(uint32_t sec )
{
  esp_sleep_enable_timer_wakeup(sec * 1000000ULL);
  esp_light_sleep_start();
}

void loop() {

  /*
      // Make sure we're still registered on the network
      if (!modem.isNetworkConnected()) {
      SerialMon.println("Network disconnected");
      if (!modem.waitForNetwork(180000L, true)) {
        SerialMon.println(" fail");
        delay(10000);
        return;
      }
      if (modem.isNetworkConnected()) {
        SerialMon.println("Network re-connected");
      }
      }

      //MQTT Check and reconnect
      if (!mqtt.connected()) {
      SerialMon.println("=== MQTT NOT CONNECTED ===");
      // Reconnect every 10 seconds
      uint32_t t = millis();
      if (t - lastReconnectAttempt > 60000L) {
        lastReconnectAttempt = t;
        if (mqttConnect()) { lastReconnectAttempt = 0; }
      }
      delay(100);
      return;
      }

      mqtt.loop();

  */

  /*

    https://components101.com/sensors/hc-sr501-pir-sensor

    HC-SR501 sensors is to turn the 'time' pot fully anticlockwise for the shortest 'on' time (~3sec).
    Then the Arduino can take care of timing.
    Leave the 'sens' pot in the middle. It does NOT control distance.

    The sketch is better written as a state machine. Do something if the PIR output CHANGES.
    Wrote a quick example (untested).

    Be patient, and sit very still. These sensors are very sensitive. And not only to human heat sources

    Range it's 5-7metres with that Fresnel lens.
    You can only influence the 'ignore' time with the sensitivity pot, to reduce false triggers

    Two LiPo batteries in series (~7.4volt) can be connected to the DC socket.
    The Uno draws about 50mA, so theoretically about 20 hours on two 1000mAh cells.
    Can ignore the PIR sensor in the calculations. It draws less than 0.1mA
  */


  display.clearDisplay();
  display.drawBitmap(0, 0, NoMovement, 128, 64, WHITE);
  display.setCursor(29, 57);
  display.print(" A R M E D ");
  display.display();
  display.display();

  // PIR Detector
  Check_PIR();

  //MQTTcount int MQTTcount = 0;
  //MQTTcount++; // increment x by one and returns the old value of x
   Serial.print("MQTT#: ");
   Serial.println(MQTTcount);
  MQTT_temp(); //call the function

  //currentTime int countDown = 0;
  countDown++; // increment x by one and returns the old value of x

  if (countDown >= 50) {
    countDown = 0; //reset countDown to 0 // x is greater than or equal to y
    TriggerCount = 0;
    Serial.print("Threshold hit, 50s timeout: ");
    Serial.println(countDown);
    Serial.print("Threshold hit, 5x trigger reset: ");
    Serial.println(TriggerCount);
  }
  else { // Display counter
    Serial.print("Timer: ");
    Serial.println(countDown);
    digitalWrite(ledPin, HIGH); // enable LED
    display.setCursor(2, 2);
    display.print("CNTR:");
    display.print(countDown); // display counter
    display.setCursor(97, 2);
    display.print("TRG:");
    display.print(TriggerCount); // display counter
    display.setCursor(2, 14);
    display.print(temp); // display CPUTemp
    display.print((char)247);// print char 1 (which is the degree)
    display.print("C");
    display.display();
    delay(1000);
  }

  //If the first (oldest) time in the list is more than 50 seconds ago, remove that time and move the other times (if any) up the list
  if (TriggerCount > 0 &&
      millis() - TriggerTimes[0] >= timeinterval) //51 seconds counts to 50 resets on 51
  {
    for (unsigned tt = 1; tt < TriggerCount; tt++)
    {
      TriggerTimes[tt - 1] = TriggerTimes[tt];
    }
    TriggerCount--;
  }
}


void Check_PIR()
{
  // PIR Detector
  int pirState = digitalRead(pirPin);
  if (pirState)   // if LOW to HIGH
  { // The opening bracket goes HERE...
    Short_Flash_LED();
    temp = modem.getTemperature(); //get CPUtem
    Serial.print("Status: ");
    Serial.println("Motion Detected!");
    Serial.print("Trigger Count: ");
    Serial.println(TriggerCount);
    // ... not HERE
    PIR_Triggered(); //Call Trigger Function
  }
}

// PIR triggers, add the time (millis()) to the bottom of the list.
// If the length of the list has reached 3, sound the alarm and clear the list.
void PIR_Triggered()
{
  TriggerTimes[TriggerCount++] = millis();
  if (TriggerCount >= 5)
  {
    // SOUND THE ALARM HERE
    TriggerCount = 0;
    countDown = 0;
    Serial.print("Status: ");
    Serial.println("Alarm triggered, alert sent!");
    Serial.print("Trigger, 5x threshold met, reset trigger to: ");
    Serial.println(TriggerCount);
    Serial.print("Trigger, 50s threshold met, reset counter to: ");
    Serial.println(countDown);
    Movement_NoMovement(); //display alarms
    Long_Flash_LED ();
  }
}

void MQTT_temp() // publish MQTT temp every 30 counts approx 30secs
{
  MQTTcount++; // increment x by one and returns the old value of x
  if (MQTTcount >= 30) {
    MQTTcount = 0; //reset MQTTcountn to 0 // x is greater than or equal to y
    temp = modem.getTemperature(); //get CPUtem
    // Convert the value to a char array
    char tempString[8];
    dtostrf(temp, 1, 1, tempString);
    Serial.print("MQTT#2: ");
    Serial.println(MQTTcount);
    mqttConnect();
    mqtt.connect("Protect");
    SerialMon.print("MQTT Connected ");
    //mqtt.publish(topicTemperature, tempString); //publish temp // has addtional characters
    mqtt.publish("Protect/temperature", tempString); //publish temp // has addtional characters
  }
}

void Long_Flash_LED() // Long Flash the LED
{
  digitalWrite(ledPin, HIGH);
  delay (800);
  digitalWrite(ledPin, LOW);
  delay (800);
  digitalWrite(ledPin, HIGH);
  delay (800);
  digitalWrite(ledPin, LOW);
}

void Short_Flash_LED() //Short Flash the LED
{
  digitalWrite(ledPin, HIGH);
  delay (100);
  digitalWrite(ledPin, LOW);
  delay (100);
  digitalWrite(ledPin, HIGH);
  delay (100);
  digitalWrite(ledPin, LOW);
  delay (100);
  digitalWrite(ledPin, HIGH);
  delay (100);
  digitalWrite(ledPin, LOW);
  delay (100);
}

void Movement_NoMovement() //animate the alarm symbol
{
  display.clearDisplay();
  display.drawBitmap(0, 0, Movement, 128, 64, WHITE);
  display.setCursor(29, 57);
  display.print(" A L E R T ");
  display.display();
  display.clearDisplay();
  delay(600);
  display.drawBitmap(0, 0, NoMovement, 128, 64, WHITE);
  display.setCursor(27, 57);
  display.print("S M S - S e n t");
  display.display();
  display.clearDisplay();
  delay(600);
  display.drawBitmap(0, 0, Movement, 128, 64, WHITE);
  display.setCursor(27, 57);
  display.print("P X T - S e n t");
  display.display();
  display.clearDisplay();
  delay(600);
}

image

O and two boxes? Thoughts?

Connects and publishes ok but some time comes up with non numerical number.

Please post a complete sketch that illustrates the problem as it may not be where you think.

char tempString[2];

There is only room for 2 characters in this array. Is that enough ?

Sketch is very large hence why I added the portions that are for the MQTT, full code is now added/
Revised the following only after publishing the temp.

char tempString[8];

The code needs alot of work as I get a better understanding.

Sorry, but I don't know what you mean by that. Is it in the code that you did not post and, if so, what is the scope of the new tempString array that you are declaring

Added the complete code to the original post as request. As I am learning code if you could pointers in this case the extra characters :slight_smile: Also I revised from char tempString from 2 to 8 is what I meant.

What do you see if you print temp before publishing it ? Print it with a a ">" before it and "<" after it which may show up hidden characters at the start or end of temp

Sorry dont follow add < and > so its

"<temp>" 

Both of these print the correct output

display.print(temp); // display CPUTemp

and

Serial.println(temp);

this returns

temp = modem.getTemperature()
Serial.print("<");
Serial.print(temp);
Serial.println(">");

If there are characters before or after the value then they will show, but may not be readable, as they will ne printed between the brackets and the value of temp

thanks output is

MQTT Connected 
Temperature: <21.00>
<21.00>

mqttConnect();
mqtt.connect("Protect");
SerialMon.print("MQTT Connected ");

Serial.print("Temperature: ");
Serial.print("<");
Serial.print(tempString);
Serial.println(">");
Serial.print("<");
Serial.print(temp);
Serial.println(">");
Serial.println(topicTemperature);
Serial.println(tempString);

mqtt.publish(topicTemperature, tempString);

In your original post you said that the problem only occurs some times, which makes debugging difficult

If the value that you publish is correct then the problem has to be somewhere other than in the code

Thanks started over again and used the example that came with the board and now got past this point with no additional characters.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.