Ir ao conteúdo
  • Cadastre-se

ESP8266 - A Pequena Maravilha para Comunicação WIFI


aphawk

Posts recomendados

@Intrudera6 ,

 

Concordo com você em tudo que você escreveu, meu amigo ! O meu calo é qualquer coisa em C ...... porisso não consigo ajudar mais aqui neste tópico.

 

Se todos postarem os seus códigos que funcionaram, simplificará muito para os outros !

 

Off-Topic :

 

Notei que você também programou para 6502 e Z-80 !  Minhas lembranças desse tempo são ótimas !

Eu cheguei ao absurdo de misturar o assembler do 6502 e do Z80 em vários programas, pois eu entendia como o CPM-80 do Apple trabalhava com o 6502, e alguns anos depois também fiz uma mistura doida nos IBM-PC, misturando o assembler do NEC-V20 ( podia rodar como Z-80 ! ) e do 8088.

 

Paulo

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Brincando aqui, liguei o esp8266 diretamente no conversor usb/serial, seguindo este tutorial: 

https://alselectro.wordpress.com/2015/05/13/wifi-module-esp8266-2-tcp-client-server-mode/

funcionou direitinho, vejam a imagem dos meus testes.

 

Agora posso voltar ele pra pcb sabendo que se aparecer lixo é porque tem falha de comunicação e como eu já disse antes, vou dar um jeito de baixar a frequência da serial 115200 realmente é muita coisa principalmente pra mim que sempre trabalhei com 9600 kkkk. O problema em baixar a frequência vai ser a inicialização do sistema, não quero acoplar o esp na pcb já configurado com uma frequência mais baixa porque se algo der errado, ele terá que ser sacado para ser reconfigurado novamente. Por questão de segurança estou implementando de forma que todas as vezes em que o sistema for reiniciado o PIC reseta o esp nas configurações de fábrica e coloca todas novamente, de uma a uma. Desta forma vai ser mais trabalhoso acertar a frequência (baud rate) do PIC com ele rodando, não sei se vai dar, mas vou tentar desta forma.

 

Abrass!!

 

 

ESP07.png

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Na minha época eu tinha muito tempo e principalmente muita paciência (e disposição para virar muitas noites tentando fazer as coisas funcionarem, mas faltava e dinheiro e era tudo caro). Se existisse umas coisas como estes ESP8266  ou Arduinos ao preço que são hoje eu teria feito miséria com eles (2 dólares é pouco dinheiro até para estudante). O preço destas coisas hoje é tão baixo que eu comprei vários deles para testar (estou cheio deles), e se eu fritar algum ou alguns não seria um grande problema (isto vai acabar acontecendo em algum momento). Mas por enquanto estou no aprendizado, tentando entender como o C funciona, quando estiver com mais confiança tentarei coisas mais complicadas.

 

Poucas coisas me dão mais prazer do que fazer uma coisas destas funcionar (ainda sinto tesão por programar uns brinquedos desses apesar de já ter passado de meio século de idade), e quando começo a programar normalmente eu tenho dificuldade de interromper, o que é um problema para quem tem que acordar as 4:35 de segunda a sexta, eu não tenho mais pique para aguentar uma noite em claro e ainda conseguir trabalhar direito, a idade pesa, eu não aguento isto mais isto sem ter problemas no dia seguinte.

 

O tempo para isto está realmente curto, estou investindo bastante tempo e algum dinheiro para finalmente aprender inglês, e desta vez pretendo ir até o fim, mas desse jeito o meu tempo disponível para aprender C e dominar o ESP8266 está curto, senão eu já teria ido muito mais longe.

 

Se não fosse o prazer que eu tenho de fazer uma coisa destas funcionar eu já teria largado de lado pela quase total falta de tempo para isso. Apesar da dificuldade de entender como as coisas funcionam no C, eu gostei tremendamente da flexibilidade da linguagem, dá pra fazer coisas muito interessantes com ela (tremendamente mais flexível que o Bascon, mas nada bate o assembler em termos de poder de fogo e flexibilidade). E já estou começando a entender os programas em C encontrados na internet (o que antes para mim era quase como olhar para hieróglifos). Consegui a documentação sobre o Assembler do ESP8266, e tem uma instruções bem interessantes, mas ainda estou tendo muitos problemas com o C para tentar me meter agora em mais este abacaxi.

 

 

Estou deixando em anexo aqui algo (um PDF do fabricante do ESP8266 com a arquitetura e o assembler do processador)  para que os mais corajosos possam meter as caras (imagino que o aphawk se divertiria muito programando um ESP8266 em Assembler).

 

 

xtensalx_overview_handbook.pdf

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@aphawk

 

