LER DATA E HORA NO ARDUINO . Erro no código

Através de PHP, podes mandar dados do Arduino para uma base de dados.

PedroS23:
Mortis, experimentei o codigo que me deste, alterando apenas o long interval, que tinhas definido para 3 minutos, para 5 segundos!

Pedro,

Peço desculpas, mas me esqueci ne no arduino o incremento de variável não funciona dentro de uma função. Alterei o código colocando o incremento fora do if e coloquei o intervalo de 1 segundo para facilitar a visualização (na serial sairá após 5 segundos)

Corrigi também o tipo da variável previousMillis de long para unsigned long (a mesma do millis)

int PinAnalogA0 = 0;     //Sensor

unsigned long previousMillis = 0; // ultimo tempo de execução
long interval = 1000;  // intevalo de 1 segundo para cada amostragem

int samples[5]; //Array para guardar os samples
int curSample = 0; //Array para guardar o exemplo atual

void setup() {
  Serial.begin(9600); //Inicia a serial
  Serial.println("iniciado");
}

void loop() //loop infinito que nunca deve ser travado ;)
{
  unsigned long currentMillis = millis(); //pega o milesimo de segunto atual
  
  if(currentMillis - previousMillis >= interval) { //calcuta para saber se o intervalo desejado já ocorreu
    previousMillis = currentMillis;
    
    int total = 0;
    float media = 0;
    
    samples[curSample] = ( 5.0 * analogRead(PinAnalogA0)) / 1024;
    curSample++; //incrementa +1
    
    if(curSample >= 5){ //Já temos 5 amostrages (0 a 4), como 5*3=15 é tempo de notificar o pc
      curSample = 0; //zera o contador para reiniciar as amostragens (editado)
      for (int i=0; i<4; i++) //corre as amostragens 
        total += samples[i]; //soma na variável total
      
      media=total/5;//tira a média das amostragens
      
      Serial.print("Tensao="); //imprime o texto
      Serial.println(media);    //imprime o valor
    }
  }
}

Agora eu testei e a cada 5 segundos você terá "Tensao=#.##" na porta serial

Como o bubulindo postou, é possível, mas você precisa de um ethernet shield para conectar o arduino na rede.

Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.

media=total/5;//tira a média das amostragens

media é do tipo float , total é do tipo inteiro e 5 é um inteiro.Diz a lenda que dividir inteiro por inteiro resulta em um inteiro, logo aqui neste passo estas a perder valores porque estão a ser feitos arredondamentos.Solução faz um cast à variavel total ( float(total)/5 ) para ela ser tratada como um float no momento da conta.

Muito Obrigado! Vou testar amanhã :slight_smile:

Eu penso que é possível conetar-me diretamente sem ser necessário usar o Ethernet Shield, pois utilizo o Processing, e posso a partir do Processing, conetar-me ao servidor mySQL, pois coneto-me através do cabo USB.

Se quiserem podem consultar este exemplo que descobri à pouco, para quem não tenha conhecimento, ou compre sem ser sempre necessário fazê-lo:

No meu caso, talvez não venha a ser necessário, pois como estou a gravar os dados para um bloco de texto, eu faço o upload do mesmo para a base de dados, e depois apresento os dados numa tabela e posteriormente em gráficos!!

Amanhã colocarei aqui os resultados.

Outra questão, é possível colocar os valores de tensão a aparecer-me só com uma casa decimal?
em vez 0.00, ficar 0.0, arredondando??

Como no meu caso, a Tensão, vai corresponder a Temperatura, não faz muito sentido, ter valores de Temperatura com 2 casas decimais, visto que a mesma varia imenso e a casa correspondente à centésima iria estar sempre a alterar-se!!

Muito Obrigado pelas vossas respostas!

Estou a aprender imenso convosco e a explorar imenso as potencialidades do Arduino.

Bem hajam!

Abraços

Ok com o processing tambem dá.
Existe outra forma tambem facil usando o PHP a recolher directamente os dados da porta Serie do arduino.Depois e so criar a conecçao ao MySql e guardar la dentro.
O que vais usar para criar o grafico que falas?

Vê isto:

Muito Obrigado!!
É um exemplo muito bom, que amanhã irei ver com mais calma!!

Eu irei ter de criar gráficos diários, semanais, mensais e anuais.
Para isso, penso que a melhor ideia seria o utilizador ter dois calendários.
No primeiro escolhia a data início e no segundo a data fim. Se fosse a mesma era diário, da data 23/07/2013 00:00:0 até 24/07/2013 00:00:0, por exemplo. Em que aparecia as horas no eixo dos X, e a Temperatura no eixo dos Y.

