Update WiFiNINA firmware
The first step for working with an Arduino board with the WiFiNINA module is to update its firmware. The boards usually come with firmware 1.2.3 and this is way outdated. With the Arduino IDE it can be updated to at least 1.3.0 and this should be done. The process is described here: https://arduino-insights.com/board/mkr-wifi-1010/wifi-firmware-update-nina-w102/
MQTT client
The Software for my controllable power outlet is mainly built around the MQTT client. There exist several MQTT libraries for Arduino but some of them only support publish and not subscribe. For my application MQTT subscribe is the main function. So I decided to go with the PubSubClient (https://github.com/knolleary/pubsubclient ).
Source code
The sketch is based on the mqtt_basic example of the library. It only subscribes to the /power_priority topic, receives the messages and compares them to a local value. If the power priority is lower the output (and the builtin led) is enabled, otherwise disabled.
Here is the source code:
#include <SPI.h> #include <WiFiNINA.h> #include <PubSubClient.h> #define SECRET_SSID "" #define SECRET_PASS "" char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) int status = WL_IDLE_STATUS; // the WiFi radio's status #define LOCAL_POWER_PRIO 70 // set local power priority #define POWERPIN 4 IPAddress server(192, 168, 1, 61); void callback(char* topic, byte* payload, unsigned int length) { char buf[10]; // local buffer Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i=0;i<length;i++) { Serial.print((char)payload[i]); if(i<10) buf[i]=(char)payload[i]; // copy to buffer } buf[9]=0; if(length<10) buf[length]=0; // limit length Serial.println(); float power_priority=atof(buf); // convert to float Serial.println(power_priority); if(power_priority<LOCAL_POWER_PRIO) // local power priority is higher so set everything on { Serial.println("output on"); digitalWrite(LED_BUILTIN, HIGH); digitalWrite(POWERPIN, HIGH); } else // local power priority is higher so set everything off { Serial.println("output off"); digitalWrite(LED_BUILTIN, LOW); digitalWrite(POWERPIN, LOW); } } WiFiClient ethClient; PubSubClient client(ethClient); void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect("arduinoClient")) { Serial.println("connected"); // ... and subscribe client.subscribe("/power_priority"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void setup() { Serial.begin(57600); digitalWrite(POWERPIN, LOW); pinMode(POWERPIN, OUTPUT); client.setServer(server, 1883); client.setCallback(callback); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } // check for the WiFi module: if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } // you're connected now, so print out the data: Serial.print("You're connected to the network"); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); }
Video
The following video shows how the whole system works with a battery charger connected. The power priority is simulated by the script ramping up and down from 0 to 100.
In the video you can see the LED at the relay going on and off and thus see the battery charging (blinking LEDs at the battery). You may even hear the sound of the relay toggling.