Paulo, programador e hobista são duas coisas bem distintas e eu ainda estou na segunda classe hehehe. Não manjo muito de programação é de nada na verdade e também não esquento muito, afinal o gostoso da coisa é fazer por prazer e se virar uma ocupação pode deixar de ser prazeroso. Mas pode ficar tranquilo as minhas experiências mesmo que precárias serão todas registradas aqui e em C.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Seguindo este tutorial do link, eu fiz funcionar no CCS C, só está acontecendo uma coisinha estranha, ao clicar na página WEB no botão "enviar", o comando vai e o microcontrolador responde, só que a pagina na web fica com a ampulheta aguardando alguma coisa, daí eu só consigo enviar o próximo comando se eu mandar o site parar. Penso que quando o microcontrolador executa o comando ele deva mandar alguma coisa de volta pra página web parar, eu tentei desconectar com o comando AT+CIPCLOSE mas aí a página da web fecha por desconexão.

 

Alguém saberia me dizer como resolvo isso?

 

Link para o comentário
Compartilhar em outros sites

14 horas atrás, ViniciusKruz disse:

Seguindo este tutorial do link, eu fiz funcionar no CCS C, só está acontecendo uma coisinha estranha, ao clicar na página WEB no botão "enviar", o comando vai e o microcontrolador responde, só que a pagina na web fica com a ampulheta aguardando alguma coisa, daí eu só consigo enviar o próximo comando se eu mandar o site parar. Penso que quando o microcontrolador executa o comando ele deva mandar alguma coisa de volta pra página web parar, eu tentei desconectar com o comando AT+CIPCLOSE mas aí a página da web fecha por desconexão.

 

Alguém saberia me dizer como resolvo isso?

 

 

Esquece esta dúvida, já descobri que terei que estudar socket  tcp ip pra entender os retornos necessários...

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Dei um melhorada na minha rotina, mas infelizmente não consigo mais editar a mensagem anterior, vou postar aqui, se algum moderador quiser colocar lá no lugar, agradeceria.

 

/*

==== NTPClient.ino ====

 Udp NTP Client

 Get the time from a Network Time Protocol (NTP) time server
 Demonstrates use of UDP sendPacket and ReceivePacket
 For more on NTP time servers and the messages needed to communicate with them,
 see http://en.wikipedia.org/wiki/Network_Time_Protocol

 created 4 Sep 2010
 by Michael Margolis
 modified 9 Apr 2012
 by Tom Igoe
 updated for the ESP8266 12 Apr 2015 
 by Ivan Grokhotkov

 This code is in the public domain.

 */

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Ticker.h> // biblioteca de timers
Ticker Alarme; // define timer

#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 20 chars and 4 line display
#define Endereco_LCD 0x27
#define Col_LCD 20
#define Lin_LCD 4
LiquidCrystal_I2C  lcd(Endereco_LCD,2,1,0,4,5,6,7,3,POSITIVE);

#include <Wire.h>
#define SDA 4 // SDA = PIN 4 = GPIO4 = D2 (ESP-12 V0.9)
#define SCL 5 // SCL = PIN 5 = GPIO5 = D1 (ESP-12 V0.9)

#include "BME280.h"
BME280 bme280;
double temp = 0.0, pressure = 0.0, humid = 0.0;


const unsigned char meses[13] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const unsigned int ndias[13]  = {0, 0, 31, 59, 90,120,151,181,212,243,273,304,334};
const char *nomemes[] = {"","janeiro", "fevereiro", "marco", "abril", "maio", "junho", "julho" , "agosto", "setembro", "outubro", "novembro", "dezembro"};
const char *dsemana[] = {"domingo", "segunda", "terca", "quarta", "quinta", "sexta", "sábado"};

String usegundo = "000000";
unsigned long usec = 0, usecAnt = 0, ustampAnt = 0, ustamp = 0;
unsigned char hora = 0, minuto = 0, segundo = 0, dia = 0, dsem = 0, mes = 0;
unsigned int ano = 0;

uint32_t TInt = 0;

//static char stringbuffer[40+1]; // buffer usado para conversões de String

#define  BUF_LEN 20
char tempbuf[BUF_LEN], humidbuf[BUF_LEN], pressurebuf[BUF_LEN], altitudebuf[BUF_LEN], buf[BUF_LEN];

char ssid[]     = "??????";          //  your network SSID (name)
char password[] = "?????????";       // your network password


#define LED 2          // (LED Azul ESP-12 V0.9)
#define nivel_do_mar (float)1013.25 // pressão em hPa ao nível do mar


unsigned char contador = 0, conexao = 0;
ADC_MODE(ADC_VCC);

int timezone = -3;


unsigned int localPort = 2390;      // local port to listen for UDP packets

