[código]2 Sensores temperatura, Enc28j60, InfraVermelho, controle de 2 coolers.

Boa tarde, há meses, em meu escasso tempo livre, venho tentado automatizar minha sala de tv com arduino. Aprendi a programar, o básico :), relembrei noções de eletrônica das aulas de física do colégio 8). DIY é minha praia, aprender com erros. Porém cheguei ao limite, não consigo mais progredir sozinho, logo solicito-vos ajuda.

Tenho um HomeTheater Onkyo que esquenta muito necessitando de ventilação. Instalei 2 coolers 12v (genéricos de PC 0,2 amp) no fundo de minha rack. e coloquei um sensor LM35 acima dele no intuito de ligar os coolers através de 2 transistores NPN BD139 quando o LM 35 acuse temperatura que isso seja necessário.

Problemas: 1. Não sei se devido ao código ter ficado complexo e poluído o LM 35 acusa temperaturas muito superiores e o arduíno fica instável. 2. Se coloco os fans com AnalogWrite (PWM) e diminuo 10% na sua potencia total (ex. 230) faz um barulho horrível. Optei por deixá-los em digitalWrite (100%).
O que preciso: Primariamente melhorar esse código, o loop parece grande mas não consigo retirar funções dele. O arduíno está muito instável. Secundariamente, conseguir medições mais espaçadas com o LM35 sem atrasar o código, exemplo medir a temperatura apenas de 2 em 2 minutos para não deixar os fans loucos.

Apesar da instabilidade, tudo funciona por um tempo.
Agradeço de antemão aos nobres geeks que prestarem tão útil auxílio .

//excertos de vários e vários lugares que nem sei por onde citar
#include <etherShield.h>
#include <ETHER_28J60.h>
#include <NewTone.h> 
#include <IRremote.h> 
#include <Limits.h>
#include <DHT.h>

#define DHTTYPE DHT22 //Define o tipo de sensor DHT utilizado
#define DHTPIN A0 //pino de dados do sensor DHT22
#define fan1 9 //Fan 1
#define fan2 5//Fan 2
#define buzzer 7 //Buzzer
#define sensorTemp 5//Pino ANALOG IN em que o sensor de temperatura LM35 está conectado.
#define lux1 2 // LAMP1 
#define lux2 3  // LAMP2
#define RECV_PIN 4 //Ligado ao pino do receptor IR 

#define tempMin 30 //Define a temperatura mínima de acionamento do Fan
#define tempMax 45 //Temperatura que os fans estarao a todo vapor
#define tempAlert 70 //Temperatura que acionará o alarme

int fanmode = 1;
int fanLCD;
int valorSensorTemp = 0; 
int tempSys  = INT_MAX;
int armazenavalor = 0;
int estadorele1 = HIGH; 
int estadorele2 = HIGH;

static uint8_t mac[6] = {
  0x54, 0x55, 0x58, 0x10, 0x00, 0x24};   
static uint8_t ip[4] = {
  192, 168, 0, 150}; // IP address
static uint16_t port = 80; 
ETHER_28J60 e;

DHT dht(DHTPIN, DHTTYPE);

IRrecv irrecv(RECV_PIN);  
decode_results results;  


void setup()
{ 
  e.setup(mac, ip, port);
  pinMode(lux1, OUTPUT);
  pinMode(lux2, OUTPUT);
  digitalWrite(lux1, HIGH);
  digitalWrite(lux2, HIGH);
  pinMode(fan1, OUTPUT);
  pinMode(fan2, OUTPUT);
  pinMode(buzzer, OUTPUT);
  irrecv.enableIRIn(); // Inicializa o receptor IR  
}

