[106] Arduino i sieć cz. 3
![[106] Arduino i sieć cz. 3](/_next/image?url=https%3A%2F%2Farduino.pl%2Fimgproxy%2F1Dmkw8z6tmYHN7pq86YliM0WcC5eIVYmdeXpR0ftiUk%2Ff%3Awebp%2Fw%3A1200%2FbG9jYWw6Ly8vaW1hZ2VzLzAtNjgwL2E4MzhhL2UwM2EwLzAtNjgwYTgzOGFlMDNhMDY5NTU0NDUzNy5wbmc%3D.webp&w=3840&q=75)
A jednak nie wszystko – choć w poprzednim artykule napisałem: to już wszystko. Płytka edukacyjna TME zawiera wyświetlacz, więc grzechem byłoby go nie wykorzystać. Postanowiłem poświęcić jeszcze chwilę i przerzucić część komunikatów na niego, ponieważ docelowo urządzenie będzie pracowało samodzielnie, a wizualizacja danych w postaci napisów zamiast światełek jest bardziej atrakcyjna. Światełka zresztą zostawimy.
// Deklaracje
char ssid[] = "Smialek"; // Nazwa sieci WiFi.
char pass[] = "1234"; // Hasło do sieci WiFi.
const char* adresWWW = "www.google.com"; // Adres stromy do badania dostępności internetu.
const int opoznienie = 3000; // Opóźnienie w ms dla ustabilizowania połączeń z WiFi.
const int przerwa = 10000; // Przerwa między wysyłaniem pingów.
const byte iloscProb = 10; // Ilość prób połączenia z routerem, zanim zostanie zresetowany.
const int czasWylaczenia = 35000; // Czas w ms wyłączenia routera.
const int czasWlaczenia = 60000; // Czas w ms wyłączenia routera.
#include "WiFiS3.h" // Biblioteka obsługująca WiFi na Arduino R4
int modulWiFi = WL_IDLE_STATUS; // Zmienna stanu WiFi.
int czas; // Czas w milisekundach dla funkcji ping.
byte numerProby = 0; // Numer bieżącej próby połączenia się z wybraną stoną interneetową.
const byte czerwonyLed = 9; // Czerwona dioda.
const byte zielonyLed = 10; // Zielona dioda.
const byte przekaznik = 13; // Przekaźnik rozłączający router.
#include <Wire.h> // Biblioteka obsługująca magistralę I2C
#include <hd44780.h> // Biblioteka obsługująca wyświetlacze 44780
#include <hd44780ioClass/hd44780_I2Cexp.h> // Dodatek obsługujący wyświetlacze podłączone do ekspandera I2C
hd44780_I2Cexp lcd(0x20, I2Cexp_MCP23008, 7, 6, 5, 4, 3, 2, 1, HIGH); // Konfiguracja połączeń wyświetlacza LCD
void setup() {
pinMode(czerwonyLed, OUTPUT);
pinMode(zielonyLed, OUTPUT);
pinMode(przekaznik, OUTPUT);
czerwone(); // Włącz czerwone światło.
lcd.begin(16, 2); // Inicjalizacja wyświetlacza LCD
if (WiFi.status() == WL_NO_MODULE) { // Sprawdź połączenie z modułem WiFi na płytce.
while (true) {} // Brak połączenia z modułem WiFi, zakończ pracę.
}
}
void loop() {
zolte(); // Badamy połączenie z wybraną stroną internetową, włącz żółte światło.
lcd.setCursor(10, 0); // Wyświetl RSSI.
lcd.print(abs(WiFi.RSSI()));
lcd.print(" dBm ");
lcd.setCursor(0, 0);
czas = WiFi.ping(adresWWW); // Wyślij ping do wybranej strony internetowej.
if (czas > 0) { // Jeśli wrócił...
zielone(); // Włącz zielone światło.
lcd.print(czas); // Wyświetl opóźnienie.
lcd.print(" ms ");
lcd.setCursor(0, 1); // Wyświetl adres pingowanej strony.
lcd.print(adresWWW);
numerProby = 0; // Resetuj licznik nieudanych połączeń.
} else { // Jeśli nie wrócił...
czerwone(); // Włącz czerwone światło.
lcd.print("Czekam...");
numerProby++; // Zmniejszaj licznik nieudanych połączeń.
lcd.setCursor(0, 1); // Wyświetl komunikat o próbach połączenia.
lcd.print("Odliczam: ");
lcd.print(numerProby);
lcd.print("/");
lcd.print(iloscProb);
lcd.print(" ");
resetWifi(); // Odłącz i podłącz się ponownie do WiFi.
if (numerProby == iloscProb) { // Jeśli wyczerpał się limit prób połączeń...
digitalWrite(przekaznik, HIGH); // Wyłącz zasilanie routera.
lcd.setCursor(0, 1);
lcd.print("Router odlaczony");
delay(czasWylaczenia); // Czas, przez jaki router będzie odłączony od zasilania.
digitalWrite(przekaznik, LOW); // Włącz zasilanie routera.
lcd.setCursor(0, 1);
lcd.print("Router startuje ");
delay(czasWlaczenia); // Czas na ustabilizowanie się routera po jego włączeniu.
resetWifi(); // Odłącz i podłącz się ponownie do WiFi.
numerProby = 0; // resetuj licznik prób połączeń.
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
delay(przerwa); // Przerwa między wysyłaniem pingów.
}
void resetWifi() {
modulWiFi = WiFi.disconnect(); // Odłącz się od sieci WiFi.
delay(opoznienie); // Opóźnienie niezbędne do ustabilizowania się połączenia.
modulWiFi = WiFi.begin(ssid, pass); // Połącz się z siecią WiFi.
delay(opoznienie); // Opóźnienie niezbędne do ustabilizowania się połączenia.
}
void czerwone() { // Włącz czerwone światło.
digitalWrite(czerwonyLed, HIGH);
digitalWrite(zielonyLed, LOW);
}
void zolte() { // Włącz żółte światło.
digitalWrite(czerwonyLed, HIGH);
digitalWrite(zielonyLed, HIGH);
}
void zielone() { // Włącz zielone światło.
digitalWrite(czerwonyLed, LOW);
digitalWrite(zielonyLed, HIGH);
}
Tak więc usunąłem wszystkie linie związane ze słaniem danych na terminal. Ponieważ jednak wyświetlacz jest mniejszy – tutaj dwie linie po 16 znaków, ograniczyłem się nieco. Pominę wstęp, czyli importowanie bibliotek i konfigurację wyświetlacza, bo o tym pisałem już nieraz. Przywitania tym razem nie będzie, podobnie jak komunikatu o niesprawności modułu Arduino.

W głównej pętli zaczniemy od wysłania informacji o mocy sygnału – bez minusa, bo jest zbędną informacją, dlatego użyłem funkcji abs. Jeśli pingowanie naszej strony się powiedzie, wyświetlimy opóźnienie oraz – na dole – adres pingowanej strony. Zakładam, że zmieści się na szesnastu pozycjach wyświetlacza.

Gdy router nie odpowie, wyświetli się napis Czekam... a niżej Odliczam – i numer próby połączenia łamany przez pulę połączeń zanim dojdzie do resetu. Jak więc widać, pracujemy na odwrót: zwiększamy licznik połączeń, zatem wszystkie operacje związane ze zmienną numerProby należy logicznie odwrócić względem poprzedniego szkicu.

Gdy liczba prób osiągnie maksimum, napięcie zostanie odłączone i pojawi się komunikat Router odlaczany.

Po ustalonym czasie napięcie powróci wraz z napisem Router startuje i po chwili wrócimy na początek głównej pętli.
W przypadku operacji na wyświetlaczach, trzeba dbać o czyszczenie starych danych – stąd te nadmiarowe spacje na końcu niektórych tekstów bądź wyświetlenie 16 spacji na końcu operacji resetowania routera. I jeszcze jedno: podczas prób nawiązania połączenia wartość inna od zera świadczy o utrzymywaniu połączenia z bramą lokalną przy braku wyjścia w świat. To pozwoli odróżnić istotę problemu i jest podstawą do zadzwonienia na infolinię operatora.