Boas,
No projecto que tou a elaborar gostava de ter uma informação da soma de horas de funcionamento de uma bomba ou seja o tempo total em horas em que o rele esteve em high...
Cumprimentos
Boas,
No projecto que tou a elaborar gostava de ter uma informação da soma de horas de funcionamento de uma bomba ou seja o tempo total em horas em que o rele esteve em high...
Cumprimentos
Podes usar o millis... Ou um rtc.
Quando o rele passa a high, guardas o valor do millis. Quando passa a low, guardas esse valor.
Um menos o outro a dividir por 1000 dá-te um numero em segundos e daí calculas horas. Convém ter em atenção se o relé vai estar ligado durante mais de uns dias, mas dee ser pacifico.
Um menos o outro a dividir por 1000 dá-te um numero em segundos e daí calculas horas.
A uns tempos num programa que tambem necessitava de algo semelhante fiz assim:
#define MILISECONDS_IN_DAY 86400000UL // 86400000 milliseconds in a day
#define MILISECONDS_IN_HOUR 3600000UL // 3600000 milliseconds in an hour
#define MILISECONDS_IN_MINUTE 60000UL // 60000 milliseconds in a minute
#define MILISECONDS_IN_SECOND 1000UL // 1000 milliseconds in a second
// o teu programa ...
void printTime(long val)
{
uint8_t days = val / MILISECONDS_IN_DAY ;
uint8_t hours = (val % MILISECONDS_IN_DAY) / MILISECONDS_IN_HOUR;
uint8_t minutes = ((val % MILISECONDS_IN_DAY) % MILISECONDS_IN_HOUR) / MILISECONDS_IN_MINUTE ;
uint8_t seconds = (((val % MILISECONDS_IN_DAY) % MILISECONDS_IN_HOUR) % MILISECONDS_IN_MINUTE) / MILISECONDS_IN_SECOND;
// digital clock display of current time
Serial.print(days,DEC);
printDigits(hours);
printDigits(minutes);
printDigits(seconds);
Serial.println();
}
void printDigits(byte digits){
// utility function for digital clock display: prints colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits,DEC);
}
Obtento o numero de segundos com a funçao millis() , passas esse valor na funçao printTime() e sera impresso na consola na forma de tempo 00:00:00
tecnisol:
Boas,No projecto que tou a elaborar gostava de ter uma informação da soma de horas de funcionamento de uma bomba ou seja o tempo total em horas em que o rele esteve em high...
Cumprimentos
Não estou a perceber. Isto é um contador com o numero de horas da última (ou actual se a bomba ainda estiver ligada), ou é a utilização desde sempre?
Qualquer que seja a resposta, a implementação é a sugerida nos outros dois posts, mas se for desde sempre, vai ter que ir guardando o valor, por exemplo, na EEPROM.
Isto quer dizer que a questão dos sensores de temperatura está resolvida?
boas,
Luis,
Um das minhas duvidas é a que tu perguntaste pois necessito que guarde os valores para q dê a soma desde o 1º dia da instalação por dai em diante...
Em relação as sondas ando a espera de receber material para fazer uma board nova e testar c novo material...
Assim que tiver tudo pronto volto a mencionar o anterior topico tb ando a ponderar colocar 2 arduino a comunicar um com o outro assim resolveria o problema das sondas tb.
Se utilizar o RTC como o Bubulino refere não será a melhor opção?
Hugo,
O programa q referes é para usar com um RTC?
Ainda não tenho os codigos para usar o RTC que recebi hoje
OK. O programa do HugoPT, praticamente, implementa um RTC através da função millis(). A vantagem do RTC é que normalmente, funciona com uma pilha externa que permite manter a data e hora certas, mesmo depois de uma fala de energia. Outra vantagem do RTC é que ao contrário do contador de milissegundo, sabe-se que chega a zero à meia-noite. O contador de milissegundo, também chega a zero, mas não se sabe quando (ou melhor, não é todos os dias à mesma hora) e assim, o código vai ter que verificar constantemente, se o contador já chegou (ou ultrapassou, desde a última verificação) o zero e se sim, actuar em conformidade. Por estas razões, penso que talvez seja mais fácil implementar a sua aplicação com RTC. A partir daí quando liga o relé deve guardar a data e hora (atenção que se ao passar da meia-noite o relé estiver activo o programa deve saber e deve conseguir fazer os cálculos, por isso, penso que deve ser melhor guardar a data também) e quando desliga o relé, deve guardar também os valores, fazer os cálculos do tempo que o relé esteve activo e deve guardar o valor do "tempo acumulado" em memória não volátil (EEPROM). Normalmente os módulos RTC trazem também (na mesma placa) uma memória EEPROM.
Eu tenho por aqui um par deles igual a esse. Não é grande coisa (desacerta bastante), mas por esse preço, também não se pode pedir muito mais. Se não precisar de muita precisão (e não houver problema em perder um par de minutos por mês) é suficiente. Esse é uma das tais placas que já trazem uma memória EEPROM incorporada (é o chip AT24C32 - que se vê na descrição). O RTC propriamente dito é o DS1307. É fácil encontrar na net exemplos de código para fazer esse RTC funcionar.
Encontrei este codigo mas ainda n testei
//Arduino 1.0+ Only
//Arduino 1.0+ Only
#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527
void setup(){
Wire.begin();
Serial.begin(9600);
setDateTime(); //MUST CONFIGURE IN FUNCTION
}
void loop(){
printDate();
delay(1000);
}
void setDateTime(){
byte second = 45; //0-59
byte minute = 40; //0-59
byte hour = 0; //0-23
byte weekDay = 2; //1-7
byte monthDay = 1; //1-31
byte month = 3; //1-12
byte year = 11; //0-99
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(zero); //stop Oscillator
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(weekDay));
Wire.write(decToBcd(monthDay));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.write(zero); //start
Wire.endTransmission();
}
byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}
void printDate(){
// Reset the register pointer
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(zero);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
int second = bcdToDec(Wire.read());
int minute = bcdToDec(Wire.read());
int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
int monthDay = bcdToDec(Wire.read());
int month = bcdToDec(Wire.read());
int year = bcdToDec(Wire.read());
//print the date EG 3/1/11 23:59:59
Serial.print(month);
Serial.print("/");
Serial.print(monthDay);
Serial.print("/");
Serial.print(year);
Serial.print(" ");
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
}
mas tb encontrei muita coisa a falar o que referes qual seria a melhor opção RTC para n vir a ter problemas no futuro?
Não gosto desse código! Pela simples razão que não usa uma biblioteca para implementar as funções de comunicação com o RTC. O que isso vai originar é uma de duas coisas:
Há várias bibliotecas que implementam a comunicação com esse RTC e que têm tudo o que é necessário. Se pesquisar nesta secção do fórum, vai encontrar muita informação sobre esse tema, pois já foi várias vezes discutido nos últimos meses.
Em relação a qual é o melhor RTC, não sei dizer de cabeça. Teria que ir pesquisar os vários módulos RTC que existem e ver as características deles. Normalmente os que falam de "compensação de temperatura" são muito superiores aos outros. No entanto, penso que esse que tem dá perfeitamente para começar e fazer algo minimamente funcional.
OK vou fazer novas buscas e encontrar outros codigos
O rtc não é necessariamente mais preciso ou melhor.
O ds1307 costuma desviar bastante por dia também. O ds1307 não garante que as leituras são guardadas em caso de falha de energia.
Logo a não ser que o rtc seja usado para mais alguma coisa ou o processador tenha algo que interfira com o millis, não me parece que seja melhor.
Mas isto depende do sistema como um todo.
Bubulino,
fazendo da forma q referes perde a memoria os o n de horas se ficar sem corrente electrica certo? eu ja fiz o teste e no meu caso perdeu a contagem e pretendia algo que mantesse a soma total mesmo com falta de corrente.
O facto de perder a contagem não está relacionado com a forma como é feita a contagem do tempo, mas sim com o local onde é armazenada essa contagem. No caso, para que a contagem não seja perdida tem que ser armazenada na EEPROM.
Pode procurar alguns exemplos na net sobre esse assunto. Aqui no site estão estes dois exemplos (um programa escreve e o outro lê):
Mesmoi Assim tou a ter problema e não estou a ver o porque, quero q comece a contar quando o diferencial for 7ºC e pare de contar aos 3ªC mas o que acontece com este codigo é: começa logo a contar depois para de contar quando for superior a 5ºC e volta a contar abaixo dos 3.
Acerca do Eprom como posso juntar a este codigo? não o estou a entender bem.
// Load RTD library and create new instance
//----------------------------------------------------------------------------
#include <Wire.h>
#include "RTDModule.h"
RTDModule rtd;
String SB1;
int Rele1 = 6;
//----------------------------------------------------------------------------
// Temperature variables
//----------------------------------------------------------------------------
double CYLB,CYLT,COL;
double Sen1 = 0;
double Sen2 = 0;
int Dif1=0;
unsigned char flagHIGH=0;
unsigned long temp1;
unsigned long temp2;
unsigned long tempHL;
//----------------------------------------------------------------------------
// Setup
//----------------------------------------------------------------------------
void setup()
{
rtd.setPins(4,5,2); //RTD PT1000 pins 4,5 are digital pins for multiplexer, 2 is analog input
//rtd.calibration( input number, scaler, offset )
rtd.calibration(0, 0.120270927, -15.066198679); //INPUT 0 pin 12
rtd.calibration(1, 0.120821076, -13.824162893); //INPUT 1 pin 14
rtd.calibration(2, 0.120400012, -14.91327759); //INPUT 2 pin 15
analogReference(INTERNAL); //Set reference to 1.1V ready for RTD measurements
Serial.begin(9600);
pinMode (6, OUTPUT);
}
//----------------------------------------------------------------------------
// Main loop
//----------------------------------------------------------------------------
void loop()
{
delay(1000);
//Get temperatures and pass through digital low pass filter
COL = digitalLowPass(COL, rtd.getTemperature(0) ,0.90);
CYLB = digitalLowPass(CYLB, rtd.getTemperature(1) ,0.90);
CYLT = digitalLowPass(CYLT, rtd.getTemperature(2) ,0.90);
//Print temperatures out to serial
Serial.print ("Sensor 1: ");
Serial.println(COL);
Serial.print("Sensor 2: ");
Serial.println(CYLB);
//Serial.print("Sensor 2: ");
//Serial.println(CYLT);
lcd.clear();
Sen1=COL;
Sen2=CYLB;
Dif1=int(Sen1-Sen2);
if(Dif1 <= 3){Bomba1_Off();}else if (Dif1 >=7){Bomba1_On();}
Displaybomba();
}
void Bomba1_On(){
digitalWrite(Rele1, LOW);
SB1="ON";
temp1=millis();
flagHIGH=1;
}
void Bomba1_Off(){
digitalWrite(Rele1, HIGH);
SB1="OFF";
temp2=millis();
tempHL=(temp2-temp1)/1000;
flagHIGH=0;
Serial.println(tempHL);
}
//----------------------------------------------------------------------------
//Digital low pass filter
double digitalLowPass(double last_smoothed, double new_value, double filterVal)
{
double smoothed = (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
return smoothed;
}
Como sabes a que temperaturas liga e desliga?
Estas a fazer print das temperaturas e do diferencial para confirmar o que estas a dizer?
Consegues simular as temperaturas com alguma precisao de forma a que a activacao da bomba nao interfira com as leituras?
Bubulino sim tou a fazer o print das leituras e o que vejo n me esta a dar o que pretendo possivelmente porque tou a fazer algo errado dai colocar aqui o codigo
Ok... mas sem vermos algo mais, não é fácil de detectar o que se passa.
Os prints que eu vejo são sim das temperaturas, mas a bomba liga e desliga com base no diferencial. Estás a imprimir o diferencial? Isso não aparece no código que colocaste, daí estar a perguntar.
Estás a fazer isto com temperatura ou com resistências de modo a poderes simular?
Este bocado de código tem coisas que podem causar coisas estranhas.
//isto está aqui a mais, podes fazer a conta com as variáveis COL e CYLB.
Sen1=COL;
Sen2=CYLB;
Dif1=int(Sen1-Sen2);
Serial.println(Dif1); // faz um print aqui...
if(Dif1 <= 3)
Bomba1_Off();
if (Dif1 >=7)
Bomba1_On();
Pode também ser o filtro, mas sem saber como estás a simular as temperaturas é impossível de ter a certeza.
sim tens razao vou verificar tudo eu so tou a fazer o print das temperaturas n dos diferenciais mas vou analizar depois informo obrigado