Como o bloco de notas iria estar a ser atualizado e preenchido com os valores da temperatura de hora em hora, por exemplo, a mesma seria atualizada e preenchida nos gráficos também!!

Se escolhesse periodo de 7 até 30 dias, apresentava os dias da semana no eixo dos X, e a temperatura média de cada dia no eixo dos Y.
Se fosse meses, igual...

Eu queria mesmo era fazer algo identico a este exemplo:

Se alteraram a Ativity trend - last 30 days, para Date interval, podem obter os gráficos com a data de inicio e fim e ver os resultados que pretendem e as variações ao longo desse tempo todo.. era mesmo isso que eu queria...

Terei de fazer os mesmos em Html, mas principalmente PHP..

Sabem de algum site ou código que possa utilizar?
Sei que o google charts tem algo idêntico que possa utilizar!!

Depois juntamente a cada gráfico, queria apresentar numa pequena tabela lateral ou assim a Temperatura média, minima e maxima registada dentro desse intervalo de Data definidas!!

Em relação às casas decimais, eu sei que em linguagem C, eu fazia assim:
float f = 99.2253;
printf ( "%.2f",f );
e o resultado era 99.23, agora, não sei se no Arduino é igual visto nao ter usado a %. mas amanha irei experimentar também!!

Cumprimentos :slight_smile:

HugoPT:
Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.

media=total/5;//tira a média das amostragens

media é do tipo float , total é do tipo inteiro e 5 é um inteiro.Diz a lenda que dividir inteiro por inteiro resulta em um inteiro, logo aqui neste passo estas a perder valores porque estão a ser feitos arredondamentos.Solução faz um cast à variavel total ( float(total)/5 ) para ela ser tratada como um float no momento da conta.

Falha minha! Obrigado por corrigir! :slight_smile:

Pedro,

