LM35 und Spannungsmessung (Ain)

Hallo
ich bin gerade dabei mir eine Steuerung für eine Helmlampe fürs Biken zu entwickeln. Das Ganze kommt in ein kleines Aluminiumgehäuse auf dem Helm uns soll mit einem ATtiny85 realisiert werden. Programmieren werde ich mit einem Arduino UNO als ISP. Ich werde also auch in Arduino Programmieren.
Um alles erst einmal zu simulieren, benutze ich einen Arduino.

Die Steuerung soll folgendes machen:

-Temperatur des Gehäuses mit einem LM35 überwachen. Bei steigender Temperatur sinkt der LED-Strom.
-Taster zum Ein/Ausschalten und durchschalten der Modi
-Ansteuerung der KSQ(Konstanststromquelle) mit PWM
-Akkuspannungsüberwachung, sobald gewisse Spannungen unterschritten werden blinkt die LED oder geht aus.

Hier mal ein Bild der Schaltung:

Mein Problem ist, dass die Temperaturmessung nur funktioniert wenn ich die Spannungsmessung ausschalte.
Was mache ich falsch?
Die Eingänge beeinflussen sich wohl gegenseitig...

Und hier der Code:

int temp = 0;
int sensorValue =0;
const int buttonPin = A0;
const int ledPin = 3;
int buttonPresses = 1;
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
int zeit = 0;
int schutzwert = 0;
int tempMax1 = 24;  //Schalttemperatur
int tempMax2 = 26;  //Schalttemperatur
int tempMax3 = 28;  //Schalttemperatur
int leistungsFaktorTemp =10;
float leistungsFaktorVolt =1;
int i=0;
float v =0;
float voltage =0;
int voltagevar = 1;
int once = 0;

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 30;   // the debounce time; increase if the output flickers
long previousMillis = 0;        // will store last time LED was updated
long interval = 5000;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() 
{  
//####### Temp ################################################################
  sensorValue = analogRead(A1);
  temp = (sensorValue * 500) / 1024;
  Serial.println(temp);
  delay(1);
//####### Volt ################################################################
  v = analogRead(A2);
  voltage = v/102;
  
  
//####### Button ################################################################
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    
    lastDebounceTime = millis();
  } 
 if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
    buttonState = reading;
  }
    if (reading > lastButtonState) {      
    buttonPresses++;
   
  } 

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;

 if(buttonPresses >= 4){
   buttonPresses = 1;
  }
  
 
   unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  

     
     //Serial.println(temp); 
     //Serial.println(sensorValue); 
   
     if(temp < tempMax1){
      leistungsFaktorTemp=10;
      }
      if(temp >= tempMax1){
      leistungsFaktorTemp=5;
      }
      if(temp >= tempMax2){
      leistungsFaktorTemp=3;
      }
      if(temp >= tempMax3){
      leistungsFaktorTemp=0;
      }
      
      
     
     
      
      if(voltage > 6.12)
      {
      voltagevar = 1;
      }
      if(voltage <= 6.12 && voltage > 4.9)
      {
      voltagevar = 2;
      }
      if(voltage <= 4.9)
      {
      voltagevar = 3;
      }
      
      switch (voltagevar) 
    {
   
    case 1:
      leistungsFaktorVolt = 1;
      break;
    case 2:
    if(once==0){
      analogWrite(ledPin, 255);
      delay(300);
      analogWrite(ledPin, 30);
      delay(300);
      analogWrite(ledPin, 255);
      delay(300);
      analogWrite(ledPin, 30);
      delay(300);
      analogWrite(ledPin, 255);
      delay(300);
      analogWrite(ledPin, 30);
      delay(300);
      analogWrite(ledPin, 255);
      delay(300);
      analogWrite(ledPin, 30);
      delay(300);
      leistungsFaktorVolt = 1;
      once = 1;}
      break;
    case 3:
      leistungsFaktorVolt = 0;
      
      break;
    }
    
      
      
      
      
     
   }
   //Serial.println(buttonPresses);
  switch (buttonPresses) 
    {
   case 0:
     analogWrite(ledPin, 0);
     break;
    case 1:
      analogWrite(ledPin, 3*leistungsFaktorTemp*leistungsFaktorVolt);
      break;
    case 2:
      analogWrite(ledPin, 8*leistungsFaktorTemp*leistungsFaktorVolt);
      break;
    case 3:
      analogWrite(ledPin, 25*leistungsFaktorTemp*leistungsFaktorVolt);
      //Serial.println(25*leistungsFaktor);
      break;
    }
   
 
 //Serial.println(voltage);
 //Serial.println("\t");
 //Serial.println(leistungsFaktorVolt);
 //Serial.println(leistungsFaktorTemp);
 //Serial.print(25*leistungsFaktorTemp*leistungsFaktorVolt);
 //Serial.println("");
 
}

