Billedgalleri
Styring Til Solvarme Eller andet
Til salg
Fri fragt + Tryg betaling 22 kr.
Tryg handel med Fiks færdig
Efter leveringen har du 24 timer til at kontrollere produktet. Hvis der er noget galt med produktet, får du dine penge tilbage
Varebeskrivelse
Stand: Brugt - men i god stand
Det program der ligge på den
Kan progameres via Arduino ide (gratis)
og al dokumentation kan du få med
#include
#include
#include
#include
// --- DS18B20 Tilføjelser ---temperatur sensor
#include
#include
#define ONE_WIRE_BUS 14 // Vælg den pin hvor din DS18B20 dataledning er tilsluttet
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// --- FASTE DS18B20 ROM-ADRESSER ---
// Indtast dine 8 føleres unikke hex-adresser herunder:
DeviceAddress addr_Sol = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x01 };
DeviceAddress addr_Tankbund = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x02 };
DeviceAddress addr_Tanktop = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x03 };
DeviceAddress addr_Tanktop2 = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x04 };
DeviceAddress addr_Tankbun2 = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x05 };
DeviceAddress addr_Solretur = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x06 };
DeviceAddress addr_Slojfe = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x07 };
DeviceAddress addr_Ude = { 0x28, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08 };
// --- KALMAN FILTER STRUKTUR OG VARIABLER ---
struct KalmanFilter {
float q = 0.05; // Processtøj (hvor hurtigt reagerer filteret på ændringer)
float r = 0.50; // Målestøj (hvor meget støj filtreres væk)
float p = 1.00; // Estimeret fejl
float x = 0.00; // Estimeret værdi (temperatur)
};
KalmanFilter kalman[9]; // 8 kanaler (bruger indeks 1-8)
float updateKalman(int channel, float measurement) {
// 1. Prediction update
kalman[channel].p = kalman[channel].p + kalman[channel].q;
// 2. Measurement update
float k = kalman[channel].p / (kalman[channel].p + kalman[channel].r); // Kalman Gain
kalman[channel].x = kalman[channel].x + k * (measurement - kalman[channel].x);
kalman[channel].p = (1.0 - k) * kalman[channel].p;
return kalman[channel].x;
}
#define CS_PIN 8
#define TFT_DC 9
#define TFT_CS 10
const byte debounceTime = 50;
volatile unsigned long lastButtonPress;
volatile boolean buttonPressed = 0;
int navNum0;
int navNum1;
Adafruit_ST7796S_kbv tft = Adafruit_ST7796S_kbv(TFT_CS, TFT_DC);
Encoder enc1(28,27); // Nano / Teensy
int buttonPin = 26; // Nano / Teensy
int Los = 0;
double AD [10];
int pwm_pin = 32; // PWM pin 32
int a, i;
int Pir = 10;
int Vis = 0, Side = 0, Inst = 6, Tou = 120, Soltank = 0, Led_Display = 180, Prio = 0, Fjernvarme = 0, Vt = 0, Vf = 0;
int Output = 2, TopTankInst = 0, OHeat = 0, Trin = 0, Displayvis = 0, Gem_hent = 3, Ude = 0;
float Diffon = 8, Diffoff = 5, Toptank = 55, OverHeatOn = 75, OverHeatOFF = 50;
double Sol = 0, Tankbund = 0, Tanktop = 0, Tanktop2 = 0, Tempsol = 0, Solretur = 0, Tankbun2 = 0, Slojfe = 0;
unsigned long previousTime = 0;
byte seconds;
byte minutes;
// Colors for fonts
const uint16_t BLACK = 0x0000;
const uint16_t GREY = 0x7AEF;
const uint16_t BLUE = 0x001F;
const uint16_t RED = 0xF800;
const uint16_t GREEN = 0x07E0;
const uint16_t CYAN = 0x07FF;
const uint16_t MAGENTA = 0xF81F;
const uint16_t YELLOW = 0xFFE0;
const uint16_t WHITE = 0xFFFF;
void setup() {
pinMode(26, INPUT_PULLUP); // Encoder button
pinMode(22, OUTPUT); // Display lys
pinMode(7, OUTPUT); // Relæ
pinMode(24, OUTPUT); // Relæ
pinMode(25, OUTPUT); // Relæ
pinMode(0, OUTPUT); // Relæ
pinMode(1, OUTPUT); // Relæ
pinMode(3, OUTPUT); // Relæ
pinMode(5, OUTPUT); // Relæ
pinMode(6, OUTPUT); // Relæ
Eeprom_hent();
while (!Serial && (millis() <= 1000));
pinMode(buttonPin, INPUT_PULLUP);
pinMode(pwm_pin, OUTPUT);
Serial.begin(9600);
// Start DS18B20 sensorene
sensors.begin();
digitalWrite(22, HIGH);
Serial.println("teensy nano v1 - DS18B20 med Kalman");
tft.begin();
tft.setRotation(3);
tft.setTextSize(3);
tft.setTextColor(GREEN);
tft.fillScreen(BLACK);
digitalWrite(22, HIGH);
tft.setCursor(0, 0);
tft.print("teensy nano v1");
delay(4000);
}
void Read(void) {
// Anmod om temperaturmåling fra alle DS18B20 sensorer på bussen
sensors.requestTemperatures();
// Mål rå-temperaturer direkte ved hjælp af faste ROM-adresser
float raw1 = sensors.getTempC(addr_Sol);
float raw2 = sensors.getTempC(addr_Tankbund);
float raw3 = sensors.getTempC(addr_Tanktop);
float raw4 = sensors.getTempC(addr_Tanktop2);
float raw5 = sensors.getTempC(addr_Tankbun2);
float raw6 = sensors.getTempC(addr_Solretur);
float raw7 = sensors.getTempC(addr_Slojfe);
float raw8 = sensors.getTempC(addr_Ude);
// Send målingerne igennem Kalman-filteret
AD[1] = updateKalman(1, raw1);
AD[2] = updateKalman(2, raw2);
AD[3] = updateKalman(3, raw3);
AD[4] = updateKalman(4, raw4);
AD[5] = updateKalman(5, raw5);
AD[6] = updateKalman(6, raw6);
AD[7] = updateKalman(7, raw7);
AD[8] = updateKalman(8, raw8);
Serial.print("Los =");
Serial.println(Los);
Serial.print("Vis =");
Serial.println(Vis);
Serial.print("Inst =");
Serial.println(Inst);
Serial.print("OverHeatOFF =");
Serial.println(OverHeatOFF);
}
void Input(void) {
if (Tanktop - Diffon > TopTankInst)
Prio = 1;
if (Tanktop - Diffoff < TopTankInst)
Prio = 0;
if (Sol - Diffon > Tankbund)
Soltank = 1;
if (Sol - Diffoff < Tankbund)
Soltank = 0;
if (Sol > OverHeatOn)
OHeat = 1;
if (Sol < OverHeatOFF)
OHeat = 0;
if (Tanktop2 > OverHeatOn) // Tank2 Fjernvarme ind
Fjernvarme = 1;
if (Tanktop2 < OverHeatOFF)
Fjernvarme = 0;
if (OHeat == 1) {
digitalWrite(0, HIGH); // solpumpe on
digitalWrite(6, LOW);
digitalWrite(3, HIGH); // overheat ventil on
analogWrite(pwm_pin, 204); // solpumpe på max
Output = 1;
}
if (OHeat == 0) {
digitalWrite(3, LOW); // overheat ventil off
digitalWrite(6, HIGH);
if (Soltank == 1) {
digitalWrite(0, HIGH); // solpumpe on
Trin = 1;
}
if (Soltank == 0) {
digitalWrite(0, LOW); // solpumpe off
digitalWrite(3, LOW); // overheat ventil off
digitalWrite(6, HIGH);
Trin = 2;
}
}
i = Sol;
i = map(i, 50, 100, 60, 204);
if (i < 60) {
i = 60;
}
if (i > 204) {
i = 204;
}
a = i * 100 / 256;
if (Tanktop > 50) {
digitalWrite(1, HIGH); // ventil on tar fra soltank
Vt = 1;
}
if (Tanktop < 45) {
digitalWrite(1, LOW); // ventil off
Vt = 0;
}
if (Tankbun2 > 50) {
digitalWrite(5, LOW); // ventil on varme tilskud
Vf = 0;
}
if (Tankbun2 < 45) {
digitalWrite(5, HIGH); // ventil off
Vf = 1;
}
}
void Eeprom_gem(void) {
tft.begin();
tft.setRotation(3);
tft.setTextSize(3);
tft.setTextColor(GREEN);
tft.fillScreen(RED);
tft.setCursor(0, 0);
tft.print(" Gemmer i Eprom ");
Displayvis = 0;
tft.fillScreen(RED);
int a;
a = EEPROM.read(0);
if (a != Diffon) {
EEPROM.write(0, Diffon);
tft.setCursor(0, 0);
tft.print("Opdater Diff on ");
} else {
tft.setCursor(0, 0);
tft.print(" Diff on OK ");
}
a = EEPROM.read(1);
if (a != Diffoff) {
EEPROM.write(1, Diffoff);
tft.setCursor(0, 30);
tft.print("Opdater Diff on");
} else {
tft.setCursor(0, 30);
tft.print(" Diff on OK");
}
a = EEPROM.read(2);
if (a != Toptank) {
EEPROM.write(2, Toptank);
tft.setCursor(0, 60);
tft.print("Opdater Toptank");
} else {
tft.setCursor(0, 60);
tft.print(" Toptank OK");
}
a = EEPROM.read(3);
if (a != OverHeatOn) {
EEPROM.write(3, OverHeatOn);
tft.setCursor(0, 90);
tft.print("Opdater OverHeatOn");
} else {
tft.setCursor(0, 90);
tft.print(" OverHeatOn OK");
}
a = EEPROM.read(4);
if (a != OverHeatOFF) {
EEPROM.write(4, OverHeatOFF);
tft.setCursor(0, 120);
tft.print("Opdater OverHeatOFF ");
} else {
tft.setCursor(0, 120);
tft.print(" OverHeatOFF OK ");
}
Vis = 0;
}
void Eeprom_hent(void) {
int a;
a = EEPROM.read(0);
if (a < 100) {
Diffon = a;
}
a = EEPROM.read(1);
if (a < 100) {
Diffoff = a;
}
a = EEPROM.read(2);
if (a < 100) {
Toptank = a;
}
a = EEPROM.read(3);
if (a != 255) {
OverHeatOn = a;
}
a = EEPROM.read(4);
if (a != 30) {
OverHeatOFF = a;
}
}
void Time(void) {
digitalWrite(22, HIGH);
if (millis() >= (previousTime)) {
previousTime = previousTime + 1000;
seconds = seconds + 1;
if (seconds == 60) {
seconds = 0;
minutes = minutes + 1;
}
if (minutes == 60) {
minutes = 0;
}
}
}
void VisButton(void) {
tft.fillRoundRect(0, 200, 50, 45, 20, RED);
tft.fillRoundRect(60, 200, 50, 45, 20, RED);
tft.fillRoundRect(130, 200, 50, 45, 20, RED);
tft.fillRoundRect(200, 200, 50, 45, 20, RED);
tft.fillRoundRect(270, 200, 50, 45, 20, RED);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.setCursor(1, 215);
tft.println("Side");
tft.setCursor(61, 215);
tft.println("Inst");
tft.setTextSize(4);
tft.setCursor(145, 210);
tft.println("+");
tft.setTextSize(4);
tft.setCursor(215, 210);
tft.println("-");
tft.setTextSize(2);
tft.setCursor(277, 215);
tft.println("Gem");
}
void Vis_0(void) {
tft.begin();
tft.setRotation(3);
tft.setTextSize(3);
tft.setTextColor(GREEN);
tft.fillScreen(BLACK);
tft.setCursor(0, 0);
tft.print("Sol = ");
tft.setCursor(0, 30);
tft.print("Tanktop = ");
tft.setCursor(0, 60);
tft.print("Tankbund = ");
tft.setCursor(0, 90);
tft.print("Tanktop2 = ");
tft.setCursor(0, 120);
tft.print("Tankbun2 = ");
tft.setCursor(0, 150);
tft.print("Solretur = ");
tft.setCursor(0, 180);
tft.print("Slojfe = ");
tft.setCursor(90, 210);
tft.setTextColor(YELLOW, BLACK);
tft.setTextSize(2);
tft.println("PWM =");
tft.setCursor(220, 210);
tft.println("P =");
Vis = 1;
}
void Vis_1(void) {
tft.setTextSize(3);
tft.setRotation(3);
tft.setTextColor(GREEN, BLACK);
tft.setCursor(190, 0);
tft.print(Sol, 1);
tft.setCursor(300, 0);
tft.println("C");
tft.setCursor(190, 30);
tft.println(Tanktop, 1);
tft.setCursor(300, 30);
tft.println("C");
tft.setCursor(190, 60);
tft.println(Tankbund, 1);
tft.setCursor(300, 60);
tft.println("C");
tft.setCursor(190, 90);
tft.println(Tanktop2, 1);
tft.setCursor(300, 90);
tft.println("C");
tft.setCursor(190, 120);
tft.println(Tankbun2, 1);
tft.setCursor(300, 120);
tft.println("C");
tft.setCursor(190, 150);
tft.println(Solretur, 1);
tft.setCursor(300, 150);
tft.println("C");
tft.setCursor(190, 180);
tft.println(Slojfe, 1);
tft.setCursor(300, 180);
tft.println("C");
tft.setTextColor(YELLOW, BLACK);
tft.setTextSize(2);
tft.setCursor(160, 210);
tft.println(i, 1);
tft.setCursor(270, 210);
tft.println(a, 1);
tft.setCursor(300, 210);
tft.println("%");
if (Trin == 1) {
tft.setCursor(0, 210);
tft.setTextColor(YELLOW, BLACK);
tft.setTextSize(2);
tft.println("I Tank ");
}
if ((Trin == 2) || (Trin == 6)) {
tft.setCursor(0, 210);
tft.setTextColor(YELLOW, BLACK);
tft.setTextSize(2);
tft.println("Stopper");
}
}
void Vis_2(void) {
tft.begin();
tft.setRotation(3);
tft.setTextSize(3);
tft.setTextColor(GREEN);
tft.fillScreen(BLACK);
tft.setCursor(0, 30);
tft.print("TopTankInst");
tft.setCursor(0, 60);
tft.print("Diff on = ");
tft.setCursor(0, 90);
tft.print("Diff off = ");
tft.setCursor(0, 120);
tft.print("OverHeatOn ");
tft.setCursor(0, 150);
tft.print("OverHeatOFF");
Vis = 3;
}
void Vis_3(void) {
tft.setTextSize(3);
tft.setRotation(3);
tft.setTextColor(YELLOW, BLACK);
tft.setCursor(0, 0);
tft.print(TopTankInst);
tft.setCursor(30, 0);
tft.println("BT");
tft.setCursor(105, 0);
tft.println(Soltank);
tft.setCursor(135, 0);
tft.println("ST");
tft.setCursor(205, 0);
tft.println(OHeat);
tft.setCursor(235, 0);
tft.println("SG");
tft.setTextSize(2);
tft.setCursor(80, 180);
tft.println(Trin);
tft.setCursor(0, 180);
tft.println("Trin");
tft.setCursor(240, 180);
tft.println(Output);
tft.setCursor(120, 180);
tft.println("Output");
tft.setTextSize(3);
tft.setCursor(220, 30);
tft.println(Toptank, 1);
tft.setCursor(220, 60);
tft.println(Diffon, 1);
tft.setCursor(220, 90);
tft.println(Diffoff, 1);
tft.setCursor(220, 120);
tft.println(OverHeatOn, 1);
tft.setCursor(220, 150);
tft.println(OverHeatOFF, 1);
if (Inst == 0) {
tft.fillRect(300, 60, 90, 20, BLACK);
if (Los == 2) {
tft.fillRect(300, 30, 90, 20, GREEN);
}
if (Los == 1) {
tft.fillRect(300, 30, 90, 20, RED);
}
tft.setTextSize(2);
tft.setTextColor(WHITE);
tft.setCursor(277, 215);
tft.println("Gem");
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(277, 5);
tft.println("INS");
}
if (Inst == 1) {
tft.fillRect(300, 30, 90, 20, BLACK);
tft.fillRect(300, 90, 90, 20, BLACK);
if (Los == 2) {
tft.fillRect(300, 60, 90, 20, GREEN);
}
if (Los == 1) {
tft.fillRect(300, 60, 90, 20, RED);
}
}
if (Inst == 2) {
tft.fillRect(300, 60, 90, 20, BLACK);
tft.fillRect(300, 120, 90, 20, BLACK);
if (Los == 2) {
tft.fillRect(300, 90, 90, 20, GREEN);
}
if (Los == 1) {
tft.fillRect(300, 90, 90, 20, RED);
}
}
if (Inst == 3) {
tft.fillRect(300, 90, 90, 20, BLACK);
tft.fillRect(300, 150, 90, 20, BLACK);
if (Los == 2) {
tft.fillRect(300, 120, 90, 20, GREEN);
}
if (Los == 1) {
tft.fillRect(300, 120, 90, 20, RED);
}
}
if (Inst == 4) {
tft.fillRect(300, 120, 90, 20, BLACK);
if (Los == 2) {
tft.fillRect(300, 150, 90, 20, GREEN);
}
if (Los == 1) {
tft.fillRect(300, 150, 90, 20, RED);
}
tft.setTextSize(2);
tft.setTextColor(WHITE);
tft.setCursor(277, 215);
tft.println("Gem");
}
if (Inst == 5) {
tft.fillRect(300, 30, 90, 20, BLACK);
tft.fillRect(300, 150, 90, 20, BLACK);
tft.setTextSize(2);
tft.setTextColor(GREEN);
tft.setCursor(277, 215);
tft.println("Gem");
tft.setTextColor(BLACK);
tft.setCursor(277, 5);
tft.println("INS");
}
if (Inst == 6) {
tft.fillRect(300, 30, 90, 20, BLACK);
tft.setTextSize(2);
if (Los == 0) {
tft.setTextColor(RED, BLACK);
tft.setCursor(277, 5);
tft.println("OUT");
}
if (Los == 1) {
tft.setTextColor(GREEN, BLACK);
tft.setCursor(277, 5);
tft.println("INS");
}
tft.setTextColor(WHITE);
tft.setCursor(277, 215);
tft.println("Gem");
}
}
void Vis_4(void) {
tft.begin();
tft.setRotation(3);
tft.setTextSize(2);
tft.setTextColor(GREEN);
tft.fillScreen(BLACK);
tft.setCursor(0, 30);
tft.print("Sol Pumpe = ");
tft.setCursor(0, 60);
tft.print("OverHeat = ");
tft.setCursor(0, 90);
tft.print("Ventil Tank = ");
tft.setCursor(0, 120);
tft.print("Ventil Fjern Varme = ");
Vis = 5;
}
void Vis_5(void) {
tft.setTextSize(2);
tft.setRotation(3);
tft.setTextColor(GREEN, BLACK);
if (Soltank == 1) {
tft.setCursor(150, 30);
tft.setTextColor(RED, BLACK);
tft.println(" Solpumpe ON ");
}
if (Soltank == 0) {
tft.setTextColor(GREEN, BLACK);
tft.setCursor(150, 30);
tft.println(" Solpumpe OFF ");
}
if (OHeat == 0) {
tft.setTextColor(GREEN, BLACK);
tft.setCursor(150, 60);
tft.println(" OverHeat OFF ");
}
if (OHeat == 1) {
tft.setTextColor(RED, BLACK);
tft.setCursor(150, 60);
tft.println(" OverHeat ON ");
}
if (Vt == 0) {
tft.setCursor(200, 90);
tft.setTextColor(GREEN, BLACK);
tft.println(" OFF ");
}
if (Vt == 1) {
tft.setCursor(200, 90);
tft.setTextColor(RED, BLACK);
tft.println(" ON ");
}
if (Vf == 0) {
tft.setCursor(250, 120);
tft.setTextColor(GREEN, BLACK);
tft.println(" OFF ");
}
if (Vf == 1) {
tft.setCursor(250, 120);
tft.setTextColor(RED, BLACK);
tft.println(" ON ");
}
}
void menuNav(byte dir) {
// LEFT
if ((dir == 0) && (Los == 2)) {
if ((Inst == 0) && (Toptank <= 100)) {
Toptank = Toptank - 1;
}
if ((Inst == 1) && (Diffon > 0)) {
Diffon = Diffon - 1;
}
if ((Inst == 2) && (Diffoff > 0)) {
Diffoff = Diffoff - 1;
}
if ((Inst == 3) && (OverHeatOn > 0)) {
OverHeatOn = OverHeatOn - 1;
}
if ((Inst == 4) && (OverHeatOFF > 0)) {
OverHeatOFF = OverHeatOFF - 1;
}
}
if ((dir == 0) && (Los == 1)) {
Inst--;
if (Inst < 0) {
Inst = 6;
}
}
if ((dir == 0) && (Los == 0)) {
if (Vis == 1) Vis = 2;
if (Vis == 3) Vis = 4;
if (Vis == 5) Vis = 6;
if (Vis == 6) Vis = 0;
}
// RIGHT
if ((dir == 1) && (Los == 2)) {
if ((Inst == 0) && (Toptank <= 100)) {
Toptank = Toptank + 1;
}
if ((Inst == 1) && (Diffon < 20)) {
Diffon = Diffon + 1;
}
if ((Inst == 2) && (Diffoff < 20)) {
Diffoff = Diffoff + 1;
}
if ((Inst == 3) && (OverHeatOn < 180)) {
OverHeatOn = OverHeatOn + 1;
}
if ((Inst == 4) && (OverHeatOFF < 130)) {
OverHeatOFF = OverHeatOFF + 1;
}
}
if ((dir == 1) && (Los == 1)) {
Inst++;
if (Inst >= 7) {
Inst = 0;
}
}
if ((dir == 1) && (Los == 0)) {
if (Vis == 1) Vis = 6;
if (Vis == 3) Vis = 0;
if (Vis == 5) Vis = 2;
if (Vis == 6) Vis = 4;
}
}
void buttonNav() {
if (((Los == 1) && (Vis == 3) && (Inst == 6))) {
Los = 0;
} else if (((Los == 1) && (Vis == 3) && (Inst == 5))) {
Gem_hent = 2;
} else if ((Los == 1) && (Vis == 3)) {
Los = 2;
} else if ((Los == 0) && (Vis == 3)) {
Los = 1;
} else if ((Los == 2) && (Vis == 3)) {
Los = 1;
} else {
Los = 0;
}
}
void button_ISR() {
if (digitalRead(buttonPin) == LOW) {
buttonPressed = 1;
buttonNav();
} else {
buttonPressed = 0;
}
}
void loop() {
int newEnc1 = enc1.read() / 4;
if (newEnc1 > 0) { // left
Serial.println(" enc1 ");
enc1.write(0);
menuNav(1);
}
if (newEnc1 < 0) { // right
enc1.write(0);
menuNav(0);
}
Read();
// Hent de filtrerede Kalman-værdier over i dine variabler
Sol = AD[1];
Tankbund = AD[2];
Tanktop = AD[3];
Tanktop2 = AD[4];
Tankbun2 = AD[5];
Solretur = AD[6];
Slojfe = AD[7];
Ude = AD[8];
Time();
button_ISR();
if (Gem_hent == 2) {
Eeprom_gem();
delay(1500);
Gem_hent = 0;
Vis = 2;
}
Input();
if (Vis == 0) Vis_0();
if (Vis == 1) Vis_1();
if (Vis == 2) Vis_2();
if (Vis == 3) Vis_3();
if (Vis == 4) Vis_4();
if (Vis == 5) Vis_5();
}
Brugerprofil
Du skal være logget ind for at se brugerprofiler og sende beskeder.
Annoncens metadata
Sidst redigeret: 28.8.2026 kl. 12:54 ・ Annonce-ID: 24379630

