0

Since my last post, I've been trying to do some extra things with my Stranger Things Wall Project.

I connected a LCD Screen (16x2) that will take any text being processed to the wall and show what is being written (So we can read the full message even if we lost the first chars being flashed)

The original example I followed used a Bluetooth App to send the message, however I want to use a Web Server with Ethernet.

My current challenge is if it is possible to make a WebServer to feed text to arduino, without the use of a SD card. I did manage to find an example that sends a simple command, but in my case, I need to call a function and sends a string.

My knowledge is limited on the areas of HTML and JS, so any help is welcome. If it matters, the Ethernet Shield I am using currently is the W5100.

The schematic is the same as the last post, however, here is the updated code:

#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

//Pin connected to ST_CP of 74HC595
#define latchPin 5
//Pin connected to SH_CP of 74HC595
#define clockPin 7
////Pin connected to DS of 74HC595
#define dataPin 6
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   90
// size of buffer that stores a line of text for the LCD + null terminator
#define LCD_BUF_SZ   17
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer
LiquidCrystal_I2C lcd(0x27,16,2);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ATRIBUIÇÃO DE ENDEREÇO 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);                                           //Velocidade de comunicação
  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");
  // no point in carrying on, so do nothing forevermore:
    delay(5000);
    return;
  }
  // print your local IP address:
  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");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<h2>Stranger Things</h2><br />");
          client.println("</HTML>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    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) {                                      //verifica se a string text tem 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 passando a string text como parâmetro
    }
  }
  text = "";                                                    //limpa a string 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 do Ethernet
      digitalWrite(i, LOW);
    }
  }
  if (line >= 1 && line <=3){
    if (line == 3) { line = 7; } //porta 4 usada pelo SD do 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 to 255
  analogWrite(9, 255-brt);
}
  • your code has no SD card functions ... it is unclear what you are asking – jsotola Nov 17 '20 at 19:55
  • Yes. I do not have SD card functions and I am not looking to use them. I would like to know if it is possible to do the "On press send process code" without an SD card. Every example I've found so far requires the SD card and uses Ajax/js or something related. – Feeds Nov 17 '20 at 20:01
  • You can build a simple webserver for the Arduino, and create an HTML page as the user interface to send commands to the Arduino from a webbrowser. If you want to go all the way, you can even have the Arduino host that webpage and communicate over a websocket, if you can get all of that to fit in the memory of an Arduino Uno. I have implemented such a thing, so it is doable, but it was on an Arduino Nano 33 IoT. BTW I don't get what the SD card has to do with it. – ocrdu Nov 17 '20 at 20:05
  • i am certain that you can find minimal ajax code that does not store javascript files locally .... your problem is that you are searching in the arduino realm ... the answers are in the html/javascript/ajax realm ... your question is not really about an arduino – jsotola Nov 17 '20 at 20:07
  • I see, so this is the wrong place to ask such a question. Should I delete it or keep it up and wait for the vote to close? The SD thing is just because I can only find examples that work on the SD directly – Feeds Nov 17 '20 at 20:11
2

Yes, and it's not too hard, but do you do need to do string parsing in C to achieve it.

In your code you read the header of the HTTP request byte by byte and send it to serial, essentially discarding it.

Instead you need to read the header line by line (at least the first line) and parse the URL parameters.

The format of the first line should be something like:

GET / HTTP/1.1

or:

GET /?text=This+will+be+displayed HTTP/1.1

You need to parse that to get everything between = and the the space if they exist. You can then display it as you wish.

Next you also need to alter the code that is sending the web page content to also include a simple HTML form with the GET method and the destination of /, which contains a text field called text.

  • I followed your idea and, while googling on how to deal with the resulting strings, found your examples on how to use a Char array instead of a string. It worked pretty well! Thanks! I also followed your answer to convert the %20 to space and so on, but got stuck on the accented letter problem, because some chars are over the 127 (like Ã), but I guess I'll just remember not to use them. – Feeds Nov 23 '20 at 11:23
  • 1
    @Feeds Accents are a nasty subject. There's no standard for how to fit them into 8 bit values and each language has its own arrangement. That's why UTF was created. And that gets really nasty to parse since there's multiple UTF standards... – Majenko Nov 23 '20 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.