Millis in Sekunden / Minuten / Stunden umrechnen

Liebes Forum!

Vielleicht habe ich gerade nur ein Brett vorm Kopf, aber ich komme nicht auf den Fehler:

Ich will für eine Schaltung Millis in Sekunden, später noch in Minuten und Stunden umrechnen.

In der Hoffnung, es dann zu verstehen, habe ich mit einem ganz kleinen Sketch angefangen, der nur bedingt funktioniert. Angeschlossen ist nur ein Poti:

char PotiPin = A0;
unsigned long PotiWert = 0;
unsigned long MilliWert =0;
unsigned long SekundenWert = 0;
void setup()
{
 
Serial.begin (9600);
PotiPin = INPUT;
}

void loop()
{
  PotiWert = analogRead (PotiPin);
  MilliWert = map(PotiWert, 0,1024, 1, 3600000);
  SekundenWert = MilliWert / 60000;
  Serial.print ("Poti: ");
  Serial.print (PotiWert);
  Serial.print ("Millis: ");
  Serial.println (MilliWert);
  Serial.println (SekundenWert);
  delay (500);}

Jetzt bekomme ich bis zum PotiWert von ca, 550 sinnvolle Werte in Sekunden, danach springen die angegebenen Millisekunden in der Map-Funktion auf Phantasiewerte.

Ich vermute, es läuft eine Variabel über, aber welche. Habe doch schon long genutzt, da sollte noch Platz sein.

Also: Brett vorm Kopf oder nicht?

Ohne jetzt nachgerechnet zu haben: map arbeitet mit (signed) long.

Gruß Tommy

Ohne jetzt nachgerechnet zu haben: map arbeitet mit (signed) long.

Das kann man ändern…

#include <Streaming.h> // die Lib findest du selber ;-)
Stream &cout = Serial; // cout Emulation für AVR Arduinos

template<typename T>
T map(T x, T in_min, T in_max, T out_min, T out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} 

void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  
  for(int i=0; i<1024; i += 25)
   cout << "i: " << i << "   " << map<unsigned long>(i, 0,1024, 1, 3600000) << endl;
  
}

void loop() 
{ 
}

@Tommy56: Meintest Du: "Arbeitet "nicht" mit signed long?
Weil: Millis ist doch signed long"

@Combie: Da muss ich erst mal länger nachdenken, bis ich dass verstehe.
Aber: Ist ja Sonntag und es regnet...

Weil: Millis ist doch signed long"

Nöö, sondern: unsigned long

@Combie: Da muss ich erst mal länger nachdenken, bis ich dass verstehe.
Aber: Ist ja Sonntag und es regnet…

Denken wird überbewertet!
Einfach das map Funktionstemplate verwenden und gut ist.

Den Rest am besten noch nicht einmal ignorieren

vollderhonk:
@Tommy56: Meintest Du: "Arbeitet "nicht" mit signed long?
Weil: Millis ist doch signed long"

Nein, ich meine es so, wie ich es geschrieben habe.
millis ist unsigned long.

Gruß Tommy

combie:
Nöö, sondern: unsigned long

Das müßtesr Du aber erst nach 24,86 Tagen merken.
Grüße Uwe

Er benutzt ja kein millis().

Gruß Tommy

Eigentlich ist die Verwendung von map() hier völlig überzogen....

Betrachtet man es von der Geradengleichung her, spielt sich alles im oberen rechten Quadranten ab. Zudem ist der Koordinatenursprung der Linie hier exakt/fest auf 0,1.
Es müssen ja nur ein paar Stützpunkte berechnet werden und nicht großartig linear interpoliert.

Diese Einschränkungen bieten Raum für großartige Vereinfachungen.

constexpr unsigned long offset = 1;
constexpr unsigned long steigung = (3600000UL - offset) / 1024;

unsigned long eingestellteZeit = offset + steigung * analogRead(A0);

Ufff…

Hat ein paar Tage gedauert, aber letztendlich…

