Skip to content

Commit

Permalink
Doc
Browse files Browse the repository at this point in the history
  • Loading branch information
pu2clr committed Oct 8, 2024
1 parent e0240b1 commit 7c59c72
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 46 deletions.
210 changes: 164 additions & 46 deletions examples/10_Nano33IoT/NANO_IOT_WEB/NANO_IOT_WEB.ino
Original file line number Diff line number Diff line change
@@ -1,59 +1,98 @@
#include <WiFiNINA.h> // Install from https://www.arduino.cc/reference/en/libraries/wifinina/
/*
Nano 33 IoT board
1. This sketch uses HTML form to get and process commands from external browser applications to configure the
FM transmitter based on QN8066.
Nano 33 IoT Wire up
| Device name | QN8066 Pin | Nano 33 IoT |
| --------------------------| -------------------- | ----------------- |
| QN8066 | | |
| | VCC | 3.3V |
| | GND | GND |
| | SDIO / SDA (pin 2) | A4 |
| | SCLK (pin 1) | A5 |
| --------------------------| ---------------------| ----------------- |
| PWM Power Controller [1] | | |
| | | D9 |
1. A suggestion if you intend to use PWM to control the RF output power of an amplifier.
Prototype documentation: https://pu2clr.github.io/QN8066/
PU2CLR QN8066 API documentation: https://pu2clr.github.io/QN8066/extras/apidoc/html/
By PU2CLR, Ricardo, Oct 2024.
*/

#include <QN8066.h>
#include <WiFiNINA.h> // Install from https://www.arduino.cc/reference/en/libraries/wifinina/

#define I2C_SDA 4 // A4
#define I2C_SCL 5 // A5


// Definição da rede Wi-Fi
char ssid[] = "PU2CLR"; // Coloque o nome da sua rede Wi-Fi
char pass[] = "pu2clr123456"; // Coloque a senha da sua rede Wi-Fi
char ssid[] = "PU2CLR"; // Coloque o nome da sua rede Wi-Fi
char pass[] = "pu2clr123456"; // Coloque a senha da sua rede Wi-Fi


long rdsTimePS = millis();
long rdsTimeRT = millis();
long rdsDateTime = millis();

uint16_t currentFrequency = 1069; // 106.9 MHz
uint16_t previousFrequency = 1069; // 106.9 MHz
char ps[9] = "PU2CLR \r";
char rt[33] = "QN8066 WEB Server control \r";

uint16_t currentFrequency = 1069; // 106.9 MHz
uint16_t previousFrequency = 1069; // 106.9 MHz
uint8_t currentPower = 0;


int status = WL_IDLE_STATUS; // Variável para armazenar o status da conexão
WiFiServer server(80); // Cria um servidor na porta 80
int status = WL_IDLE_STATUS; // Variável para armazenar o status da conexão
WiFiServer server(80); // Cria um servidor na porta 80

WiFiClient client;
WiFiClient client;

QN8066 tx;

void setup() {

Serial.begin(9600);
Serial.println("Starting WiFi!");

// Verifica o status do módulo Wi-Fi
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("WiFi Error!");
while (true);
while (true)
;
}

while (status != WL_CONNECTED) {
Serial.print("Connecting to: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(5000);
delay(5000);
}

// Starting Server
server.begin();
Serial.println("Server started");

Serial.print("IP do Arduino: ");
Serial.println(WiFi.localIP());

}

