Hallo miteinander!
Ich beschäftige mich schon länger mit Arduino und hab schon ein paar Programme geschrieben. Nur jetzt hab ich ein Problem
Ich programmiere den ATTINY85 mithilfe vom Arduino, klappt wunderbar.
Mein Projekt ist ein Thermometer dass die Temperatur an ein 16x2 Display ausgibt.
Displayansteuerung über 2-Wire und Schieberegister funktioniert.
Mein Problem ist der Interrupt. Ich will wenn ich auf einen Knopf drücke (Pin0) soll die Beleuchtung angehen und wenn ich länger drücke soll er zu "min" "Max" wechseln.
nach ein paar Sekunden soll er wieder schlafen gehen und alle paar Sek. einmal messen.
Momentan misst er alle ~8 sek. und ich kann zwischen min und max nur wechseln wenn er vom schlaf modus aufwacht und die loop() einmal durchfährt.
Könnt Ihr mir helfen?
LG Paz
#include <ShiftRegLCD.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
volatile boolean f_wdt=1;
ShiftRegLCD srlcd(3, 2, 1,2,1);
const int buttonPin = 0;
float temparatur =0; //Variable zum Zwischenspeichern der Temperatur
int x,y,m1,m2,m3,m4;
float temp_old=0;
float ergbnis_old;
int buttonState = 0;
int lastButtonState=0;
int r=0;
void setup()
{
// Print a message to the LCD.
pinMode(4,OUTPUT);
pinMode(0,INPUT);
analogWrite(4,125);
//sbi(GIMSK,PCIE);
//sbi(PCMSK,PCINT0);
m1=25;
m2=25;
m3=1;
m4=1;
cbi( MCUCR,SE ); // sleep enable, power down mode
cbi( MCUCR,SM0 ); // power down mode
sbi( MCUCR,SM1 ); // power down mode
setup_watchdog(9);
delay(1000);
}
void loop()
{
if (f_wdt==1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs
f_wdt=0;
digitalWrite(4,LOW);
buttonState = digitalRead(buttonPin);
umrechnen();
if(buttonState==HIGH)
{
r=!r;
}
if(r==1)
{
schreiben();
delay(200);
}
if(r==0)
{
schreiben();
delay(200);
}
}
else{
digitalWrite(4,HIGH);
system_sleep();
delay(500);
}
}
float temp(int rawadc)
// Hilfsfunktion zur Umrechnung auf Grad Celsius
{
int r1 = 4600; // Wert des Festen Wiederstandes des sabbungsteiler
int r2 = 4700; // Wiederstand des Thermristors bei 25grad
int b = 3977; // Fixwert aus Datenblatt
float r_akt; // Aktueller Wiederstand
float temp; //Temporäre Variable
float ergebnis; //
float tn = 23; //Basistemperatur in Grad Celsius
// Wiederstand Therm ausrechnen
//Widerstand auf Temperatur umrechnen
tn = tn+273.15; // Basitemperatur auf Kelvin umrechnen
r_akt = ((4.65/(4.65/1023*rawadc))*r1)-r2; //Aktuellen Widerstand ermitteln
temp = b*tn/(b+log10((r_akt/r2))*tn);
temp = temp - 273.15; //Ergebnis in Grad Celsius umwandeln
ergebnis =temp;
return ergebnis;
}
void umrechnen(){
temparatur = temp(analogRead(0));
x=int(temparatur);
y=int((temparatur*10)-(x*10));
buttonState = digitalRead(buttonPin);
if(temparatur>=temp_old&&x>=m1&&y>=m3){
m1=x;
m3=y;
}
if(temparatur<=temp_old&&x<=m2&&y<=m4){
m2=x;
m4=y;
}
temp_old=temparatur;
}
void schreiben(){
switch (r){
case 0:
srlcd.clear();
srlcd.setCursor(0,0);
srlcd.print("Temperatur");
srlcd.setCursor(0, 2);
srlcd.print(x);
srlcd.print(".");
srlcd.print(y);
srlcd.write(0xDF);
srlcd.print("C");
break;
case 1:
srlcd.clear();
srlcd.setCursor(0, 0);
srlcd.print("Min");
srlcd.setCursor(5, 0);
srlcd.print(m2);
srlcd.print(".");
srlcd.print(m4);
srlcd.write(0xDF);
srlcd.print("C");
srlcd.setCursor(0, 2);
srlcd.print("Max");
srlcd.setCursor(5, 2);
srlcd.print(m1);
srlcd.print(".");
srlcd.print(m3);
srlcd.write(0xDF);
srlcd.print("C");
break;
}
}
void system_sleep() {
cbi(ADCSRA,ADEN); // Switch Analog to Digital converter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable();
sbi(ADCSRA,ADEN); // Switch Analog to Digital converter ON
}
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
//6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
//****************************************************************
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
f_wdt=1; // set global flag
}