void loop()
{  
  ///** DHT inicio  
  float h = dht.readHumidity(); //Le o valor da umidade
  float t = dht.readTemperature(); //Le o valor da temperatura
  ///** DHT fim  
  ///** ethernet inicio
  if (e.serviceRequest())
  {
    e.print("<!DOCTYPE HTML><html><head><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\"><style> html { height:100%; }");
    e.print(" body { height: 100%;  margin: 5px; font-family: helvetica, sans-serif; } ");  
    e.print(" </style></head><body>"); 
    e.print("<h2>Temperatura ambiente: </h2>");
    e.print(t);
    e.print(" &#176;C

");  
    e.print("<h2>Umidade ambiente: </h2>");
    e.print(h);
    e.print(" %

"); 
    e.print("<h4>Temperatura do sistema de som: </h4>");
    e.print(tempSys);
    e.print(" &#176;C

"); 
    e.print("<h4>Refrigera&ccedil;&atilde;o do sistema de som: </h4>");
    e.print(fanLCD);
    e.print(" %</body></html>");   

    e.respond();      
  }
  ///** ethernet fim
  ///**LM35 inicio  
  tempSys  = INT_MAX; //Inicializando a variável com o maior valor int possível
  for (int i = 1; i <= 8; i++) {
    valorSensorTemp = analogRead(sensorTemp);  //Lendo o valor do sensor de temperatura   
    valorSensorTemp *= 0.54 ; //Transformando sensor de temperatura em graus celsius 
    if (valorSensorTemp < tempSys) {   //Mantendo sempre a menor temperatura lida
      tempSys = valorSensorTemp;    
    }
  }
  ///** LM35 fim
  ///*** IRemote inicio
  if (irrecv.decode(&results))   
  {  
    //    Serial.print("Valor lido : "); 
    //    Serial.println(results.value, HEX);
    armazenavalor = (results.value);   
    switch (armazenavalor)  
    {  
    case 0x4BB69867: //Verifica se a tecla >> foi acionada  
      estadorele1 = !estadorele1;  
      //      Serial.println(digitalRead(lux1));
      digitalWrite(lux1, estadorele1);   
      break;  
    case 0x4BB658A7: //Verifica se a tecla << foi acionada  
      estadorele2 = !estadorele2;  
      digitalWrite(lux2, estadorele2); 
      break;  
    case 0x4BB6A857: //Verifica se a tecla play foi acionada (STOP 0x4BB6C837)
      fanmode = !fanmode;  
      digitalWrite(fan1, fanmode); 
      digitalWrite(fan2, fanmode);  
      break; 
    }
    irrecv.resume(); //Le o próximo valor  
  }
  ///*** IRemote fim
  ///** início controle dos fans
  if (fanmode == 1){
    while(tempSys < tempMin) { 
      fanLCD = 0; 
      digitalWrite(fan1, LOW);
      digitalWrite(fan2, LOW); 
      break;      
    } 
    while((tempSys >= tempMin) && (tempSys < tempMax)) {  
      fanLCD = 50;
      digitalWrite(fan1, HIGH); 
      digitalWrite(fan2, LOW);
      break;  
    } 
    while((tempSys >= tempMax) && (tempSys < tempAlert)) { 
      fanLCD = 100; 
      digitalWrite(fan1, HIGH);
      digitalWrite(fan2, HIGH); 
      break;      
    } 
    while(tempSys > tempAlert) {  
      digitalWrite(fan1, HIGH);       
      digitalWrite(fan2, HIGH);       
      fanLCD = 100;  
      alarm(); 
      break;  
    } 
  }
  else {
    fanLCD = 0; 
    digitalWrite(fan1, LOW);
    digitalWrite(fan2, LOW);
  }
  ///** fim controle dos fans
} //**FIM DO LOOP

void alarm()
{
  NewTone(buzzer,200,100);   
  // delay(100);
  //  noNewTone(buzzer);  
}

Porque não fazes uma média das temperaturas?

O que é que o dht está a fazer?

A fan fazer barulho pode não ser um problema do Arduino ou código...

O DS18B20 pelo que li anteriormente é mais fiável que o lm35

Porque não usas um float para a temperatura do lm35?

Sobre o LM35: Sim talvez uma média seja uma boa idéia. Como está, peguei de algum fórum por aí, ele mede 8 x a temperatura e fornece a menor. Tens idéia de como fazer uma média à partir das leituras do LM35? O que continuará atrapalhando é a interferência.

Sobre o barulho: Quando alimento os coolers com qualquer voltagem diretamente da fonte não fazem ruído. Quando alimento via transistor regulado pelo PWM do arduino dai é barulho na certa. Tentei alterar a frequência e saídas PWM sem sucesso.

Nota1: Alimento o arduíno com fonte 12v 1a de notebook. A partir do Vin que curiosamente fornece somente 10 v transfiro aos coolers via transistor.
Nota2: o DHT mede a temperatura ambiente da minha sala e envia via ENC28j60

Grato.

No teu ciclo for... somas um certo numero de vezes as leituras da temperatura... quando o ciclo for acabar, divides o resultado dessa soma pelo numero de vezes que somaste. Isso é uma média. Escusas também de converter.

  unsigned long tempSys  = INT_MAX; //Inicializando a variável com o maior valor int possível
  float temperatura = 0.0;
  for (int i = 0; i < 8; i++) {
    tempSys += analogRead(sensorTemp);  //Lendo o valor do sensor de temperatura   
    }
   temperatura = (tempSys/8) * 0.54;

Como estás a fazer a comutação da tensão para os motores?

Nota também que o que poderá a estar a dar cabo da leitura do lm35 ser ruído eléctrico vindo dos motores. Já experimentaste fazer leitura de temperatura sem motores?

Alimento os motores em paralelo com a saída Vin (que me oferece 10v) . O ground está ligado à transistores que regulam (fazendo barulho quando não a 100%) esta tensão.

Se os motores são acionados ou as lampadas do rele a leitura da temperatura sofre ruídos e altera 10 graus por saída em estado HIGH. Pensei que fosse ruído de campo eletromagnético dos motores dos coolers. Mas não é pois os reles também geram ruído.
Já testei aterrar todos os analogIn vazios, sem resultado. Testei todas entradas analógicas, também sem resultado.

Penso que o problema seja a frequência fornecida pelos transistores troquei pelo BD135 sem resultados. O pino coletor que recebe o polo negativo do motor possivelmente admite uma frequência baixa.

Como que eu forneço 12v, confirmados pelo multímetro, pela fonte ao arduíno e este me libera apenas 10v pela saída Vin?
As saídas PWM do arduíno me fornecem (255) 4,68v aproximadamente cada. O que me causa estranheza também.