map() auch mit Nachkommastellen?

Hallo,

habe einen industriellen Temp- und Feuchtefühler der mir 0-10V ausgibt (-20° - 80°C , 0 - 100% r.F).
Zum einlesen hab ich mir fix einen Spannungsteiler gebaut.
Hier der Code

#include <LiquidCrystal.h>
LiquidCrystal lcd (9, 8, 5, 4, 3, 2);

int temp_pin     = A1;
int hum_pin      = A2;


void setup()
{
  Serial.begin(9600);
  lcd.begin(20,4);
}



void loop()
{

  
  
  int temp_raw   = analogRead(temp_pin);
  int hum_raw    = analogRead(hum_pin);
  
  float temp_volt  = temp_raw * (5 / 1023.0);
  float hum_volt   = hum_raw  * (5 / 1023.0);
  
  float temp_val   = map (temp_raw, 0, 1023, -20,   80 );
  float hum_val    = map (hum_raw,  0, 1023,   0,   100);
  
  
  lcd.clear();

  lcd.setCursor(9,0);
  lcd.print("Temp, rF%");

  lcd.setCursor(0,1);
  lcd.print("Volt:");

  lcd.setCursor(9,1);
  lcd.print(temp_volt);

  lcd.setCursor(15,1);
  lcd.print(hum_volt);

  lcd.setCursor(0,2);
  lcd.print("Roh:");

  lcd.setCursor(9,2);
  lcd.print(temp_raw);

  lcd.setCursor(15,2);
  lcd.print(hum_raw);

  lcd.setCursor(0,3);
  lcd.print("Gemappt:");

  lcd.setCursor(9,3);
  lcd.print(temp_val);

  lcd.setCursor(15,3);
  lcd.print(hum_val);

  
  Serial.println("Rohwerte: Temp, rF%");
  Serial.println(temp_raw);
  Serial.println(hum_raw);
  Serial.println("gemappt:");
  Serial.println(temp_val);
  Serial.println(hum_val);
  Serial.println("Volt:");
  Serial.println(temp_volt);
  Serial.println(hum_volt);
  delay(500);
  
}

Alles simpel und soweit funktional.

Jedoch stellt sich mir die Frage: Wie kann ich meine ausgelesen und gemappten Werte mit Nachkommastellen versehen?
Eine Stelle würde genügen.

Hab schon Versucht:

float temp_val   = map (temp_raw, 0, 1023.0, -20.0,   80.0 );
float hum_val    = map (hum_raw,  0, 1023.0,   0.0,   100.0);

bekomm zwar zb. "25.00" angezeigt.. aber es bleibt bei "x.00"

Tipps?

Gruß

mußt Du Dir halt selbst ausrechnen.

wenn Du den wert temp_raw durch 10,23 dividierst, bekommst Du werte von 0 bis 100. zieh' 20 ab und Du hast Die temperatur.
bei der feuchtigkeit mußt Du nichts abziehen.

gruß stefan

Hallo,

falls es Dir um die Anzeige der Vor- und Nachkommastellen geht, hilft villeicht folgender Mini-Sketch:

#include <stdio.h>
#include <stdlib.h>

void setup() {
  Serial.begin(9600);
}

void loop()
{
  char t[20];
  double x=12.3;
  int vk, nk;
  
  vk=(int) x;
  nk=x*10-vk*10;
  sprintf(t, "%d.%d", vk, nk);
  Serial.println(t);
}

Das gibt x mit einer Nachkommastelle über die serielle Schnittstelle aus. Betrifft das Deine Frage oder geht es Dir um die Berechnung?

Gruß,
Ralf

Fr33man:
Tipps?

Lineare Interpolation.

Formel bei Wikipedia: Interpolation (Mathematik) – Wikipedia

Ich glaube, es geht dem TO eher darum, wie er die Nachkommastellen anzeigen und von der Integer-Mathematik von map() wegkommen kann. Nicht so sehr darum, wie das Ergebnis zu berechnen ist, oder?

Gruß,
Ralf

hi,

Ich glaube, es geht dem TO eher darum, wie er die Nachkommastellen anzeigen und von der Integer-Mathematik von map() wegkommen kann. Nicht so sehr darum, wie das Ergebnis zu berechnen ist, oder?

macht das nicht das, was ich geschrieben habe?

gruß stefan

@Eisebaer: Ich denke nicht. So wie ich das verstehe, geht es ihm darum genau eine Nachkommastelle anzuzeigen. Also z.B. 24.1°C oder so ähnlich.

Gruß,
Ralf

hi,

steh' ich jetzt auf dem schlauch? dürfte nicht mein tag sein, aber ich versteh's nicht.

er bekommt werte von 0 bis 1023 als integer. wenn er es mit map umrechnet, bekommt er wiederum integerwerte von -20 bis 80. dabei gehen die zwischenwerte flöten, weil map nur integer liefert.

wenn er jetzt aber den erhaltenen wert durch 10,23 dividiert, bekommt er doch diese zwischenwerte als dezimalstelle(n).

zb. 568 / 10,23 - 20 = 35,52

sorry, bin noch nicht lange munter...

gruß stefan

Eisebaer:
zb. 568 / 10,23 - 20 = 35,52

Genau :wink: Ich glaube halt er will nicht 35,52 sehen, sondern 35,5 - also eine Nachkommastelle. Kann aber auch sein, dass ich mich irre. Vielleicht warte ich am Besten mal, ob der TO sich nochmals äußert, wo genau "ihn der Schuh drückt".

Gruß,
Ralf

Map macht nur mit integer.
wenn die Zahlen nicht zu groß werden ( größer als ca 32000) dann kannst Du vor dem Map einfach mit 10 oder 100 multiplizieren und dann in ein float umwandeln und wieder dividieren.

Ansonsten machst du die bereichsumrechnung selbst wie Eisebaer vorschlägt.
Grüße Uwe

Die Formel von map ist in der Referenz angegeben:

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Könnte man auch in float selbst implementieren wenn man den Divisor auf float castet und einen float zurück gibt

Danke Leute! Hätte nicht mit so einer großen Resonanz gerechnet :slight_smile:

Also vielleicht habe ich mich wirklich etwas undeutlich ausgedrückt:

Ich lese einen Analogwert von 0 - 1023 ein was dem Temperaturwert -20 - +80°C entspricht (Industrieller Temperaturfühler mit 0-10V Ausgang welcher über einen Spannungsteiler auf 0 - 5V umgewandelt wird)

Mit map() bekomm ich zwar die entspechenden Werte "umgerechnet" doch leider bei 24,5°C zb. halt nur 25°C angezeigt.

Mir geht es dabei weniger darum, wie viele Nachkommastellen angezeigt werden, sondern eher darum, wie ich überhaupt Nachkommastellen bekommen kann da ich mit map() ja allerhöchstens 24,00°C bekomme und keine Zehntelwerte.

Auf die Idee mit dem vorherigen dividieren bzw manuellem Umrechen bin ich gar nicht gekommen. :~

hi,

na dann ist es ja einfach:

float temp_val = temp_raw / 10.23 - 20;
float hum_val = hum_raw / 10.23;

gruß stefan