Go Down

Topic: LER DATA E HORA NO ARDUINO . Erro no código (Read 14 times) previous topic - next topic

PedroS23

Muito Obrigado!
Neste momento não estou no laboratorio a desenvolver o projeto, na próxima 2ª feira irei de manha para o mesmo e posteriormente irei colocar aqui os resultados que irei obter!!

Se entretando se lembrarem de mais alguma coisa não hesitem em mencionar!!

Muito Obrigado, e aproveito para desejar um bom fim de semana a todos!!

Um abraço!

Mortis

As vezes tentamos apenas visualizar (imaginar) funcionarão as coisas, mas fazendo e testando é mais fácil de ver os resultados e fazer as mudanças que se mostrarem necessárias.

Um bom final de semana!  :D

PedroS23

Olá Pessoal!!
Espero que tenham passado um bom fim de semana!!

Mortis, experimentei o codigo que me deste, alterando apenas o long interval, que tinhas definido para 3 minutos, para 5segundos!
Não consegui visualizar no Serial Monitor o valor da tensão, fechei o ciclo for primeiro e depois imprimi, mas a tensão era sempre 0V, o que não poderia ser!!

Estou a pensar deixar o meu código desta forma:

Code: [Select]
int PinAnalogA0 = 0;
float valAnalog=0;  // Coloca o Pino A0 a 0
int redPin=13; //Led Vermelho - Porta 13
int yellowPin=12; //Led Vermelho - Porta 12
int greenPin=11; //Led Vermelho - Porta 11

float temp = 0; // Variavel tensao a zero
float maxi=0, mini=1000000; //Definir valor min e max
// int samples[4]; // variavel para melhor exatidão


void setup() // função executada apenas uma vez, sendo de preparação
{
  Serial.begin(9600);  // abre a porta série, define a taxa de transmissão para 9600 bps
 
    pinMode(redPin, OUTPUT);  // Saida do LED Vermelho
    pinMode(yellowPin, OUTPUT);  // Saída do LED Amarelo
    pinMode(greenPin, OUTPUT);    // Saída do LED Verde
}

void loop () // Código a ser executado - Leitura de entradas provocando saidas
{
    valAnalog = analogRead(PinAnalogA0); // Leitura do Pino Analógico do Arduino - A0
    temp = (valAnalog * 5.0) /1024; // Leitura do valor da Tensão = valor *5V /1024 bites
   
    if(temp > maxi)
    {
      maxi = temp;
    } // regista temperatura maxima
   
    if(temp < mini)
    {
      mini = temp;
    } // regista temperatura minima

    if(temp > 4.5)
    {
      digitalWrite(redPin, HIGH);   // coloca LED Vermelho ON
      digitalWrite(greenPin, LOW);
      digitalWrite(yellowPin, LOW);           
    }
   
    if(temp <= 1.0)
    {
      digitalWrite(yellowPin, HIGH); // Coloca LED Amarelo ON
      digitalWrite(redPin, LOW);   
      digitalWrite(greenPin, LOW);
    }

    if(temp > 1.0 && temp <= 4.5)
    {
      digitalWrite(greenPin, HIGH); // Coloca o LED Verde ON
      digitalWrite(redPin, LOW);   
      digitalWrite(yellowPin, LOW);
    }

    Serial.print("  Tensao = " );
    Serial.print(temp);
    Serial.print(" || Tensao min= " );
    Serial.print(mini);
    Serial.print(" || Tensao max= " );
    Serial.print(maxi);
    Serial.println("");
 
    delay(1000);
}



No processing, estou a apresentar numa janela a tensão a atualizar a tensao medida no canal A0, ou seja, de 1 em 1 segundo, e coloquei o código:

Code: [Select]
if(second()==0 || second()==15 || second()==30 || second()==45)

e estou a conseguir gravar nesses precisos segundos!!

Queria era msm implementar o tal ciclo para fazer a média das medições, como tinhas-me mencionado no código anterior!!!

É possivel no Arduino, mandar diretamente o valor da tensao medida no momento exato para uma base de dados, para um localhost??

bubulindo

Através de PHP, podes mandar dados do Arduino para uma base de dados.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Mortis


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)

Code: [Select]

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.

HugoPT

Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.
Code: [Select]
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.

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

PedroS23

Muito Obrigado! Vou testar amanhã :)

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:
http://esperimenti-arduino.blogspot.pt/p/processing-mysql.html

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

HugoPT

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:
http://blog.bsoares.com.br/php/controlling-arduino-with-php
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

PedroS23

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:
http://forum.processing.org/user/philho
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  :)

Mortis


Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.
Code: [Select]
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!  :)

Mortis

Pedro,

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

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

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.


PedroS23



Ola camaradas.
Uma possível perda de fiabilidade no teu codigo.
Code: [Select]
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!  :)


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

PedroS23


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  :)

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

PedroS23

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

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:

Quote
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:

Code: [Select]

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

Go Up