Code:
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
#define ein 1
#define aus 2
#define Servopin_high (PORTD |= (1<<DDD3))
#define Servopin_low (PORTD &= ~(1<<DDD3))
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
}
//-------------------------------
#define ONE_WIRE_BUS 2 //Pin 17 als OneWire
OneWire ourWire(ONE_WIRE_BUS); /* Ini oneWire instance */
DallasTemperature sensors(&ourWire);
float Pooltemp,Solartemp,Hys;
char buffer[20];
int dallas_sensor_counter,Poolsoll,Hysterese,servo,servo_alt;
unsigned long millis_alt,millis_altx;
volatile char servopin;
// Servosteuerung von https://www.pololu.com/docs/0J57/8.a
// This line specifies what pin we will use for sending the
// signal to the servo. You can change this.
//#define SERVO_PIN 3 ==> direkter Befehl an PIN
// This is the time since the last rising edge in units of 0.5us.
uint16_t volatile servoTime = 0;
// This is the pulse width we want in units of 0.5us.
uint16_t volatile servoHighTime = 3000;
// This is true if the servo pin is currently high.
boolean volatile servoHigh = false;
void Anzeige()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Pool");
lcd.setCursor(0,1);
lcd.print("Solar");
}
//---------------------------------------------
void setup() {
lcd.begin(16, 2); // start the library
Anzeige();
sensors.begin();
sensors.setResolution(12);
//pinMode(3, OUTPUT); // sets the pin3 as output
DDRD |=(1<<DDD3); // servo pin3 as output
Poolsoll=EEPROM.read(10);
Hysterese=EEPROM.read(12);
if (Poolsoll<20) Poolsoll=20;
if (Poolsoll>32) Poolsoll=32;
if (Hysterese<1) Hysterese=1;
if (Hysterese>10) Hysterese=10;
millis_alt=0;
millis_altx=0;
// Turn on CTC mode. Timer 2 will count up to OCR2A, then
// reset to 0 and cause an interrupt.
TCCR2A = (1 << WGM21);
// Set a 1:8 prescaler. This gives us 0.5us resolution.
TCCR2B = (1 << CS21);
// Put the timer in a good default state.
TCNT2 = 0;
OCR2A = 255;
TIMSK2 |= (1 << OCIE2A); // Enable timer compare interrupt.
sei(); // Enable interrupts.
}
void servoSetPosition(uint16_t highTimeMicroseconds)
{
TIMSK2 &= ~(1 << OCIE2A); // disable timer compare interrupt
servoHighTime = highTimeMicroseconds * 2;
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt
}
ISR(TIMER2_COMPA_vect)
{
// The time that passed since the last interrupt is OCR2A + 1
// because the timer value will equal OCR2A before going to 0.
servoTime += OCR2A + 1;
static uint16_t highTimeCopy = 3000;
static uint8_t interruptCount = 0;
if(servoHigh)
{
if(++interruptCount == 2)
{
OCR2A = 255;
}
// The servo pin is currently high.
// Check to see if is time for a falling edge.
// Note: We could == instead of >=.
if(servoTime >= highTimeCopy)
{
// The pin has been high enough, so do a falling edge.
Servopin_low;
servoHigh = false;
interruptCount = 0;
}
}
else
{
// The servo pin is currently low.
if(servoTime >= 40000)
{
// We've hit the end of the period (20 ms),
// so do a rising edge.
highTimeCopy = servoHighTime;
if (servopin==ein) Servopin_high; // nur einschalten wenn nötig
servoHigh = true;
servoTime = 0;
interruptCount = 0;
OCR2A = ((highTimeCopy % 256) + 256)/2 - 1;
}
}
}
//---------------------------------------------
//------------------------------------------------
void loop() {
{
if (millis()-millis_alt>=1000UL)
{
sensors.requestTemperatures(); // Temperaturen abfragen
if (dallas_sensor_counter==0) Pooltemp = sensors.getTempCByIndex(0)-0.9;
if (dallas_sensor_counter==1) Solartemp = sensors.getTempCByIndex(1);
dallas_sensor_counter++;if (dallas_sensor_counter>=2)dallas_sensor_counter=0;
millis_alt=millis();
}
dtostrf( Pooltemp, 5, 1, buffer );
lcd.setCursor(6,0);
lcd.print(buffer);
dtostrf( Solartemp, 5, 1, buffer );
lcd.setCursor(6,1);
lcd.print(buffer);
if (Solartemp>=Pooltemp+(float)Hysterese)
{
servo=ein;
}
if (Solartemp<=Pooltemp+0.2)
{
servo=aus;
}
if (Pooltemp>(float)Poolsoll)
{
servo=aus;
}
if (Solartemp<10) servo=aus; // bei Fehler im Sensor ausschalten
if (Pooltemp<10) servo=aus;
}
if (servo!=servo_alt) // nur Servo einschalten wenn sich der Status ändert.
{
lcd.setCursor(13,0); lcd.print("x");
millis_altx=millis();
if (servo== ein)
{
lcd.setCursor(13,1);
servoSetPosition(1900);
lcd.print("Ein");
}
if (servo== aus)
{
lcd.setCursor(13,1);
servoSetPosition(1100);
lcd.print("Aus");
}
servo_alt= servo;
servopin=ein;
}
if (millis()-millis_altx>=2000UL) {servopin=aus;lcd.setCursor(13,0); lcd.print(" ");} // nach ca 2s Servo ausschalten
read_LCD_buttons();
lcd_key = read_LCD_buttons();
if (lcd_key==btnSELECT)
{
Poolsoll=Poolsoll-1; if (Poolsoll<20) Poolsoll=20;
EEPROM.update(10, Poolsoll);
dtostrf( Poolsoll, 5, 1, buffer );
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Pool Soll Temp");
lcd.setCursor(0,1);
lcd.print(buffer);
_delay_ms(1500);Anzeige();
}
if (lcd_key==btnLEFT)
{
Poolsoll=Poolsoll+1; if (Poolsoll>32) Poolsoll=32;
EEPROM.update(10, Poolsoll);
dtostrf( Poolsoll, 5, 1, buffer );
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Pool Soll Temp");
lcd.setCursor(0,1);
lcd.print(buffer);
_delay_ms(1500);Anzeige();
}
if (lcd_key==btnUP)
{
Hysterese=Hysterese+1; if (Hysterese>10) Hysterese=10;
EEPROM.update(12, Hysterese);
dtostrf( Hysterese, 5, 1, buffer );
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hysterese");
lcd.setCursor(0,1);
lcd.print(buffer);
_delay_ms(1500);Anzeige();
}
if (lcd_key==btnDOWN)
{
Hysterese=Hysterese-1; if (Hysterese<1) Hysterese=1;
EEPROM.update(12, Hysterese);
dtostrf( Hysterese, 5, 1, buffer );
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hysterese");
lcd.setCursor(0,1);
lcd.print(buffer);
_delay_ms(1500);Anzeige();
}
if (lcd_key==btnRIGHT) {}
Lesezeichen