Não tenho conhecimentos em processing, apesar das linguagens serem parecidas (programo em c#), e nada sei de PHP :blush:. Mas estás no caminho certo, continue pesquisando e testando, é o melhor caminho para aprender. :wink:

Comentei do shield, pois tua pergunta foi "É possivel no Arduino, mandar diretamente o valor da tensao medida no momento exato para uma base de dados, para um localhost??" e diretamente, só com shield. Mas como estas a usar o processing, as possibilidades são quase infinitas ^^

Monitoro a temperatura de alguns datacenters com arduino + ethershield + DHT11 com a lib Agentuino para monitoramento pela rede via protocolo SNMP.

Uso o Centreon, é um frontend para o Nagios. Ele faz a leitura pela rede da temperatura e humidade e gera os gráficos. Configuro temperatura para warning (25oC) e para critical (28oC) e ele me manda email com o aviso.

Nos gráficos, posso selecionar o período, inclusive por horários:

Dá para fazer o Nagios ler o dado direto da serial, neste caso somente a temperatura, já que a data será do próprio computador.

Mortis:

HugoPT:
Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.

media=total/5;//tira a média das amostragens

media é do tipo float , total é do tipo inteiro e 5 é um inteiro.Diz a lenda que dividir inteiro por inteiro resulta em um inteiro, logo aqui neste passo estas a perder valores porque estão a ser feitos arredondamentos.Solução faz um cast à variavel total ( float(total)/5 ) para ela ser tratada como um float no momento da conta.

Falha minha! Obrigado por corrigir! :slight_smile:

No ciclo for:
for (int i=0; i<=4; i++) //corre as amostragens
faltava colocar o = a 4, porque assim só estava a fazer a média de 4 amostras!
ou colocava <5, ou <=4.
Reparei nisto pke a tensão que estava a ler era muito baixa, face ao que correspondia no Multimetro!!

Lago:
Monitoro a temperatura de alguns datacenters com arduino + ethershield + DHT11 com a lib Agentuino para monitoramento pela rede via protocolo SNMP.

Uso o Centreon, é um frontend para o Nagios. Ele faz a leitura pela rede da temperatura e humidade e gera os gráficos. Configuro temperatura para warning (25oC) e para critical (28oC) e ele me manda email com o aviso.

Nos gráficos, posso selecionar o período, inclusive por horários:

Dá para fazer o Nagios ler o dado direto da serial, neste caso somente a temperatura, já que a data será do próprio computador.

Lago, agradeco a tua resposta :slight_smile:

Mas como estou a desenvolver um projeto para uma empresa, não devo utilizar já softwares existentes, mas criar algo de raiz, de forma a corresponder ao que é exatamente pretendido por eles!!

O gráfico que dei como exemplo, na post acima, seria msm o ideal!!

Obrigado!!

Se ainda tiverem ideia como diminuir a casa decimal comuniquem!!

Cumps

Mortis, o código que forneceste, funciona perfeitamente :slight_smile:

Agora no Processing é k estou a ver que será mais dificil de contornar, pois como estou a gravar ao segundo 0, de cada minuto.
No Arduino definimos:

long interval = 1000; // intervalo de 1 segundo para cada amostragem

devolvendo posteriormente a média de 5 leituras de tensão, ele começa a ler os dados no segundo que comunico com o Arduino.

dessa forma grava-me por exemplo:

11:23:02
11:23:07
11.23:12, etc...

Se colocar no Processing, o codigo que tinha anteriormente:

if(second()==0)
output.println(year() + "/" + month() + "/" + day() + "\t" + hour() + ":" + minute() + ":" + second() + "\t" + sensorReading); // Escrever Data/Tempo e Tensao

Ele não grava, porque não acertei no segundo 0 ( ou 5)...

Queria tentar fazer a média na mesma, mas que grava-se no segundo 0, talvez um pouco mais dificil de contornar essa forma..

Alguma sugestão??

Ha uma coisa que me esta a fazer confusão.Que sensor estas a usar para leres a temperatura?
Se queres ler temperatura para que estares a fazer media?
Por acaso o teu sensor e assim tão impreciso para teres de achar a media?
Lembro me de uma vez usar um LM35dz que e analógico e também tinha de andar a fazer medias devido a variação.
A minha solução foi desistir dele e usar sensores one-wire DS18B20 que são uma maravilha no que toca a precisão.

PedroS23:
(...)ele começa a ler os dados no segundo que comunico com o Arduino.

dessa forma grava-me por exemplo:

11:23:02
11:23:07
11.23:12, etc...

Pedro,

Coloquei um segundo para efeito de teste, por isso ele dispara a cada cinco segundos. Você pode alterar o intervalo para 3 minutos, e o disparo ocorrerá em intervalos de 15 minutos como você pretendia, recebendo no processing a "notificação do arduino" nesse intervalo de tempo.

É possível fazer como o bubulindo sugeriu e o processing fazer a requisição ao arduino.

no lugar de:

if(curSample >= 5){ //Já temos 5 amostrages (0 a 4), como 5*3=15 é tempo de notificar o pc
      curSample = 0; //zera o contador para reiniciar as amostragens (editado)
      for (int i=0; i<4; i++) //corre as amostragens 
        total += samples[i]; //soma na variável total
      
      media=total/5;//tira a média das amostragens
      
      Serial.print("Tensao="); //imprime o texto
      Serial.println(media);    //imprime o valor
    }

você pode usar:

   if(curSample >= 5){ //Já temos 5 amostrages (0 a 4), como 5*3=15 é tempo de notificar o pc
      curSample = 0; //zera o contador para reiniciar as amostragens (editado)
      for (int i=0; i<4; i++) //corre as amostragens 
        total += samples[i]; //soma na variável total
      
      media=total/5;//tira a média das amostragens
    }
   //Código do bubulindo
   if (Serial.available() >0) {
     if (Serial.read() == 'M') {   
      Serial.print("Tensao="); //imprime o texto
      Serial.println(media);    //imprime o valor    
     }
   }

No processing você pode usar um Timer (creio que exista algo do tipo) que dispare um evento a cada 15 minutos (e segundo zero) e neste evento enviar para o arduino o char 'M', o arduino devolverá a última média gravada. Como já falei não sei sobre processing, em uma busca rápida encontrei isso: Google Code Archive - Long-term storage for Google Code Project Hosting. não sei se te serve, procura um pouco que tu encontras.

Para hora-minuto-segundo especifico, no programa do arduino precisas voltar alguns posts (a lib para sincronizar com o PC ou usar um RTC).

PedroS23:
Se colocar no Processing, o codigo que tinha anteriormente:

if(second()==0)

output.println(year() + "/" + month() + "/" + day() + "\t" + hour() + ":" + minute() + ":" + second() + "\t" + sensorReading); // Escrever Data/Tempo e Tensao

Pura e simples lógica, pensa um pouco e logo verás os porquês. Não é tão obscuro assim :wink:

O circuito que eu fiz é o da imagem em baixo e utilizei um térmistor NTC:

Eu posso definir o minuto e segundo que quero gravar, a questão é mesmo como gravar no tempo exato...

Por exemplo, se mandar a letra M, do Processing para o Arduino, sempre que seconds()==0, ele imprime então a média gravada até esse momento correto???

Então, segundo o link que colocou deve ser enquadrado neste exemplo:

void keyReleased() {
  if (key == 'M') {
    // Turn the ellipseTimedEventGenerator on and off.
    ellipseTimedEventGenerator.setEnabled(
        !ellipseTimedEventGenerator.isEnabled());

Talvez fazendo:

 void keyReleased() {
if (key=='M' && second()==0) {
output.println(year() + "/" + month() + "/" + day() + "\t" + hour() + ":" + minute() + ":" + second() + "\t" + sensorReading); // Escrever Data/Tempo e Tensao
}

aqui a questão é mesmo testar, porque não é pretendido que o utilizador tenha de clicar em alguma tecla para gravar dados...
vou experimentar!!

Obrigado!!! :slight_smile:

Pedro
Eu se estivesse a fazer esse projecto NUNCA iria usar um termistor para obter a temperatura
O fazeres a media para veres valores mais certos é um remendo...
Vai por mim desiste dele e arranja um onewire

HugoPT:
Pedro
Eu se estivesse a fazer esse projecto NUNCA iria usar um termistor para obter a temperatura
O fazeres a media para veres valores mais certos é um remendo...
Vai por mim desiste dele e arranja um onewire

A precisão do mesmo é aumentada pois o circuito tem e irá mesmo ser calibrado!!
Irei construir uma reta de calibração com o mesmo, em que a determinada tensão sei qual será a temperatura lida e vice-versa!!
Foi algo que aprendi nas aulas de instrumentação do meu curso.
Por exemplo,

T(ºC) = 0.3*tensao^3 + 4.3*tensao^2 + 0.23*tensao + 13

Essa formula será colocada no Arduino.

E sabendo o valor da tensao, sabes a Temperatura.

No caso do Arduino que trabalha de 0 a 5V apenas, e precisando de trabalhar, neste projeto, numa gama de valores de 17 a 33ºC, irei fazer da seguinte forma:

25ºC = 2.5V
25ºC + 8 = 33ºC = 5.0V
25ºC - 8 = 17ºC = 0V

Para isso precisas de ter um ambiente de temperatura muito controlado para saber a temperatura que estará exatamente no local do termistor, que no meu caso eu tenho!! :slight_smile:

Bom se tu assim queres.
No entanto passa só os olhos e vê a simplicidade do circuito do DS18B20 e vê o codigo que necessitas para ler a temperatura.
http://www.hobbytronics.co.uk/ds18b20-arduino
Com isto não necessitas de médias, calibração ,circuitos adicionais para correção, linearidade do sensor e SIMPLICIDADE no código. Também tem uma fiabilidade que duvido que iras atingir com tudo isso.
Este sensor one-wire tem a resolução do ADC dele configurável podendo ir ate 12 bits.Super preciso e nao tens perdas na transmissão.Apenas necessitas de 2 fios no modo parasita
Na altura que usei o LM35DZ como tu estas a fazer recorrendo a medias para alisar o resultado final , confrontando o resultado obtido com outro termômetro havia discrepâncias.
Sabendo isto queres construir um sistema de monitorização que logo de inicio tens de andar a recorrer a medias para teres valores estáveis?
Vais poder confiar nessas leituras?
Tu com este sensor apenas tens de o invocar com o tempo que queres correndo a simples funcao sensors.getTempCByIndex(0); em vez de todo o código que tens + correção dos valores ....
Acredita que não vale a pena.
O preço do sensor e super barato.

No caso do Arduino que trabalha de 0 a 5V apenas, e precisando de trabalhar, neste projeto, numa gama de valores de 17 a 33ºC, irei fazer da seguinte forma:

25ºC = 2.5V
25ºC + 8 = 33ºC = 5.0V
25ºC - 8 = 17ºC = 0V

Que sistema e esse que logo de inicio tens valores "ideais". O mundo real as vezes prega partidas ...
O que esperas acontecer se a temperatura andar abaixo dos 17c e superior aos 33?

Algumas alternativas para o sensor:
http://www.squidoo.com/arduino-temperature-sensors

@Hugo,

Para alguém dum mestrado de instrumentação e medidas apresentar um projecto com um DS18B20 (embora bom do ponto de vista eléctrico) seria, na minha opinião, merecedor dum zero.

Creio que o interesse aqui é mesmo trabalhar com o sensor e apresentar como fazer a calibração do mesmo. Da mesma forma que é temperatura, poderia ser outra coisa qualquer.

Do mal o menos, de todos os sensores escolhidos, o NTC não é dos piores. Imagina se era um PTC... LOL

@Pedro, como medes a influência dos erros de arredondamento do microprocessador no erro global do sistema?
Como sabes que a curva desse sensor é de ordem três?