Signaal van temperatuursensor op een ander manier omzetten

Ik ben een fancontroller aan het maken die reageert op de temperatuur die gemeten wordt door een tmp 36 sensor. In de starterskit wordt de onderstaande stappen gebruikt om het analoge signaal om te zetten in een temperatuur die in graden Celcius wordt weergegeven.

//Signaal van tmp36 omzetten naar graden Celcius volgens starterskit

  Tempwaarde_f = analogRead(temp_IN);           //Signaal van temperatuur sensor uitlezen
  Tempvolt_f = (Tempwaarde_f/1023)*5000;        //Waarde omzetten naar Volts
  Temperatuur = (Tempvolt_f - 500)/10;          //Waarde omzetten naar graden celcius

In de starterskit wordt bij een andere opdracht gebruik gemaakt van de map functie. Hierdoor hoef je zelf niet zoveel berekeningen te maken en kan je toch het ingangssignaal omzetten naar een gewenste bereik. In de onderstaande voorbeeld krijg ik wel de juiste temperatuur, maar deze wordt alleen in hele graden weergegeven, terwijl het wel een float variabele is zoals in de berekening hierboven.

//Een ander manier om het ingangssignaal om te zetten naar graden celsius
  Temperatuur = map(Tempwaarde_f, 20 , 410, -40, 150);

Is er een oplossing voor dit probleem of werkt de map functie alleen met integer getallen?

map werkt met longs - from the core

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;
}

je kan deze variant in je eigen code opnemen

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

De reden dat ik de map functie wil gebruiken is om de code overzichtelijk te houden. Bij het bovenstaande ben ik drukker bezig om alles te begrijpen dan de methode toe te passen die in het starterskit staat.

Maar bedankt voor het antwoord. Weet ik dat ook weer.

Met de fancontroller sketch wil ik ook 2 led’s laten knipperen. Beide hebben hun eigen aan/uit tijd en dat wil ik realiseren door een functie(subroutine) aan te maken. Het maken van een functie lukt wel, maar alleen gaan de led’s wel aan na de ingestelde tijd, maar ze gaan niet meer uit.
Ik heb het voorbeeld gebruikt van blinkWithoutDelay en zonder functie werkt deze wel goed, maar niet in de functie.

Hieronder de code die ik nu gebruik. Het setup deel achterwege gelaten, omdat de led’s wel worden aangestuurd en daar volgens mij de fout niet kan zitten.

void loop () {
  led_1 = knipper_fc(1000);                //knipperfunctie wordt gestart met een tijdwaarde van 500 ms
  led_2 = knipper_fc(5000);                //knipperfunctie wordt gestart met een tijdwaarde van 2000 ms
  
  digitalWrite(led_1_OUT, led_1);         //Stuur de uitgang aan zodat de led gaat knipperen
  digitalWrite(led_2_OUT, led_2);

}
//Hieronder wordt de functie gemaakt

boolean knipper_fc(int x) {
  unsigned long tijdwaarde = 0;
  unsigned long tijdwaarde_oud = 0;
  boolean waarde = false;
  
  tijdwaarde = millis();
  if(tijdwaarde - tijdwaarde_oud > x) {
    tijdwaarde_oud = tijdwaarde;
     waarde = !waarde;
   return waarde;
  }
}

x is in deze functie de in te stellen tijd.

Als je in een functie een variabele creëert en deze niet static maakt, dan is deze variabele verdwenen na het einde van de functie.
Als je in de functie binnenkomt worden ze (nu en oud) allebei op 0 gezet. Tevens is waarde op false gezet.
Daarna ga je testen.
Die conditie wordt nooit waargemaakt omdat je altijd wel onder de 1000msec blijft binnen die functie. De waarde blijft dus false. Daarnaast geef je niets terug (dus onvoorspelbaar) als de conditie niet gehaald wordt.
Als je nu wel een knipper centrale wilt, zou je een tabel moeten maken met per entry:
a) pin nummer
b) unsigned long timer
c) interval tijd

dan zou je bijv. deze code kunnen gebruiken:

voor de setup()

struct knipperLed {
  uint8_t ledPin;
  unsigned long timer;
  unsigned long t=interval;
};

#define AANTAL_LEDS 2
knipperLed tabel[AANTAL_LEDS];    // 2 entries met leds

in de setup()

pinMode etc.

tabel[0].ledPin = led1Pin;
tabel[1].ledPin = led2Pin;
tabel[0].timer  = millis();
tabel[1].timer  = millis();
tabel[0].interval = 1000;
tabel[1].interval = 5000;

in de loop()

