Zdravím,
Trošku jsem experimentoval s tímto perfektním kódem a aplikací Blynk. Vypustil jsem LCD a přidal nějaké, pro mě důležité funkce. Program Arduina funguje tak, že měří napětí, hlídá hladinu vody a spíná čerpadlo, spíná měnič, měří teploty a vše zobrazuje na mobilní aplikaci Blynk.
Obrázek. Jsem Arduino začátečník, pravděpodobně by šel kód "učesat", nicméně funguje a to je hlavní

Ještě budu přidávat automatické startování centrály při nízkém napětí. To už bude chtít upravit centrálu na startér, čidlo hladiny benzínu, snímač otáček atd...
Pokusím se popsat co je vlastně na obrázku:
Levá horní část - voltmetr, aktualizovaný co dvě vteřiny
Pravá horní část - kontrolka nízkého napětí, kontrolka zapnutí měniče, tlačítko pro ruční zapnutí/vypnutí měniče, kontrolka nízkého stavu hladiny ve vodní nádrži, kontrolka zapnutí čerpadla
Střed - graf napětí
Spodní část - analogový výstup čidel hladiny vody, teplotní čidla
Edit: Analogové měření vodní hladiny pomocí elektrické vodivosti není dobrý nápad, chce to plováky. Využil jsem prozatím sondy z jiného, předešlého systému.
- Kód: Vybrat vše
#define BLYNK_PRINT Serial // Enables Serial Monitor
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <SimpleTimer.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Put your Auth Token here. (see Step 3 above)
int volt = A0; //voltmetr
int spodniHladina = A1; //kontakt hladinomeru
int horniHladina = A2; //kontakt hladinomeru
int ReleCerpadlo = 2; //rele cerpadla
int pwmPin = 3; //PWM pin
int ReleMenic = 4; //rele menice
float analogVoltage = 0; // hodnota na pinu volt
float analogOffset = 16.9; //zacatek rozsahu - posunute zenerkou
float analogRange = 14.1; //mereny rozsah (m)
float targetVoltage = 28.5; // hodnota ciloveho napeti
float waterVoltage = 24; //minimalni napeti, kdy se vypne rele cerpadla
float menicUpVoltage = 26.5; //napeti, kdy se sepne rele menice
float minVoltage = 25.5; // minimalni hodnota napeti
float criticalVoltage = 23; //kriticke napeti
float minHladina = 0;
float maxHladina = 0;
float ReleMenicState = LOW; //stav rele menice
float ReleCerpadloState = LOW; //stav rele cerpadla
float tempBojler, tempKotel, tempVratka;
int menicVButton1 = 0;
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 loadPower = 500; // vykon zateze W pro vypocet akumulovane energie ve Wh
float loadTime;//prubezne nacitani casu ON v milisekundach pro zobrazeni Wh
int k; //promena pro spotrebu Wh
#define DHTPIN 8 // What digital pin we're connected to
#define DHTTYPE DHT11 // DHT 11
#define ONE_WIRE_BUS 6
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Probe01 = { 0x28, 0xFF, 0x74, 0xD1, 0x00, 0x16, 0x03, 0x10 };
DeviceAddress Probe02 = { 0x28, 0xFF, 0xC2, 0xB9, 0x00, 0x16, 0x03, 0x4F };
DeviceAddress Probe03 = { 0x28, 0xFF, 0x4E, 0x34, 0x01, 0x16, 0x03, 0x4A };
DHT dht(DHTPIN, DHTTYPE);
WidgetLED led1(V1);
WidgetLED led2(V2); //volná po stykači
WidgetLED led3(V3);
WidgetLED led4(V4);
WidgetLED led5(V12);
SimpleTimer timer;
// funkce se provede po startu
void setup() {
Serial.begin(9600); // See the connection status in Serial Monitor
Blynk.begin(auth); // Here your Arduino connects to the Blynk Cloud.
dht.begin();
sensors.begin();
sensors.setResolution(Probe01, 12);
sensors.setResolution(Probe02, 12);
sensors.setResolution(Probe03, 12);
pinMode(volt,INPUT);
pinMode(ReleMenic,OUTPUT);
pinMode(ReleCerpadlo,OUTPUT);
pinMode(pwmPin,OUTPUT);
pinMode(spodniHladina,INPUT);
pinMode(horniHladina, INPUT);
attachInterrupt(digitalPinToInterrupt(ReleCerpadlo), checkPin, CHANGE);
attachInterrupt(digitalPinToInterrupt(ReleMenic), checkPin, CHANGE);
timer.setInterval(2100L, mereniNapeti);
timer.setInterval(3600L, mereniDTH11);
timer.setInterval(5000L, cidloHladiny);
timer.setInterval(3500L, mereniTeplot);
timer.setInterval(600L, checkPin);
}
void mereniTeplot()
{
sensors.requestTemperatures();
tempBojler = sensors.getTempC(Probe01);
tempKotel = sensors.getTempC(Probe02);
tempVratka = sensors.getTempC(Probe03);
if (tempBojler != -127) {
Blynk.virtualWrite(V7, tempBojler);
}
if (tempKotel != -127) {
Blynk.virtualWrite(V8, tempKotel);
}
if (tempVratka != -127) {
Blynk.virtualWrite(V9, tempVratka);
}
}
void cidloHladiny()
{
minHladina = analogRead(spodniHladina);
maxHladina = analogRead(horniHladina);
Blynk.virtualWrite(V10, minHladina);
Blynk.virtualWrite(V11, maxHladina);
if ((minHladina <= 50)&&(maxHladina <= 50)) {
led5.on();
}
if ((minHladina <= 50)&&(maxHladina <= 50)&&(ReleMenicState == HIGH)) {
ReleCerpadloState = HIGH; //zapis stav rele do prommene
digitalWrite(ReleCerpadlo, ReleCerpadloState); //zapni rele cerpadla
}
if ((minHladina >=80)&&(maxHladina >=80)) {
ReleCerpadloState = LOW; //zapis stav rele do prommene
digitalWrite(ReleCerpadlo, ReleCerpadloState); //vypni rele cerpadla
led5.off();
}
}
void mereniDTH11()
{
float h = dht.readHumidity();
float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V5, h);
Blynk.virtualWrite(V6, t);
}
void mereniNapeti()
{
k = ( loadTime / 1000 * loadPower / 3600);
Blynk.virtualWrite(V13, k);
Blynk.virtualWrite(V0, analogVoltage);
if(analogVoltage <= criticalVoltage){
led1.on();
}
else{
led1.off();
}
{
if((analogVoltage <= minVoltage)&&(ReleCerpadloState == LOW)) {
ReleMenicState = LOW; //zapis stav rele do prommene
digitalWrite(ReleMenic, ReleMenicState); //vypni rele menice
}
if((analogVoltage <= waterVoltage)&&(ReleCerpadloState == HIGH)) {
ReleCerpadloState = LOW; //zapis stav rele do prommene
digitalWrite(ReleCerpadlo, ReleCerpadloState); //vypni rele cerpadla
ReleMenicState = LOW; //zapis stav rele do prommene
digitalWrite(ReleMenic, ReleMenicState); //vypni rele menice
}
if (analogVoltage >= menicUpVoltage){
ReleMenicState = HIGH; //zapis stav rele do prommene
digitalWrite(ReleMenic, ReleMenicState); //zapni rele menice
}
}
}
void checkPin()
{
{
// Invert state, since button is "Active LOW"
if (digitalRead(ReleCerpadlo)) {
led3.on();
} else {
led3.off();
}
}
{
// Invert state, since button is "Active LOW"
if (digitalRead(ReleMenic)) {
led4.on();
} else {
led4.off();
}
}
{
if (menicVButton1 > 0)
{
ReleMenicState = !ReleMenicState;
}
digitalWrite(ReleMenic, ReleMenicState);
}
}
BLYNK_WRITE(V15)
{
menicVButton1 = param.asInt(); // Get the state of the VButton
}
void loop() {
Blynk.run(); // All the Blynk Magic happens here..
timer.run(); // Initiates SimpleTimer
analogVoltage= (analogRead(volt) * analogRange)/1024+analogOffset;
// Serial.println(analogVoltage);
// 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;
}
// 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);
}
}
}