Nesse vídeo mostro como incluir imagens, javascript, e outros tipos de arquivos e mídias na sua aplicação web baseada no Ethernet Shield W5100
31/10/2016 - Observação
Erro de login
Várias pessoas têm me relatado problemas no login, e eu não havia conseguido achar o problema, mas o Rodrigo (nos comentários abaixo) encontrou o problema e postou a solução. Vou manter o código original, e se quem tiver erros, siga o que o Rodrigo recomendou:
//Descobri o problema e mudei o meu código. //A função base64_encode não retorna corretamente o primeiro byte codificado, //por isso a função validar_usuario sempre recebia a string "out" errada. //Tive que trocar a função base64_encode para uma que retornasse o valor //inteiro de "out" codificado. Dai minha função validar_usuario ficou assim: boolean validar_usuario(char * linebuf) { char usuario_senha[] = "admin:admin"; //"admin:admin"; byte t = strlen(usuario_senha); int tamanhoEnc = (((t-1) / 3) + 1) * 4; //tamanho da string codificada char *out = base64_encode(usuario_senha, t); char out2[tamanhoEnc]; for (t=0; t<(tamanhoEnc); t++) { out2[t] = linebuf[21+t]; } return (strstr(out2, out)>0); }
Entenda o Mime Types:
https://pt.wikipedia.org/wiki/MIME
Lista de todos (acredito eu) os Mime Types de Arquivos:
http://www.sitepoint.com/web-foundations/mime-types-complete-list/
Para rodar a aplicação, copie os seguintes arquivos para dentro do SDCard
atmel.pdf
Qualquer arquivo PDF chamado atmel.pdf (cuidado com o tamanho do arquivo)
favicon.ico
qualquer arquivo do tipo ico, chamado favicon.ico
uno.jpg
qualquer imagem do tipo jpg, chamada uno.jpg
os demais arquivos, devem ser conforme mostrados abaixo
HTML - index.htm
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="/css.css"> <script src="/js.js"></script> </head> <body onload="init();"> <h1>ARDUINO - ETHERNET SHIELD + SDCARD + ARQUIVOS</h1> <br> <img src="/uno.jpg" /> <br> <a href="/atmel.pdf">Download datasheet</a> | <a href='/logoff'>Logoff</a> <br> </body> </html>
Javascript - js.js
function init(){ window.alert("hello world!"); }
CSS - css.css
body { background-color: #FAEBD7; } h1 { margin-left: 40px; }
Sketch - código-fonte:
/* Web Server - HTTP Autentication Baseado na versão de exemplo do Arduino. - exemplo que mostra como incluir html, css, javascript e imagem em arquivos no sdcard e também como fazer download de um arquivo pdf do sdcard. by Fabiano A. Arndt (fabianoallex) */ /********************************************************************************** ************************************BIBLIOTECAS************************************ **********************************************************************************/ #include <SPI.h> #include <Ethernet.h> #include <SD.h> /********************************************************************************** ********************************FIM BIBLIOTECAS************************************ **********************************************************************************/ /********************************************************************************** *************************ROTINAS USUARIO E SENHA*********************************** ***********************************************************************************/ boolean validar_usuario(char * linebuf) { /* nesse exemplo o usuario e senha estão definidos dentro do código fonte. mas o usuário e senha poderiam ser autenticados de diversas maneiras, lendo os dados de um servidor web, arquivo texto, etc, bastando apenas atribuir o valor lido para a variável usuario_senha. */ char usuario_senha[] = "admin:admin"; //usuario e senha para acessar a pagina int t = strlen(usuario_senha); int tamanhoEnc = (((t-1) / 3) + 1) * 4; //tamanho da string codificada char out[tamanhoEnc]; base64_encode(out, usuario_senha, t+1 ); //---desconta é usado pra eliminar os caracteres '=' int desconta = 0; if ((t%3) == 1) { desconta = 2; } if ((t%3) == 2) { desconta = 1; } char out2[tamanhoEnc-desconta]; byte i; for (i=0; i<(tamanhoEnc-desconta);i++){ out2[i] = out[i]; } out2[i] = '\0'; return ( strstr(linebuf, out2)>0 ); } /********************************************************************************** *************************FIM ROTINA USUARIO E SENHA******************************** ***********************************************************************************/ /**************************************************************************************** ****************************SD CARD INICIO*********************************************** ****************************************************************************************/ #define PIN_SD_CARD 4 boolean iniciar_sd_card() { pinMode(10, OUTPUT); digitalWrite(10, HIGH); if (!SD.begin(PIN_SD_CARD)) { return false; } return true; } /**************************************************************************************** ****************************SD CARD FIM************************************************** ****************************************************************************************/ /********************************************************************************** ***********************************PAGINAS HTML************************************ ***********************************************************************************/ EthernetServer * server; void write_from_file(EthernetClient &client, char * filename){ File webFile = SD.open(filename); if (webFile) { while(webFile.available()) { client.write(webFile.read()); } webFile.close(); } else { Serial.print("Erro SD CARD: "); Serial.println(filename); } } void iniciar_ethernet_01(){ byte ip[4] = {192,168,200,25}; //definir aqui o ip byte gateway[4] = {192,168,200,254}; byte subnet[4] = {255,255,255,0}; byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; int porta = 80; server = new EthernetServer(porta); Ethernet.begin(mac, ip, gateway, subnet); //caso necessario gateway utilizar essa linha server->begin(); } void iniciar_ethernet_02(){ byte ip[4] = {192,168,200,25}; //definir aqui o ip byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; int porta = 80; server = new EthernetServer(porta); Ethernet.begin(mac, ip); server->begin(); } void iniciar_ethernet() { //escolher apenas um dos dois modos de iniciar o ethernet shield iniciar_ethernet_01(); //inicia com ip, gateway, mascara e porta //iniciar_ethernet_02(); //inicia só com ip e porta } void html_cab_200_ok(EthernetClient &client){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: text/html\n" "Connection: keep-alive\n\n")); } void html_logoff(EthernetClient &client){ client.print(F( "HTTP/1.1 401 Authorization Required\n" "Content-Type: text/html\n" "Connnection: close\n\n" "<!DOCTYPE HTML>\n" "<html><head><title>Logoff</title>\n" "<script>document.execCommand('ClearAuthenticationCache', 'false');</script>" //IE logoff "<script>try {" //mozila logoff " var agt=navigator.userAgent.toLowerCase();" " if (agt.indexOf(\"msie\") != -1) { document.execCommand(\"ClearAuthenticationCache\"); }" " else {" " var xmlhttp = createXMLObject();" " xmlhttp.open(\"GET\",\"URL\",true,\"logout\",\"logout\");" " xmlhttp.send(\"\");" " xmlhttp.abort();" " }" " } catch(e) {" " alert(\"erro ao fazer logoff\");" " }" "function createXMLObject() {" " try {if (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();} else if (window.ActiveXObject) {xmlhttp=new ActiveXObject(\"Microsoft.XMLHTTP\");}} catch (e) {xmlhttp=false;}" " return xmlhttp;" "}</script>" "</head><body><h1>Voce nao esta mais conectado</h1></body></html>\n")); } void html_autenticar(EthernetClient &client) { client.print(F("HTTP/1.1 401 Authorization Required\n" "WWW-Authenticate: Basic realm=\"Area Restrita\"\n" "Content-Type: text/html\n" "Connnection: close\n\n" "<!DOCTYPE HTML>\n" "<html><head><title>Error</title>\n" "</head><body><h1>401 Acesso nao autorizado</h1></body></html>\n")); } void html_autenticado(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: text/html\n" "Connection: keep-alive\n")); write_from_file(client, filename); } void js_file(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: text/javascript\n" "Connection: keep-alive\n")); write_from_file(client, filename); } void css_file(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: text/css\n" "Connection: keep-alive\n")); write_from_file(client, filename); } void favicon_file(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: image/x-icon\n" "Connection: keep-alive\n")); write_from_file(client, filename); } void pdf_file_download(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: application/download\n" "Connection: close\n")); write_from_file(client, filename); } void jpg_file(EthernetClient &client, char * filename){ client.println(F("HTTP/1.1 200 OK\n" "Content-Type: file/jpg\n" "Connection: close\n")); write_from_file(client, filename); } void exec_ethernet() { EthernetClient client = server->available(); if (client) { char linebuf[80]; memset(linebuf, 0, sizeof(linebuf)); int charCount = 0; boolean autenticado = false; boolean currentLineIsBlank = true; boolean logoff = false; boolean indCss = false; boolean indJs = false; boolean indPdfDataSheet = false; boolean indJpgUno = false; boolean indFavicon = false; while (client.connected()) { if (client.available()) { char c = client.read(); linebuf[charCount] = c; if (charCount<sizeof(linebuf)-1) { charCount++; } Serial.write(c); if (c == '\n' && currentLineIsBlank) { if (autenticado && !logoff ) { if (indJs){ js_file(client, "js.js"); //js file } else if(indCss){ css_file(client, "css.css"); //css file } else if(indPdfDataSheet){ pdf_file_download(client, "atmel.pdf"); //datasheet download } else if(indJpgUno){ jpg_file(client, "uno.jpg"); //jpg file } else if(indFavicon){ jpg_file(client, "favicon.ico"); //icone do browser } else { html_autenticado(client, "index.htm"); //página inicial } } else { logoff ? html_logoff(client) : html_autenticar(client); } break; } if (c == '\n') { currentLineIsBlank = true; if (strstr(linebuf, "GET /logoff" )>0 ) { logoff = true; } if (strstr(linebuf, "Authorization: Basic")>0 ) { if ( validar_usuario(linebuf) ) { autenticado = true; } } if (strstr(linebuf, "GET /css.css" )>0 ) { indCss = true; } if (strstr(linebuf, "GET /js.js" )>0 ) { indJs = true; } if (strstr(linebuf, "GET /atmel.pdf" )>0 ) { indPdfDataSheet = true; } if (strstr(linebuf, "GET /uno.jpg" )>0 ) { indJpgUno = true; } if (strstr(linebuf, "GET /favicon.ico" )>0 ) { indFavicon = true; } memset(linebuf, 0, sizeof(linebuf)); charCount = 0; } else if (c != '\r') { currentLineIsBlank = false; // you've gotten a character on the current line } } } delay(1); client.stop(); } } /********************************************************************************** **************************************** FIM PAGINAS HTML************************** ***********************************************************************************/ /********************************************************************************** *************************BASE 64 CODE/DECODE DO USUARIO E SENHA******************** ***********************************************************************************/ void a3_to_a4(unsigned char * a4, unsigned char * a3); void a4_to_a3(unsigned char * a3, unsigned char * a4); unsigned char b64_lookup(char c); int base64_encode(char *output, char *input, int inputLen) { const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i=0, j=0, encLen=0; unsigned char a3[3], a4[4]; while(inputLen--) { a3[i++] = *(input++); if(i == 3) { a3_to_a4(a4, a3); for(i=0; i<4; i++) { output[encLen++] = b64_alphabet[a4[i]]; } i = 0; } } if (i) { for(j = i; j < 3; j++) { a3[j] = '\0'; } a3_to_a4(a4, a3); for(j = 0; j < i + 1; j++) { output[encLen++] = b64_alphabet[a4[j]]; } while((i++ < 3)) { output[encLen++] = '='; } } output[encLen] = '\0'; return encLen; } /* int base64_decode(char * output, char * input, int inputLen) { int i = 0, j = 0; int decLen = 0; unsigned char a3[3]; unsigned char a4[4]; while (inputLen--) { if (*input == '=') { break; } a4[i++] = *(input++); if (i == 4) { for (i = 0; i <4; i++) { a4[i] = b64_lookup(a4[i]); } a4_to_a3(a3,a4); for (i = 0; i < 3; i++) { output[decLen++] = a3[i]; } i = 0; } } if (i) { for (j=i; j<4; j++) { a4[j] = '\0'; } for (j=0; j<4; j++) { a4[j] = b64_lookup(a4[j]);} a4_to_a3(a3,a4); for (j=0; j<i-1; j++) { output[decLen++] = a3[j]; } } output[decLen] = '\0'; return decLen; } */ //int base64_enc_len(int plainLen) { // int n = plainLen; // return (n + 2 - ((n + 2) % 3)) / 3 * 4; //} //int base64_dec_len(char * input, int inputLen) { // int i = 0; // int numEq = 0; // for(i = inputLen - 1; input[i] == '='; i--) { numEq++; } // return ((6 * inputLen) / 8) - numEq; //} void a3_to_a4(unsigned char * a4, unsigned char * a3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = (a3[2] & 0x3f); } //void a4_to_a3(unsigned char * a3, unsigned char * a4) { // a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); // a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); // a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; //} unsigned char b64_lookup(char c) { if(c >='A' && c <='Z') return c - 'A'; if(c >='a' && c <='z') return c - 71; if(c >='0' && c <='9') return c + 4; if(c == '+') return 62; if(c == '/') return 63; return -1; } /********************************************************************************** *************************FIM BASE 64 CODE/DECODE DO USUARIO E SENHA**************** ***********************************************************************************/ /********************************************************************************** **************************************** VOID / LOOP ****************************** ***********************************************************************************/ void setup() { Serial.begin(9600); iniciar_sd_card(); iniciar_ethernet(); } void loop() { exec_ethernet(); } /********************************************************************************** *************************************FIM VOID / LOOP******************************* ***********************************************************************************/
Fabiano, poderia passar onde entraria o código no arquivo.ino para acionar as lâmpadas por exemplo.
ResponderExcluirno html vc vai incluir o código que envia os comandos que vc quer executar, algo assim:
Excluir< form method="GET" action="/comandos" >
< input type="checkbox" name="led7" > Ligar led 7
< input type="submit" value="Submit">
< /form >
e no scketch vc vai incluir um if nessa lista abaixo:
if (strstr(linebuf, "GET /logoff" )>0 ) { logoff = true; }
if (strstr(linebuf, "Authorization: Basic")>0 ) { if ( validar_usuario(linebuf) ) { autenticado = true; } }
if (strstr(linebuf, "GET /css.css" )>0 ) { indCss = true; }
if (strstr(linebuf, "GET /js.js" )>0 ) { indJs = true; }
if (strstr(linebuf, "GET /atmel.pdf" )>0 ) { indPdfDataSheet = true; }
if (strstr(linebuf, "GET /uno.jpg" )>0 ) { indJpgUno = true; }
if (strstr(linebuf, "GET /favicon.ico" )>0 ) { indFavicon = true; }
if (strstr(linebuf, "GET /comandos" )>0 ) { executa_comandos(linebuf); }
veja que a ultima linha acima foi incluida pra tratar os comandos
ai vc cria a função que ira tratar os comandos recebidos
void executa_comandos(char * linebuf) {
pinMode(7, OUTPUT);
if (strstr(linebuf, "led13=on" )>0 ) {
digitalWrite(7, LOW);
} else {
digitalWrite(7, HIGH);
}
//aqui vc coloca os demais comandos que serão recebidos do html
}
qualquer duvida só falar.
corrigindo...
Excluirvoid executa_comandos(char * linebuf) {
pinMode(7, OUTPUT);
if (strstr(linebuf, "led7=on" )>0 ) {
digitalWrite(7, HIGH);
} else {
digitalWrite(7, LOW);
}
//aqui vc coloca os demais comandos que serão recebidos do html
}
eu estou apanhando nesse mesmo lugar!!! por favor poderia me explicar melhor?
Excluirmeu email é gtautomotivo@hotmail.com
muito obrigado
william
to fazendo um artigo novo sobre ethernet shiedl, com mais alguns detalhes, mas to meio sem tempo de terminar, mas assim que der ele vai tá no ar, acho que vai ajudar nessas dúvidas.
ExcluirBoa noite, você poderia disponibilizar esse artigo?
ExcluirOlá fabiano como eu conseguiria ler um sensor na porta analógica? Poderia me mandar um email com o código fbramos27@gmail.com
ResponderExcluirNesta linha "//aqui vc coloca os demais comandos que serão recebidos do html" os "comandos" são obrigatórios ou opcionais?
ResponderExcluirSe obrigatórios, poderia dizer quais são?
na verdade são os parâmetros que serão passados do html para o arduino. no exemplo, led7=on significa que é pra ligar um led. Ou seja, tem um parâmetro que é passado, e que quando recebido ele executa um comando, que seria ligar o led, poderia ser qualquer outra coisa. Não são obrigatórios.
ExcluirFabiano, muito obrigado pela atenção e presteza.
ExcluirJá consegui acionar até 3 relés com os códigos "htm" inseridos no próprio sketch. Mas, utiliza muita memória e não consigo aumentar a quantidade de relés.
Estou tentando fazer acionar 4 relés e para isso preciso escrever os códigos da página "htm", gravar no SDCard e trazer os comandos para o sketch interpretar.
Caso você possua alguma coisa que possa compartilhar faça esse favor. Vou continuar procurando solução, caso obtenha, posto aqui.
De antemão, mais uma vez, obrigado!
to fazendo um artigo novo sobre ethernet shiedl, com mais alguns detalhes, mas to meio sem tempo de terminar, mas assim que der ele vai tá no ar, acho que vai ajudar nessas dúvidas.
ExcluirBom dia Fabiano.
ExcluirSeria de grande ajuda se você puder explicar sobre este ponto.
Preciso enviar um sinal de valor lógico 1 por um botão contido nessa página.
Parabéns pela qualidade dos seus trabalhos!
Lembrando que a sua explicação a esta questão ao colega que lhe perguntou eu testei exatamente e não acendeu o led. Obrigado.
ExcluirObs: existem outros exemplos que acende um led pelo webserver do arduino, porém é mais complicado de achar quando a página é gerada pelo código html dentro do cartão SD.
a questão aqui é que exige conhecimentos um pouco mais avançados. No meu exemplo, to mostrando como carregar arquivos do cartão, no caso dos arquivos html, eles são estáticos, não dinâmicos, apenas pra exemplificar como carregar algo do cartão de memória.
Excluira ideia é mostrar alguns conceitos, e não aprofundar tudo que é possível fazer.
pra incluir dinamicidade às páginas é preciso usar outros recursos, como javascript, ajax, requisições assíncronas, etc.
mas isso já são questões de desenvolvimento web, e eu não queria misturar os conceitos. Seria interessante buscar esses conhecimentos sem serem especificamente voltados para Arduino. Por isso não quis misturar as coisas, pra não bagunçar.
eu to com outro artigo pra terminar que queria tratar um pouco desses outros detalhes, mas to sem tempo, e por enquanto ainda não tenho previsão de terminar.
Este comentário foi removido pelo autor.
ResponderExcluirFantastic exemplo! ¡Fantástico ejemplo! Fantastic example!
ResponderExcluirboa tarde
ResponderExcluirmuito bom o exemplo criado por voce
e temos que agradecer a iniciativa de compartilhar seu conhecimento
seria possivel me auxiliar em uma duvida
quando envio valor led7=on toda pagina e recarregada
bom dia, valeu. quanto a sua dúvida, só verificando o código pra eu conseguir saber o que pode estar errado. qualquer coisa manda um email pra fabianoallex@gmail.com. abraço
ExcluirBoa noite.
ResponderExcluirTentei usar seu código para um teste, e não sai da pagina de login.
oque pode ser?
ta dando alguma mensagem de erro?
ExcluirBoa Noite....
ExcluirEntão, Não aparece mensagem de erro... apos fazer a autenticação (admin admin) ele voltar na pagina para autenticar novamente, vira um ciclo.
Estou testando com o arduino mega 2560 e shield Ethernet w5100
muda alguma configuração por ser no mega?
O meu está com o mesmo problema. Só fica pedindo usuario e senha....
ExcluirO meu uno também está com o mesmo problema.
ExcluirAcho que o problema está na função validar_usuario, pois ela nunca retorna true. Tentei debugar o código, e aparentemente a string out2 nunca está contida na string linebuf. Alguma luz aí?
ExcluirDescobri o problema e mudei o meu código. A função base64_encode não retorna corretamente o primeiro byte codificado, por isso a função validar_usuario sempre recebia a string "out" errada. Tive que trocar a função base64_encode para uma que retornasse o valor inteiro de "out" codificado. Dai minha função validar_usuario ficou assim:
Excluirboolean validar_usuario(char * linebuf) {
char usuario_senha[] = "admin:admin"; //"admin:admin";
byte t = strlen(usuario_senha);
int tamanhoEnc = (((t-1) / 3) + 1) * 4; //tamanho da string codificada
char *out = base64_encode(usuario_senha, t);
char out2[tamanhoEnc];
for (t=0; t<(tamanhoEnc); t++) {
out2[t] = linebuf[21+t];
}
return (strstr(out2, out)>0);
}
obrigado Rodrigo, várias pessoas tem relatado esse problema, mas ainda não tinha conseguido um tempo pra verificar o que poderia ser. Vou editar no artigo pra quem estiver com problema seguir sua solução.
ExcluirRodrigo, tentei esse cod que vc deixou acima, mas da um erro, -> invalid convertion fron 'byte {aka unsigned char}' to 'char*'[-fpermissive] <- esse erro da na linha : char out = base64_encode(usuario_senha, t); , se puder me ajudar eu agradeço
ExcluirComigo também dá erro, char *out = base64_encode(usuario_senha, t);.
ExcluirA função base64_encode pede 3 parâmetros e no caso aqui manda só 2.
mesma coisa comigo. pede 3 parametros mas so tem 2.
ExcluirBom dia amigo. Preciso enviar dados de um banco de dados para o meu arduino, como por exemplo o usuário e senha. Você tem ideia de como eu fazer? Consigo enviar do arduino para o banco de dados o qual estão atrelados por um servidor php, mas o contrário eu não consigo.
ResponderExcluirGostaria de saber se existe algum comando ou algo do tipo.
Muito obrigado.
Boa tarde Fabiano, ainda não consegui fazer com que meu html acione minha saída, teria como você mandar um exemplo para meu email..
ResponderExcluireduardoewertoncruzdelima@gmail.com
Muito show o post, porém ainda tenho dificuldades com a programação.
Vlw
Olá Fabiano. Sei que não é exatamente sobre o assunto desse post, mas estou a bastante tempo pesquisando e até agora não achei nenhuma resposta descente. Como faço para jogar valores de variáveis de sensores, para uma pagina HTML que esta sendo lida de dentro do cartão SD(index.htm)? obs: estou usando o shield ethernet.
ExcluirBom dia Fabiano/Rodrigo,
ResponderExcluirAinda estou com o probleminha do login, ja fiz a alteração da função validar o usuario, quanto a alteração da função base64_encode não sei como editá-la, poderia me ajudar com o código?
Boa tarde! O meu problema é : entro com senha e login, mas ele entra em uma tela branca, poderia me ajudar ?
ResponderExcluirOla boa tarde!
ResponderExcluirFabiano eu estou usando a placa Mega 2560 com Eth Shield e não estou tendo sucesso em rodar este seu escript. Vi que no codigo você usa os pinos 4 e 10 do arduino UNO para habilitar/desabiltar o cartão SD e a ETH. Me pareceu que no Mega 2560 o pino 53 tem a mesma função do pino 4 do UNO, mas o pino 10, não consigo encontrar equivalente. Tambem não sei se só seria este dois os pontos. Gravei os arquivos no SD e no PC estão funcionando como esperado, porem no Arduino não passam do Login, rejeitando o usuario e senha admin:admin.. Vc pode me ajudar?? Obrigado
Galera, consegui achar a função que transforma o login_senha para base64.
ResponderExcluirPrimeiro: Substituam a função validar_usuario exatamente como o Rodrigo postou.
Segundo: Tirem toda aquela parte entre /**** BASE 64 ****/ e /**** FIM DA BASE64 ****/
Terceiro: Coloquem o codigo abaixo nesse lugar. PS: obrigado ao Fabiano por postar esse código para nós!!!
static const char b64all[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789+/";
const char *base64_encode(const char *original, int length) {
// Se o tamanho não for informado, consideramos uma string bem
// formada
if (length == 0)
length = strlen(original);
// Inteiro com o tamanho do código a ser gerado
int b64length = ((length + 2) / 3) * 4 + 1;
// Contadores para percorrer as strings
int i=0, j=0;
// Alocando memória para o código
char *b64 = (char *) malloc(sizeof(char) * b64length);
memset(b64, 0, b64length);
while (i < length) {
// Codifica um grupo de três bytes...
_encode(
(uint8_t *) b64 + j,
(const uint8_t *) original + i,
(length - i)
);
// E segue para o próximo grupo
i += 3;
j += 4;
}
// Retorna o código
return (const char *) b64;
}
void _encode(uint8_t *dest, const uint8_t *src, int len) {
// Menor que 1, nada a fazer
if (len < 1)
return;
// Dados a serem retornados
int aux[] = { 0, 0, 0, 0 };
// Primeiro elemento: os 6 bits mais significativos do primeiro
// byte
aux[0] = src[0] >> 2;
// Segundo elemento: os 2 bits menos significativos do primeiro e
// os quatro bits mais significativos do segundo byte
aux[1] = (src[0] & 0x03) << 4;
if (len > 1) {
// SE houver um segundo...
aux [1] |= (src[1] & 0xf0) >> 4;
// Terceiro elemento: os quatro bits menos significativos do
// segundo e os dois mais significativos do terceiro byte
aux [2] = (src[1] & 0x0f) << 2;
if (len > 2) {
// Se houver um terceiro...
aux[2] |= src[2] >> 6;
// Quarto elemento: os seis bits menos significatos do
// terceiro byte
aux[3] = src[2] & 0x3f;
}
}
// Codifica agora os valores numéricos para string
dest[0] = b64all[aux[0]];
dest[1] = b64all[aux[1]];
dest[2] = '=';
dest[3] = '=';
if (len > 1) {
dest[2] = b64all[aux[2]];
if (len > 2)
dest[3] = b64all[aux[3]];
}
}
aqui pra mim mesmo seguindo isso ainda da errado
ExcluirPra mim funcionou! Muito obrigado a todos que colaboraram!
Excluirwhy i cant use admin admin for enter ?
ResponderExcluirthx for fabiano :D
ResponderExcluirEste comentário foi removido pelo autor.
ResponderExcluirFabiano este Código fonte que mandei em partes tem com você unir com este seu código fonte.
ExcluirFicaria uma ótima automação, por hora eu agradeço.
o site que eu achei foi este (http://startingelectronics.org/articles/arduino/switch-and-web-page-button-LED-control/)
#include
ResponderExcluir#include
#include
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ 60
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
IPAddress ip(192, 168, 1, 102); // IP address, may need to change depending on network
EthernetServer server(8081); // create a server at port 80
File webFile; // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0; // index into HTTP_req buffer
boolean LED_state[2] = {0}; // stores the states of the LEDs
void setup()
{
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Serial.begin(9600); // for debugging
// initialize SD card
Serial.println("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("ERROR - SD card initialization failed!");
return; // init failed
}
Serial.println("SUCCESS - SD card initialized.");
// check for index.htm file
if (!SD.exists("index.htm")) {
Serial.println("ERROR - Can't find index.htm file!");
return; // can't find index file
}
Serial.println("SUCCESS - Found index.htm file.");
// switches
pinMode(2, INPUT);
pinMode(3, INPUT);
// LEDs
pinMode(30, OUTPUT);
pinMode(31, OUTPUT);
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
}
void loop()
ResponderExcluir{
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// limit the size of the stored received HTTP request
// buffer first part of HTTP request in HTTP_req array (string)
// leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
if (req_index < (REQ_BUF_SZ - 1)) {
HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
// remainder of header follows below, depending on if
// web page or XML page is requested
// Ajax request - send XML file
if (StrContains(HTTP_req, "ajax_inputs")) {
// send rest of HTTP header
client.println("Content-Type: text/xml");
client.println("Connection: keep-alive");
client.println();
SetLEDs();
// send XML file containing input states
XML_response(client);
}
else { // web page request
// send rest of HTTP header
client.println("Content-Type: text/html");
client.println("Connection: keep-alive");
client.println();
// send web page
webFile = SD.open("index.htm"); // open web page file
if (webFile) {
while(webFile.available()) {
client.write(webFile.read()); // send web page to client
}
webFile.close();
}
}
// display received HTTP request on serial port
Serial.print(HTTP_req);
// reset buffer index and all buffer elements to 0
req_index = 0;
StrClear(HTTP_req, REQ_BUF_SZ);
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
// read buttons and debounce
ButtonDebounce();
}
void ButtonDebounce(void)
ResponderExcluir{
static byte buttonState[2] = {LOW, LOW}; // the current reading from the input pin
static byte lastButtonState[2] = {LOW, LOW}; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
static long lastDebounceTime[2] = {0}; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
byte reading[2];
reading[0] = digitalRead(2);
reading[1] = digitalRead(3);
for (int i = 0; i < 2; i++) {
if (reading[i] != lastButtonState[i]) {
// reset the debouncing timer
lastDebounceTime[i] = millis();
}
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading[i] != buttonState[i]) {
buttonState[i] = reading[i];
// only toggle the LED if the new button state is HIGH
if (buttonState[i] == HIGH) {
LED_state[i] = !LED_state[i];
}
}
}
} // end for() loop
// set the LEDs
digitalWrite(30, LED_state[0]);
digitalWrite(31, LED_state[1]);
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState[0] = reading[0];
lastButtonState[1] = reading[1];
}
// checks if received HTTP request is switching on/off LEDs
// also saves the state of the LEDs
void SetLEDs(void)
{
// LED 1 (pin 6)
if (StrContains(HTTP_req, "LED1=1")) {
LED_state[0] = 1; // save LED state
digitalWrite(30, HIGH);
}
else if (StrContains(HTTP_req, "LED1=0")) {
LED_state[0] = 0; // save LED state
digitalWrite(30, LOW);
}
// LED 2 (pin 7)
if (StrContains(HTTP_req, "LED2=1")) {
LED_state[1] = 1; // save LED state
digitalWrite(31, HIGH);
}
else if (StrContains(HTTP_req, "LED2=0")) {
LED_state[1] = 0; // save LED state
digitalWrite(31, LOW);
}
}
// send the XML file with analog values, switch status
// and LED status
void XML_response(EthernetClient cl)
{
int analog_val; // stores value read from analog inputs
int count; // used by 'for' loops
int sw_arr[] = {2, 3}; // pins interfaced to switches
cl.print("");
cl.print("");
// LED1
cl.print("");
if (LED_state[0]) {
cl.print("on");
}
else {
cl.print("of");
}
cl.println("");
// LED2
cl.print("");
if (LED_state[1]) {
cl.print("on");
}
else {
cl.print("of");
}
cl.println("");
cl.print("");
}
// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
for (int i = 0; i < length; i++) {
str[i] = 0;
}
}
// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
char found = 0;
char index = 0;
char len;
len = strlen(str);
if (strlen(sfind) > len) {
return 0;
}
while (index < len) {
if (str[index] == sfind[found]) {
found++;
if (strlen(sfind) == found) {
return 1;
}
}
else {
found = 0;
}
index++;
}
return 0;
}
Olá bom dia a todos. Estou com um problema em meu codigo, ele funciona perfeitamente, porem ele demora cerca de 10 segundos para responder (passar valores do site para o arduino). Eu simplesmente não sei como resolver isso, alguem poderia me ajudar? Muito obrigado!
ResponderExcluiremail: jonashenrique989@gmail.com
Fiz conforme o Caio Queiroz orientou no comentário, e funcionou perfeitamente.
ResponderExcluirObrigado a todos!!!!
fabiano estou tentando colocar mais esta linha neste sketch, mas so da este erro exit status 1
ResponderExcluirredefinition of 'void jpg_file(EthernetClient&, char*)' como posso fazer para resolver isto?
Linha De Programação
void jpg_file(EthernetClient &client, char * trip){
client.println(F("HTTP/1.1 200 OK\n"
"Content-Type: file/jpg\n"
"Connection: close\n"));
write_from_file(client, trip);
}
Boa noite Fabiano, gostaria de solicitar a sua ajuda. Sou novo na programação html. Estou tentando passar os dados de uma leitura analógica para o web server e depois coletar com o Node-red, para montar um gráfico. O meu problema está no código html no Arduino. Ao fazer a programação e testar, eu não estou conseguindo passar os valores da leitura como números, e sim como string. Daí não consigo tratar esses dados no Node-red. Você saberia como ajudar?
ResponderExcluirObrigado desde já.