/* Don't hardwire the IP address or we won't get the benefits of the pool.
 *  Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
//const char* ntpServerName = "time.nist.gov";
const char* ntpServerName = "ntp.puc-rio.br";

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

// ============== rotina Altitude() ====================

double Altitude(float nmar, float Pv) { // em metros em relação ao nível do mar
  return 44330 * (1 - exp(log((double)Pv / (double)nmar) * 0.19029495718));
}

// ============== rotina mapeiaredes() =================

void mapeiaredes() {
  // mapeias redes sem fio e seleciona para conexão
  
  const char *listassid[] = {"????????", "??????"};
  const char *listapass[] = {"?????????", "?????????"};

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(10);
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1) {
    while (true);
  }

  for(int i = 0; i < 2; i++) {
    for (int thisNet = 0; thisNet < numSsid; thisNet++) {
      if (stricmp(listassid[i],WiFi.SSID(thisNet).c_str()) == 0) {
        // converte WiFi.SSID(thisNet) para char array e compara com listassid[i]
        strcpy(ssid,listassid[i]);     // copia listassid[i] para ssid
        strcpy(password,listapass[i]); // copia listapass[i] para password
        // =========== se encontrar (listassid[i] = WiFi.SSID(thisNet)) sai sem testar as outras redes ============
        thisNet = numSsid; 
        i = 2;
      }
      //Serial.print(WiFi.RSSI(thisNet)); potencia do sinal
    }
  }
  WiFi.begin(ssid, password);
}

// ============== função ftoa() =================

// digits = parte inteira; precision = digitos fração
int ftoa(char *str, float f, unsigned char digits, unsigned char precision) {
  signed char i=0,k,l=0;
  long a,c;
  long pow10[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
  unsigned char b;
  char decimal='.';

  if(digits>=10) {return 0;};
  // check for negative float
  if(f<0.0) {
    str[i++]='-';
    f*=-1;
    (0<digits?digits--:digits++);
    }
  a=(int)f; // extracting whole number
  f-=a; // extracting decimal part
  k = digits;
  // number of digits in whole number
  while(k>=0)   {
    c = pow10[k];
    c = a/c;
    if(c>0) { break; }
    k--;
  } // number of digits in whole number are k+1
  if (0<k && digits==k && c>10) { //overflow
    decimal = 'e';
  }
  if (k < 0) { k = 0; }
  //Serial.print(" k=" + String(k) + " ");
/*
extracting most significant digit i.e. right most digit , and concatenating    to string
obtained as quotient by dividing number by 10^k where k = (number of digit -1)
*/
  for(l=abs(k);l>=0;l--){
    c = pow10[l];
    b = a/c;
    //str[i++]=(l&&!b?' ':b+48); //digit or pad
    str[i++]=b+48; //digit or pad
    /*if (l<=4 && l>=0) {
      Serial.print(" l=" + String(l) + " => i=" + String(i) + " b=" + String(b) + " a=" + String(a) + " c=" + String(c) + "(l&&!b?' ':b+48)=" + (l&&!b?' ':b+48) + " ");
    }*/
    a%=c;
  }
  if (precision) {str[i++] = decimal;};
/* extracting decimal digits till precision */
  if (0>precision) {k=0; precision=abs(precision);}
  for(l=0;l<precision;l++) {
    f*=10.0;
    b = (int)f; //math floor
    str[i++]=b+48; //48 is ASCII 0
    f-=(float)b;
    if (!k && 0==f) { break; } //nothing left, save chars.
    //won't work if there are any floating point errors.
    }
  str[i]='\0';
  return i;
}

// ============== função sendNTPpacket() =================

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
  Serial.println("sending NTP packet...");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  udp.beginPacket(address, 123); //NTP requests are to port 123
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();

}

// ============== rotina pegaNTP() ==============

int pegaNTP() {

  int cb = udp.parsePacket();
  
  int x = 0;
  if (cb) {
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
  
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
  
    unsigned long highusec = word(packetBuffer[44], packetBuffer[45]);
    unsigned long lowusec  = word(packetBuffer[46], packetBuffer[47]);
    
    usec = (highusec << 16 | lowusec)/4295;
  
    /*
    unsigned long aux = usec;
    char usegundo[] = "      ";
    //usegundo[6] = "\0"; finaliza string
    for (int i = 5; i >= 0; i--) {
      usegundo[i] = aux % 10 + 48;
      aux/=10;
    }
    */
    
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
  
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    // ustamp = tempo em segundos desde  1 de janeiro de 1970 com fuso horário
    ustamp = secsSince1900 - seventyYears + timezone * 3600;
  }
  return cb;
}

// ========= função bissexto() ==========



// dia bissexto ?
unsigned char bissexto(unsigned int ent_ano) {

  if ((ent_ano % 400 == 0) || ((ent_ano % 4 == 0) && (ent_ano % 100 != 0))) {
    return 1;
  }
  else {
    return 0;
  }
}

// ========= função mes_bissexto() ==========


unsigned char mes_bissexto(unsigned char ent_mes, unsigned int ent_ano) {

  if (ent_mes > 2) {
    return bissexto(ent_ano);
  }
  else {
    return 0;
  }
}

// ========= função numdias() ==========


// número de dias de 01/01/0001 até a data informada
unsigned long numdias(unsigned char ent_dia, unsigned char ent_mes, unsigned int ent_ano) {

  ent_ano--;
  return (ent_ano / 4) - (ent_ano / 100) + (ent_ano / 400) + ent_ano * 365 + ndias[ent_mes] + mes_bissexto(ent_mes, ent_ano + 1) + ent_dia;
}

// ========= função DiasEntreDatas() ==========

