attiny85 + lm335

Ciao a tutti, il progetto di fine anno è quasi completo ma ho ancora qualche problema, in pratica rilevo la temperatura con l'lm335 tramite bluetooth la mando su qualche dispositivo e nel frattempo in base alla temperatura ci sono dei led rgb che cambiano colore.
Ho avuto non pochi problemi e ho fatto mille test e sono arrivato ad un punto morto (delle mie conoscenze purtroppo).
Ho scoperto che alimentando il tiny e l'lm335 con una alimentazione tutta per loro ho una lettura giusta ma che varia ogni tanto di 1°C sul monitor seriale, invece se uso una sola alimentazione per tutto rilevo tutto sballato.
L'lm è collegato come nella foto dell'allegato R 2.2k e C 1000uF, mi basta anche sistemare quell'errore di 1° che mi da e usare due alimentazioni, ma mi piacerebbe anche capire il perchè ho questo problema...

PS: lm335 e il tiny funzionano con i 5v dell'arduino collegato al pc e il resto funziona con 4 batterie AA

Lo LM335 ha un errore tra 1 e 2°C, mentre il modello LM335A tra 0.5 e 1°C (@25°C).

Sostituirei il condensatore con uno da 10μF od anche da 4.7μF, posti vicino ai terminali di alimentazione del LM335, mentre quello da 1000μF (che mi sembrano troppi) dovrebbe essere messo sull'alimentazione del Attiny85 in parallelo ad uno da 100nF, quest'ultimo molto vicino al +Vcc.

Fatto questo, ricordati di effettuare una media di 10 letture analogiche per ridurre il "rumore" della misura.

intendi così i condensatori?

Sì, anche se è quello da 100nF (di tipo ceramico o poliestere) che deve stare vicino al pin del +Vcc, mentre quello elettrolitico (secondo me max 470μF) può essere anche lontano.

ho cercato svariati modi per fare la media ma non ho avuto tempo di applicarne nemmeno uno perchè ho trovato di fronte sempre gli array che non ho mai usato, solo con l'array si può fare la media??

ciao

guixi:
solo con l'array si può fare la media??

Anche no.

crei una variabile =0; sommi al valore della variabile il valore letto per il numero delle letture di cui vuoi fare la media; dividi il valore della variabile per il numero delle letture fatte.

tipo:

int a =0;
int media;
for (int x =0; x<10;x++){
a = a + analogread(pin);
}
media = a / 10;

ciao
pippo72

in questo modo intendi?

