Files
examples/arduino-example/src/main.cpp
2026-01-28 09:05:24 +08:00

215 lines
6.1 KiB
C++

/**
*
* Copyright (c) 2020-2025 IRext Opensource Organization
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <Arduino.h>
#include <WiFiS3.h>
#include <ArduinoGraphics.h>
#include <Arduino_LED_Matrix.h>
#include "configure.h"
#include "remote.h"
#include "serial_log.h"
#define WIFI_SERVER_PORT (8000)
#define ALIVE_DEBUG_INTERVAL (20 * 1000)
// global variable definitions
constexpr char ssid[] = SECRET_SSID;
constexpr char pass[] = SECRET_PASS;
// commands and events
auto *aHello = "a_hello";
auto *eHello = "e_hello";
auto *aBin = "a_bin";
auto *eBin = "e_bin";
auto *aControl = "a_control";
auto *eControl = "e_control";
auto *aError = "a_error";
auto *eError = "e_error";
int status = WL_IDLE_STATUS;
unsigned long lastStatusCheck = 0;
boolean wifiStatusPrinted = false;
ArduinoLEDMatrix matrix;
WiFiServer server(WIFI_SERVER_PORT);
WiFiClient client;
boolean clientConnected = false;
void drawIp(const char *ipAddr) {
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(100);
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(ipAddr);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
}
void printWiFiStatus() {
unsigned long currentMillis = millis();
if (currentMillis - lastStatusCheck >= ALIVE_DEBUG_INTERVAL) {
const IPAddress ip = WiFi.localIP();
if (0 == strcmp(ip.toString().c_str(), "0.0.0.0")) {
return;
}
serialPrint(LOG_INFO, "Wi-Fi SSID: %s", WiFi.SSID());
serialPrint(LOG_INFO, "Wi-Fi IP address: %s", ip.toString().c_str());
const long rssi = WiFi.RSSI();
serialPrint(LOG_INFO, "Wi-Fi signal strength (RSSI): %ld dBm", rssi);
lastStatusCheck = currentMillis;
if (0 == wifiStatusPrinted) {
drawIp(ip.toString().c_str());
wifiStatusPrinted = true;
}
}
}
static void sendToClient(WiFiClient *client, const char* content) {
client->println(content);
client->flush();
}
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
remoteInit();
matrix.begin();
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(100);
constexpr char text[] = "IRext Example";
matrix.textFont(Font_4x6);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
serialPrint(LOG_INFO, "IRext Arduino example started in station mode");
serialPrint(LOG_INFO, "Attempting to connect to SSID: %s", ssid);
status = WiFi.begin(ssid, pass);
if (status == WL_CONNECTED) {
serialPrint(LOG_INFO, "Connected to Wi-Fi");
server.begin();
}
else {
serialPrint(LOG_ERROR, "Failed to connect Wi-Fi, status: %d", status);
}
}
void onConnected(WiFiClient *client) {
client->flush();
serialPrint(LOG_DEBUG, "Client connected");
sendToClient(client, eHello);
}
void onDisconnected(WiFiClient *client) {
remoteClose();
client->flush();
client->stop();
serialPrint(LOG_DEBUG, "Client disconnected");
}
void onError(WiFiClient *client) {
client->flush();
client->stop();
}
void onCommand(WiFiClient *client, const String *command) {
if (command->startsWith(aHello)) {
serialPrint(LOG_DEBUG, "Received hello command");
sendToClient(client, eBin);
} else if (command->startsWith(aBin)) {
serialPrint(LOG_DEBUG, "Received bin command");
#if !defined TEST_BIN_RECEIVE
if (remoteOpen(command->c_str()) > 0) {
sendToClient(client, eControl);
} else {
serialPrint(LOG_ERROR, "Failed to parse bin command");
sendToClient(client, eError);
}
#else
sendToClient(client, eControl);
#endif
} else if (command->startsWith(aControl)) {
serialPrint(LOG_DEBUG, "Received control command");
remoteControl(command->c_str());
} else if (command->startsWith(aError)) {
serialPrint(LOG_DEBUG, "Received error command");
onError(client);
}
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
serialPrint(LOG_INFO, "Connection lost, reconnecting");
status = WiFi.begin(ssid, pass);
if (status == WL_CONNECTED) {
serialPrint(LOG_INFO, "Reconnected");
}
} else {
printWiFiStatus();
if (!client || !client.connected()) {
client = server.available();
if (client) {
clientConnected = true;
onConnected(&client);
}
}
if (client && client.connected()) {
if (client.available()) {
String received = client.readStringUntil('\n');
received.trim();
if (received.length() > 0) {
serialPrint(LOG_VERBOSE, "Data received: %d", received.length());
onCommand(&client, &received);
}
}
} else if (clientConnected) {
onDisconnected(&client);
clientConnected = false;
client.stop();
}
}
}