// diferenca entre datas (1. data - 2. data)
long DiasEntreDatas(unsigned char ent_dia1, unsigned char ent_mes1, unsigned int ent_ano1, unsigned char ent_dia2, unsigned char ent_mes2, unsigned int ent_ano2) {

  return numdias(ent_dia1, ent_mes1, ent_ano1) - numdias(ent_dia2, ent_mes2, ent_ano2);
}

// ========= função diasemana() ==========

// dia da semana (0 para domingo), 04/01/1970 é domingo
unsigned char diasemana(unsigned char ent_dia, unsigned char ent_mes, unsigned int ent_ano) {
  unsigned char saida = (DiasEntreDatas(ent_dia, ent_mes, ent_ano, 4, 1, 1970) ) % 7;
  if (saida < 0) {
    saida = saida + 7;
  }
  return saida;
}

// ========= rotina incdia() ==========

// incrementa uns poucos dias e calcula nova data
void incdia(unsigned char inc, unsigned char *ent_dia, unsigned char *ent_mes, unsigned int *ent_ano) {

  (*ent_dia) = (*ent_dia) + inc;
  unsigned char bissexto_aux = 0;
  if ((*ent_mes) == 2) {
    bissexto_aux = bissexto((*ent_ano));
  }
  if (((*ent_dia) < 1) || ((*ent_dia) > meses[(*ent_mes)] + bissexto_aux)) {
    if ((*ent_dia) < 1) {
      if ((*ent_mes) > 1) {
        (*ent_mes)--;
        if ((*ent_mes) == 2) {
          bissexto_aux = bissexto((*ent_ano));
        }
        else {
          bissexto_aux = 0;
        }
        (*ent_dia) = (*ent_dia) + meses[(*ent_mes)] + bissexto_aux;
      }
      else {
        (*ent_mes) = 12;
        (*ent_dia) = (*ent_dia) + meses[(*ent_mes)];
        (*ent_ano)--;
      }
    }
    else {
      (*ent_dia) = (*ent_dia) - meses[(*ent_mes)] ;
      if ((*ent_mes) < 12) {
        (*ent_dia) = (*ent_dia) - bissexto_aux;
        (*ent_mes)++;
      }
      else {
        (*ent_mes) = 1;
        (*ent_ano)++;
      }
    }
  }
}

// ========= rotina ustamp_dh() ==========

// converte ustamp (data de servidor SNTP da Internet) para data e hora
void ustamp_dh(unsigned long ent_ustamp, unsigned char *ent_hora, unsigned char *ent_minuto, unsigned char *ent_segundo, unsigned char *ent_dia, unsigned char *ent_mes, unsigned int *ent_ano) {

  unsigned long num_dias = ent_ustamp / 86400;

  (*ent_hora) = ent_ustamp % 86400 / 3600;
  (*ent_minuto) = ent_ustamp % 3600 / 60;
  (*ent_segundo) = ent_ustamp % 60;
  
  (*ent_ano) = 1970 + num_dias * 100 / 36525;
  
  (*ent_mes) = (num_dias - ((*ent_ano) - 1970) * 36525 / 100) / 30 + 1;
  if ((*ent_mes) < 1) {
    (*ent_mes) = 12;
    (*ent_ano)--;
  }
  else if ((*ent_mes) > 12) {
    (*ent_mes) = 1;
    (*ent_ano)++;
  }
  (*ent_dia) = (num_dias - ((*ent_ano) - 1970) * 36525 / 100 - ndias[(*ent_mes)] + 1) - mes_bissexto((*ent_mes), (*ent_ano));
  if ((*ent_dia) < 1) {
    (*ent_mes)--;
    if ((*ent_mes) < 1) {
      (*ent_mes) = 12;
      (*ent_ano)++;
    }
    (*ent_dia) = meses[(*ent_mes)];
    if ((*ent_mes) == 2) {
      (*ent_dia) = (*ent_dia) + bissexto((*ent_ano));
    }
  }
  else if (((*ent_dia) > meses[(*ent_mes)] && ((*ent_mes) != 2 || bissexto((*ent_ano)) == 0)) || (((*ent_dia) > meses[(*ent_mes)] + 1) && ((*ent_mes) == 2 && bissexto((*ent_ano)) > 0))) {
    (*ent_mes)++;
    if ((*ent_mes) > 12) {
      (*ent_mes) = 1;
      (*ent_ano)++;
    }
    (*ent_dia) = 1;
  }

  // unsigned long 
  long num_dias2 = DiasEntreDatas((*ent_dia),(*ent_mes),(*ent_ano),1,1,1970); // diferença de data e 01/01/1970
  if (num_dias != num_dias2) {
    incdia(num_dias - num_dias2, &(*ent_dia), &(*ent_mes), &(*ent_ano));
  }
}


// ============== função String stringdigitos() ===================

//char* stringdigitos(unsigned long entrada, unsigned char digitos) {

/*
String stringdigitos(unsigned long entrada, unsigned digitos) {
  stringbuffer[digitos] = 0; // finaliza string
  for (int i = digitos-1; i >= 0; i--) {
    stringbuffer[i] = entrada % 10 + 48;
    entrada/=10;
  }
  return stringbuffer;
}
*/

