Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non blocking WiFi.begin() & Client.connect() #273

Open
tech9492 opened this issue Jan 29, 2024 · 15 comments · May be fixed by #252
Open

Non blocking WiFi.begin() & Client.connect() #273

tech9492 opened this issue Jan 29, 2024 · 15 comments · May be fixed by #252
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement

Comments

@tech9492
Copy link

Hi all,

Below is the code operating on an Arduino RP2040 Nano Connect. I am facing an issue with WiFi/MQTT reconnection portion of my code. When WiFi and MQTT are connected, the code functions as expected. In the event that one is missing, it obstruct void loop().

I am guessing WiFi.begin() and Client.connect() are both blocking. Is there any workaround I can apply?

Thank you.

#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoMqttClient.h>
#include "arduino_secrets.h"

const int PSON = A3;
const int SSR = 8;
const int FAN = 6;

unsigned long ssrTimer = 0;  // SSR timer
unsigned long fanTimer = 0;  // Fan timer

int psState = 0;   // PSON status
int ssState = 0;   // SSR status
int fnState = 0;   // FAN status

//Enter data in secret tab(arduino_secrets.h)
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const char broker[] = "10.0.0.2";
int port = 1883;
const char topic[] = "RP2040Nano/PSon";
const char topic2[] = "RP2040Nano/SSR";
const char topic3[] = "RP2040Nano/FAN";

void setup() {
  pinMode(PSON, INPUT);  // analog pin A3 as input
  pinMode(SSR, OUTPUT);  // digital pin 8 as output
  pinMode(FAN, OUTPUT);  // digital pin 6 as output

  digitalWrite(SSR, LOW);
  digitalWrite(FAN, LOW);

  // Attempt to connect to WiFi network:
  WiFi.begin(ssid, pass);

  mqttClient.setKeepAliveInterval(0);
  // Username and Password for MQTT authentication
  mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
  mqttClient.connect(broker, port);
}

void loop() {
  psState = analogRead(PSON);  // read analog input status
  ssState = digitalRead(SSR);  // read digital output status
  fnState = digitalRead(FAN);  // read digital output status

  // call poll() regularly to allow the library to send MQTT and prevent disconnection by the broker
  mqttClient.poll();

  if (psState > 50) {
    ssrTimer = 100;  // delay SSR for 10 seconds
  }

  psOFF();

  if (ssState == 1) {
    fanTimer = 100;  // delay Fan for 10 seconds
  }

  fnOFF();

  if (WiFi.status() != WL_CONNECTED) {
    WiFi.end();
    WiFi.begin(ssid, pass);
  }

  if (WiFi.status() == WL_CONNECTED && !mqttClient.connected()) {
    mqttClient.stop();
    mqttClient.connect(broker, port);
  }

  if (WiFi.status() == WL_CONNECTED && mqttClient.connected()) {
    tele();
  }
}

void psOFF() {
  static unsigned long sspreviousTime;
  unsigned long sscurrentTime = millis();  // return time since board active

  // move forward if 100 ms has elapsed
  if (sscurrentTime - sspreviousTime < 100) {
    return;
  }
  
  sspreviousTime = sscurrentTime;

  if (!ssrTimer) {
    digitalWrite(SSR, LOW);  // if timer is done or still 0, set digital output LOW
  } else {
    digitalWrite(SSR, HIGH);  // set digital output HIGH
    digitalWrite(FAN, HIGH);  // set ditigal output HIGH
    ssrTimer--;
  }
}

void fnOFF() {
  static unsigned long fnpreviousTime;
  unsigned long fncurrentTime = millis();  // return time since board active

  // move forward if 100 ms has elapsed
  if (fncurrentTime - fnpreviousTime < 100) {
    return;
  }

  fnpreviousTime = fncurrentTime;

  if (!fanTimer) {
    digitalWrite(FAN, LOW);  // if timer is done or still 0, set digital output LOW
  } else {
    digitalWrite(FAN, HIGH);  // set digital output HIGH
    fanTimer--;
  }
}

