Go Down

Topic: Betriebsstundenzähler / Drehzahlmessung (Read 5828 times) previous topic - next topic

201001

Feb 26, 2010, 05:49 pm Last Edit: Feb 26, 2010, 05:55 pm by 201001 Reason: 1
Hallo, ich stehe gerade vor einem Problem einen Betriebsstundenzähler umzusetzen.
Die kleine Aufgabe hierzu wäre einen Betriebsstundenzähler mit einer Drehzahlmessung zu vereinen. Ich möchte gerne an meiner Drehbank die Drehzahl messen.
Das geht auch schon! Jetzt käme noch ein Betriebsstundenzähler hinzu. Nach einer Stunde Spindelbetrieb soll dann eine Meldung auf das LCD ausgegeben werden, wo hier der Hinweis kommt, dass die Maschine gefettet bzw. geschiert werden muss.  

Ich würde hierzu gerne mal den Code für die Drehzahmesser bekannt geben.
Dazu gibt es auch schon einen kleinen Post an falscher Stelle:)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266879129/0

hier der Code:
Code: [Select]
#include <LiquidCrystal.h>
LiquidCrystal lcd(0, 1, 4, 5, 6, 7);
       
volatile byte rpmcount;
volatile int status;

unsigned int rpm;

unsigned long timeold;
void rpm_fun()
{
  rpmcount++;
   
    if (status == LOW) {
    status = HIGH;
  } else {
    status = LOW;
 }
  //digitalWrite(statusPin, status);
}

void setup()
{
  //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
  //Triggers on FALLING (change from HIGH to LOW)
  attachInterrupt(0, rpm_fun, FALLING);
 
  rpmcount = 0;
  rpm = 0;
  timeold = 0;
  status = LOW;
  lcd.begin(16, 2);
 
  lcd.setCursor(0,0);
  lcd.print("Spindeldrehzahl");
}
void loop()
{
  //Update RPM every second
  delay(1000);
  detachInterrupt(0);
  rpm = 31*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
 
  lcd.setCursor(0,1);
  lcd.print(rpm,DEC);
  lcd.print(" =U/min");
  attachInterrupt(0, rpm_fun, FALLING);
 }


..und hier die Bilder vom Versuchsaufbau.

http://img714.imageshack.us/i/img6240.jpg/
http://img704.imageshack.us/i/img62392.jpg/

Würde mich freuen, wenn Ihr mir Ansätze und Ideen liefern könntet, das ganze zu realisieren.
Nur eins sei noch dazu gesagt, ich bin im Programieren noch Anfänger und kenne mich nicht ganz so gut aus.
Dafür bin ich aber in der Hardware recht stark ;)

Also dann...
Liebe Grüße
Mike :)

Otacon2k

Hey hanno_mike,

Gratulation zu deinem Projekt, sieht ja schon ganz gut aus (so, jetzt hab ich auch meine Pflicht getan ;)).
Wenn du das Ein-und Ausschalten der Maschine messen kannst (z.B. immer wenn die Drehzahl null wird = aus, wenn Drehzahl steigt = an), dann kannst du über die einfache Formel

Ausschaltzeit - Einschaltzeit = Betriebsdauer

immer die Betriebsdauer für einen Lauf berechnen. Die speicherst du im internen EEPROM des ATMega ab, damit sie auch ohne Strom erhalten bleibt.
Wird die Maschine das nächste Mal angeschmissen, berechnet sich wieder die Betriebsdauer. Dann kannst du den alten Wert aus dem EEPROM auslesen, die neue Betriebsdauer dazuaddieren, und das ganze wieder im EEPROM speichern (am besten im nächsten Byte, damit alle Zellen gleichmäßig beansprucht werden).
Speicherst du nicht immer in der gleichen Speicherzelle, sondern in verschiedenen, dann musst du irgendwo auf dem EEPROM auch die Information ablegen, wo die Betriebsdauer das letzte Mal hingeschrieben wurde. Deutlich einfacher (und halt beanspruchender für einzelne EEPROM-Zellen) wäre natürlich, einfach immer in die gleichen Zellen zu schreiben, dann kannst du dir die Adressspeicherei sparen (sollte man wohl auch nicht überbewerten mit den Schreibzyklen...).

Viel Erfolg,
Otacon2k

ChrisS

So, also ich... als Mikes kaputtes Programmiergehirn hatte mir folgendes ausgedacht ;) :

Code: [Select]
#include <EEPROM.h>

unsigned long current_millis_value = 0;
unsigned long previous_millis_value = 0;
unsigned long m = 0;
unsigned int sekunden = 0;
unsigned int minuten = 0;
unsigned int stunden = 0;
float millisekunden;
float millisekundentemp;
int value;
float millitemp;
float gesammtzeit;
float millisekundenalt;


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