Hier mal ein Minimalbeispiel:

void setup() {
  Serial.begin(9600);
  
}
 
 
 void loop() 
{    
    
      delay(1000);
      int sensorValue = analogRead(A1);
      int temp = (5 * sensorValue * 100) / 1024;
      int v = analogRead(A2);
      int voltage = v/102;
    
    Serial.println(temp);
    Serial.println(voltage); 
}

Der Aufbau ist derselbe. Der Code liest die Spannung und die Temperatur aus.
Funktioniert ebensowenig. Die Spannung stimmt, die Temperatur hingegen nicht.

Der serielle Output ist in der Regel sowas hier:

5
15
5
25
5
19
5
23
5
17
5
14
5
26
5
21
5
18
5
17
5
21
5
21
5
20
5
23
5
20
5
27
5
18
5
15
5
26

Sieht eher so aus, als hättest du nen sauberen Variablenüberlauf produziert. Wenn du einen Sensorwert von rund 600 (entspricht etwa 3V) erwartest und diese 600 mit 5 und mit 100 multiplizierst, liegst du schon bei 300.000. Das passt nicht mehr in den Integer.

Hallo,
schau mal, was bei
int voltage = v;
rauskommt.
Da bei einem Bruch einfach die Nachkommastellen abgeschnitten werden, kannst Du leider nicht sagen, ob die angezeigte Spannung wirklich 5V entspricht.
Laß deshalb den Teiler ( /102) weg und schau was raus kommt.
Gruß
Reinhard

Hab die Lösung gefunden!
Ich habe einen 10KOhm Widerstand als Pulldown an den LM35 gehängt!

@sth77

ich teile ja aber auch noch durch 1024. und dann passts...

@spaceball

da hast du recht, aber das war nicht das Problem! :wink:

triplelag:
Hab die Lösung gefunden!
Ich habe einen 10KOhm Widerstand als Pulldown an den LM35 gehängt!

Hast du aber nicht gezeichnet...

triplelag:
ich teile ja aber auch noch durch 1024. und dann passts...

Ich glaube, da bist du auf dem Holzweg: + - Arduino Reference

@sth77

ich habe als lösung herausgefunden, dass ich einen pulldown widerstand an den LM35 hängen muss. Das wusste ich, als ich die Zeichnung erstellt habe ja noch nicht.

das mit der 1024... ja da bin ich auf dem holzweg :wink:

Ich hab auch noch nie die Beschaltung des LM35 mit einem Pulldown-Widerstand gesehen? Wofür soll der denn sein? :smiley:

sth77:
Ich hab auch noch nie die Beschaltung des LM35 mit einem Pulldown-Widerstand gesehen? Wofür soll der denn sein? :smiley:

Man kann damit den LM35 dazu bringen den vollen Messbereich (-55 bis ...) auszunutzen, sonst gehts wohl erst bei 2°C los. Allerdings geht der Widerstand im Datenblatt nicht gegen GND, sondern -VSS.

Ich vermute mal das das durch den Pulldown die Ausgangsspannung gerade soweit runtergezogen wird, das es nicht zu einem Überlauf kommt.