void tele() {
  static unsigned long previousMillis;
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= 10000) {
 
    previousMillis = currentMillis;

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

    mqttClient.beginMessage(topic2);
    mqttClient.print(ssState);
    mqttClient.endMessage();

    mqttClient.beginMessage(topic3);
    mqttClient.print(fnState);
    mqttClient.endMessage();

    mqttClient.beginMessage(topic4);
    mqttClient.print(temp_deg);
    mqttClient.endMessage();
  }
}
@JAndrassy
Copy link

#252

@tech9492
Copy link
Author

@JAndrassy thank you very much for your quick response. I did come across #252 but was not sure if that was the solution.

Regarding WiFi.begin(), would WiFi.setTimeout() be the solution?

Thank you.

@JAndrassy
Copy link

JAndrassy commented Jan 29, 2024

Regarding WiFi.begin(), would WiFi.setTimeout() be the solution?

what can your sketch do without WiFi connected to AP?

as first remove the useless wait time in WiFiClient.connect. this

while (!connected() && millis() - start < 10000)
    		delay(1);

it jus wastes 10 seconds if the connection ended with timeout in firmware

@tech9492
Copy link
Author

what can your sketch do without WiFi connected to AP?

It reads the value of input pin A3 and controls 2 pins(output). When pin A3 is LOW, it will activate a timer to switch outputs LOW. This portion of the code should be able to execute even without WiFi.

@JAndrassy
Copy link

you can do 3 things with WiFi.begin:

  1. don't try to connect every loop
  2. run wifi scan before attempting to connect

maybe you can control the pins with MCU events/timers/interrupts so that they are independent from loop

@tech9492
Copy link
Author

you can do 3 things with WiFi.begin:

  1. don't try to connect every loop
  2. run wifi scan before attempting to connect

Thank you for the suggestions. Wifi scan before connecting seem to be a good workaround.

Regarding Client.connect(), I applied all the required changes from #252 to my WiFiNINA library. I tried a timeout of 1000(1 second), it does not solve the issue.

Thank you.

@JAndrassy
Copy link

applied all the required changes from #252 to my WiFiNINA library

the firmware too?

@tech9492
Copy link
Author

By firmware, do you mean server_drv.h?

I have modified the 4 files listed in #252. Did I miss something?

@JAndrassy
Copy link

there are changes in the nina-fw for the NINA Esp32 module as linked in the description of the PR

@tech9492
Copy link
Author

there are changes in the nina-fw for the NINA Esp32 module as linked in the description of the PR

Just to confirm, is it Client connect timeout support #89?

@JAndrassy
Copy link

Just to confirm, is it arduino/nina-fw#89?

yes that is the PR for the firmware

@tech9492
Copy link
Author

I am a little lost now.

Where are firmware files located? Could you please guide me how to carry out this procedure.

Thank you.

@JAndrassy
Copy link

Where are firmware files located?

in the repository with the PR of course

https://github.com/arduino/nina-fw/blob/master/README.md

@per1234 per1234 added type: enhancement Proposed improvement topic: code Related to content of the project itself labels Jan 31, 2024
@per1234 per1234 linked a pull request Jan 31, 2024 that will close this issue
@sebdehne
Copy link

sebdehne commented Oct 8, 2024

I have the same issue (WiFi.begin()) being a blocking function. I have made some slight modification to WiFiNINA locally:

  1. expose WiFiDrv::wifiSetPassphrase() publicly
  2. added begin() which does exactly what begin(const char* ssid, const char *passphrase) does, but without the loop. It just callsWiFiDrv::getConnectionStatus() and returns the status.

This should make it possible to (re-)connect in a non-blocking way.

Would it be possible to have this available in a public release?

@JAndrassy
Copy link

@sebdehne did you read the comments above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants