#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8 //ds18s20
#define data 2 //data 74hc164
#define clock 3 //clock 74hc164
#define set1 4 //7segment 1 l
#define set2 5 //7segment 2 c
#define set3 6 //7segment3 r4z5i
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
// bit por led
byte zero = B01111110;
byte one = B00000110;
byte two = B11011010;
byte three = B11010110;
byte four = B10100110;
byte five = B11110100;
byte six = B11111100;
byte seven = B01000110;
byte eight = B11111110;
byte nine = B11110110;
byte space = B00000000;
byte h = B10101110;
byte e = B11111000;
byte l = B00111000;
int a=0;
int b= 0;
int c;
byte digit[3];
//char tempo=0;
byte var;
char i;
void setup()
{
sensors.begin();
pinMode(clock, OUTPUT); // clock pin output
pinMode(data , OUTPUT); // data pin output3
pinMode(set1, OUTPUT);
pinMode(set2, OUTPUT);
pinMode(set3, OUTPUT);
}
void loop()
{
sensors.requestTemperatures(); // Send the command to get temperatures
a=sensors.getTempCByIndex(0);
for(i=0;i<100;i++){ //para ver o tempo
rot(a);
}
}
void rot (int a){
c=a;
digit[2] = c % 10;
digit[1] = (c / 10) % 10;
digit[0] = (c/ 100) % 10;
for(byte d=0;d<3;d++){
digit[d]=caso(digit[d]);
}
seg(digit[0],digit[1],digit[2]);
//delay(1);
}
byte caso(byte test){
switch (test){
case 0:
return zero;
break;
case 1:
return one;
break;
case 2:
return two;
break;
case 3:
return three;
break;
case 4:
return four;
break;
case 5:
return five;
break;
case 6:
return six;
break;
case 7:
return seven;
break;
case 8:
return eight;
break;
case 9:
return nine;
break;
}
}
void seg(byte un,byte dos, byte tres){
digitalWrite(set1,HIGH);
digitalWrite(set2, LOW); //Primeiro Segmento
digitalWrite(set3, LOW);
shiftOut(data, clock, LSBFIRST, un);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, HIGH); //Segundo segmeto
digitalWrite(set3, LOW);
shiftOut(data, clock, LSBFIRST, dos);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, LOW); //terceiro segmento
digitalWrite(set3, HIGH);
shiftOut(data, clock, LSBFIRST, tres);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, LOW); //se atrasar nenhum acende, e o inverso no que dará, ficara o valor antigo ?
digitalWrite(set3, LOW);
}
unsigned long currentMillis = millis();
if(b==0){
sensors.requestTemperatures();
b=1;
} /// Send the command to get temperatures //0.75s para obter
}
if(b==1){
if(currentMillis- pretime > time){
pretime = currentMillis;
a=sensors.getTempCByIndex(0); //*enquanto não obter bloqueia.
b=0;
}
****
Inicialmente :void DallasTemperature::requestTemperatures(void)
{
_wire->reset();
_wire->skip();
_wire->write(STARTCONVO, parasite);
switch (conversionDelay)
{
case TEMP_9_BIT:
delay(94);
break;
case TEMP_10_BIT:
delay(188);
break;
case TEMP_11_BIT:
delay(375);
break;
case TEMP_12_BIT:
default:
delay(750);
break;
}
}
{
if(b==0){
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
b=1;
} /// Send the command to get temperatures //0.75s para obter
if(b==1){
if(currentMillis- pretime > time){
pretime = currentMillis;
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++){ // we need 9 bytes
data[i] = ds.read();
}
//
// Parte da conversão que falta
//
a=...; //a temperatura
}
}
b=0;
rot(a);
}
Mais uma vez agradeço ajuda, o que é certo é que se o display tive-se buffer podia "esquecer" este problema, mas neste caso, quero tentar dar-lhe a volta..
void DallasTemperature::requestTemperatures(void)
{
_wire->reset();
_wire->skip();
_wire->write(STARTCONVO, parasite);
}
@ Asena:Mais uma vez agradeço ajuda, o que é certo é que se o display tive-se buffer podia "esquecer" este problema, mas neste caso, quero tentar dar-lhe a volta..
O que queres dizer com o display ter buffer? qual o sentido?
Os buffers podem ser criados no micro. O CPU é o micro, o resto são periféricos.
O teu problema é que o teu display é actualizado consoante o código e não tens nenhuma base de tempo fixa, se meteres um timer a gerar um interrupt para um refrescamento ai de 25-30Hz e a fazeres a actualização dos displays dentro do interrupt gerado pelo timer não interessava se o sensor demora-se 1ms ou 1h a ler.@senso, sim tal era uma maneira, mas se não tou enganado não ia a interrupção tornar mais lenta ainda a leitura? certo é que apesar de ser rapido o ciclo de escrita parao display ainda ia consumir o seu tempo :-\
O teu problema é facilimo de resolver. Só tens que partir o método requestTemperatures(void) em 2, mandar fora a 2ª parte,@Njay, ve-la que passou-me completamente ao lado, estava tão focado em procurar alternativa simples, que nem me apercebi disso (Exames queimam-me o tiko e o teko).
...
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8 //ds18s20
#define data 2 //data 74hc164
#define clock 3 //clock 74hc164
#define set1 4 //7segment 1 l
#define set2 5 //7segment 2 c
#define set3 6 //7segment3 r4z5i
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
// bit por led
byte zero = B01111110;
byte one = B00000110;
byte two = B11011010;
byte three = B11010110;
byte four = B10100110;
byte five = B11110100;
byte six = B11111100;
byte seven = B01000110;
byte eight = B11111110;
byte nine = B11110110;
byte space = B00000000;
byte h = B10101110;
byte e = B11111000;
byte l = B00111000;
int a=0;
int b= 0;
int c;
byte digit[3];
//char tempo=0;
byte var;
char i;
unsigned int time=2000; //se quisserem alterar o tempo entre medições deve ser >0.75seg
unsigned long pretime=0;
unsigned long currentMillis;
void setup()
{
sensors.begin();
pinMode(clock, OUTPUT); // clock pin output
pinMode(data , OUTPUT); // data pin output3
pinMode(set1, OUTPUT);
pinMode(set2, OUTPUT);
pinMode(set3, OUTPUT);
sensors.requestTemperatures();
intro(); //mostra HELLO em scroll para o delay (1seg)
a=sensors.getTempCByIndex(0); //primeira leitura valida;
}
void loop(){
termo();
rot(a);
}
void termo(void){
currentMillis = millis();
if(b==0){
sensors.requestTemperatures();
b=1;
} /// Send the command to get temperatures //0.75s para obter o valor, esperamos 2s para reduzir o efeito do pequeno atraso aqui presente
if(b==1){
if(currentMillis- pretime > time){
pretime = currentMillis;
a=sensors.getTempCByIndex(0); //*enquanto não obter bloqueia, daí o uso do millis();
b=0;
}
}
}
void rot (int a){ //subdivide a centena em partes
c=a;
digit[2] = c % 10;
digit[1] = (c / 10) % 10;
digit[0] = (c/ 100) % 10;
for(byte d=0;d<3;d++){
if(d==0){
if(digit[d]==0){
digit[d]=space;
}
}
else
digit[d]=caso(digit[d]);
}
seg(digit[0],digit[1],digit[2]);
//delay(1);
}
byte caso(byte test){ //descodifica os números no respectivo byte do display.
switch (test){
case 0:
return zero;
break;
case 1:
return one;
break;
case 2:
return two;
break;
case 3:
return three;
break;
case 4:
return four;
break;
case 5:
return five;
break;
case 6:
return six;
break;
case 7:
return seven;
break;
case 8:
return eight;
break;
case 9:
return nine;
break;
}
}
void seg(byte un,byte dos, byte tres){
digitalWrite(set1,HIGH);
digitalWrite(set2, LOW); //Primeiro Segmento
digitalWrite(set3, LOW);
shiftOut(data, clock, LSBFIRST, un);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, HIGH); //Segundo segmeto
digitalWrite(set3, LOW);
shiftOut(data, clock, LSBFIRST, dos);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, LOW); //terceiro segmento
digitalWrite(set3, HIGH);
shiftOut(data, clock, LSBFIRST, tres);
delay(6);
digitalWrite(set1,LOW);
digitalWrite(set2, LOW); //se atrasar nenhum acende, e o inverso daria em valores todos iguais dos segmentos
digitalWrite(set3, LOW);
}
void intro(){ //Mensagem de arranque, só para encher para o o primeiro delay não parecer tão grande.
delay(100);
seg(space, space, h);
delay(100);
seg(space,h,e);
delay(100);
seg(h,e,l);
delay(100);
seg(e,l,l);
delay(100);
seg(l,l,zero);
delay(100);
seg(l,zero,space);
delay(100);
seg(zero,space,space);
delay(100);
seg(space,space,space);
delay(100);
}
// bit por led
byte zero = B01111110;
byte one = B00000110;
byte two = B11011010;
byte three = B11010110;
byte four = B10100110;
byte five = B11110100;
...
byte caso(byte test){ //descodifica os números no respectivo byte do display.
switch (test){
case 0:
return zero;
break;
...
byte caso (byte test)
{
static const byte sDigitTable[] = {B01111110, B00000110, ...};
return sDigitTable[test];
}
Tens o loop() a correr a toda a velocidade, uma vez que optaste por não usar uma base de tempo fixa (o delay no fim da função). Não é muito relevante para o exemplo, mas isto faz com que o mega consuma mais energia pois o CPU está sempre a bombar. Além disso, como não tens uma base de tempo certa, não podes facilmente adicionar mais "tarefas" para fazer ao mesmo tempo, a não ser estares sempre a recorrer à leitura do millis() o que implica teres mais variáveis de tamanho grande.O meu problema é que estou totalmente dependente de um ciclo sempre a bombar para fazer o mux dos displays, ou isso ou passar para interrupções (que ainda tou meio a nora no arduino).
Bastava fazer return dos valores directamente (return B01111110; ...). Ou, melhor, implementar com uma tabela (não é preciso mais nada do que esta função):Código: [Seleccione]byte caso (byte test)
{
static const byte sDigitTable[] = {B01111110, B00000110, ...};
return sDigitTable[test];
}
Tens 2s de espera pelo resultado da conversão e não 0.75s.
Tens o loop() a correr a toda a velocidade, uma vez que optaste por não usar uma base de tempo fixa (o delay no fim da função). Não é muito relevante para o exemplo, mas isto faz com que o mega consuma mais energia pois o CPU está sempre a bombar. Além disso, como não tens uma base de tempo certa, não podes facilmente adicionar mais "tarefas" para fazer ao mesmo tempo, a não ser estares sempre a recorrer à leitura do millis() o que implica teres mais variáveis de tamanho grande.O meu problema é que estou totalmente dependente de um ciclo sempre a bombar para fazer o mux dos displays, ou isso ou passar para interrupções (que ainda tou meio a nora no arduino).
void loop (void)
{
static unsigned long wakeupTime = 0;
static unsigned long now = 0;
termo();
rot(a);
do {
now = millis();
} while (now < wakeupTime);
wakeupTime = now + 6; // 6 = 6 ms
}
Ora, cá esta uma optimização, coisa que ainda não tenho grande jeito a fazer,assim reduzo a dimensão do codigo e de ciclos de maquina, uma outra questão não posso passar o valor como hex? A pouco pus-me a pensar nisso ;) ex.: 0x7E ?
void loop(){
termo();
rot(a);
switch (i){
case 0:
seg0(digit[0]);
i++;
break;
case 1:
seg1(digit[1]);
i++;
break;
case 2:
seg2(digit[2]);
i=0;
break;
}
do {
currentMillis = millis();
} while (currentMillis < wakeupTime);
wakeupTime = currentMillis + 5; //Nota aumento ou diminuição deste valor altera taxa de refresh dos segmentos, ajustar (4-8)
}