knipperLeds();

de functie knipperLeds()

void knipperLeds(){

  for (uint8_t i = 0; i < AANTAL_LEDS; i++){
    // 
    // eerst kijken of de tabel timer uit staat
    //
    if (tabel[i].timer != 0) {
      //
      // nee dus nu kijken of de timer verlopen is
      //
      if ((millis() - tabel[i].timer) > tabel[i].interval){
        //
        // interval is verlopen dus nu de desbetreffende LED flippen
        //
        digitalWrite(tabel[i].ledPin, !digitalRead(tabel[i].ledPin);
        //
        // en stel de timer voor deze led opnieuw in
        //
        tabel[i].timer = millis();
      } 
    }
  }
}

Als je een timer uit wil zetten (dus knippert hij niet meer) dan zet je de timer gewoon op 0. Kan zijn dat er nog een foutje in zit. Heb het niet gecompileerd.

Hieraan toegevoegd:

Je neemt aan dat het setup gedeelte niet interessant is.
Aannames zijn heel gevaarlijk en vaak de oorzaak van dergelijke problemen.
Aan Nico's antwoord kun je zien dat dat gedeelte wel degelijk van belang is, en je het daarom niet had moeten weglaten.

@Nico: Er zaten 2 foutjes in het programma. Het gaat om de onderstaande regels

  unsigned long t=interval;                  //t= wordt niet door compiler geaccepteerd

Er verschijnen daardoor diverse meldingen waaronder: ISO C++ forbids initialization of member ‘t’ en een van de opvolgende meldingen is: error: ‘struct knipperLed’ has no member named ‘interval’ die ik heb opgelost door t= te verwijderen.

en er was een sluithaakje te weinig in de volgende regel

digitalWrite(tabel[i].ledPin, !digitalRead(tabel[i].ledPin);

Hier is er aan het eind een sluithaakje bijgekomen. Hierna kon de sketch wel gecompiled worden.

Helaas werkt het programma niet. Geen enkele led wordt aangestuurd.
Het programma zoals ik het nu heb staat hieronder

struct knipperLed {
  uint8_t ledPin;
  unsigned long timer;
  unsigned long interval;
};
const int led1Pin = 12;         //ledpins benoemen
const int led2Pin = 13;

#define AANTAL_LEDS 2
knipperLed tabel[AANTAL_LEDS];    // 2 entries met leds

void setup(){

  tabel[0].ledPin = led1Pin;
  tabel[1].ledPin = led2Pin;
  tabel[0].timer  = millis();
  tabel[1].timer  = millis();
  tabel[0].interval = 1000;
  tabel[1].interval = 5000;
  
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);

}

void loop() {
  knipperLeds();

}

void knipperLeds(){

  for (uint8_t i = 0; i < AANTAL_LEDS; i++){
    // 
    // eerst kijken of de tabel timer uit staat
    //
    if (tabel[i].timer != 0) {
      //
      // nee dus nu kijken of de timer verlopen is
      //
      if ((millis() - tabel[i].timer) > tabel[i].interval){
        //
        // interval is verlopen dus nu de desbetreffende LED flippen
        //
        digitalWrite(tabel[i].ledPin, !digitalRead(tabel[i].ledPin));
        //
        // en stel de timer voor deze led opnieuw in
        //
        tabel[i].timer = millis();
      } 
    }
  }
}

Via de seriële communicatie ben ik erachter gekomen dat de tabel[0 en 1].timer de waarde 0 blijft geven.

@MAS3: Ik ben het met jouw eens dat aannames verkeerd kunnen zijn. In de eerder geplaatste programma staat alleen de onderstaande tekst. De kans dat er dan iets fout is mag als klein worden beschouwd.

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

Dat mogen we nu dus aannemen, maar het gaat er om dat we dat niet konden weten.
Dan mist er dus informatie en hier zou bijvoorbeeld een of andere initialisatie mis kunnen gaan.

Ga er bij het inschakelen van een "hulplijn" van uit dat die niet in de zelfde denk-modus zitten als jij op dat moment, en ook de voorafgaande ontwikkeling niet hebben meegemaakt.
Een passend antwoord is waarschijnlijker als je alle informatie beschikbaar stelt.

jouw tmp kun je toch ook in een functie zetten je geeft op welke pin en je krijgt een temperatuur terug.

Dat is ook mogelijk, alleen niet aan gedacht om te doen.
Een van de redenen om het knippereffect in een functie te plaatsen komt doordat die meerdere keren wordt gebruikt.
Op deze manier kan ik met minder programma regels toe met hetzelfde effect.