String stringdigitos(unsigned long entrada, signed char ndigitos) {
  String aux = "";
  while (entrada > 0 || ndigitos > 0) {
    if (entrada > 0) {
      aux = String(entrada % 10) + aux;
      entrada/=10;
    }
    else {
      aux = "0" + aux;
    }
    ndigitos--;
  }
  return aux;
}


// ============== rotina imprime() =================

void imprime() {
  
  TInt = micros(); // tempo inicial em microsegundos
  
  contador++;
  if (WiFi.status() != WL_CONNECTED) {
    conexao = 0;
    mapeiaredes();
    digitalWrite(LED, contador & 1);  // faz o LED piscar, LED: 0 = on, 1 = off
    //digitalWrite(LED, HIGH);  // faz o LED piscar, LED: LOW = on, HIGH = off, LED: 0 = on, 1 = off
  } else {
    digitalWrite(LED, LOW);            // mantem o LED aceso, LED: LOW = on, HIGH = off
    if (conexao == 0) {
      conexao = 1;
      Serial.print("ssid='" + String(ssid) + "' Conectado !");
      Serial.print(" IP address: " + WiFi.localIP().toString());
    }
  }
  
  
  
  
  //get a random server from the pool
  //WiFi.hostByName(ntpServerName, timeServerIP); 

  Serial.print(" timeServerIP = " + timeServerIP.toString() + " ");
  sendNTPpacket(timeServerIP); // send an NTP packet to a time server
  // wait to see if a reply is available

  //delay(100);
  int cb = 0;
    if (conexao > 0) {
    cb = pegaNTP(); // pega a data e hora (com microsegundo) da Internet pelo protocolo NTP
    if (cb) {
      usegundo = stringdigitos(usec,6);
      
      if (usec < usecAnt || (signed long)usec - usecAnt >= 100000) {
        usecAnt = usec;
      
        // now convert NTP time into everyday time:

        if (ustampAnt != ustamp) {
          ustamp_dh(ustamp, &hora, &minuto, &segundo, &dia, &mes, &ano);
        }
        // imprime a hora, minuto e segundo:
        Serial.print("A hora e ");       // UTC + timezone
        Serial.print(stringdigitos(hora,2) + ":" + stringdigitos(minuto,2) + ":" + stringdigitos(segundo,2));
        Serial.print("." + usegundo);
        Serial.println("   " + String(micros()));
      }
    }
  }
  if ((ustampAnt != ustamp) || (conexao == 0)) {
    temp = bme280.readTemperature();
    humid = bme280.readHumidity();
    pressure = bme280.readPressure();
    float altitude = Altitude(nivel_do_mar, pressure);
    
    //ftoa(tempbuf, temp, 2, 6);
    //ftoa(humidbuf, humid, 2, 5);
    ftoa(pressurebuf, pressure, 4, 1);
    ftoa(altitudebuf, altitude, 4, 1);
  }
  
  Serial.println(" temp = " + String(temp) + "C umidade = " + (int)humid + "% pressao = " + pressurebuf + "hPa altitude = " + altitudebuf + "m");
  if ((ustampAnt != ustamp) || (conexao == 0)) {
    lcd.setCursor (0,0); // cursor na coluna 0, linha 0
    lcd.print(String(temp) + (char)223 + "C" + (int)humid + "%");
  }
  Serial.print(" conexao = " + String(conexao) + " ");
  Serial.print("cb = " + String(cb) + " ");
  lcd.print(stringdigitos(hora,2) + ":" + stringdigitos(minuto,2) + ":" + stringdigitos(segundo,2) + "." + String(usegundo[0]));
  if ((ustampAnt != ustamp) || (conexao == 0)) {
    lcd.setCursor (0,1); // cursor na coluna 0, linha 1
    lcd.print(String(pressurebuf) + "hPa " + String(altitudebuf) + "m  ");
  }
  
  //ambient.post("temp", tempbuf, "humid", humidbuf, "pressure", pressurebuf);

  //Serial.print(String(ESP.getVcc()/1000.0) + "V ");
  Serial.print(String(ESP.getVcc()/842.0) + "V ");
  if (cb) {
    Serial.print(" - " + String(dsemana[dsem]) + ", " + stringdigitos(dia,2) + "-" + String(nomemes[mes]) + "-" + String(ano)); // termina com retorno
    Serial.println();
    if (ustampAnt != ustamp) {
      lcd.setCursor (0,2);        // cursor na coluna 0, linha 2
      dsem = diasemana(dia,mes,ano);
      lcd.print(String(dsemana[dsem]) + ", " + stringdigitos(dia,2) + "/" + stringdigitos(mes,2) + "/" + String(ano));
    }
  }
  lcd.setCursor (0,3);        // cursor na coluna 0, linha 3
  //lcd.print(String(micros()) + " "+  String(ESP.getVcc()/1000.0) + "V   ");
  lcd.print(String(micros()) + " "+  String(ESP.getVcc()/842.0) + "V   ");

  if ((ustampAnt != ustamp) || (conexao == 0)) {
    ustampAnt == ustamp;
  }
}