int TemperaturaKelvin  = 0;
int temperatureC = 0;
long Sensore           = 0;
int a =0;
int media;
void loop() {
   Sensore = analogRead(A0);
TemperaturaKelvin =  Sensore*500/1023;
  temperatureC = TemperaturaKelvin-278;
  delay(6);
for (int x =0; x<10;x++){
a = a + temperatureC;
}
media = a / 10;
 mySerial.println(media);

guixi:
in questo modo intendi?

Quasi... :confused:
La formula per la media è corretta, solo che tu stai sommando ad a sempre lo stesso valore.
Devi spostare la lettura della temperatura dentro il cicli for

void loop() {
  for (int x =0; x<10;x++){
  Sensore = analogRead(A0);
  TemperaturaKelvin =  Sensore*500/1023;
  temperatureC = TemperaturaKelvin-278;
  delay(6);

a = a + temperatureC;
}
media = a / 10;
 mySerial.println(media);

Altra cosa: Il "codice" che ti ho passato era da prendere come un esempio; credo che a te non possa andare bene così com'è perchè è fatto solo con interi.
Se non ti interessano i decimi di grado non c'è nessun problema ma se (come penso) ti interessano devi dichiarare le variabili come float e a devi dividerlo per 10.0 e non 10
Anche nella formula che calcola la temperatura kelvin devi dividere per 1023.0 e non 1023

ciao
pippo72

no non mi interessano i decimali, a quindi con quel codice che mi ha messo poco fa era solo esempio?

void loop() {
  for (int x =0; x<10;x++){
  Sensore = analogRead(A0);
  TemperaturaKelvin =  Sensore*500/1023;
  temperatureC = TemperaturaKelvin-278;
  delay(6);

a = a + temperatureC;
}
media = a / 10;
 mySerial.println(media);
  delay(6);

non funziona nemmeno con questo

ciao

mi riferivo al codice postato nel quinto post.
Per "esempio" intendo che non puoi fare copia-incolla al codice così com'è; serve a farti capire come si può fare una cosa.

guixi:
...non funziona nemmeno con questo

Con "non funziona" cosa intendi?
-sbaglia a fare la media?
-non hai letture della temperatura?
-ecc.

Posta il codice completo e gli errori che ti dà così possiamo aiutarti.

ciao
pippo72

int TemperaturaKelvin  = 0;
int temperatureC = 0;
long Sensore   = 0;
int a = 0;
int media;

void loop() {
  for (int x =0; x<10;x++){
  Sensore = analogRead(A0);
  TemperaturaKelvin =  Sensore*500/1023;
  temperatureC = TemperaturaKelvin-278;
  delay(6);

a = a + temperatureC;
}
media = a / 10;
 mySerial.println(media);
  delayMicroseconds(15000);

questo è il codice mi da valori sbagliati, non capisco cosa c'è di sbagliato se poi a la divido per 10

Prova così:

float GradiK = 0.0;
float GradiC = 0.0;

void setup() {
}

void loop() {
  
  unsigned long Somma = 0;

  for (byte i = 0; i < 10; i ++) {
    Somma += analogRead(A0);
    delayMicroseconds(260);
  }
  
  Somma /= 10;

  GradiK =  Somma * 500 / 1023.0;
  GradiC = GradiK - 278;

  delay(1000);
}

grazie, i valori sono ok, ma il problema è che quando mi trovo a cavallo di una condizione per l'accensione dei led per esempio
giallo da 21 a 26 e rosso da 26 a 30 gradi se per caso ci sono 25.5 e 26 i led mi lampeggiano da un colore all'altro come se impazzissero.. è questo che voglio evitare..

Mostra lo sketch.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 4); // RX, TX
float GradiK = 0.0;
float GradiC = 0.0;
void setup() {
  mySerial.begin(9600);
}
void loop() {
  unsigned long Somma = 0;

  for (byte i = 0; i < 10; i ++) {
    Somma += analogRead(A0);
    delayMicroseconds(260);
  }
  
  Somma /= 10;

  GradiK =  Somma * 500 / 1023.0;
  GradiC = GradiK - 278;

  delay(1000);
  mySerial.println(GradiC);
  delayMicroseconds(10000);

if (GradiC > 21 && GradiC < 30) { Giallo
if (GradiC > 30 && GradiC < 40) { Rosso

sono fuori casa e ho scritto tutto a memoria (lo so manca la parte di accensione led), i led si accendono e si spengono in base alla temperatura
il problema si presenta quando sto tra i 29 e 30 gradi perchè oscilla di quello 0.5° o 1° e quindi i led impazziscono per un momento..

Come è possibile aiutarti con uno sketch approssimativo?

//sulla stessa linea tiny ed lm335 il resto con altra alimentazione

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 4); // RX, TX
float GradiK = 0.0;
float GradiC = 0.0;
#define PIN       1
#define NUMPIXELS      16
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
  strip.begin();
  mySerial.begin(9600);
}
void loop() {
  unsigned long Somma = 0;

  for (byte i = 0; i < 10; i ++) {
    Somma += analogRead(A0);
    delayMicroseconds(260);
  }
  
  Somma /= 10;

  GradiK =  Somma * 500 / 1023.0;
  GradiC = GradiK - 278;

  delay(1000);
  mySerial.println(GradiC);
  delayMicroseconds(10000);

 for (int a=0; a<strip.numPixels(); a++) 
{
    strip.setPixelColor(a,0,0,0);
}
if (GradiC > -10.0 && GradiC < -3.0) {for (int a=0; a<2; a++) {strip.setPixelColor(a,0,200,200);} strip.show();} //White on first LEDs
for (int a=0; a<strip.numPixels(); a++) 
if (GradiC > -3.0 && GradiC < 3.0) {for (int a=0; a<4; a++) {strip.setPixelColor(a,0,200,200);} strip.show();} //Sky-Blue on first LEDs
for (int a=0; a<strip.numPixels(); a++) 
if (GradiC > 3.0 && GradiC < 11.0) {for (int a=0; a<7; a++) {strip.setPixelColor(a,0,0,200);} strip.show();}  //Blue on first 4 LEDs
for (int a=0; a<strip.numPixels(); a++) 
if (GradiC > 11.0 && GradiC < 21.0) {for (int a=0; a<10; a++) {strip.setPixelColor(a,200,200,0);} strip.show();} //Yellow on first 7 LEDs
for (int a=0; a<strip.numPixels(); a++) 
if (GradiC > 21.0 && GradiC < 30.0) {for (int a=0; a<13; a++) {strip.setPixelColor(a,200,50,0);} strip.show();} //Orange on first 13 LEDs
for (int a=0; a<strip.numPixels(); a++) 
if (GradiC > 30.0 && GradiC < 40.0) {for (int a=0; a<16; a++) {strip.setPixelColor(a,200,0,0);} strip.show();} //Red on first 16 LEDs
}

Non ho potuto provare lo sketch, ma dovrebbe funzionare:

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#define PIN          1
#define NUMPIXELS    16

SoftwareSerial mySerial(3, 4); // RX, TX

float GradiK = 0.0;
float GradiC = 0.0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  mySerial.begin(9600);

  for (int a = 0; a < strip.numPixels(); a ++) {  // All LED off
    strip.setPixelColor(a, 0, 0, 0);
  }
  strip.show();
}

void loop() {
  unsigned long Somma = 0;

  for (byte i = 0; i < 10; i ++) {
    Somma += analogRead(A0);
    delayMicroseconds(260);
  }

  Somma /= 10;

  GradiK =  Somma * 500 / 1023.0;
  GradiC = GradiK - 278;

  mySerial.println(GradiC);

  if (GradiC >= -10.0 && GradiC < -3.0) {
    for (int a = 0; a < 2; a ++) {                  // White on first 2 LEDs
      strip.setPixelColor(a, 200, 200, 200);
    }
    for (int a = 2; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  else if (GradiC >= -3.0 && GradiC < 3.0) {
    for (int a = 0; a < 4; a ++) {                  // Sky-Blue on first 4 LEDs
      strip.setPixelColor(a, 0, 200, 200);
    }
    for (int a = 4; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  else if (GradiC >= 3.0 && GradiC < 11.0) {
    for (int a = 0; a < 7; a ++) {                  // Blue on first 7 LEDs
      strip.setPixelColor(a, 0, 0, 200);
    }
    for (int a = 7; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  else if (GradiC >= 11.0 && GradiC < 21.0) {
    for (int a = 0; a < 10; a ++) {                 // Yellow on first 10 LEDs
      strip.setPixelColor(a, 200, 200, 0);
    }
    for (int a = 10; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  else if (GradiC >= 21.0 && GradiC < 30.0) {
    for (int a = 0; a < 13; a ++) {                  // Orange on first 13 LEDs
      strip.setPixelColor(a, 200, 50, 0);
    }
    for (int a = 13; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  else if (GradiC >= 30.0 && GradiC < 40.0) {
    for (int a = 0; a < 16; a ++) {                  // Red on first 16 LEDs
      strip.setPixelColor(a, 200, 0, 0);
    }
    for (int a = 16; a < strip.numPixels(); a ++) {  // All others LED off
      strip.setPixelColor(a, 0, 0, 0);
    }
  }
  strip.show();
  delay(1000);
}

tutto ok, ho sistemato qualcosa nel tuo programma perchè i led non si accendevano, sembra un pò più stabile la lettura..

sono alle ultime rifiniture, ho messo tutta la basetta millefori ed è tutto ok, regolata anche la lettura e va tutto bene, l'ultima cosa che mi manca è nella visualizzazione
adesso visualizzo così

Gradi C ...
Gradi K ...
Gradi F ...
Gradi C ...
Gradi K ...
Gradi F ...
Gradi C ...
Gradi K ...
Gradi F ...
Gradi C ...
Gradi K ...
Gradi F ...

io vorrei visualizzare così

Gradi C ...
Gradi K ...
Gradi F ...

Gradi C ...
Gradi K ...
Gradi F ...

Gradi C ...
Gradi K ...
Gradi F ...

Gradi C ...
Gradi K ...
Gradi F ...

come aggiungo lo spazio tra le 3 letture?
il codice che ho messo è questo

mySerial.print(GradiC);
  mySerial.println("° Gradi Celsius");
  mySerial.print(GradiK);
  mySerial.println("° Gradi Kelvin");
  mySerial.print(GradiF);
  mySerial.println("° Gradi Fahrenheit");