Отправить строку через текстовое поле веб-сервера без использования SD-карты?
Со времени моего последнего постая пытался сделать кое-что еще с моим проектом Stranger Things Wall.
Я подключил жидкокристаллический экран (16x2), который выводит любой обрабатываемый текст на стену и показывает, что пишется (чтобы мы могли прочитать полное сообщение, даже если мы потеряли первые мигающие символы).
В исходном примере, которому я следовал, для отправки сообщения использовалось приложение Bluetooth, однако я хочу использовать веб-сервер с Ethernet.
Моя текущая задача заключается в том, можно ли создать веб-сервер для передачи текста на arduino без использования SD-карты. Мне удалось найти пример, который отправляет простую команду, но в моем случае мне нужно вызвать функцию и отправить строку.
Мои знания ограничены в области HTML и JS, поэтому любая помощь приветствуется. Если это имеет значение, то Ethernet Shield, который я использую в настоящее время, - это W5100.
Схема такая же, как и в предыдущем посте, однако вот обновленный код:
#include <Wire.h> //INCLUSÃO DE BIBLIOTECA
#include <LiquidCrystal_I2C.h> // INCLUSÃO DE BIBLIOTECA
#include <SPI.h> //INCLUSÃO DE BIBLIOTECA
#include <Ethernet.h> //INCLUSÃO DE BIBLIOTECA
//Вывод, подключенный к ST_CP 74HC595
#define latchPin 5
//Контакт, подключенный к SH_CP 74HC595
#define clockPin 7
////Контакт, подключенный к DS 74HC595
#define dataPin 6
// размер буфера, используемого для захвата HTTP-запросов
#define REQ_BUF_SZ 90
// размер буфера, в котором хранится строка текста для ЖК-дисплея + нулевой терминатор
#define LCD_BUF_SZ 17
char HTTP_req[REQ_BUF_SZ] = {0}; // буферизованный HTTP-запрос, сохраненный как строка с нулевым завершением
char req_index = 0; // индекс в буфер HTTP_req
LiquidCrystal_I2C lcd(0x27,16,2);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //АТРИБУТ КОНЕЧНОГО MAC AO ETHERNET SHIELD W5100 - ETIQUETINHA
EthernetServer server(80);
String text; //Variável do tipo string que receberá o texto
void setup() {
Serial.begin(9600); //Скорость связи
for (int i = 2; i < 7; i++) {
if (i != 4) {
pinMode(i, OUTPUT); //Declarando o pino como saída
}
}
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
lcd.init();
lcd.setBacklight(HIGH);
lcd.setCursor(0,0);
lcd.print("Iniciando");
if (Ethernet.begin(mac) == 0) {
lcd.clear();
lcd.setCursor(1,0);
lcd.print("FALHA AO PEGAR");
lcd.setCursor(7,1);
lcd.print("IP");
// нет смысла продолжать, так что больше ничего не делай:
delay(5000);
return;
}
// выведите свой локальный IP-адрес:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("PRONTO");
lcd.setCursor(0,1);
lcd.print(Ethernet.localIP());
server.begin();
brilho(255);
inicializationEffect(); //Chamada da Função responsável pelo efeito inicial
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// http-запрос заканчивается пустой строкой
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// если вы дошли до конца строки (получили новую строку
// символ) и строка пуста, http-запрос завершен,
// так что вы можете отправить ответ
if (c == '\n' && currentLineIsBlank) {
// отправить стандартный заголовок HTTP-ответа
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // соединение будет закрыто после завершения ответа
client.println("Refresh: 5"); // обновляйте страницу автоматически каждые 5 секунд
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<h2>Stranger Things</h2><br />");
client.println("</HTML>");
break;
}
if (c == '\n') {
// ты начинаешь новую линию
currentLineIsBlank = true;
} else if (c != '\r') {
// вы получили символ в текущей строке
currentLineIsBlank = false;
}
}
}
// дайте веб-браузеру время для получения данных
delay(1);
// закрыть соединение:
client.stop();
Serial.println("client disconnected");
}
//receiveText(); //Chamada da função responsável por receber o texto digitado
}
//Função que recebe o texto diitado
void receiveText() {
while (Serial.available() > 0) { //Verifica se existe alguma informação na Serial
char c = Serial.read(); //atribui cada caractere a variável c que é do tipo char
if (c != '\n') text.concat(c) ; //verifica se a variável do tipo char recebeu uma quebra de linha que indica o fim da palavra ou frase e concatena todos os caracteres na String text
delay(10); //aguarda 10 milissegundos
}
if (text.length() > 0) { //проверка текста строки тем tamanho maior que 0
text.toUpperCase(); //transforma tudo que estiver na string text para maiúsculo
if (text[0]=='#'){
waveEffect();
}else if(text[0]=='!'){
blink();
}else {
executeEffect(text); //chama a função executeEffect передает строковый текст с параметрами
}
}
text = ""; //лимпа строковый текст
}
//Função responsável por ativar linha que recebe como parâmetro o número da linha
void lineActivation(int line, int keepalive) {
if (keepalive == 0) {
for (int i = 2; i <= 4; i++) {
if (i == 4) { i = 8; } //porta 4 usada pelo SD делать Ethernet
digitalWrite(i, LOW);
}
}
if (line >= 1 && line <=3){
if (line == 3) { line = 7; } //porta 4 usada pelo SD делать Ethernet
digitalWrite(line+1, HIGH); //coloca a linha 1 em estado lógico alto
}
}
void activateLetter(char letter, int on, int off) {
int lt;
brilho(255);
lt = (((int)letter - 64) % 9);
if (((int)letter - 64) > 8) {
lt = lt + 1;
}
if (on) {
callCol(1<<lt-1);
delay(on); //mantém o pino em nível lógico alto durante o tempo que foi determinado no parâmetro da função
}
if (off) {
callCol(0);
delay(off); //mantém o pino em nível lógico baixo durante o tempo que foi determinado no parâmetro da função
}
}
void callCol(int col){
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, highByte(col));
shiftOut(dataPin, clockPin, MSBFIRST, lowByte(col));
digitalWrite(latchPin, HIGH);
}
void executeEffect(String text) {
for (int i = 0; i < text.length(); i++) {
if (text[i] == ' ') {
delay(1000);
} else if ((int)text[i] < 65 or (int)text[i] > 90) {
} else {
lineActivation(int(((int)text[i] - 64) / 9) + 1, 0);
activateLetter(text[i], 1000, 200);
}
}
}
void inicializationEffect() {
for (int i = 1; i < 27; i++) {
lineActivation(int(i / 9) + 1, 0); //ativa a linha
activateLetter(char(64 + i), 100, 10); //ativa a letra
}
}
void waveEffect() {
Serial.println("Wave");
for (int i = 1; i < 4; i++) {
lineActivation(i, 1); //ativa a linha
}
for (int i = 1; i < 10; i++) {
activateLetter(char(72 + i), 100, 0);
}
for (int i = 1; i < 10; i++) {
activateLetter(char(72 + i), 0, 100);
}
lineActivation(0, 0); //ativa a linha
}
void blink() {
Serial.println("Blink");
callCol(511);
lineActivation(1,1);
lineActivation(2,1);
lineActivation(3,1);
for (int i = 0; i < 256; i++){
brilho(i);
delay(1);
}
delay(100);
for (int i = 255; i >= 0; i--){
brilho(i);
delay(1);
}
}
void brilho(byte brt) { // от 0 до 255
analogWrite(9, 255-brt);
}
@Feeds, 👍0
Обсуждение1 ответ
Лучший ответ:
Да, и это не так уж сложно, но нужно ли вам выполнять синтаксический анализ строк на языке Си, чтобы достичь этого?
В своем коде вы байт за байтом считываете заголовок HTTP-запроса и отправляете его в serial, по сути отбрасывая его.
Вместо этого вам нужно прочитать заголовок построчно (по крайней мере, первую строку) и проанализировать параметры URL.
Формат первой строки должен быть примерно таким:
GET / HTTP/1.1
или:
GET /?text=This+will+be+displayed HTTP/1.1
Вам нужно проанализировать это, чтобы получить все между =
и пробелом, если они существуют. Затем вы можете отобразить его по своему усмотрению.
Далее вам также необходимо изменить код, который отправляет содержимое веб-страницы, чтобы он также включал простую HTML-форму с методом GET и назначением /
, которая содержит текстовое поле с именем text
.
Я последовал вашей идее и, погуглив о том, как обращаться с результирующими строками, нашел ваши примеры того, как использовать массив символов вместо строки. Это сработало очень хорошо! Спасибо! Я также последовал вашему ответу, чтобы преобразовать%20 в пробел и так далее, но застрял на проблеме с акцентированными буквами, потому что некоторые символы превышают 127 (например, Â), но, думаю, я просто не забуду их использовать., @Feeds
@Feeds Акценты - неприятная тема. Не существует стандарта для того, как подогнать их к 8-битным значениям, и каждый язык имеет свое собственное расположение. Вот почему был создан UTF. И это становится * действительно * неприятным для анализа, поскольку существует несколько стандартов UTF..., @Majenko
- Ethernet Shield не подключается
- Как получить данные из базы данных моего сервера в переменную в моем Arduino?
- Отправка данных Arduino через Ethernet на сервер PHP.
- Простая веб-страница с Ethernet-шилдом Arduino на SD-карте
- Подключение Arduino ethernet shield (ip-адрес - 0.0.0.0)
- Arduino uno R4 против платы разработчика ESP32
- Как отправить HTTP-post данные в Node Express API с Arduino esp822 6?
- Можно ли использовать AWS и Arduino Uno для загрузки данных с Arduino на веб-сайт, работающий на моем локальном хосте?
ваш код не имеет функций SD - карты ... непонятно, о чем вы спрашиваете, @jsotola
ДА. У меня нет функций SD-карты, и я не собираюсь их использовать. Я хотел бы знать, возможно ли выполнить команду "On press отправить код процесса" без SD-карты. Каждый пример, который я нашел до сих пор, требует SD-карты и использует Ajax / js или что-то связанное., @Feeds
Вы можете создать простой веб-сервер для Arduino и создать HTML-страницу в качестве пользовательского интерфейса для отправки команд в Arduino из веб-браузера. Если вы хотите пройти весь путь, вы даже можете разместить на Arduino эту веб-страницу и обмениваться данными через websocket, если вы сможете разместить все это в памяти Arduino Uno. Я реализовал такую вещь, так что это выполнимо, но это было на Arduino Nano 33 IoT. Кстати, я не понимаю, какое отношение к этому имеет SD-карта., @ocrdu
я уверен, что вы можете найти минимальный код ajax, который не хранит файлы javascript локально .... ваша проблема в том, что вы ищете в области arduino... ответы находятся в области html / javascript / ajax ... ваш вопрос на самом деле не об arduino, @jsotola
Я понимаю, так что это неподходящее место, чтобы задавать такой вопрос. Должен ли я удалить его или оставить в силе и дождаться завершения голосования? Проблема с SD заключается только в том, что я могу найти только примеры, которые работают непосредственно на SD, @Feeds
Ну, вам нужно запустить веб-сервер на Arduino, этот бит принадлежит здесь, и вопросы о создании веб-интерфейса для управления Arduino меня не так сильно беспокоят, но мнения сильных мира сего могут отличаться., @ocrdu
Что ж, пока я буду продолжать в том же духе, и если каким-то образом я получу решение, я сам отвечу на него, он остается открытым., @Feeds