Schönen guten Morgen,
ich habe das jetzt einmal mit Interrupts probiert. Es scheint soweit zu laufen ( die Grundfunktion ist gegeben ) aber es geht immer noch nicht mit den 60 min. Ich kann maximal mit einem Intervall von 55 min die Temperatur auslesen und speichern.
Der Code gefällt mir im allgemeinen auch noch nicht, es ist sehr unübersichtlich, weiß aber nicht wie ich es besser machen kann?.
Vlt. habt Ihr noch ein paar kleine Tipps wie ich das Programm verbessern kann und meine gewünschte Funktion erreichen kann.
Hier der Code
#include <avr/io.h>
#include <avr/interrupt.h>
#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include "RTClib.h"
LiquidCrystal lcd ( A2, A1, 6, 5, 2, 3 );
OneWire ds ( 9 );
const int chipSelect = 4;
RTC_DS1307 RTC;
byte secound;
double Wert = 1;
byte timer = 0;
const int hoch = 7; // Taster für Hochzählen defenieren
const int runter = 8; // Taster für Runterzählen defenierern
int l = 0;
void setup () {
lcd.begin(16,2); // lcd initialisieren
lcd.clear ();
pinMode ( hoch, INPUT ); // Port als input
pinMode ( runter, INPUT ); // Port als input
digitalWrite ( hoch, HIGH ); // Pull up
digitalWrite ( runter, HIGH ); // pull up
Wire.begin();
RTC.begin();
lcd.print ( "Init SD card..." );
delay ( 1000 );
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
lcd.clear();
lcd.print("Card failed");
delay ( 2000 ); // don't do anything more:
return;
}
lcd.clear();
lcd.print("card init.");
delay ( 2000 );
lcd.clear();
cli();
TCCR1A = 0;
TCCR1B = 0;
OCR1A = 15624;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
sei();
lcd.setCursor ( 0,0 );
lcd.print ( "Log: " );
lcd.print ( Wert );
lcd.print ( " min." );
}
void loop () {
if ( digitalRead ( hoch ) == LOW ) {
l = 0;
Wert += 1.0f; // zählt in 1,0'ner schritten hoch
lcd.clear();
lcd.setCursor ( 0,0 );
lcd.print ( "Log: " );
lcd.print ( Wert );
lcd.print ( " min." );
secound = 0;
// Entprellung
while ( digitalRead ( hoch ) == LOW ) {}
}
// Taster für Runterzählen abfragen
if ( digitalRead ( runter ) == LOW ) {
l = 0;
Wert -= 1.0f; // zählt in 1,0'ner schritten runter
lcd.clear();
lcd.setCursor ( 0,0 );
lcd.print ( "Log: " );
lcd.print ( Wert );
lcd.print ( " min." );
secound = 0;
// Entprellung
while ( digitalRead ( runter ) == LOW ) {}
}
}
ISR ( TIMER1_COMPA_vect) {
secound ++;
if ( secound == 60 ) {
secound = 0;
timer ++;
}
if ( timer == Wert ) {
timer = 0;
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
return;
}
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
type_s = 1;
break;
case 0x28:
type_s = 0;
break;
default:
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1);
delay(750);
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// convert the data to actual temperature
unsigned int raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// count remain gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
if ( celsius >= 100 ) {
lcd.setCursor ( 0,1 );
lcd.print ( "Temp: ");
lcd.print ( "-");
lcd.print ( 4095 - celsius ); // Wenn Temperatur ins Negative geht, dann diese Berechnung
lcd.print(0xDF,BYTE); // 0xDF, BYTE geht nur für LCD
lcd.print("C");
} else {
lcd.setCursor ( 0,1 );
lcd.print("Temp.: ");
lcd.print(celsius ); // Temperatur im positiven ausgeben
lcd.print(0xDF,BYTE); // 0xDF, BYTE geht nur für LCD
lcd.print("C");
}
DateTime now = RTC.now();
File dataFile = SD.open("datalog.txt", FILE_WRITE); // Temperatur in .txt schreiben
if (dataFile) {
if ( celsius >= 100 ) {
dataFile.print ( "-");
dataFile.print ( 4095 - celsius );
dataFile.print ( " ; " );
dataFile.print(now.hour(),DEC);
dataFile.print(":");
dataFile.print(now.minute(),DEC);
dataFile.print ( " ; " );
dataFile.print(now.day(),DEC);
dataFile.print(".");
dataFile.print(now.month(),DEC);
dataFile.print(".");
dataFile.println(now.year(),DEC);
dataFile.close();
} else {
dataFile.print(celsius);
dataFile.print ( " ; " );
dataFile.print(now.hour(),DEC);
dataFile.print(":");
dataFile.print(now.minute(),DEC);
dataFile.print ( " ; " );
dataFile.print(now.day(),DEC);
dataFile.print(".");
dataFile.print(now.month(),DEC);
dataFile.print(".");
dataFile.println(now.year(),DEC);
dataFile.close();
}}
}
}
Liebe Grüße