void loop() {
delay(5000);

// zuletzt gespeicherte Dauer aus dem eeprom lesen
stunden=EEPROM.read(0);
minuten=EEPROM.read(1);
sekunden=EEPROM.read(2);  

Serial.println("Zeitwert im EEPROM:");
Serial.print(" Stunden: ");
Serial.print(stunden);
Serial.print(" Minuten: ");
Serial.print(minuten);
Serial.print(" Sekunden: ");
Serial.println(sekunden);

millitemp=sekunden*1000;
millisekundenalt=millisekundenalt+millitemp;
millitemp=minuten*60000;
millisekundenalt=millisekundenalt+millitemp;
millitemp=stunden*3600000;
millisekundenalt=millisekundenalt+millitemp;
// jetzt habe ich die alte Zeit in millisekundenalt



millisekunden=millis();
milliconverttotime();

Serial.println("Aktuelle Laufzeit");
Serial.print(" Stunden: ");
Serial.print(stunden);
Serial.print(" Minuten: ");
Serial.print(minuten);
Serial.print(" Sekunden: ");
Serial.println(sekunden);

if (Serial.read()==35){
millisekunden=millisekundenalt+millis();
milliconverttotime();
EEPROM.write(0,stunden);
EEPROM.write(1,minuten);
EEPROM.write(2,sekunden);
}


if (Serial.read()==48){
EEPROM.write(0,0);
EEPROM.write(1,0);
EEPROM.write(2,0);
}



}


void milliconverttotime() {
 m=0;
 sekunden=0;
 minuten=0;
 stunden=0;
 previous_millis_value=0;
 current_millis_value=0;
 cli();
 current_millis_value = millisekunden;
 sei();
 m += current_millis_value - previous_millis_value;
 sekunden += m / 1000;
 m = m % 1000;
 minuten += sekunden / 60;
 sekunden = sekunden % 60;
 stunden += minuten / 60;
 minuten = minuten % 60;
 stunden = stunden % 24;
 previous_millis_value = current_millis_value;
}




Aber man höre und staune... es funzt mal wieder nicht....

Vielleicht gibts dazu mal einen kleinen Hint....

Aktuell wird die 0 zum löschen abgefragt...
das doppelkreuz zum speichern... quasi der "'Maschine geht aus-Zustand".

Lieber Gruß
ChrisS


willich

#3
Feb 26, 2010, 06:25 pm Last Edit: Feb 26, 2010, 06:26 pm by willich Reason: 1
Es gibt auch Libraries, die "große Zahlen" ins EEprom speichern. Sonst passt immer nur 0-255 da rin!
Irgendwas mit "multi-type-variable in eeprom" oder sinngemäß.
Mal im Playgroud rumstöbern!

Immer nächste Zelle beschreiben klingt in der Theorie gut, nur: In welche Zelle speicherst du den Zeiger, bei welcher Zelle du grad bist :)

EDIT: Zeitgleichpost..... OK, wenn du sek, min und h getrennt speicherst, sollte das wohl auch mit "kleinen Zahlen" gehen :)

ChrisS

#4
Feb 26, 2010, 06:30 pm Last Edit: Feb 26, 2010, 06:31 pm by ChrisS Reason: 1
Hihi... sollte gehen... ja...

nur der läuft mir ziemlich die alte Zeit über....
ich guck nochmal nach der Library....
Meinst aber nicht die EEPROM String Geschichte oder?

:)

Lieber Gruß
ChrisS

Joghurt

Quote
nur: In welche Zelle speicherst du den Zeiger, bei welcher Zelle du grad bist

Naja, man könnte ganz am Anfang oder Ende seines "Datenbrockens" einen Marker setzen; eine bestimmte Byte-Kombination oder so, die man sonst nicht verwendet.

Und wenn man das nächste Mal was schreibt, dann fängt man nicht "sauber" hinter dem alten Datenbrocken an sonder "kurz davor", so dass man den alten Marker überschreibt.

Damit müsste man dann (passende Anzahl zu speichernde Bytes vorausgesetzt) eigentlich immer schön im Kreis rum schreiben und alle möglichen Speicherplätze längerfristig gleichmäßig nutzen...

Otacon2k

@OP: Wäre gut zu wissen was genau nicht funzt, ansonsten kann man schlecht Vermutungen anstellen. Schmeißt der Compiler eine Fehlermeldung aus? Wird nicht gespeichert? Hängt der Sketch sich auf?

ChrisS


Wie gesagt, die alte Zeit läuft über bzw. hängt.

Es kommen nach dem Neustart relativ merkwürdige Zeitwerte heraus.

Beispiel:
1. Ich lasse es 30 Sekunden laufen... speichere ins eeprom (Reset-Simulation)
2. er fängt neu an zu starten, holt sich die 30 sekunden... zählt weiter...
3. nach erneutem speichern nach 40 sekunden zeigt er auch wirklich 1:10min. an... soweit ok...

4. ich speichere erneut... mache ein reset... nun steht hier 9:55:14 ...
total falsche Zeit....

Da die Millis korrekt sein müssen...und sind, kann es sich bei dem Fehler nur um einen Rechen oder Deklarationsfehler handeln.... im eeprom steht nach überprüfung der richtige wert.

da er das temporäre speichern richtig macht... gehe ich nicht von einem Logikfehler im Code aus... schließe das natürlich aber nicht aus...

einfach mal laden und ausführen....
0 - Byte 0 bis 3 löschen
# - aktuellen Wert speichern

mal resetten, und schauen was er als alte Zeit ausgibt....

Lieber Gruß
ChrisS

Go Up