da hast du recht, aber das war nicht das Problem! :wink:

Naja, den Teil, den ich ansprach, sollte ja Deiner Meinung nach beweisen, dass die Spannung an sich konstant ist.

Die Spannung stimmt, die Temperatur hingegen nicht.

Mit deinem Code /102 schaffst Du es aber leider nicht, den Beweis wirklich zu führen...
Aber probier mal interessehalber, was Dein Arduino ausspuckt, wenn Du den Teiler wegläßt.

Gruß
Reinhard

Ich habe versucht andere Analogeingänge für die Spannung bzw. die Temperatur zu nutzen. Sobald ich zwei Analogeingänge einlese, springt die ausgelesene Temperatur ständig. Ich hab auch schon versucht die beiden Berechnnungen wegzulassen. Das macht das Ganze nicht besser.

Ich habe dann aus Verzweiflung einen Pulldown Widerstand reingehängt und siehe da, es funktioniert! Ich habe im Datenblatt gesehen, dass man einen Widerstand gegen -V reinhängen kann. Aber woher eine negative Spannung nehmen? Warum nicht gegen GND? Mache ich etwas kaputt?

Hast Du schon versucht, mit einem Kondensator eventuelle Signal-Schwankungen "auszubügeln"?
Vielleicht probierst Du auch mal eine andere Stromquelle.

gruß
Reinhard

PS.: Wie verhalten sich die Kontrollwerte der "voltage"-Variablen? springen die auch so?

Ich habe es geschafft mit meinen LM35CZ negative Temperaturen zu messen. Da er einen Widerstand gegen -Vss braucht um negativ zu messen habe ich ihm eine Virtuelle Masse 0,7V oberhalb Arduino GND gebaut. Damit kann es dann den vollen bereich ausnutzten. Da der LM35 eine Betriebstspannung von4-30V hat kann man ihn halt locker mit 4,3V betreiben.
Im Anhanhg eine handzeichung vom Aufbau.
Somit hat man bei 0 Bit Theoretisch -70°C bei 10mC/°C vom LM35.
Die Virutelle masse befindet sich ca. 0,7 V oberhalb von GND 700mV/4mv=175Bit sind 0°C und so kann man es weiter umrechnen.

Die erste Messung beim Wechsel des Eingangs ist nicht verläßlich. Lies den Eingang mehrmals ein (verwirf die erste messung und mach einen Mittelwert der restlichen 5 messungen)

Bezüglich Messung negativer Temperaturen:
Das Datenblatt National Semiconductor DS005516 datasheet pdf gibt die Schaltung Figur 7 Seite 6 an. Alternative ist del LM335 der in Kelvin mißt. Wie volvodani sagt sind aber 2 Dioden bei 5V Versorgungspannung etwas zuviel des Guten weil so die minmale Versorgungspannung unterschritten wird.
Grüße Uwe

Deswegen habe ich auch nur eine Genommen und es funtkioniert zuerlässig:
Habe aber das Problem von einem Driften gahbt das habe ich dann mit einem Zusätzlichen querstrom über die Diode in de Griff bekommen.
Gruß
Der DAni

volvodani:
Deswegen habe ich auch nur eine Genommen und es funtkioniert zuerlässig:
Habe aber das Problem von einem Driften gahbt das habe ich dann mit einem Zusätzlichen querstrom über die Diode in de Griff bekommen.
Gruß
Der DAni

Querstrom meinst Du, Du hast einen Widerstand zwischen Anode der Diode und +5V geschaltet (paralell zur Stromversogung des LM35) ?
Grüße Uwe

Richtig denn je kälter es wurde (bzw der LM35 desto verschobener die Dioden Spannung (bis zu 100mV), da sich der Strom des LM35 verändert. Hat jetzt die Diode permanent Belastst ändert sich ab einem bstimmten Strom der Spannungsabfall nicht. Je nach Temperatur der LM hatte ich Spannungen zwischn 750-850mV was bei der "virtuellen" Masse schon10° Unterschied sind.
Gruß
Der Dani