MQTT Disconnects when I close the IDE?

I have an Arduino Uno, Ethernet shield, temperature sensor and a DS1307 RTC connected to an MQTT broker using the ArduinoMqttClient library. It connects fine when I have the IDE open, if I close the IDE, it seems to work for a minute and stop.

The only way to get it connected again is to open the IDE and I can see in the serial output that it connects and I see the temperature in the broker. Does anyone have any ideas whats going on?

This is my first project and I am learning how it all works together. see my ugly code below that I pieced together from the posts on here. thanks!

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoMqttClient.h>
#include <RTClib.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x00, 0x02, 0x0A, 0x0F, 0x06, 0x0E};
IPAddress ip(192, 168, 1, 2);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 240);

// Setup the broker
IPAddress broker(192,168,1,3);
int        port     = 1883;
const char topic[]  = "temperature";

// Create an ethernet client
EthernetClient ethClient;
MqttClient mqttClient(ethClient);

// Declare RTC Object
RTC_DS1307 rtc;

// Data wire from temp sensor is on port 2
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9

// setup the instance
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// setup the variables
int count = 0;                        // just a counter for the mqtt broker connections
int inPin = 7;                          // Pushbutton on pin 7
int pushButtonValue = 0;                // variable to store the read value
float previousTemperatureF = 0;         // keep track of the last temperature
unsigned long previousUnixTime = 0;     // last time update
long interval = 300;                    // Interval to wait to do sumpin, 300s = 5min

// Used for mapping the days of the week
char daysOfTheWeek[7][12] = {
  "Sunday",
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday"
};

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // sets the digital pin 7 as input for the button
  pinMode(inPin, INPUT);

  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (!rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }

  // Start the ethernet connection
  Ethernet.begin(mac, ip, gateway, subnet);

  //print out the IP address
  Serial.print("IP = ");
  Serial.println(Ethernet.localIP());
  
  // Connect to the broker
  mqttClient.setId("arduino");
  mqttClient.setUsernamePassword("username", "password");

  Serial.print("Attempting to connect to the MQTT broker at address "); Serial.print(broker);
  Serial.print(" on port "); Serial.println(port);

  while (!mqttClient.connect(broker, port)) {
    Serial.print("Connection Attempt: ");
    Serial.println(count);
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    count++;
    delay(1000);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // Start up the sensor library to read the temperature
  sensors.begin();
}


void printTime(DateTime time) {
  Serial.print("Current Time: ");
  Serial.print(time.year(), DEC);
  Serial.print('/');
  Serial.print(time.month(), DEC);
  Serial.print('/');
  Serial.print(time.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[time.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(time.hour(), DEC);
  Serial.print(':');
  Serial.print(time.minute(), DEC);
  Serial.print(':');
  Serial.println(time.second(), DEC);
}


void loop() {
  // read the input pin
  pushButtonValue = digitalRead(inPin);

  // call poll() regularly to allow the library to send MQTT keep alive which
  // avoids being disconnected by the broker
  mqttClient.poll();
  
  sensors.requestTemperatures();                          // Send the command to get temperatures
  float currentTemperatureF = sensors.getTempFByIndex(0); // get the temp in F, we only have one temp module so its 0

// Whats the time!
  DateTime now = rtc.now();     // current time
  //DateTime future;  // time to add too
  unsigned long currentUnixTime = now.unixtime();

  // check every 5 minutes to see if there was a change
  if ((currentUnixTime-previousUnixTime) > interval) {
    // Keep track of the time we took the temperature sample
    previousUnixTime = currentUnixTime;

    // check if the temperate has changed, if not, dont send it.
    if (currentTemperatureF != previousTemperatureF) {
      // Now they are 
      previousTemperatureF = currentTemperatureF;

      Serial.print("Sending message to topic: ");         Serial.println(topic);
      Serial.print("Value being sent to topic: ");        Serial.println(currentTemperatureF);
      printTime(now); // Print current time

      // send message, the Print interface can be used to set the message contents
      mqttClient.beginMessage(topic);
      mqttClient.print(currentTemperatureF);
      mqttClient.endMessage();
      Serial.println();
    }
  }
}

You mean "You're connected to the MQTT broker!"? That message is only in setup, and the sketch only attempts to connect there. Are you also manually restarting the Uno to get it connected again? Or is it restarting by itself?

First, try moving the connection into the loop. Test with mqttClient.connected(). It should be false to start, so it should then try to connect. If it ever disconnects, it will try to reconnect.

Second, add a "heartbeat" topic, and send the millis() uptime and the connection attempt count every few seconds. Does the Uno reconnect or restart?

2 Likes

some general thinking about your problem:

-a- usually when close the IDE the board continues working
when restart IDE it reset and boots

-b- you want make code for a board what generally also works if it is connected to charger only ( no PC or IDE )
in that case it might be needed ( for some boards ) to do

while (!Serial && (millis() < 10000));

or it will be stuck in that while forever

-c- if the Serial.print fills a internal buffer a board type can fail,
so possibly make a general switch like

#define DIAG true // false
//...
if(DIAG) Serial.print("bla bla bla");

and set to false if want run it without USB communication
but there are other MACRO ways for a print en/disable

1 Like

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