Ukladani prebytku "Drama"

Rizeni boileru podle Dramy, doplneno o LCD a mereni teploty, zobrazuji se Wh odeslane do boileru.
Display (cim vice radku tim lepe), ja pouzivam 4 radky 20 znaku, maji je treba tu:
http://aukro.cz/lcd-ctyrradkove-20x4-lc ... 98912.html
nebo tu:
http://aukro.cz/display-lcd-displej-200 ... 73803.html
zapojeno podle prikladu:
http://arduino.cc/en/Tutorial/LiquidCrystal
v prikladu neni podsviceni LED, to jsou posledni 2 piny
a pak se jeste musi pres lcd.begin rict, jak velky je displej, v mem pripade
lcd.begin(20,4);
(s pripojenim LCD me navedl prodejce, fungujenaprosto bez potizi)
teplotni cidla trebas tahle (jde to i bez nich):
http://www.ges.cz/cz/cidlo-teploty-ds18 ... 00306.html
Dale se musi stahnout a rozbalit knihovny OneWire a DallasTemperature, stahoval jsem nejake neaktualni a hazelo to chyby, nakonec jsem pouzil spravne a ok.
Zatim neni uchozen modbus ("nekdo" musi natahnout kabel), tak pouzivam delic se zenerkou (priblizne hodnoty pro 24V), aby se z napeti 18 - 32 stalo 0-5V, no ten AD prevodnik arduina neni moc stabilni, skace to i o 0,2V:
plus
|
zenerka na 18V
|
odpor 4k7
|
odsud drat k arduinu
|
odpor 2k7
|
spolecna zem
Tu je aktualni kod:
Display (cim vice radku tim lepe), ja pouzivam 4 radky 20 znaku, maji je treba tu:
http://aukro.cz/lcd-ctyrradkove-20x4-lc ... 98912.html
nebo tu:
http://aukro.cz/display-lcd-displej-200 ... 73803.html
zapojeno podle prikladu:
http://arduino.cc/en/Tutorial/LiquidCrystal
v prikladu neni podsviceni LED, to jsou posledni 2 piny
a pak se jeste musi pres lcd.begin rict, jak velky je displej, v mem pripade
lcd.begin(20,4);
(s pripojenim LCD me navedl prodejce, fungujenaprosto bez potizi)
teplotni cidla trebas tahle (jde to i bez nich):
http://www.ges.cz/cz/cidlo-teploty-ds18 ... 00306.html
Dale se musi stahnout a rozbalit knihovny OneWire a DallasTemperature, stahoval jsem nejake neaktualni a hazelo to chyby, nakonec jsem pouzil spravne a ok.
Zatim neni uchozen modbus ("nekdo" musi natahnout kabel), tak pouzivam delic se zenerkou (priblizne hodnoty pro 24V), aby se z napeti 18 - 32 stalo 0-5V, no ten AD prevodnik arduina neni moc stabilni, skace to i o 0,2V:
plus
|
zenerka na 18V
|
odpor 4k7
|
odsud drat k arduinu
|
odpor 2k7
|
spolecna zem
Tu je aktualni kod:
- Kód: Vybrat vše
//knihovny a inicializace pro teplomery
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 7
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//display
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int analogPin = 3; // pin na kterem merime napeti na baterii
float targetVoltage = 29; // hodnota ciloveho napeti
int targetPinUp = 50;//pin zmena ciloveho napeti nahoru
int targetPinDown = 52;//pin zmena ciloveho napeti dolu
float targetVoltageStep = 0.1;//skok pro zmenu ciloveho napeti
float minVoltage = 28; // minimalni hodnota napeti, pri ktere se vypina PWM
float analogVoltage = 0; // hodnota na pinu analogPin
int pwmPin = 13; // pin na kterem vyrabime PWM signal
float analogOffset = 18.67;//zacatek rozsahu - posunute zenerkou
float analogRange = 14.1;//mereny rozsah (m)
float diffMax = 0.07; // maximalni odchylka od ciloveho napeti
byte pwmDuty = 0; // kolik % PWM cyklu bude rele zapnuto
byte pwmStepUp = 2; // minimalni zmena skoku PWM nahoru
byte pwmStepDown = 4; // minimalni zmena skoku PWM dolu
int pwmMax = 100; // maximalni povoleny vykon v %
int pwmFreq = 50; // frekvence PWM - maximalne 100Hz!
int pwmCycle = 1; // cas v sekundach mezi zmenou PWM duty
int sumTime = 0; // celkova delka PWM cyklu v ms
int pwmLength = 0; // delka jednoho cyklu v milisekundach
int tempDelay = 10;//kolik cyklu se nevycita teplota (zdrzuje)
int loadPower = 1200; // vykon zateze W pro vypocet akumulovane energie ve Wh
float loadTime;//prubezne nacitani casu ON v milisekundach pro zobrazeni Wh
int j;//pomocna promena pro pocitani cyklu
int k; //pro teplotu, neumim zaokrouhleni jinak
// funkce se provede po startu
void setup() {
lcd.begin(20, 4);
sensors.begin();
// nastaveni digitalniho pinu jako vystup
pinMode(pwmPin, OUTPUT);
pinMode(targetPinUp, INPUT);
pinMode(targetPinDown, INPUT);
// par odberu pro odstraneni hlouposti;
analogRead(analogPin);
analogRead(analogPin);
delay(500);
analogRead(analogPin);
delay(500);
analogRead(analogPin);
}
void loop() {
//zmena ciloveho napeti tlacitky
if (digitalRead(targetPinUp) == HIGH){
targetVoltage +=targetVoltageStep;
}
else if(digitalRead(targetPinDown) == HIGH){
targetVoltage -=targetVoltageStep;
}
// nacteme aktualni napeti (poradi clenu dela bordel, asi pocita na malo desetinych mist?)
analogVoltage= (analogRead(analogPin) * analogRange)/1024+analogOffset;
// pokud je rozdil napeti skutecneho a ciloveho
// ve stanovene mezi, zvysime vykon, jinak snizujeme
if (targetVoltage - analogVoltage < diffMax)
{
if (pwmDuty+pwmStepUp > pwmMax)
{
pwmDuty=pwmMax;
}
else
{
pwmDuty=pwmDuty+pwmStepUp;
}
}
else
{
if (pwmDuty-pwmStepDown < 0)
{
pwmDuty=0;
}
else
{
pwmDuty=pwmDuty-pwmStepDown;
}
}
// skokove stazeni vykonu, pokud dojde k poklesu napeti
if ( analogVoltage < minVoltage)
{
pwmDuty=0;
}
lcd.setCursor(0, 0);
lcd.print("Bat");
if(analogVoltage > analogOffset + 0.1){
lcd.print(analogVoltage, 1);
}
else{
lcd.print("--.-");
}
lcd.print("V ");
lcd.setCursor(10, 0);
lcd.print("On:");
lcd.print(targetVoltage, 1);
lcd.print("V ");
lcd.setCursor(0, 1);
lcd.print("Load ");
lcd.print(pwmDuty);
lcd.print("% ");
//cteni teploty jednou za deset cyklu (zdrzuje)
j++;
if(j==tempDelay){
j=0;
sensors.requestTemperatures();
lcd.setCursor(0, 2);
lcd.print("T1:");
//lcd.setCursor(3, 2);
lcd.print(sensors.getTempCByIndex(0),1);
lcd.print((char)223);
lcd.setCursor(10, 2);
lcd.print("T2:");
//lcd.setCursor(13, 2);
lcd.print(sensors.getTempCByIndex(1),1);
lcd.print((char)223);
lcd.setCursor(10, 1);
lcd.print("Wh:");
//bez pouziti promene typu int a pretypovani primo ve vysledku obcas lezly zaporne hodnoty ??
k = ( loadTime / 1000 * loadPower / 3600);
lcd.print(k);
//loadTime=0;
}
// Vlastni PWM cyklus
sumTime = 0;
pwmLength = 1000 / pwmFreq;
while ( sumTime < pwmCycle * 1000)
{
if(pwmDuty == 100){
digitalWrite(pwmPin, HIGH);
sumTime=pwmCycle * 1000;
loadTime +=pwmCycle * 1000;
delay(pwmCycle * 1000);
}
else if (pwmDuty > 0)
{
sumTime=sumTime+pwmLength+pwmLength*(100-pwmDuty)/pwmDuty;
digitalWrite(pwmPin, HIGH);
loadTime +=pwmLength;
delay(pwmLength);
digitalWrite(pwmPin, LOW);
delay(pwmLength*(100-pwmDuty)/pwmDuty);
}
else
{
digitalWrite(pwmPin, LOW);
sumTime=pwmCycle * 1000;
delay(pwmCycle * 1000);
}
}
}