void handleRoot() {
void doFormParameters() {
String htmlPage = "<html><head>";

htmlPage += "<style>";
htmlPage += "body { font-family: Arial, sans-serif; background-color: #006400; color: yellow;"; // Fundo verde Amazonas (#006400) e texto amarelo
htmlPage += "body { font-family: Arial, sans-serif; background-color: #006400; color: yellow;"; // Fundo verde Amazonas (#006400) e texto amarelo
htmlPage += " display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; margin: 0; }";
htmlPage += "h1 { text-align: center; margin-bottom: 20px; color: yellow; }"; // Título com fonte amarela
htmlPage += "h1 { text-align: center; margin-bottom: 20px; color: yellow; }"; // Título com fonte amarela
htmlPage += "table { border-collapse: collapse; width: auto; margin-top: 20px; }";
htmlPage += "td, th { border: 1px solid black; padding: 8px; color: yellow; }"; // Texto da tabela amarelo
htmlPage += "td input[type='text'], td select { width: 32ch; color: yellow; background-color: #004d00; border: 1px solid yellow; }"; // Campos com fundo verde escuro e borda amarela
htmlPage += "td:nth-child(1) { text-align: right; }"; // Alinha os rótulos à direita
htmlPage += "td, th { border: 1px solid black; padding: 8px; color: yellow; }"; // Texto da tabela amarelo
htmlPage += "td input[type='text'], td select { width: 32ch; color: yellow; background-color: #004d00; border: 1px solid yellow; }"; // Campos com fundo verde escuro e borda amarela
htmlPage += "td:nth-child(1) { text-align: right; }"; // Alinha os rótulos à direita
htmlPage += "</style>";

htmlPage += "</head><body>";
Expand All @@ -64,24 +103,24 @@ void handleRoot() {

// Formulário com Ajax e solução tradicional
htmlPage += "<form method='POST' action='/setParameters'>";

// Tabela para alinhar campos e botões
htmlPage += "<table>";

// Frequency
htmlPage += "<tr>";
htmlPage += "<td>Transmission Frequency (MHz):</td>";
htmlPage += "<td><input type='text' id='frequency' name='frequency' maxlength='6' size='6' value='" + String((float) currentFrequency / 10.0) + "'></td>";
htmlPage += "<td><input type='text' id='frequency' name='frequency' maxlength='6' size='6' value='" + String((float)currentFrequency / 10.0) + "'></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"frequency\")'>Set</button></td>";
htmlPage += "</tr>";

// Power (Not implemented so far)
htmlPage += "<tr>";
htmlPage += "<td>Power:</td>";
htmlPage += "<td><input type='text' id='power' name='power' maxlength='3' size='3' value='" + String(currentPower) + "'></td>";
htmlPage += "<td><input type='text' id='power' name='power' maxlength='3' size='3' value='" + String(currentPower) + "'></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"power\")'>Set</button></td>";
htmlPage += "</tr>";

// Stereo / Mono
htmlPage += "<tr>";
htmlPage += "<td>Stereo/Mono:</td>";
Expand Down Expand Up @@ -121,29 +160,29 @@ void handleRoot() {
htmlPage += "</select></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"rds_pty\")'>Set</button></td>";
htmlPage += "</tr>";

// RDS Programa Station (PS)
htmlPage += "<tr>";
htmlPage += "<td>RDS PS:</td>";
htmlPage += "<td><input type='text' id='rds_ps' name='rds_ps' maxlength='8'></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"rds_ps\")'>Set</button></td>";
htmlPage += "</tr>";

// RDS Radio Text (RT)
htmlPage += "<tr>";
htmlPage += "<td>RDS RT:</td>";
htmlPage += "<td><input type='text' id='rds_rt' name='rds_rt' maxlength='32'></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"rds_rt\")'>Set</button></td>";
htmlPage += "</tr>";

// Linha do RDS DT

htmlPage += "<tr>";
htmlPage += "<td>RDS DT:</td>";
htmlPage += "<td><input type='text' id='rds_dt' name='rds_dt' maxlength='32'></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"rds_dt\")'>Set</button></td>";
htmlPage += "</tr>";

// Frequency Derivation list
htmlPage += "<tr>";
htmlPage += "<td>Frequency Derivation:</td>";
Expand Down Expand Up @@ -178,8 +217,8 @@ void handleRoot() {
htmlPage += "<option value='1' selected>6dB</option>";
htmlPage += "<option value='2'>9dB</option>";
htmlPage += "<option value='3'>12dB</option>";
htmlPage += "<option value='4'>15dB</option>";
htmlPage += "<option value='5'>18dB</option>";
htmlPage += "<option value='4'>15dB</option>";
htmlPage += "<option value='5'>18dB</option>";
htmlPage += "</select></td>";
htmlPage += "<td><button type='button' onclick='sendData(\"buffer_gain\")'>Set</button></td>";
htmlPage += "</tr>";
Expand All @@ -199,10 +238,10 @@ void handleRoot() {
// Fechar tabela e botão de enviar o formulário completo (solução tradicional)
htmlPage += "</table><br>";
htmlPage += "<input type='submit' value='Submit All Parameters'>";

// Close the form definition
htmlPage += "</form>";

// Script para enviar dados via Ajax (envio individual)
htmlPage += "<script>";
htmlPage += "function sendData(fieldId) {";
Expand All @@ -218,33 +257,112 @@ void handleRoot() {
htmlPage += " xhr.send(fieldId + '=' + encodeURIComponent(value));";
htmlPage += "}";
htmlPage += "</script>";

htmlPage += "</body></html>";
client.println(htmlPage);
}


String getValue(String data, String field) {
int startIndex = data.indexOf(field + "=") + field.length() + 1;
int endIndex = data.indexOf('&', startIndex);
if (endIndex == -1) {
endIndex = data.length();
}
return data.substring(startIndex, endIndex);
}


void doFormUpdate() {
String body = client.readString();
Serial.println("Request: " + body);

int nLen;

// Processa e aplica o valor do campo correspondente
if (body.indexOf("frequency=") >= 0) {
String frequency = getValue(body, "frequency");
currentFrequency = (uint16_t)(frequency.toFloat() * 10);
if (currentFrequency != previousFrequency) {
tx.setTX(currentFrequency);
previousFrequency = currentFrequency;
}
Serial.println("Frequency updated to: " + String(frequency) + " MHz");
}
/* else if (field == "power") {
String power = server.arg("power");
Serial.println("Power updated to: " + String(power));
} else if (field == "rds_pty") {
String rds_pty = server.arg("rds_pty");
tx.rdsSetPTY(rds_pty.toInt());
Serial.println("RDS PTY updated to: " + String(rds_pty));
} else if (field == "rds_ps") {
String rds_ps = server.arg("rds_ps");
nLen = rds_ps.length();
strncpy(ps, rds_ps.c_str(), nLen);
ps[nLen] = '\r';
ps[nLen+1] = '\0';
Serial.println("RDS PS updated to: " + String(ps));
} else if (field == "rds_rt") {
String rds_rt = server.arg("rds_rt");
nLen = rds_rt.length();
strncpy(rt, rds_rt.c_str(), nLen);
rt[nLen] = '\r';
rt[nLen+1] = '\0';
Serial.println("RDS RT updated to: " + String(rt));
} else if (field == "frequency_derivation") {
String frequency_derivation = server.arg("frequency_derivation");
tx.setTxFrequencyDerivation(frequency_derivation.toInt());
Serial.println("Frequency Derivation updated to: " + String(frequency_derivation));
} else if (field == "input_impedance") {
String input_impedance = server.arg("input_impedance");
tx.setTxInputImpedance(input_impedance.toInt());
Serial.println("Input Impedance updated to: " + String(input_impedance));
} else if (field == "stereo_mono") {
String stereo_mono = server.arg("stereo_mono");
tx.setTxMono(stereo_mono.toInt());
Serial.println("Stereo/Mono updated to: " + String(stereo_mono));
} else if (field == "buffer_gain") {
String buffer_gain = server.arg("buffer_gain");
tx.setTxInputBufferGain(buffer_gain.toInt());
Serial.println("Buffer Gain updated to: " + String(buffer_gain));
} else if (field == "pre_emphasis") {
String pre_emphasis = server.arg("pre_emphasis");
tx.setPreEmphasis(pre_emphasis.toInt());
Serial.println("Pre-Emphasis updated to: " + String(pre_emphasis));
} else if (field == "soft_clip") {
String soft_clip = server.arg("soft_clip");
tx.setTxSoftClippingEnable(soft_clip.toInt());
Serial.println("Soft Clip updated to: " + String(soft_clip));
}
*/
// Enviar resposta ao cliente confirmando o recebimento do campo
// server.send(200, "text/plain", field + " has been updated.");
}


void loop() {
// Verifica se há clientes conectados
client = server.available();
if (client) {
Serial.println("Connected");

String request = client.readStringUntil('\r');
client.flush();
// Aguarda até o cliente enviar dados
while (client.connected()) {
if (client.available()) {
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
handleRoot();
break;
if (request.indexOf("POST") >= 0) {
while (client.connected()) {
if (client.available()) {
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
break;
}
doFormUpdate();
}
} else {
doFormParameters();
}

client.stop();
Serial.println("Connection Closed");
}
}


5 changes: 5 additions & 0 deletions examples/10_Nano33IoT/NANO_IOT_WEB/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Nano 33 IoT

To compile this sketch, install the library WiFiNINA (https://www.arduino.cc/reference/en/libraries/wifinina/)


0 comments on commit 7c59c72

Please sign in to comment.