Ir ao conteúdo

Intrudera6

Membro Pleno
  • Posts

    451
  • Cadastrado em

  • Última visita

Tudo que Intrudera6 postou

  1. O DS3231 funciona com 3,3 ou 5V (tensões abaixo de 3,3V também), mas a plaquinha que eu tenho usa uma bateria recarregável de lítio, então eu alimento com 5V (para sempre manter a bateria 100% carregada) e uso um conversor de nível para colocar para falar com o ESP8266 por I2C. O meu ESP8266 de desenvolvimento, nos meus testes, está com um erro no cristal de -6,7ppm (o que é excelente para um cristal comum) comparando com um DS3231 calibrado, não testei com outros ESP8266 mas certamente terão erros diferentes (piores ou melhores), e os meus DS3231 estão calibrados e consigo precisão melhor que +/-0,1ppm (a precisão de um DS3231 sem o devido ajuste fino é +/-2,0ppm, os meus chegam em algumas situações a +/-0,05ppm, tenho vários DS3231 para testar, brincar e até detonar ele em caso de barbeiragem, já danifiquei um conectando errado na pressa).
  2. @lucianolcoa Tem, mas você tem que tomar cuidado para não gastar as 100 mil escritas permitidas (tem documentação que diz que é só 10 mil), pois se você escreve demais com o programa de forma automática pode ser que estoure as 100 mil escritas rapidamente (ou 10 mil considere o pior caso). Eu já vi exemplos de código para escrever no flash do ESP8266, se não me falha a memória a pouco posts atrás, simulando uma EEPROM, mas no meu caso eu estou usando uma plaquinha com um DS3231, que além de fornecer um RTC muito preciso ainda posso utilizar os 4KBytes da EEPROM AT24C32, e que além de tudo, elas são garantidas até 1 milhão de escritas. E se por um acaso pifar algum dia no futuro distante é só trocar, o que no meu caso custou só 0,75 USD cada a plaquinha com o DS3231 + a EEPROM AT24C32 (quase de graça). E é possível escrever na memória RAM do ESP8266 numa área especial que não é perdida nem em caso de reset, apenas o corte de energia apaga ela.
  3. O problema é que um sistema sem bateria (tie grid) sai muito mais barato e tem uma vida útil muito maior que um off grid (a bateria custa caro e deve durar uns 5 anos no máximo com muita voa vontade, um tie grid dura 15 ou 20 anos sem dor de cabeça). Mas acho que nada impede que se monte um tie grid certificado bem menor e mais barato, e depois se amplie (com painéis solares e inversores tie grid chineses comprados pelo ebay ou aliexpess) sem dizer nada a empresa de energia, o relógio vai medir do mesmo jeito e no final você acaba usando o que quiser sem pedir permissão a concessionária de energia. (não sei se a empresa de energia não vai estranhar o aumento da energia devolvida a rede elétrica e não vai fazer outra vistoria, eu não sou dá área e pode ser que eu esteja equivocado). Um dia destes eu vi pela internet numa destas empresas que instalam painéis solares (sistema tie grid certificados) e pela lista dos equipamentos (com os seus preços) fui pesquisar na internet e encontrei os mesmo equipamentos por um valor muito menor que a metade do preço, o que significa que se eu comprasse tudo pagando todos os impostos ainda iria ficar muito mais barato. Eu já pesquiso isto há um bom tempo e até comecei a conhecer um pouco destes sistemas, eu tenho grande interesse em montar um sistema destes, meu problema é ter local para instalar por morar em apartamento. Mas para quem tem casa de praia já é possível, usando a energia produzida na casa de praia para abater o consumo noutro lugar (isto é permitido se for na mesma concessionária de energia). Links de empresas instaladoras: http://www.energiapropria.com.br/kits.php (no sul do Brasil) http://www.brasilsolair.com.br/ (na Bahia) http://portaldaenergia.com/renova-green/ (esta aluga sistemas de energia solar)
  4. O meu programa que postei na página 83 (se não me falha a memória) tem tudo isso, pois eu gravo a configuração IP, SSD, Password e outras coisas na EEPROM do DS3231, mas a rotina é bem parecida para fazer isso na memória flash do ESP8266 (por sinal foi baseado nela e de um exemplo na Internet que fiz a minha para escrever as configurações na EEPROM). Mas se for no ESP32 ainda estou dando umas cabeçadas e não estou conseguindo utilizar as bibliotecas do Arduino, ainda não consigo fazer muita coisa no ESP32 (quase nada). O meu programa tem umas rotinas para fazer isso, vou postar abaixo as rotinas de escrever e ler da EEPROM do DS3231 (da placa que eu tenho com o DS3231) com trechos do código que podem ser uteis. // =========== Rotinas para ler e escrever na EEPROM AT24C32 =========== #define AT24C32 0x57 // Endereço da EEPROM AT24C32 no barramento I2C, (A0, A1 e A2 abertos) void i2c_eeprom_write_byte(int deviceaddress, unsigned int eeaddress, byte data) { int rdata = data; Wire.beginTransmission(deviceaddress); Wire.write((int) (eeaddress >> 8)); // MSB Wire.write((int) (eeaddress & 0xFF)); // LSB Wire.write(rdata); Wire.endTransmission(); } // WARNING: address is a page address, 6-bit end will wrap around // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes void i2c_eeprom_write_page(int deviceaddress, unsigned int eeaddresspage, byte *data, byte length) { Wire.beginTransmission(deviceaddress); Wire.write((int) (eeaddresspage >> 8)); // MSB Wire.write((int) (eeaddresspage & 0xFF)); // LSB byte c; for (c = 0; c < length; c++) Wire.write(data[c]); Wire.endTransmission(); } byte i2c_eeprom_read_byte(int deviceaddress, unsigned int eeaddress) { byte rdata = 0xFF; Wire.beginTransmission(deviceaddress); Wire.write((int) (eeaddress >> 8)); // MSB Wire.write((int) (eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress, 1); if (Wire.available()) rdata = Wire.read(); return rdata; } // maybe let's not read more than 30 or 32 bytes at a time! void i2c_eeprom_read_buffer(int deviceaddress, unsigned int eeaddress, byte *buffer, int length) { Wire.beginTransmission(deviceaddress); Wire.write((int) (eeaddress >> 8)); // MSB Wire.write((int) (eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress, length); int c = 0; for (c = 0; c < length; c++) if (Wire.available()) buffer[c] = Wire.read(); } void loadDefault() { user = UsuarioPadrao; pwd = SenhaPadrao; GravaUsuario(user, pwd); // Grava usuário e senha padrão gravaIpLocal("192.168.15.21"); // Grava rede padrão gravaSubrede("255.255.255.0"); gravaGateway("192.168.15.1"); gravaSsid("Esp8266", "1234"); // Grava o nome padrão da rede wifi a ser conectada gravaServidorNTP("ntp.puc-rio.br"); // Grava o Servidor NTP padrão i2c_eeprom_write_byte(AT24C32, end_fusohorario, timezonedefault); // grava -3 } boolean gravaSsid(String qsid, String qpass) { byte tamanho = qsid.length() + 1; if (tamanho > 0) { if (tamanho > tam_SSID) { tamanho = tam_SSID; qsid[tamanho - 1] = '\0'; // se a string for maior que o tamanho máximo trunca o que passar do máximo } Serial.println("Gravando ssid na eeprom " + qsid); for (int i = 0; i < tamanho; i++) { i2c_eeprom_write_byte(AT24C32, i, qsid[i]); delay(10); } //i2c_eeprom_write_page((AT24C32, 0, &qsid, tamanho); //delay(10); Serial.println("Gravando senha na eeprom"); tamanho = qpass.length() + 1; if (tamanho > tam_Senha_Wifi) { tamanho = tam_Senha_Wifi; qpass[tamanho - 1] = '\0'; // se a string for maior que o tamanho máximo trunca o que passar do máximo } for (int i = 0; i < tamanho; i++) { i2c_eeprom_write_byte(AT24C32, i + end_Senha_Wifi, qpass[i]); delay(10); } //i2c_eeprom_write_page((AT24C32, tam_SSID, &qpass, tamanho); //delay(10); //EEPROM.commit(); // EEPROM Virtual return true; } else { return false; } } boolean GravaUsuario(String usuario, String senha) { byte tamanho = usuario.length() + 1; if (tamanho > 0) { if (tamanho > tam_Usuario) { tamanho = tam_Usuario; usuario[tamanho - 1] = '\0'; // se a string for maior que o tamanho máximo trunca o que passar do máximo } Serial.println(); Serial.print("tamanho = " + String(tamanho) + " usuário = \"" + usuario + "\""); for (int i = end_Usuario; i < end_Usuario + tamanho; i++) { // grava o novo nome do usuário na EEPROM i2c_eeprom_write_byte(AT24C32, i, usuario[i - end_Usuario]); delay(10); } /*i2c_eeprom_write_page(AT24C32, end_Usuario, &usuario, tamanho); // grava o novo nome de usuário na EEPROM Serial.print(usuario); delay(10);*/ //EEPROM.commit(); // EEPROM Virtual tamanho = senha.length() + 1; if (tamanho > tam_Senha_Login) { tamanho = tam_Senha_Login; senha[tamanho - 1] = '\0'; // se a string for maior que o tamanho máximo trunca o que passar do máximo } //Serial.print(" tamanho = " + String(tamanho) + " senha = \"" + senha + "\""); for (int i = end_Senha_Login; i < end_Senha_Login + tamanho; i++) { // grava o novo nome do usuário na EEPROM i2c_eeprom_write_byte(AT24C32, i, senha[i - end_Senha_Login]); delay(10); } Serial.println(); /*i2c_eeprom_write_page(AT24C32, end_Senha_Login, &senha, tamanho); // grava a nova senha de usuário na EEPROM Serial.println(pwd); delay(10);*/ //EEPROM.commit(); // EEPROM Virtual return true; } else { Serial.println("Não Gravou o Usuário e Senha !"); return false; } } boolean gravaServidorNTP(String Servidor_NTP) { byte tamanho = Servidor_NTP.length() + 1; if (tamanho > 0) { if (tamanho > tam_Servidor_NTP) { tamanho = tam_Servidor_NTP; Servidor_NTP[tamanho - 1] = '\0'; // se a string for maior que o tamanho máximo trunca o que passar do máximo } Serial.println(); Serial.println("tamanho = " + String(tamanho) + " Servidor NTP = \"" + Servidor_NTP + "\" "); for (int i = end_Servidor_NTP; i < tamanho + end_Servidor_NTP; i++) { // grava o novo nome do Servidor NTP na EEPROM i2c_eeprom_write_byte(AT24C32, i, Servidor_NTP[i - end_Servidor_NTP]); delay(10); } return true; } else { Serial.println("Não Gravou o Servidor NTP na EEPROM!"); return false; } } boolean gravaIpLocal(String _qip) { IPAddress qip; if (qip.fromString(_qip.c_str())) { for (int i = 0; i < 4; i++) { // grava o novo IP i2c_eeprom_write_byte(AT24C32, i + 200, qip[i]); delay(10); } //i2c_eeprom_write_page(AT24C32, 200, &qip, 4); // grava o novo IP //delay(10); //EEPROM.commit(); return true; } else { return false; } } boolean gravaSubrede(String _qmsk) { IPAddress qmsk; if (qmsk.fromString(_qmsk.c_str())) { for (int i = 0; i < 4; i++) { // grava o novo IP i2c_eeprom_write_byte(AT24C32, i + 208, qmsk[i]); delay(10); } //i2c_eeprom_write_page(AT24C32, 208, &qmsk, 4); // grava o novo IP //delay(10); //EEPROM.commit(); return true; } else { return false; } } boolean gravaGateway(String _qgtw) { IPAddress qgtw; if (qgtw.fromString(_qgtw.c_str())) { for (int i = 0; i < 4; i++) { //grava o novo Gateway i2c_eeprom_write_byte(AT24C32, i + 204, qgtw[i]); delay(10); } //i2c_eeprom_write_page(AT24C32, 204, &qgtw, 4); // grava o novo Gateway //delay(10); //EEPROM.commit(); return true; } else { return false; } } String esid = ""; char aux; for (int i = 0; i < tam_SSID; i++) { aux = char(i2c_eeprom_read_byte(AT24C32, i)); if (!aux) { break; } esid += aux; } Serial.println("SSID: \"" + esid + "\""); Serial.println("Lendo a senha da rede na EEPROM"); String epass = ""; for (int i = end_Senha_Wifi; i < end_Senha_Wifi + tam_Senha_Wifi; i++) { aux = char(i2c_eeprom_read_byte(AT24C32, i)); if (!aux) { break; } epass += aux; } //lê o ip da EEPROM for (int i = 0; i < 4; i++) { ip[i] = i2c_eeprom_read_byte(AT24C32, i + 200); } //lê o Gateway da EEPROM for (int i = 0; i < 4; i++) { gateway[i] = i2c_eeprom_read_byte(AT24C32, i + 204); } //lê a Sub-rede da EEPROM for (int i = 0; i < 4; i++) { subnet[i] = i2c_eeprom_read_byte(AT24C32, i + 208); } String Str_Servidor_NTP_Aux = ""; //lê o nome do Servidor NTP da EEPROM for (int i = end_Servidor_NTP; i < end_Servidor_NTP + tam_Servidor_NTP; i++) { aux = char(i2c_eeprom_read_byte(AT24C32, i)); if (!aux) { // para se for igual a 0, FIM do String Str_Servidor_NTP = Str_Servidor_NTP_Aux; break; } Str_Servidor_NTP_Aux += aux; // ntpServerName } Isto é parte do meu programa de sincronismo do DS3231. Todas as rotinas estão lá se eu esqueci de colocar alguma coisa. As bibliotecas para acessar a flash do ESP8266 como EEPROM, e trabalhar com número IP é: #include <EEPROM.h> // EEPROM virtual #include <IPAddress.h>
  5. Consegue 4km, mas só com duas boas antenas direcionais, e mesmo assim em campo aberto.
  6. Acho que você não tem como escapar de usar um on-line se quiser confiabilidade.
  7. @Papibakigrafo Tenho um destes mas ainda não testei (guardado na gaveta). Fico imaginando que seja possível, com um pouco de inteligência (muita na verdade) e uma programação competente, fazer um GPS off-line usando um destes para que o geo-posicionamento continue funcionando mesmo em ambientes internos em que o GPS não tenha sinal.
  8. Estou testando o ESP32, consegui compilar alguns exemplos com o Arduino IDE, mas parece que as bibliotecas para ele ainda estão um pouco pobres, por exemplo, as bibliotecas do ESP8266 como ESP8266HTTPClient.h, ESP8266WiFi.h, ESP8266WebServer.h, Tiker.h e outras não estão compilando (sendo aceitas pelo Arduino IDE compilando para ESP32), e até o momento não estou achando alternativas (imagino que devem existir para algumas sem que precise reescrever totalmente os programas). Acho que ainda tenho muito que aprender, mas como isto foi a minha primeira tentativa no ESP32, ainda tem muita água para rolar, e eu ainda nem entendo direito os exemplos.
  9. Eu errei na sintaxe do comando millis(), que é uma variável de 32 bits contadora de milissegundos, eu errei e escrevi miles() , mas não consigo mais editar o meu post anterior (já passou muito tempo). Será que um moderador não poderia editar o meu texto corrigindo isso para que não fique esta informação errada no Fórum ?
  10. @lucianolcoa Tem várias formas, abaixo tem um exemplo. miles() serve para mostrar um contador que é incrementado a cada milissegundo, ele não gera interrupção. Para definir uma interrupção por tempo usando a biblioteca Ticker.h (por exemplo) // Rotina bem básica #include <Ticker.h> // biblioteca de timers extern "C" { #include "user_interface.h" } uint32_t contador = 0; // contador de segundos (32 bits sem sinal) boolean flag = false; Ticker Alarme; // define timer void rotina() { contador++; // incrementa 1 no contador de segundos flag = true; // sinaliza interrupção } void Setup() { Serial.begin(115200); // define serial em 115200 bps Alarme.attach_ms(1000, rotina); // define interrupção e executa a cada 1000 milessegundos. } void loop() { if (flag) { Serial.println(String(contador)); flag = false; } }
  11. Isto que você está querendo seria bastante fácil para mim, tenho todas as rotinas necessárias no meu programa de calibração do DS3231, mas neste caso acho que você deveria fazer alguma coisa e escrever algum código. Você tem todas as rotinas auxiliares que eu tive muito trabalho para criar e depurar, agora fica tudo muito mais fácil para você ou qualquer um que queira fazer um programa de relógio ou timer com o ESP8266. E nem precisa de um RTC real, o próprio ESP8266 pode funcionar como um, com um contador 32 bits sem sinal incrementado por interrupção a cada segundo (por exemplo), que no caso do ESP8266 é bastante precisa (ele não perde interrupção nem quando está tentando conectar no WIFI). O cristal meu ESP de teste está com uma precisão de 6,7ppm. E caso falte energia ou ele seja desligado é só fazer uma consulta na Internet usando a rotina de acesso para um servidor NTP para atualizar a hora.
  12. O meu programa (passado a poucas linhas atrás) faz algo bem parecido, usando um DS3231, mas tem muitas rotinas úteis de cálculo de data e hora (para Arduino IDE) usando servidor NTP (no meu padrão de precisão). Tenho outras coisas que funcionam sem o RTC DS3231, mas para isso eu teria que procurar, e identificar o programa, o que eu não tenho tempo de fazer agora. No programa exemplo tenho todas as rotinas necessárias e testadas, (por exemplo, captura de data hora em servidor NTP com resolução em microssegundo).
  13. @lucianolcoa Tenho este código (ntp.lua). return({ hour=0, minute=0, second=0, lastsync=0, --*** microsec="", --*** ustamp=0, tz=-3, udptimer=2, udptimeout=1000, --ntpserver="194.109.22.18", ntpserver="139.82.34.44", -- servidor SNTP ntp.puc-rio.br --*** --sai_payload="", --*** sk=nil, sync=function(self,callback) local request=string.char( 227, 0, 6, 236, 0,0,0,0,0,0,0,0, 49, 78, 49, 52, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ) self.sk=net.createConnection(net.UDP, 0) self.sk:on("receive",function(sck,payload) sck:close() self.lastsync=self:calc_stamp(payload:sub(41,44)) --*** self.microsec=payload:sub(45,48) --self.sai_payload = payload --*** self:set_time() if callback and type(callback) == "function" then callback(self) end collectgarbage() collectgarbage() end) self.sk:connect(123,self.ntpserver) tmr.alarm(self.udptimer,self.udptimeout,0,function() self.sk:close() end) self.sk:send(request) end, calc_stamp=function(self,bytes) local highw,loww,ntpstamp highw = bytes:byte(1) * 256 + bytes:byte(2) loww = bytes:byte(3) * 256 + bytes:byte(4) ntpstamp=( highw * 65536 + loww ) + ( self.tz * 3600) -- NTP-stamp, seconds since 1.1.1900 self.ustamp=ntpstamp - 2208988800 -- UNIX-timestamp, seconds since 1.1.1970 return(self.ustamp) end, set_time=function(self) self.hour = self.ustamp % 86400 / 3600 self.minute = self.ustamp % 3600 / 60 self.second = self.ustamp % 60 end, show_time=function(self) return(string.format("%02u:%02u:%02u",self.hour,self.minute,self.second)) end, run=function(self,t,uinterval,sinterval,server) if server then self.ntpserver = server end self.lastsync = sinterval * 2 * -1 -- force sync on first run tmr.alarm(t,uinterval * 1000,1,function() self.ustamp = self.ustamp + uinterval self:set_time() if self.lastsync + sinterval < self.ustamp then self:sync() end end) end }) ntp-run.lua -- ntp-run.lua hora = 0 min = 0 seg = 0 cent = 0 dia = 1 mes = 1 ano = 2015 dsem = 1 lastsync = 0 ustamp = 0 ustamp_ant = 0 inicio = 0 function sincroniza() inicio = tmr.now() loadfile("ntp.lc")():sync(function(TIME) --*** cent = math.floor(string.byte(TIME.microsec,1) / 2.56) --*** print("hora = ".. TIME:show_time().. ",".. string.format("%02d", cent)) hora = math.floor(TIME.hour) min = math.floor(TIME.minute) seg = TIME.second --cent = 0 lastsync = TIME.lastsync ustamp = TIME.ustamp --sai_payload = TIME.sai_payload print(string.format("Tempo decorrido = %6f seg",(tmr.now() - inicio) / 1e6)) --print("Tamanho Payload = ".. string.len(sai_payload)) --**print("sai_payload (".. sai_payload.. ")") --file.open("arqpayload.txt","w+") --file.write(sai_payload) --file.flush() --file.close() TIME=nil package.loaded["ntp.lc"]=nil collectgarbage() collectgarbage() print((collectgarbage("count") * 1024).. "bytes node.heap() = ".. tostring(node.heap())) end) end sincroniza() -- Relógio tmr.alarm(4, 10, 1, function() if ustamp_ant ~= ustamp then if calend == nil then require("calend") end hora, min, seg, dsem, dia, mes, ano = calend.ustamp_dh(ustamp) ustamp_ant = ustamp end if cent < 99 then cent = cent + 1 else cent = 0 if seg < 59 then seg = seg + 1 if seg % 10 == 0 then sincroniza() end else seg = 0 if min < 59 then min = min + 1 else min = 0 if hora < 23 then hora = hora + 1 else hora = 0 dia, mes, ano = calend.incdia(1, dia, mes, ano) if dsem < 7 then dsem = dsem + 1 else dsem = 1 end --sincroniza() -- sincroniza às 0:00:00 end end end end end) tmr.alarm(5, 10, 1, function() if cent == 0 then tmr.stop(5) tmr.alarm(5, 1000, 1, function() if hora ~= "" then print(string.format("%02d:%02d:%02d,%02d ",hora, min, seg, cent).. calend.dsemana[dsem].. string.format(", %02d/%02d/%04d", dia, mes, ano)) if cent < 10 then print("lastsync = ".. tostring(lastsync).. " ustamp = ".. tostring(ustamp) .. " ".. (collectgarbage("count") * 1024).. "bytes node.heap() = ".. tostring(node.heap())) end end end) end end) TIME=nil package.loaded["ntp.lc"]=nil calend = nil package.loaded["calend"]=nil calend.lua -------------------------------------------------------------------------------- -- calend.lua -------------------------------------------------------------------------------- local moduleName = ... local M = {} _G[moduleName] = M M.meses = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} M.ndias = { 0, 31, 59, 90,120,151,181,212,243,273,304,334} M.dsemana = {"domingo", "segunda", "terça", "quarta", "quinta", "sexta", "sábado"} M.nomemes = {"janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho" , "agosto", "setembro", "outubro", "novembro", "dezembro"} -- é dia bissexto ? function M.bissexto(ent_ano) if (ent_ano % 4 == 0) and (ent_ano % 100 ~= 0 or ent_ano % 400 == 0) then return 1 else return 0 end end local function mes_bissexto(ent_mes, ent_ano) if ent_mes > 2 then return M.bissexto(ent_ano) else return 0 end end -- numero de dias de 01/01/0001 ate a data informada function M.numdias(ent_dia, ent_mes, ent_ano) ent_ano = ent_ano - 1 return math.floor(ent_ano / 4) - math.floor(ent_ano / 100) + math.floor(ent_ano / 400) + ent_ano * 365 + M.ndias[ent_mes] + mes_bissexto(ent_mes, ent_ano + 1) + ent_dia end -- diferenca entre datas (1. data - 2. data) function M.DiasEntreDatas(ent_dia1,ent_mes1,ent_ano1, ent_dia2,ent_mes2,ent_ano2) return M.numdias(ent_dia1, ent_mes1, ent_ano1) - M.numdias(ent_dia2, ent_mes2, ent_ano2) end -- dia da semana (1 para domingo) function M.diasemana(ent_dia, ent_mes, ent_ano) -- 04/01/1970 é domingo local saida = (M.DiasEntreDatas(ent_dia, ent_mes, ent_ano, 4, 1, 1970) ) % 7 if saida < 0 then saida = saida + 8 else saida = saida + 1 end return saida end -- incrementa uns poucos dias e calcula nova data function M.incdia(inc, ent_dia, ent_mes, ent_ano) ent_dia = ent_dia + inc local bissexto_aux = 0 if ent_mes == 2 then bissexto_aux = M.bissexto(ent_ano) end if ent_dia < 1 or ent_dia > M.meses[ent_mes] + bissexto_aux then if ent_dia < 1 then if ent_mes > 1 then ent_mes = ent_mes - 1 bissexto_aux = 0 if ent_mes == 2 then bissexto_aux = M.bissexto(ent_ano) end end_dia = M.meses[ent_mes] + bissexto_aux + ent_dia else ent_mes = 12 ent_ano = ent_ano - 1 ent_dia = M.meses[ent_mes] + ent_dia end else if ent_mes < 12 then ent_dia = ent_dia - (M.meses[ent_mes] + bissexto_aux) ent_mes = ent_mes + 1 else ent_ano = ent_ano + 1 ent_dia = ent_dia - M.meses[ent_mes] ent_mes = 1 end end end return ent_dia, ent_mes, ent_ano end -- converte ustamp (data de servidor SNTP da Internet) para data e hora function M.ustamp_dh(ent_ustamp) local num_dias = math.floor(ent_ustamp / 86400) local hora = math.floor(ent_ustamp % 86400 / 3600) local minuto = math.floor(ent_ustamp % 3600 / 60) local segundo = ent_ustamp % 60 local ano = math.floor(1970 + num_dias / 365.25) local mes = math.floor(math.floor(num_dias - (ano - 1970) * 365.25) / 30 + 1) if mes < 1 then mes = 12 ano = ano - 1 elseif mes > 12 then mes = 1 ano = ano + 1 end local dia = math.floor(num_dias - (ano - 1970) * 365.25 - M.ndias[mes] + 1) - mes_bissexto(mes, ano) if dia < 1 then mes = mes - 1 if mes < 1 then mes = 12 ano = ano - 1 end dia = M.meses[mes] if mes == 2 then dia = dia + M.bissexto(ano) end elseif (dia > M.meses[mes] and (mes ~= 2 or M.bissexto(ano) == 0)) or ((dia > M.meses[mes] + 1) and (mes == 2 and M.bissexto(ano) > 0)) then mes = mes + 1 if mes > 12 then mes = 1 ano = ano + 1 end dia = 1 end local num_dias2 = M.DiasEntreDatas(dia,mes,ano,1,1,1970) -- diferença de data e 01/01/1970 if num_dias ~= num_dias2 then dia, mes, ano = M.incdia(num_dias - num_dias2, dia, mes, ano) end return hora, minuto, segundo, M.diasemana(dia,mes,ano), dia, mes, ano end return M main.lua -- main.lua -- -- Connect print('\nAll About Circuits main.lua\n') tmr.alarm(0, 1000, 1, function() if wifi.sta.getip() == nil then print("Connecting to AP...\n") else ip, nm, gw=wifi.sta.getip() print("IP Info: \nIP Address: ",ip) print("Netmask: ",nm) print("Gateway Addr: ",gw,'\n') tmr.stop(0) end end) function pisca_led() lighton=0 pin=4 gpio.mode(pin,gpio.OUTPUT) repeat if cont == 100 then cont = 0 tmr.wdclr() -- reset system watchdog counter. else cont = cont + 1 end until (wifi.sta.getip() ~= nil) -- testa se conectou tmr.alarm(1,500,1,function() if lighton==0 then lighton=1 gpio.write(pin,gpio.HIGH) else lighton=0 gpio.write(pin,gpio.LOW) end end) end function modula_led() duty = 1023 -- LED apagado incr = -8 -- tem que ser divisor de 1000 para frenquência de 1Hz, 500 para 2Hz, 250 para 4Hz frequencia_led = 1 -- em Hz incr_2 = incr / (frequencia_led * 2) ciclo = math.abs(incr_2) -- período da interrupção em milesegundos (menor valor é 1 mseg) maximo = 1023 minimo = 23 frequencia = 1000 pin=4 pwm.setup(pin, frequencia, duty) pwm.start(pin) tmr.alarm(1,ciclo,1, function() if (duty >= maximo and incr > 0) or (duty <= minimo and incr < 0) then incr = 0 - incr incr_2 = 0 - incr_2 else duty = duty + incr end pwm.setduty(pin, duty) end) end function testa_rtc() tmr.alarm(2,10,1, function() contador = contador + 1 if cont == 99 then cont = 0 print(string.format("RTC = %.6f Contador = %.2f",((tmr.now()-tini)/1e6),contador/1e2)) else cont = cont + 1 end end) end modula_led() --pisca_led() contador = 0 cont = 0 tini = tmr.now() testa_rtc() init.lua -- init.lua -- function sincroniza() tini = tmr.now() --if rtctime.get() == 0 then sntp.sync(servidor_sntp, function(ustamp,usec,server) hora, min, seg, dsem, dia, mes, ano = calend.ustamp_dh(ustamp - 10800) print('sync '.. string.format("%02d:%02d:%02d,%06d ", hora, min, seg, usec).. calend.dsemana[dsem].. string.format(", %02d/%02d/%04d SNTP = (", dia, mes, ano).. server.. ")") print(string.format("Tempo decorrido = %6f Seg Tamanho ocupado = ",(tmr.now() - tini) / 1e6).. (collectgarbage("count") * 1024).. " bytes node.heap() = ".. tostring(node.heap())) end, function() print('failed!') end ) --end end -- Global Variables (Modify for your network) servidor_sntp = "139.82.34.44" -- servidor SNTP ntp.puc-rio.br ssid = "seu_WIFI" pass = "sua_Senha" -- Configure serial uart.setup( 0, 115200, 8, 0, 1, 1 ) -- Configure Wireless Internet print('\nAll About Circuits init.lua\n') wifi.setmode(wifi.STATION) print('set mode=STATION (mode='..wifi.getmode()..')\n') print('MAC Address: ',wifi.sta.getmac()) print('Chip ID: ',node.chipid()) print('Heap Size: ',node.heap(),'\n') -- wifi config start wifi.sta.config(ssid,pass) -- wifi config end if calend == nil then require("calend") end tmr.alarm(0,10,1,function() if wifi.sta.getip() ~= nil then sincroniza() tmr.stop(0) end end) --calend = nil --package.loaded["calend"]=nil -- Run the main file --dofile("main.lua") Estou um pouco enferrujado em lua (faz muito tempo que não programo nada), espero que tenha passado todos os programas (e bibliotecas) que faziam a consulta ao servidor NTP e implementavam um relógio no EDP8266 em lua.
  14. Eu cheguei a fazer algo parecido em LUA (antes de me desiludir com o LUA no ESP8266), se eu procurar talvez eu consiga achar alguma coisa, só não vou poder fazer isso agora, talvez a noite, se for isso que você precisa. Mas em C (IDE Arduino) ou Espbasic é só fazer um simples timer usando alguma variável incrementada por interrupção e acertando por servidor SNTP (já estou bem maceteado nisso).
  15. Terminei a minha versão final do programa para fazer a calibração do DS3231 (sincronizo usando uma interrupção pelo DS3231 para conseguir máxima precisão), e mais algumas coisas como acessar um BME280 mostrando o resultado por um LCD I2C 20 x 4. Consigo uma ótima precisão e não mais dependo da serial, a não ser para atualizar o programa, dá para fazer tudo pela página WEB. A página é bem simples mas funciona direito fornecendo todas as informações sobre a operação de sincronismo. O programa é bem didático, e até serve para avaliar a precisão do cristal do ESP8266, no que estou testando está em 6,7ppm (a precisão do DS3231 está em 0,05ppm depois de calibrado), em outra temperatura ambiente provavelmente deve ficar diferente, programei o DS3231 para disparar uma interrupção a cada segundo e a variável micros() é incrementada em exatos 999993,3 microssegundos com precisão cada vez, ela não está sujeita a atrasos ou outros fenômenos. A última versão está abaixo compilado pelo Arduino Ide versão 1.8.1 . Agora está na hora de partir para outra coisa, como por exemplo um variador de potência usando triac controlado pela rede wifi (celular e outros), vai dar trabalho e vou ter que aprender sobre estes protocolos que existem de comunicação, que vocês já dominam e eu ainda não entendo. Já estou com um kit com um ESP32 em mãos agora só falta um ambiente para experimentar programar o bicho. E quem sabe eu volte a tentar usar o Atom na programação. Não tive nenhum problema em colocar uma variável signed char (ou byte) na EEPROM e ler ela corretamente mesmo com números negativos, sem precisar de gambiarras. Teste3.zip
  16. @test man*~ Mesmo você não tendo usinado o robô ainda é um grande trabalho. Você não imagina como é complexo o projeto de um relógio daqueles (do vídeo no youtube), mesmo tendo todo o projeto pronto ainda é algo que exige muitas horas de trabalho e algumas máquinas bastante precisas, para usinar as engrenagens por exemplo (que é o mais complexo e não foi mostrado). Eu já trabalhei em industria mecânica e sei que não é uma coisa simples (muito pelo contrário). E ainda tem o problema que após ficar pronto (depois me muitas horas de trabalho) a última coisa que você vai querer é que as peças de latão (imagino que seja feito de latão) fiquem azuis, o que vai ser bem difícil com este nosso clima (o de Salvador é devastador), só se você encapsular e injetar nitrogênio, acho que eu iria pensar seriamente em fazer nisso, e isolar permanentemente da poeira, e ainda colocaria um bom e robusto vidro blindex duplo (para ser difícil de quebrar). Mas o bom mesmo é um relógio com o mecanismo de pesos pois a corda dura muito mais tempo e o mecanismo é muito mais robusto (foi um relógio desses de corda por peso que foi usado no primeiro atentado contra Hitler como mecanismo de detonação). Um relógio de pesos pode durar muito séculos em ótimas condições.
  17. Ficou realmente muito interessante, jeito e movimento de robô comercial. Como foi que você fez as conexões mecânicas? mandou cortar com laser ou foi de outra forma (jato de água por exemplo) ? Esta é realmente a parte mais complicada de montar um robô, bem mais até que o software (que dá muito trabalho mas é acessível), pois software não depende de equipamentos de alta precisão (e custo) para construir, só de esforço mental. Achei a montagem muito limpa, coisa bastante profissional, PARABÉNS ! Fiquei com inveja.
  18. 65535 e depois retorna a ZERO (agora estou em dúvida se esta variável não é um contador de 32 bits, pois se for o valor do retorno é o mesmo do micros() ). Você tem que testar se o valor anterior é maior que o atual e incrementar um contador quando isso acontecer. Pelo que eu saiba, esta ocorrência não gera nenhuma interrupção ou coisa parecida, o ideal é testar ela por uma interrupção ou a cada vez que você precisar ler o valor.
  19. Eu também tenho este problema, fica um pouco difícil ganhar em qualquer coisa sem jogar, e não jogo porque não acredito na sorte, pois estatisticamente quem joga já sai perdendo muito dinheiro, só quem ganha dinheiro de verdade com jogo é quem banca, os outros só perdem.
  20. Um CNC era um "brinquedo" que eu gostaria de ganhar de presente do "Papai Noel", mas infelizmente custa o preço de um carro (mesmo um bem simples já custa um bom dinheiro). No meu passado distante, no meu tempo de estudante universitário, eu aprendi a programar um equipamento destes. Na década de 80 já existiam estas máquinas (até antes disso), e eu fazia miséria com um torno CNC da Romi. Ele era uma máquina com um motor de corrente contínua de 10 CV cuja rotação era variada através de SCRs, era programado em fita perfurada e usava um processador 8086, que era um parente próximo dos processadores dos PCS atuais (na época não existiam os inversores, ou pelo menos não era uma coisa muito fácil de encontrar). Mas para ter um equipamento destes é necessário ter uma boa oficina, e só um torno não é o suficiente, um fresa CNC também é interessante, e depois uma máquina de eletroerosão, e indo mais longe uma máquina de corte por jato de água. Quando eu ganhar na megasena sozinho eu compro uns "brinquedos" destes.
  21. Está ficando interessante!
  22. Coincidência, os meus são assim mesmo. Os meninos e adolescentes de hoje em dia parecem que emburreceram, acho que é excesso de vídeo game, TV ou Facebook (ou até a qualidade do ensino que parece que está piorando muito). Fritaram o cérebro por completo. E eu que me acho bem pior profissionalmente do que meu pai (ele também era uma referência na área dele, muito difícil de superar ou igualar), mas parece que os meus talvez sejam piores do que eu, estamos andando para trás ao invés de evoluir.
  23. Pois é... Todo pai gostaria que os filhos seguissem os seus passos (e que façam melhor), alguns poucos tem a sorte de conseguirem, outros os filhos vão no caminho diferente. Os meus filhos não se interessam por eletrônica, e nem por controlador, matemática ou mecânica, às vezes eles nem parecem que são meus filhos de tão diferentes que eles são. Eu, meu pai e meus irmãos somos todos engenheiros mecânicos (eu sou o único que gosta também de programação e eletrônica), mas os meus filhos estão indo em caminhos diferentes, espero que melhor (mas tenho as minhas dúvidas). A única certeza que a gente tem é que não vai durar para sempre, e torce para que alguma coisa que a gente fez seja passada para frente, poucos tem esta sorte. Paulo talvez tenha conseguido deixar algum legado para sempre, que espero que ainda seja aperfeiçoado por ele mesmo.
  24. Não resolvi, mas também não gastei tempo suficiente para isso. E ter a opção do Arduino IDE acaba me livrando e tirando um pouco a motivação.

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!