// ============== setup() =================

void setup() {

  Serial.begin(115200);
  pinMode(LED, OUTPUT);      // configura pino LED para saída (OUTPUT)
  digitalWrite(LED, HIGH);   // apaga o LED
  // activate LCD module
  lcd.begin (Col_LCD,Lin_LCD); // inicializa modulo LCD

  bme280.begin(SDA, SCL);
  // Os valores lidos imediatamente após a fonte de alimentação ser ligada são instáveis.
  bme280.readTemperature();
  bme280.readHumidity();
  bme280.readPressure();
  
  //lcd.setBacklight(HIGH);
  // ------- Quick 3 blinks of backlight -------------

  for(int i = 0; i< 3; i++) {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight();
  
  lcd.clear();                // limpa o lcd
  lcd.home ();                // set cursor to 0,0
  lcd.setCursor (0,0);        // cursor na coluna 0, linha 0
  
  Serial.println();
  Serial.println();

  // ==========  Conectando no WIFI ===================

  Serial.println("Scanning available networks...");
  lcd.setCursor (0,0);
  lcd.print("Scanning available networks...");
    
  contador = 0;
  mapeiaredes();
  Serial.println();
  Serial.println("ssid='" + String(ssid) + "' Conectando ...");
  lcd.setCursor (0,0);
  lcd.print("ssid='" + String(ssid) + "' Conec...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //digitalWrite(LED, contador++ % 2);
    digitalWrite(LED, contador++ & 1);
    Serial.print(".");
    conexao = 1;
    if (contador >= 20) {
      Serial.println();
      Serial.print(String(WiFi.status()) + " ");
      Serial.println("Saiu na Marra! ");
      conexao = 0;
      break;
    }
  }
  //digitalWrite(LED, HIGH);         // mantem o LED apagado
  if (conexao == 0) {
    digitalWrite(LED, HIGH);            // mantem o LED apagado, LED: LOW = on, HIGH = off
  }
  else {
    digitalWrite(LED, LOW);            // mantem o LED acesso, LED: LOW = on, HIGH = off
    
    lcd.setCursor (0,1);
    lcd.print("WiFi conectado!");
    
    Serial.println();
    Serial.print("ssid='" + String(ssid) + "' Conectado !");
    Serial.print(" IP address: " + WiFi.localIP().toString());
    Serial.println();
    
    lcd.setCursor (0,2);
    lcd.print("ssid= '" + String(ssid) + "'");
    lcd.setCursor (0,3);
    lcd.print("IP: " + WiFi.localIP().toString());
    delay(5000);
    // clear the screen
    lcd.clear();
    lcd.home();
  
    Serial.println("Starting UDP");
    udp.begin(localPort);
    Serial.print("Local port: ");
    Serial.println(udp.localPort());
  
    //get a random server from the pool
    WiFi.hostByName(ntpServerName, timeServerIP); // pega o endereço IP
  
    Serial.println("timeServer : " + String(ntpServerName) + " IP: " + timeServerIP.toString());
  }
  
  Alarme.attach_ms(100, imprime); //imprime a cada 100 milesegundos.
}

// ============== loop() =================
  
void loop() {

}

 

Link para o comentário
Compartilhar em outros sites

Agradeceria muito!

 

Eu nunca tinha programado antes em C e meu conhecimento anterior na linguagem era NULO. Antes de ter vontade de fazer um ESP8266 funcionar de uma forma, digamos, mais interessante (LUA no ESP8266 tem algumas limitações que me aborrecem bastante), eu nunca tinha tido uma real vontade de aprender C, e sem esta vontade aprender C parecia para mim uma missão impossível (nada como ter a motivação certa).

Link para o comentário
Compartilhar em outros sites

Uma coisa já aprendi, sem o devido tratamento da recepção dos dados que o ESP8266 devolvem para o microcontrolador, é impossível um funcionamento "perfeito", estou focado nesta parte e estou tendo que me virar nos 30 pra conseguir pegar completamente a resposta aos comandos AT, a primeira opção, é dar o comando AT e aguardar 1 ou dois segundos e pegar a resposta completa, mas pra mim isto soa muito como gambiarra, a segunda alternativa, é onde estou mais interessado, consiste em ler os CRs e LFs de fim de linha, mas o bendito do ESP não devolve apenas um sinal ('\n\r') ao fim de toda a instrução, ele devolve um monte! Vejam na imagem e vão entender o que estou passando, aliás, se alguém tiver uma ideia de uma lógica "porreta" manda aí que os neurônios aqui já estão fritando!!

 

 

esp.png

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

@ViniciusKruz , eu iria procurar biblioteca para comunicação de mais alto nível. Basicamente algo que fizesse ao menos o tratamento que você espera. Já deve existir, como utilitário do projeto de alguém. Busque no GitHub. Estou sem tempo para adentrar nisso com vocês.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Acho que consegui uma boa solução (pelo menos provisória até ter uma melhor rs):

 

Ao invés de ficar sempre esperando dois caracteres CR,LF para determinar que chegou um pacote, passei a esperar quatro: CR,LF,CR,LF, se o sistema  encontrar esta sequência ele sinaliza que tem um pacote porém aguarda um pequeno instante pra ver se o continuará a receber mais dados e sinalizará como outro pacote. Nos testes aqui, geralmente sempre vem dois pacotes, um com a informação e o outro com o OK ou o ERRO, vejam na imagem pra entender melhor a lógica. No código ficou assim:

 

(CCS C)

 

No trecho onde recebe a interrupção:

 

#int_RDA
void  RDA_isr(void) 
{
   //recOld=rec;
   rec=RCREG;//getc();//lê o dado na porta serial
   RCIFbit=0;//limpa o flag de interrupção
   
   //recOld=ESP8266Buf[indexRec];
   ESP8266Buf[indexRec]=rec;//getc();//lê o dado na porta serial
   
   if((indexRec>=5) && (indexRec < ESP8266BUFFER_LENGHT))//tamanho mínomo e máximo do pacote
   {//checa se tem o fim de pacote  
      if(rec==0x0a)//se veio o LF...
      {//confere se o byte anterior é um CR
         if(ESP8266Buf[indexRec-1]==0x0d)//se for um CR...
         {//confere se o antecessor é um LF
            if(ESP8266Buf[indexRec-2]==0x0a)//se for LF, confere o ante-antecessor se é um CR
            {
               if(ESP8266Buf[indexRec-3]==0x0d)//se for CR, é porque formou a sequência de fim de resposta: CR,LF,CR,LF
               {
                  posPct[pacote]=indexRec;//marca a posição que iniciou-se um novo pacote
                  pacote++;//contador de pacotes
                  temDados=1;//sinaliza que já tem pacote pronto
               }
            }
         }
      }
   }
   indexRec++;
}

 

 Já no programa, ao enviar um comando AT ao ESP8266 ficou assim:

 

void limpa_buffer()
{
   Clear_ESPBuffer();//limpa o buufer de recepção
   temDados=0;
   indexRec=0;
  pacote=0;
}


void Clear_ESPBuffer(void)
{
    unsigned int16 i;
    for(i=0;i<ESP8266BUFFER_LENGHT;i++)
        ESP8266Buf[i] = 0;
   
}


void main()
{
  limpa_buffer();//limpa o buffer de recepção
   int baseIndex=100;
   fputs("AT+CIFSR\r\n",USART0);//envia comandp para o ESP
      
   while(baseIndex != indexRec)//aguarda receber toda a resposta
   {  //se terminar de receber o pacote, aguarda uma pequena pause para ver se vem mais dados
      baseIndex=indexRec;
      for(pause=0;pause<100000;pause++)
      {
         #asm nop #endasm 
      }
   }
  //ao terminar, agente tem a quantidade de pacotes e a posição inicial de cada um
}

No caso da pequena pausa, não quis usar o delay_ms e sim o nop do ASM, não fiz as contas e não sei exatamente o tempo desta pause, mas o tempo que coloquei aí melhorou o desempenho e não ficou aquela coisa engessada com um tempo definido de recepção, ou seja, a pause é somente entre um pacote e outro.

 

Por hoje é isso. Aceito opiniões, objeções e tudo o que for pra melhorar.

 

Abrass!!

 

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
2 horas atrás, ViniciusKruz disse:

No caso da pequena pausa, não quis usar o delay_ms e sim o nop do ASM, não fiz as contas e não sei exatamente o tempo desta pause, mas o tempo que coloquei aí melhorou o desempenho e não ficou aquela coisa engessada com um tempo definido de recepção, ou seja, a pause é somente entre um pacote e outro.

 

Eu iria já pensar numa forma de não lidar com tempo. É muito incerto.

Link para o comentário
Compartilhar em outros sites

4 minutos atrás, alexandre.mbm disse:

Eu iria já pensar numa forma de não lidar com tempo. É muito incerto.

 

Pior que é, foi por isto que eu preferi não ficar preso em um tempo fixo. No caso, o meu ficou preso foi à resposta, entende, por exemplo, se o esp devolve um trecho da resposta, ele a recebe, guarda no buffer e espera para ver se vai receber mais e se nesse tempo não aparecer mais nada, ele fecha a recepção do pacote. Eu nem imaginava mas fazendo os testes aqui, melhorou 200%, antes, eram de 1, 2 ou 3 segundos de espera para cada comando AT, e mais 10 segundos pra pegar a resposta da conexão à rede wifi, e o tempo total chegava a 23 segundos +/-  agora ele reinicializa todo em 8 segundos. A recepção dos pacotes agora ficou muito boa, maaaasss, sempre pode melhorar né. Agora vou voltar a focar nos pacotes TCP IP.

 

Abraço.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
18 minutos atrás, ViniciusKruz disse:

se o esp devolve um trecho da resposta, ele a recebe, guarda no buffer e espera para ver se vai receber mais e se nesse tempo não aparecer mais nada, ele fecha a recepção do pacote

 

Ele pode parar por uma falha qualquer, ou ele faz um corte por tempo transcorrido, não?

 

Por favor, reproduza e comente o trecho de código específico.

Link para o comentário
Compartilhar em outros sites

25 minutos atrás, alexandre.mbm disse:

Ele pode parar por uma falha qualquer, ou ele faz um corte por tempo transcorrido, não?

 

Sim, sim! 

 

Tem um timeout: 

while(baseIndex != indexRec)//aguarda receber toda a resposta
   {  //se terminar de receber o pacote, aguarda uma pequena pause para ver se vem mais dados
      baseIndex=indexRec;
      for(pause=0;pause<100000;pause++)
      {
         #asm nop #endasm 
      }
   }

 

adicionado 20 minutos depois

 

 

Explicando melhor:

 


//indexRec é a variável de incremento do recebimento da porta serial, cada byte recebido afeta ela

//baseIndex é só para controle, a cada ciclo do loop ela será forçada a ficar igual a indexRec, o que faria parar

while(baseIndex != indexRec)//
   {  //
      baseIndex=indexRec;    //aqui o sistema está liberado para sair do loop
      for(pause=0;pause<100000;pause++) //espera pelo timeout
      {
         #asm nop #endasm 
      }//terminado o timeout, volta e confere se as variáveis ainda estão iguais, caso sim, sai do loop, caso não, significa que foram recebidos mais        //bytes
   }

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

@ViniciusKruz , o seu timeout está baseado em processamento e o tempo sem operação (NOP) então poderá variar com o poder de processamento, não? Caso se prolongue, estará consumindo energia e poderá até esquentar, certo? Não há uma função sleep?

Link para o comentário
Compartilhar em outros sites

@alexandre.mbm

5 minutos atrás, alexandre.mbm disse:

@ViniciusKruz , o seu timeout está baseado em processamento e o tempo sem operação então poderá variar com o poder de processamento, não? Caso se prolongue, estará consumindo energia e poderá até esquentar, certo? Não há uma função sleep?

 

Tem razão sobre a característica: é baseado em processamento, mas não há problema com consumo nem aquecimento, neste caso, por dois motivos, o primeiro: ele processa a instrução de comparação e depois a "NOP" (nenhuma operação), ele fica parado por uma micro fração de tempo nela sem fazer nada, não é o mesmo que piscar um led, entende, acaba sendo um sleep mesmo. O segundo motivo, é que este timeout deve ter menos de 1/4 de segundo, passou do valor predefinido o sistema sai do laço. Até seria bom fazer as contas rsrsrs, o processador está rodando a 48Mhz e a variável de estouro está contando até 100.000 loops na maioria dos casos, quanto tempo daria +/- o ciclo? Só fiz testes rápidos e não parei pra me ater aos detalhes rsrs

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

@ViniciusKruz, não é que eu esteja querendo pescar "detalhes" para criticar por criticar. Na verdade, estou vendo na circunstância talvez uma oportunidade para aprender como um sleep real seria implementado.

 

É a primeira vez que me dou conta de um NOP. Nunca fiz algo em Assembly, não conheço. Tenho apenas noções de C. Estou gostando de ver essas coisas aqui. Depois de Java, passei para Python, Ruby e Bash. Nunca pratiquei muito o baixo nível, mas antevejo que vou precisar dele em breve, "para algum coisa". Na verdade, já fiz ou busquei entender algumas coisas, mas nunca me fixei nisso.

 

Sempre pensei que havia uma instrução de processador para se fazer o sleep, tipo uma chamada direta ao hardware. Quer dizer que o sleep das linguagens de alto nível geralmente é "gambiarra" calculando-se ciclos de clock?

 

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, alexandre.mbm disse:

@ViniciusKruz

Sempre pensei que havia uma instrução de processador para se fazer o sleep, tipo uma chamada direta ao hardware. Quer dizer que o sleep das linguagens de alto nível geralmente é "gambiarra" calculando-se ciclos de clock?

 

 

O Sleep não é gambiarra de forma alguma, inclusive é um recurso muito útil em sistemas alimentados por baterias, ao ser acionado, o processador para tudo e o consumo cai bastante, não é sempre que dá certo usá-lo pois para que ele saia do sono, precisa haver um evento externo ou interno como por exemplo do watch-dog timer. Agora, não podemos misturar, uma coisa é o recurso SLEEP que é de extrema importância para economizar energia, outra coisa, são os recursos de pause, no caso do CCS C que é o que eu uso, tem o deley_ms(), deley_us()... enfim, são recursos em que o compilador faz com que o sistema paralise naquele ponto sem processar nada, na verdade, se não me engano, ele processa um monte de NOP também, o estranho é que em outras vezes quando usei recursos como delay_ms(), em que as interrupções não aconteciam, é como se o sistema parasse todo mesmo, já com os NOPs eu nunca vi isto acontecer. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...