const byte RelaisPin1 = 10; // Variabeln für die Relais (Lichtschalter auf Pin 10
const byte RelaisPin2 = 13; //... kleiner Wechselrichter auf Pin 3)
const byte triggerPin = 12; //Variabel für den Trigger-Pin des Ultraschallsensors an Pin12
const byte echoPin = 11; // Variabel für den Echo-Pim des Ultraschallsensors an Pin11
long dauerValue = 0; // Variabel für die Dauer, unter der die Zeit gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. Startwert ist hier 0.
long entfernungsValue = 0; // Variabel für die Entfernung unter der die berechnete Entfernung gespeichert wird.
unsigned long TorOeffnung = 0; // Variabel für den Zeitpunkt in Millis, wann / wenn das Tor geöffnet wurde
unsigned long LadeZeit= 0; //Variabel für die Dauer, in der die Last auf das Wechselrichterrelais gegeben wird
const byte PotiPin = A1; // Variabel für den Pin, an dem das Potentiometer angeschlossen ist
unsigned int PotiValue = 0; // Variabel für den Poti-Wert;
byte StundenWert = 0; // Variabel für die Ladezeit in Stunden für den Wechselrichter
int numArray[11][8] = {  // Array für das Segmentdisplay
  { 0,1,1,1,1,1,1,1 },  // 0 mit Punkt
  { 0,0,0,1,0,0,1,1 },  // 1 mit Punkt
  { 1,0,1,1,1,1,0,1 },  // 2 mit Punkt
  { 1,0,1,1,0,1,1,1 },  // 3 mit Punkt
  { 1,1,0,1,0,0,1,1 },  // 4 mit Punkt
  { 1,1,1,0,0,1,1,1 },  // 5 mit Punkt
  { 1,1,1,0,1,1,1,1 },  // 6 mit Punkt
  { 0,0,1,1,0,0,1,0 },  // 7
  { 1,1,1,1,1,1,1,0 },  // 8
  { 0,0,0,0,0,0,0,0 },  // aus! Achtung, eigentl. 9
  { 0,0,0,0,0,0,0,1 }   // Punkt
}; 
int pinArray[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Pins für das Segmentdisplay

void setup() {
Serial.begin (9600); // startet serielle Verbindung
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT); // Trigger-Pin ist ein Ausgang,Echo-Pin ist ein Eingang
pinMode (RelaisPin1, OUTPUT);
pinMode (RelaisPin2, OUTPUT);// beide Relais werden auf Ausgang gesetzt
pinMode (PotiPin, INPUT); // PotiPin wird als Eingang definiert
//digitalWrite (RelaisPin2, HIGH); // Wechselrichter wird schon mal angeschaltet
}

void loop() {
// Entfernungsmesser
digitalWrite(triggerPin, LOW);
delay(5); //Hier nimmt man die Spannung für 5 Millisekunden vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
digitalWrite(triggerPin, HIGH); //Jetzt sendet man eine Ultraschallwelle los. Dieser „Ton“ erklingt für 10 Millisekunden.
delay(10);
digitalWrite(triggerPin, LOW);//Dann wird der „Ton“ abgeschaltet.
dauerValue = pulseIn(echoPin, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
entfernungsValue = (dauerValue / 2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern.
Serial.print ("Entfernung:"); Serial.print (entfernungsValue); // Serielle Ausgabe des Entfernungswertes
if (entfernungsValue >= 2222 || entfernungsValue <= 0) {//Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
Serial.print (" kein Messwert");}
// Poti
PotiValue = analogRead (PotiPin); //liest den Wert des Poti aus
StundenWert = map(PotiValue, 0,1024, 0, 7); // rechnet den Wert um in einen Stundenwert
LadeZeit = StundenWert * 3600000; // rechnet den Stundenwert in millis

// if-Schleife für Licht und Wechselrichter
if ((entfernungsValue <= 22) && (entfernungsValue >= 1)) { // Wenn Tor auf:
digitalWrite (RelaisPin1, HIGH);
Serial.println (" Licht AN");// Licht geht an
digitalWrite (RelaisPin2, HIGH);
Serial.println (" Wechselrichter AN");// Wechselrichter geht an
TorOeffnung = millis (); // Es wird ein Zeitstempel gesetzt_ bisherige Laufzeit = Zeit der Öffnung
numWrite (StundenWert); // gibt den Stundenwert auf dem Display aus, nur wenn das Tor offen ist
}
  
else { // wenn Tor wieder zu...
digitalWrite (RelaisPin1, LOW);
Serial.println (" Licht AUS");// Licht aus
numWrite (9);} // Display wird ausgeschaltet

if (millis () - TorOeffnung > LadeZeit) { //Wenn das Tor mal auf war, aber jetzt wieder zu ist...
digitalWrite (RelaisPin2, LOW);
Serial.print (" Wechselricter wieder aus");}

//Serial.print ("___TorOeffnung");
//Serial.print (TorOeffnung);
//Serial.print ("PotiValue: ");
//Serial.print (PotiValue); // Wiedergabe verschiedener Werte auf dem Seriellen Monitor
//Serial.print ("Ladezeit in ml: ");
//Serial.print (LadeZeit);
//Serial.print ("Stunden: ");
//Serial.print (StundenWert);
}

void numWrite(int number) { // Methode für das Segmentdisplay
  for (int i = 0; i < 8; i++) {
    digitalWrite(pinArray[i], numArray[number][i]);}
  }

Habe noch ein Segment-Display integriert, damit ich den Stundenwert auch einstellen kann. Funktioniert wir geschmiert und ich habe einiges gelernt.

Seltsam ist nur, dass ich die serielle Ausgabe am Ende des Sketches auskommentieren muss, da sonst der Entfernungsmesser keine Daten ausgibt. Keine Ahnung, warum…

Ich danke sehr für die Hilfe! Muss mir jetzt mal ein neues Projekt überlegen, damit ich auch inhaltlich weiter komme…

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.