I'm trying to get an arduino setup with MQTT and don't seem to be able to get it to connect. The mqtt server is running fine and is working between another pc on the network.
This is what I get from the serial monitor:
21:11:23.757 -> Connecting to network
21:11:30.195 -> Connected! IP address: 192.168.0.100
21:11:30.195 -> 1,1,1,1,
21:11:30.195 -> Attempting to connect to MQTT broker at 192.168.0.101
21:11:46.795 -> Connection to MQTT server failed, rc=19716 trying again in 5 seconds
21:11:51.802 -> Attempting to connect to MQTT broker at 192.168.0.101
21:12:16.928 -> Connection to MQTT server failed, rc=-2 trying again in 5 seconds
21:12:21.980 -> Attempting to connect to MQTT broker at 192.168.0.101
21:12:47.100 -> Connection to MQTT server failed, rc=-2 trying again in 5 seconds
I've tried with an uno and a nano and the result seems to be the same.
I've found comments that the rc=-2 could be some kind of network/router issue, but I can't find anything that could be causing a problem there. Plus, as far as I can see it does connect initially - the arduino comes up in the client list on the router settings. I can't find anything about what the rc=19716 might be though, and suspect whatever it is may be causing it to lose the connection straight away.
I've got the ENC28J60 ethernet modules, so I'm trying to use the UIPEthernet library with the PubSubClient library as described in this guide: https://www.instructables.com/id/A-Simple-MQTT-PubSub-Node-With-Arduino-UNO-and-ENC/ But with code I have got from another guide.
The ENC28J60 is connected as follows:
5v - 5v
gnd - gnd
rst - rst
cs - 10
st - 11
so - 12
sck - 13
And this is my code - ethernet/mqtt setup part:
#include <SPI.h>
#include <UIPEthernet.h>
#include <PubSubClient.h>
const byte mac[] = {0xC0, 0xA8, 0x00, 0x01, 0x07, 0x7B};
const IPAddress deviceIP(192, 168, 0, 106);
const IPAddress mqttServerIP(192, 168, 0, 101);
const char* deviceID = "Switches";
EthernetClient ethernetClient;
PubSubClient MQTTclient(ethernetClient);
long lastMsgTime = 0;
char msg[64];
char topic[32];
int pulseCount = 0;
void mqttCallback(char* topic, byte* payload, unsigned int length) {
memcpy(msg, payload, length);
msg[length] = '\0';
Serial.print("Message received in topic [");
Serial.print(topic);
Serial.print("] ");
Serial.print(msg);
if (strcmp(msg, "SOLVE") == 0) {
onSolve();
}
else if (strcmp(msg, "RESET") == 0) {
onReset();
}
}
void ethernetSetup() {
if (!Serial) {
Serial.begin(9600);
}
Serial.println("Connecting to network");
if (Ethernet.begin(mac) == 0) {
Ethernet.begin(mac, deviceIP);
}
delay(2000);
Serial.print("Connected! IP address: ");
Serial.println(Ethernet.localIP());
}
void mqttSetup() {
MQTTclient.setServer(mqttServerIP, 1883);
MQTTclient.setCallback(mqttCallback);
}
void mqttLoop() {
while (!MQTTclient.connected()) {
Serial.print("Attempting to connect to MQTT broker at ");
Serial.println(mqttServerIP);
if (MQTTclient.connect(deviceID)) {
Serial.println("Connected to MQTT broker");
snprintf(topic, 32, "ToHost/%s", deviceID);
snprintf(msg, 64, "CONNECT", deviceID);
MQTTclient.publish(topic, msg);
snprintf(topic, 32, "ToDevice/%s", deviceID);
MQTTclient.subscribe(topic);
MQTTclient.subscribe("ToDevice/All");
}
else {
Serial.print("Connection to MQTT server failed, rc=");
Serial.print(MQTTclient.state());
Serial.println(" trying again in 5 seconds");
delay(5000);
}
}
MQTTclient.loop();
}
void publish(char* message) {
snprintf(topic, 32, "ToHost/%s, deviceID");
MQTTclient.publish(topic, message);
}
And the main "puzzle control" part, if it helps:
const byte numInputs = 4;
const byte inputPins[numInputs] = {2, 3, 4, 5};
const byte outputPin = 8;
bool lastInputState[numInputs];
bool solution[numInputs] = {true, false, false, true};
bool hasChanged = false;
char receivedChar;
bool newData = false;
char remoteSolve = 'S';
char remoteReset = 'R';
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
bool isPuzzleSolved() {
bool solved = true;
for (int i = 0; i < numInputs; i++) {
if (lastInputState[i] != solution[i]) {
solved = false;
}
}
return solved;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
for (int i = 0; i < numInputs; i++) {
pinMode(inputPins[i], INPUT_PULLUP);
}
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
ethernetSetup();
mqttSetup();
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
receivedChar = Serial.read();
newData = true;
}
if (newData == true) {
if (receivedChar == remoteSolve) {
onSolve();
}
if (receivedChar == remoteReset) {
onReset();
}
newData = false;
}
if ((millis() - lastDebounceTime) > debounceDelay) {
for (int i = 0; i < numInputs; i++) {
int currentInputState = digitalRead(inputPins[i]);
if (currentInputState != lastInputState[i]) {
lastDebounceTime = millis();
hasChanged = true;
lastInputState[i] = (bool)currentInputState;
}
bool puzzleIsSolved = isPuzzleSolved();
if (puzzleIsSolved) {
onSolve();
}
}
digitalWrite (outputPin, LOW);
if (hasChanged) {
sendState();
hasChanged = false;
}
}
mqttLoop();
}
void sendState() {
for (int i = 0; i < numInputs; i++) {
Serial.print(lastInputState[i]);
if (i < numInputs) {
Serial.print(",");
}
}
Serial.println("");
}
void onReset () {
asm volatile ("jmp 0");
publish("Puzzle reset");
}
void onSolve() {
digitalWrite (outputPin, HIGH);
publish("Puzzle solved");
}