Looking for some direction if it's possible to use the MKR ETH Shield as a backup/failover for the wifi on the Wifi1010. IE if connecting to wifi isnt an option we can quickly plugin a hard line to the ETH Shield and have connection quickly.
I'd love Wifi to be main, try to connect, if connection fails Ethernet looks and waits for a connections.
Yes, that's possible. You just have to take care for the failover in your code which might be tricky depending on what you intend to use that module for.
I get the impression you don't have much experience in the network area. So you should start by telling us what you're trying to achieve (and not how you think it should be achieved).
Thanks for your response. I don't have much experience in the coding and Arduino, this is my second project with Arduino.
I have 4 MKR Wifi1010 that are connected to a RPi that when the button is pushed on the MKR it relays a Light on and tells the RPI that the light is on. I have that part of the code worked out and working over wifi. My issue is I'd like to add an ETH Shield so that when the system is taken somewhere where the Wifi isnt a good option for connection we can hardwire ethernet all the units to the router and it will work.
are you aware that the MKR 1010 has two MCU? is it not an overkill for an iot button? maybe a Wemos D1 mini would do. and the esp8266 Arduino platform for the D1 is better than the esp32 IDF on which the NINA firmware in the esp32 of the MKR is based.
and even the integration of wired Ethernet is simpler for the esp8266 platform.
That's good to know.
The main part of the system is already built with MKR Wifi1010 and RELAY Shields so that is the only reason that I'm looking to add ethernet connection this way.
Ya, that is probably a better option, I thought about that but didn't know if it was earlier or not.
Here is the code, it's not amazing but it works. I'm currently working on cleaning it up.
/*
Arduino MQTT DEMO
*/
#include <ezButton.h>
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h> // for MKR1000 change to: #include <WiFi101.h>
//#include <WiFi101.h>
#include <SPI.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
// flashed in the WiFi module.
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
String msg1 ;
const char broker[] = "192.168.1.123"; // Address of the MQTT server
int port = 1883;
const char topic[] = "mqtt/main";
const char subtopic[] = "mqtt/one";
const long interval = 1000;
unsigned long previousMillis = 0;
int status = false;
int led = 1;
int led2 = 2;
ezButton button(A1); // create ezButton object that attach to pin A1;
String subMessage = "";
void setup() {
//Initialize serial
Serial.begin(9600);
button.setDebounceTime(50); // set debounce time to 50 milliseconds
pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led2, LOW);
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println();
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient.setId("one");
// You can provide a username and password for authentication
// mqttClient.setUsernamePassword("user", "password");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
// set the message receive callback
mqttClient.onMessage(onMqttMessage);
// subscribe to a topic
mqttClient.subscribe(subtopic);
}
void loop() {
button.loop(); // MUST call the loop() function first
// call poll() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker
mqttClient.poll();
if(button.isPressed()) {
Serial.println("The button is pressed");
// toggle state of LED
status = !status;
// control LED arccoding to the toggleed sate
digitalWrite(led, status);
if (status==true){
ON();
}
if (status==false){
OFF();
}
}
}
void onMqttMessage(int messageSize) {
// we received a message, print out the topic and contents
Serial.println("Received a message with topic '");
Serial.print(mqttClient.messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// use the Stream interface to print the contents
while (mqttClient.available()) {
msg1 +=(char)mqttClient.read();
Serial.println(msg1);
}
if (msg1 == "ON"){
digitalWrite(led, true);
}
if (msg1 == "OFF"){
digitalWrite(led, false);
}
msg1="";
}
void ON(){
mqttClient.beginMessage(topic);
mqttClient.print("on1");
mqttClient.endMessage();
Serial.println("Sent MQTT message.");
}
void OFF(){
mqttClient.beginMessage(topic);
mqttClient.print("off1");
mqttClient.endMessage();
Serial.println("Sent MQTT message.");
}
You have to move the instantiation of the mqttClient to setup(). There you have to get the link status by calling Ethernet.linkStatus(). If that is up, call Ethernet.begin() and provide an EthernetClient object to the MqttClient constructor, otherwise use the WiFiClient object as you do at the moment. Remember to change all usages of the mqttClient object because it will be a pointer and not a global dynamic variable anymore.
Ok, thanks for laying that out. It feels over my head but I will give it a try and see what I can do.
I guess I don't fully understand how to point it at both and choose only if one doesn't work, but I'll do some research to see if I can find out how.
Alright here is what I have.
I might be close but I don't understand how to make the MqttClient talk to the right place. I'm missing how to declare MqttClient and ethernetClient and get it to pick which depending on the "if".
Thanks!
/*
Arduino MQTT TxB Prototype
*/
#include <ezButton.h>
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h> // for MKR1000 change to: #include <WiFi101.h>
//#include <WiFi101.h>
#include <Ethernet.h>
#include <SPI.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
// flashed in the WiFi module.
String msg1 ;
const char broker[] = "192.168.1.123"; // Address of the MQTT server
int port = 1883;
const char topic[] = "mqtt/main";
const char subtopic[] = "mqtt/one";
const long interval = 1000;
unsigned long previousMillis = 0;
int Enet = 1; //1 = Ethernet connection is available
int status = false;
int led = 1;
int led2 = 2;
EthernetClient ethernetClient;
MqttClient mqttClient(ethernetClient);
ezButton button(A1); // create ezButton object that attach to pin A1;
String subMessage = "";
void setup() {
//Initialize serial
Serial.begin(9600);
button.setDebounceTime(50); // set debounce time to 50 milliseconds
pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led2, LOW);
if (Ethernet.linkStatus() == LinkON) {
Serial.println("Ethernet cable is connected.");
Enet = 1; }
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
Enet = 0; }
// attempt to connect to Wifi network:
if (Enet=0) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
}
Serial.println("You're connected to the network");
Serial.println();
//If Ethernet is not availabe
if (Enet=0) {
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
}
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient.setId("one");
// You can provide a username and password for authentication
// mqttClient.setUsernamePassword("user", "password");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
// set the message receive callback
mqttClient.onMessage(onMqttMessage);
// subscribe to a topic
mqttClient.subscribe(subtopic);
}
void loop() {
button.loop(); // MUST call the loop() function first
// call poll() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker
mqttClient.poll();
if(button.isPressed()) {
Serial.println("The button is pressed");
// toggle state of LED
status = !status;
// control LED arccoding to the toggleed sate
digitalWrite(led, status);
if (status==true){
ON();
}
if (status==false){
OFF();
}
}
}
void onMqttMessage(int messageSize) {
// we received a message, print out the topic and contents
Serial.println("Received a message with topic '");
Serial.print(mqttClient.messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// use the Stream interface to print the contents
while (mqttClient.available()) {
msg1 +=(char)mqttClient.read();
Serial.println(msg1);
}
if (msg1 == "ON"){
digitalWrite(led, true);
}
if (msg1 == "OFF"){
digitalWrite(led, false);
}
msg1="";
}
void ON(){
mqttClient.beginMessage(topic);
mqttClient.print("on1");
mqttClient.endMessage();
Serial.println("Sent MQTT message.");
}
void OFF(){
mqttClient.beginMessage(topic);
mqttClient.print("off1");
mqttClient.endMessage();
Serial.println("Sent MQTT message.");
}
@pylon, just wanted to check in and see if you had any thoughts on this. I tried a few more things tonight that I found online semi around this topic and it still failed to try to connect to the server.
@pylon That is correct, Arduino is my first experience with C++, I am learning it but only by doing right now. After this project I plan to take some time and try to learn more about C++.
Alright, that worked as far as making it connect and talk to the wifiClient but something with my code for the ethernet isn't working. It doesn't look for link them move to wifi. It just stays as whatever I set it to at the being.
int Enet = 0; //0 = Ethernet connection is not available
If that is set to "0" it connects and works with wifi, if its set to 1, I just get a Mqtt connection error.
/*
Arduino MQTT Prototype
*/
#include <ezButton.h>
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h> // for MKR1000 change to: #include <WiFi101.h>
//#include <WiFi101.h>
#include <Ethernet.h>
#include <SPI.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
// flashed in the WiFi module.
String msg1 ;
const char broker[] = "192.168.1.123"; // Address of the MQTT server
int port = 1883;
const char topic[] = "mqtt/main";
const char subtopic[] = "mqtt/one";
const long interval = 1000;
unsigned long previousMillis = 0;
int Enet = 0; //0 = Ethernet connection is not available
int status = false;
int led = 1;
int led2 = 2;
WiFiClient wifiClient;
EthernetClient ethernetClient;
MqttClient *mqttClient;
ezButton button(A1); // create ezButton object that attach to pin A1;
String subMessage = "";
void setup() {
//Initialize serial
Serial.begin(9600);
button.setDebounceTime(50); // set debounce time to 50 milliseconds
pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led2, LOW);
if (Ethernet.linkStatus() == LinkON) {
Serial.print("Ethernet cable is connected.");
Enet == 1; }
else { Serial.print("Ethernet cable is not connected.");
Enet == 0; }
// attempt to connect to Wifi network:
if (Enet == 0) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
}
Serial.println("You're connected to the network");
Serial.println();
//If Ethernet is not availabe
if (Enet == 1) {
mqttClient = new MqttClient(ethernetClient);
} else {
mqttClient = new MqttClient(wifiClient);
}
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient->setId("one");
// You can provide a username and password for authentication
// mqttClient.setUsernamePassword("user", "password");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient->connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient->connectError());
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
// set the message receive callback
mqttClient->onMessage(onMqttMessage);
// subscribe to a topic
mqttClient->subscribe(subtopic);
}
void loop() {
button.loop(); // MUST call the loop() function first
// call poll() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker
mqttClient->poll();
if(button.isPressed()) {
Serial.println("The button is pressed");
// toggle state of LED
status = !status;
// control LED arccoding to the toggleed sate
digitalWrite(led, status);
if (status==true){
ON();
}
if (status==false){
OFF();
}
}
}
void onMqttMessage(int messageSize) {
// we received a message, print out the topic and contents
Serial.println("Received a message with topic '");
Serial.print(mqttClient->messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// use the Stream interface to print the contents
while (mqttClient->available()) {
msg1 +=(char)mqttClient->read();
Serial.println(msg1);
}
if (msg1 == "ON"){
digitalWrite(led, true);
}
if (msg1 == "OFF"){
digitalWrite(led, false);
}
msg1="";
}
void ON(){
mqttClient->beginMessage(topic);
mqttClient->print("on1");
mqttClient->endMessage();
Serial.println("Sent MQTT message.");
}
void OFF(){
mqttClient->beginMessage(topic);
mqttClient->print("off1");
mqttClient->endMessage();
Serial.println("Sent MQTT message.");
}
I found the error of my ways. Here is what I changed. Let me know if you disagree.
if (Ethernet.linkStatus() == LinkON) {
Serial.println("Ethernet cable is connected.");
Enet = !Enet; }
else { Serial.println("Ethernet cable is not connected.");
Enet = Enet; }
// attempt to connect to Wifi network:
if (Enet == 0) {
Thanks again for all your help. I posted on a different forum due to it being a different question but now trying to figure out how to get the code below to work even if it isn't connected to the Mqtt Broker.
The Ethernet library expects the CS signal to be connected to pin D10. As you're using the MKR Ethernet Shield you have to tell the library the different CS pin:
Ethernet.init(5);
Insert that near the start of the setup() routine.
Yes, I disagree. The problem wasn't in these lines but in the fact that the Ethernet library didn't communicate with your WizNet chip because it used the wrong CS pin.