• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterownik LED PWM do akwarium z pomiarem temperatur, wilgotności i ciśnienia
#1
Lightbulb 
Na początek dziękuję za pomoc koledze JasQ.
Bez jego pomocy i poświęconego czasu program by pewnie nie powstał.
Program ma za zadanie sterować oświetleniem LED dwóch kanałów za pomocą PWM symulując świt, dzień, zmierzch i noc. Do tego celu użyto pinów 9 i 10.
W linii 96 i 97 ustawiamy czas w sekundach licząc od północy włączenia trybów świtu i zmierzchu, w linii 102 ustawiamy czas w sekundach trwania świtu i zmierzchu. Za pomocą pinu 6 sterujemy przekaźnikiem który ma za zadanie podać napięcie na drivery LED. Przekaźnik jest wyłączony w trybie nocnym, drivery nie są pod napięciem.
Dodatkowo program wyświetla odczyty z czujników (temperatura otoczenia, ciśnienie atmosferyczne, wilgotność otoczenia oraz temperaturę wody w zbiorniku z sondy wodoodpornej pin 11). Wyświetlacz odtwarza dwa ekrany co 10s na jednym ekranie jest wyświetlany zegar, data, tryb świecenia i status przekaźnika, na drugim zegar, datę, odczyty z czujników.
Czas przełączania ekranów ustawiamy w linii 213, czas podajmy w ms.
Hardware:
Arduino UNO
Wyświetlacz LCD 4x20 znaków
Konwerter I2C dla wyświetlacza LCD HD44780
Zegar czasu rzeczywistego - moduł RTC DS1307 + bateria – MSX
Sonda wodoodporna z czujnikiem temperatury DS18B20
BME280 - czujnik wilgotności, temperatury oraz ciśnienia I2C/SPI - moduł Adafruit
Zasilacz impulsowy 12V / 2,1A - wtyk DC 5,5 / 2,5 mm
Moduł przekaźnika RM1 z izolacją optoelektroniczną 5V 
Drivery LED z możliwością sterowania przez PWM
Diody LED

Program:
Biblioteki i fragmenty kodu znalezione w sieci.
Kod:
#include <TimerOne.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C  lcd(0x27,2,1,0,4,5,6,7);
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

OneWire  ds(11);  // on pin 11 (a 4.7K resistor is necessary)
Adafruit_BME280 bme; // I2C

const char *monthName[12] = {
"01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12"
};
byte temp[8] = //ikona temperatury
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};

byte wilg[8] = //ikona wilgotnosci
{
B00100,
B00100,
B01010,
B10001,
B10001,
B10001,
B01110,
};

byte stopnie[8] = //ikona stopni
{
   B01100,
   B10010,
   B10010,
   B01100,
   B00000,
   B00000,
   B00000,
   B00000
};

byte procent[8] = //ikona stopni
{
   B11001,
   B11001,
   B00010,
   B00100,
   B00100,
   B01000,
   B10011,
   B10011
};

byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;

unsigned long odczyt = 0;
unsigned long czas = 0;
unsigned long z = 0 ;
byte lcdx = 1;
byte strona = 1;

float temperatura ;
float wilgotnosc ;
float cisnienie ;


int ledEnable = 6; //Pin do sterowania przekaźnikiem do zasilania driverów

const int kChan0Pin = 9; // Pin PWM do sterowania LED
const int kChan1Pin = 10; // Pin PWM do sterowania LED

const long kTurnOn = 32400; // Start tu zaczyna się świt (9:00)
const long kTurnOff = 75600; // Tu ustawiamy początek zmierzchu (21:00)

const int kDayState[] = { 1023,1023 }; // daytime LED state
const int kNightState[] = { 0, 0 }; // nighttime LED state

const long kFadeDuration = 3600; // 60 minut czas świtu i zmierzchu

long ctr;

void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;

long elapsed = ctr-start_time;

out[0] = start_state[0] + per_second_delta_0 * elapsed;
out[1] = start_state[1] + per_second_delta_1 * elapsed;
}

long seconds_since_midnight() {
//  setTime(21, 45, 00, 16, 2, 2015);
//set the system time to 21hrs 45min 00sec 16,Feb 2015...does not set RTC, will reset upon powerup

time_t t = now();
long hr = hour(t);
long min = minute(t);
long sec = second(t);
long total = hr * 3600 + min * 60 + sec;
return total;
}

void set_state(const int state[]) {
if (state[0] >= 0 && state[0] <= 1023) Timer1.setPwmDuty(kChan0Pin, state[0]);
if (state[1] >= 0 && state[1] <= 1023) Timer1.setPwmDuty(kChan1Pin, state[1]);
}


// status dzień/noc

String poradnia = "";
String ledonoff = "";

void determine_state() {
if ( ctr >= 0 && ctr < kTurnOn ) { // night
  set_state(kNightState);
 
  poradnia = "NIGHT/MODE ";        
  digitalWrite(ledEnable,LOW);
  ledonoff = "LED-OFF";
 
} else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
int foo[2];
fader(kTurnOn, kNightState, kDayState, foo);
set_state(foo);

   poradnia = "SUNRISE/MODE";              
   digitalWrite(ledEnable, HIGH);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
set_state(kDayState);
 
  poradnia = "DAY/MODE";              
  digitalWrite(ledEnable, HIGH);
  ledonoff = "LED-ON ";

} else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
int foo[2];
fader(kTurnOff, kDayState, kNightState, foo);
set_state(foo);

   poradnia = "SUNSET/MODE";              
   digitalWrite(ledEnable, HIGH);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
set_state(kNightState);

   poradnia = "NIGHT/MODE";        
   digitalWrite(ledEnable,LOW);
   ledonoff = "LED-OFF";
  }
}



void setup(void) {

Serial.begin(115200);        
setSyncProvider(RTC.get);
setSyncInterval(120);
Wire.begin();
Timer1.initialize(6666);     // 150Hz PWM
pinMode(kChan0Pin, OUTPUT);    
Timer1.pwm(kChan0Pin, 0);
pinMode(kChan1Pin, OUTPUT);    
Timer1.pwm(kChan1Pin, 0);
pinMode(ledEnable,OUTPUT);   // Led control

lcd.begin(20, 4);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
//lcd.setBacklightPin(3, HIGH);
lcd.createChar(0, temp);
lcd.createChar(1, wilg);
lcd.createChar(3, stopnie);
lcd.createChar(4, procent);

if (!bme.begin()) {while (1);}

}

void loop() {

unsigned long sek = millis()/1000 ;
if ( (millis()-czas) >= 5000 ){czas = millis(); //czas zmiany ekranów
if (strona == 2){strona = 1;}
else if(strona == 1){strona = 2;}}

ctr = seconds_since_midnight(); // Original code

determine_state();              // Original code
// Serial.print("ctr: ");
// Serial.print(ctr);           // display counter
// Serial.println();


if ( (millis()-odczyt) >= 2000 ){

temperatura = bme.readTemperature() ;
wilgotnosc = bme.readHumidity() ;
cisnienie = bme.readPressure()/100.0F ;

odczyt = millis();}

if ( !ds.search(addr)){ds.reset_search();return;}
if (OneWire::crc8(addr, 7) != addr[7]){return;}

switch (addr[0]) {
  case 0x10:
      type_s = 1;break;
  case 0x28:
      type_s = 0;break;
  case 0x22:
     type_s = 0;break;
  default:
return;
}

ds.reset();
ds.select(addr);
ds.write(0x44, 1);      

present = ds.reset();
ds.select(addr);    
ds.write(0xBE);        

for ( i = 0; i < 9; i++) {data[i] = ds.read();}

int16_t raw = (data[1] << 8) | data[0];

if (type_s) {raw = raw << 3;
if (data[7] == 0x10) {raw = (raw & 0xFFF0) + 12 - data[6];}}

else {byte cfg = (data[4] & 0x60);
  if (cfg == 0x00) raw = raw & ~7;
  else if (cfg == 0x20) raw = raw & ~3;}

celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;

switch (strona) {

case 1:

if (lcdx != 1){lcd.clear();lcdx = 1;} //czyszczenie ekranu 1

tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (6, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (5, 1);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
   
}

lcd.setCursor (0, 2);
lcd.write(byte(0));
lcd.print("=");
lcd.print(temperatura, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 2);
lcd.print("P=");
lcd.print(cisnienie, 1);
lcd.print("hPa");

lcd.setCursor (0, 3);
lcd.write(byte(0));
lcd.print("=");
lcd.print(celsius, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 3);
lcd.write(byte(1));
lcd.write("=");
lcd.print(wilgotnosc, 1);
lcd.print("%");

break;

case 2:

if (lcdx != 2){lcd.clear();lcdx = 2;} //czyszczenie ekranu 2

//tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (6, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (5, 1);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
   
}

 lcd.setCursor(5,2);
 lcd.print(poradnia);        
 lcd.setCursor(6,3);
 lcd.print(ledonoff);

break;

}}

void LCDprint2digits(int number) {
if (number >= 0 && number < 10) {lcd.write('0');}
lcd.print(number);
}
Plany na przyszłość to dodanie pomiaru przepływu przez filtr w celu monitorowania jego stanu czyli określenia czasu kiedy pora już go wyczyścić.
 
Odpowiedź
#2
Można prosić schemat? Głównie chodzi mi ile diod poszczególnych kolorów wykorzystałeś żeby uzyskać dane pory dnia.

Wypalcowane
 
Odpowiedź
#3
Schemat jest w trakcie opracowania, jak będzie gotowy oczywiście go tutaj udostępnię. Muszę jeszcze rozwiązać kilka problemów z sygnałem PWM, driver który chcę użyć wymaga PWM 10V.
 
Odpowiedź
#4
Witam,

ciekawy projekt sobie dłubiesz. Masz już jakieś aktualizacje? Może filmik z działania. Nie powiem, ale projekt mi się na prawdę podoba i mam nadzieję sklecić sobie w przyszłości coś takiego, ino jeszcze sporo nauki przede mną zanim opanuję moje arduino. Będę kibicował temu projektowi.

Pozdrawiam
 
Odpowiedź
#5
Powoli coś się tam dzieje, jestem na etapie składania tego w całość, właśnie montuję LEDy w profile.
Drivery mam już opanowane, od strony programu dorabiam teraz czujniki zawilgocenia, mają być pod filtrem i alarmować w razie przecieku. Z przepływomierza będę musiał chyba zrezygnować, nie mam miejsca nad lustrem wody a na zewnątrz boję się go zamontować (nie budzi zaufania pod względem szczelności).
 
Odpowiedź
#6
Rozumiem, że filtr to kubełek. Trzymasz go w jakimś innym naczyniu/akwarium/wiaderku żeby w razie W mieć jeszcze czas na reakcję? Myślałeś nad powiadomieniem o przecieku np. mailowo albo sms?
 
Odpowiedź
#7
Tak, jest w naczyniu i planuję dodać moduł wifi ale to dalsze plany
 
Odpowiedź
#8
Dodałem do kodu dwa czujniki obecności wody (wykorzystałem do tego czujniki zawilgocenia gleby FC-28) podłączone do pinów A0 i A1 stan czujników jest wyświetlany na wyświetlaczu i dodatkowo obecność wody pod filtrem kubełkowym jest sygnalizowana buzerem podpiętym do pinu 2 Arduino.
Kod wygląda tak:
Kod:
#include <TimerOne.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C  lcd(0x27,2,1,0,4,5,6,7);
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

OneWire  ds(11);  // on pin 11 (a 4.7K resistor is necessary)
Adafruit_BME280 bme; // I2C

const char *monthName[12] = {
"01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12"
};
byte temp[8] = //ikona temperatury
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};

byte wilg[8] = //ikona wilgotnosci
{
B00100,
B00100,
B01010,
B10001,
B10001,
B10001,
B01110,
};

byte stopnie[8] = //ikona stopni
{
   B01100,
   B10010,
   B10010,
   B01100,
   B00000,
   B00000,
   B00000,
   B00000
};

byte procent[8] = //ikona stopni
{
   B00000,
   B00000,
   B00000,
   B00000,
   B10001,
   B11011,
   B11111,
   B11111
};

byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;

unsigned long odczyt = 0;
unsigned long czas = 0;
unsigned long z = 0 ;
byte lcdx = 1;
byte strona = 1;

float temperatura ;
float wilgotnosc ;
float cisnienie ;
String wilgotnosc1 = "";


int ledEnable = 6;
int ledEnable7 = 7;

const int kChan0Pin = 9; // Channel 0 Pin
const int kChan1Pin = 10; // Channel 1 Pin

const long kTurnOn = 27000; // time dawn begins - 0900hrs
const long kTurnOff = 65820; // time sunset begins - 2100hrs

const int kDayState[] = { 0,0 }; // daytime LED state
const int kNightState[] = { 1023, 1023 }; // nighttime LED state

const long kFadeDuration = 300; // 60 minutes

long ctr;

void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;

long elapsed = ctr-start_time;

out[0] = start_state[0] + per_second_delta_0 * elapsed;
out[1] = start_state[1] + per_second_delta_1 * elapsed;
}

long seconds_since_midnight() {
//  setTime(21, 45, 00, 16, 2, 2015);
//set the system time to 21hrs 45min 00sec 16,Feb 2015...does not set RTC, will reset upon powerup

time_t t = now();
long hr = hour(t);
long min = minute(t);
long sec = second(t);
long total = hr * 3600 + min * 60 + sec;
return total;
}

void set_state(const int state[]) {
if (state[0] >= 0 && state[0] <= 1023) Timer1.setPwmDuty(kChan0Pin, state[0]);
if (state[1] >= 0 && state[1] <= 1023) Timer1.setPwmDuty(kChan1Pin, state[1]);
}


// status dzień/noc

String poradnia = "";
String ledonoff = "";

void determine_state() {
if ( ctr >= 0 && ctr < kTurnOn ) { // night
  set_state(kNightState);
 
  poradnia = "NIGHT/MODE ";        
  digitalWrite(ledEnable,HIGH);
  digitalWrite(ledEnable7,HIGH);
  ledonoff = "LED-OFF";
 
} else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
int foo[2];
fader(kTurnOn, kNightState, kDayState, foo);
set_state(foo);

   poradnia = "SUNRISE/MODE";              
   digitalWrite(ledEnable, LOW);
   digitalWrite(ledEnable7, LOW);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
set_state(kDayState);
 
  poradnia = "DAY/MODE";              
  digitalWrite(ledEnable, LOW);
  digitalWrite(ledEnable7, LOW);
  ledonoff = "LED-ON ";

} else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
int foo[2];
fader(kTurnOff, kDayState, kNightState, foo);
set_state(foo);

   poradnia = "SUNSET/MODE";              
   digitalWrite(ledEnable, LOW);
   digitalWrite(ledEnable7, LOW);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
set_state(kNightState);

   poradnia = "NIGHT/MODE";        
   digitalWrite(ledEnable,HIGH);
   digitalWrite(ledEnable7,HIGH);
   ledonoff = "LED-OFF";
  }
}



void setup(void) {

Serial.begin(115200);        
setSyncProvider(RTC.get);
setSyncInterval(120);
Wire.begin();
Timer1.initialize(6666);     // 150Hz PWM
pinMode(kChan0Pin, OUTPUT);    
Timer1.pwm(kChan0Pin, 1023);
pinMode(kChan1Pin, OUTPUT);    
Timer1.pwm(kChan1Pin, 1023);
pinMode(ledEnable,OUTPUT);   // Led control
pinMode(ledEnable7,OUTPUT);

lcd.begin(20, 4);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
//lcd.setBacklightPin(3, HIGH);
lcd.createChar(0, temp);
lcd.createChar(1, wilg);
lcd.createChar(3, stopnie);
lcd.createChar(4, procent);

pinMode(A1, INPUT); //set up analog pin 1 to be input humidity
pinMode(A0, INPUT); //set up analog pin 0 to be input humidity
pinMode(2, OUTPUT); // buzer

if (!bme.begin()) {while (1);}

}

void loop() {

unsigned long sek = millis()/1000 ;
if ( (millis()-czas) >= 10000 ){czas = millis();
if (strona == 2){strona = 1;}
else if(strona == 1){strona = 2;}}

ctr = seconds_since_midnight(); // Original code

determine_state();              // Original code

if ( (millis()-odczyt) >= 2000 ){

temperatura = bme.readTemperature() ;
wilgotnosc = bme.readHumidity() ;
cisnienie = bme.readPressure()/100.0F ;

odczyt = millis();}

if ( !ds.search(addr)){ds.reset_search();return;}
if (OneWire::crc8(addr, 7) != addr[7]){return;}

switch (addr[0]) {
  case 0x10:
      type_s = 1;break;
  case 0x28:
      type_s = 0;break;
  case 0x22:
     type_s = 0;break;
  default:
return;
}

ds.reset();
ds.select(addr);
ds.write(0x44, 1);      

present = ds.reset();
ds.select(addr);    
ds.write(0xBE);        

for ( i = 0; i < 9; i++) {data[i] = ds.read();}

int16_t raw = (data[1] << 8) | data[0];

if (type_s) {raw = raw << 3;
if (data[7] == 0x10) {raw = (raw & 0xFFF0) + 12 - data[6];}}

else {byte cfg = (data[4] & 0x60);
  if (cfg == 0x00) raw = raw & ~7;
  else if (cfg == 0x20) raw = raw & ~3;}

celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;

//wilgotnosc start
{
 int s1 = analogRead(A0);
 int s2 = analogRead(A1); //take a sample
//  Serial.print(s1); Serial.print(" - ");
//  Serial.print(s2); Serial.print(" - ");

if(s1 < 400 || s2 < 400) {
//   Serial.println("Sensor in WATER");
    wilgotnosc1 = "WATER";
    digitalWrite(2, HIGH);
}
else {
 if((s1 < 600) || (s2 < 600)) {
   wilgotnosc1 = "Humidity";
   digitalWrite(2, HIGH);
 }  
else {
 if((s1 < 1000)  || (s2 < 1000)) {
    wilgotnosc1 = "Dry";
    digitalWrite(2, HIGH);
 }
else {
    wilgotnosc1 = "OK";
    digitalWrite(2, LOW);
   }
 }
}
}
//wilgotność end


switch (strona) {

case 1:

if (lcdx != 1){lcd.clear();lcdx = 1;} //czyszczenie ekranu 1

tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (0, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (10, 0);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
   
}

lcd.setCursor(0,1); //wilgotnosc
lcd.write(byte(4));
lcd.print("=");
lcd.print(wilgotnosc1);  //wilgotnosc

lcd.setCursor (0, 2);
lcd.write(byte(0));
lcd.print("=");
lcd.print(temperatura -1.8, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 2);
lcd.print("P=");
lcd.print(cisnienie, 1);
lcd.print("hPa");

lcd.setCursor (0, 3);
lcd.write(byte(0));
lcd.print("=");
lcd.print(celsius, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 3);
lcd.write(byte(1));
lcd.write("=");
lcd.print(wilgotnosc, 1);
lcd.print("%");

break;

case 2:

if (lcdx != 2){lcd.clear();lcdx = 2;} //czyszczenie ekranu 2

//tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (6, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (5, 1);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
   
}

 lcd.setCursor(5,2);
 lcd.print(poradnia);        
 lcd.setCursor(6,3);
 lcd.print(ledonoff);


break;

}}

void LCDprint2digits(int number) {
if (number >= 0 && number < 10) {lcd.write('0');}
lcd.print(number);
}

Oczywiście wszystkie uwagi i sugestie mile widziane.
 
Odpowiedź
#9
Tak się zastanawiam że przydałoby się jeszcze zrobić żeby można było włączać i wyłączać oświetlenie (PWM na 100%) niezależnie od ustawionego harmonogramu za pomocą przycisku. Niestety nie mam pojęcia jak się za to zabrać. Macie jakiś pomysł na to?
 
Odpowiedź
#10
Pin 4 do masy włącza oświetlenie na 100 % ale sprawdź timery w tych linijkach bo nie pamiętam czy 1023 to max czy min oświetlenie .

if ( digitalRead(4) == LOW ){

digitalWrite(ledEnable,HIGH);
digitalWrite(ledEnable7,HIGH);
Timer1.pwm(kChan1Pin, 1023);
Timer1.pwm(kChan0Pin, 1023);

}else{ determine_state(); }



Kod:
#include <TimerOne.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 3
LiquidCrystal_I2C  lcd(0x27,2,1,0,4,5,6,7);
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

OneWire  ds(11);  // on pin 11 (a 4.7K resistor is necessary)
Adafruit_BME280 bme; // I2C

const char *monthName[12] = {
"01", "02", "03", "04", "05", "06",
"07", "08", "09", "10", "11", "12"
};
byte temp[8] = //ikona temperatury
{
B00100,
B01010,
B01010,
B01110,
B01110,
B11111,
B11111,
B01110
};

byte wilg[8] = //ikona wilgotnosci
{
B00100,
B00100,
B01010,
B10001,
B10001,
B10001,
B01110,
};

byte stopnie[8] = //ikona stopni
{
   B01100,
   B10010,
   B10010,
   B01100,
   B00000,
   B00000,
   B00000,
   B00000
};

byte procent[8] = //ikona stopni
{
   B00000,
   B00000,
   B00000,
   B00000,
   B10001,
   B11011,
   B11111,
   B11111
};

byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;

unsigned long odczyt = 0;
unsigned long czas = 0;
unsigned long z = 0 ;
byte lcdx = 1;
byte strona = 1;

float temperatura ;
float wilgotnosc ;
float cisnienie ;
String wilgotnosc1 = "";


int ledEnable = 6;
int ledEnable7 = 7;

const int kChan0Pin = 9; // Channel 0 Pin
const int kChan1Pin = 10; // Channel 1 Pin

const long kTurnOn = 27000; // time dawn begins - 0900hrs
const long kTurnOff = 65820; // time sunset begins - 2100hrs

const int kDayState[] = { 0,0 }; // daytime LED state
const int kNightState[] = { 1023, 1023 }; // nighttime LED state

const long kFadeDuration = 300; // 60 minutes

long ctr;

void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;

long elapsed = ctr-start_time;

out[0] = start_state[0] + per_second_delta_0 * elapsed;
out[1] = start_state[1] + per_second_delta_1 * elapsed;
}

long seconds_since_midnight() {
//  setTime(21, 45, 00, 16, 2, 2015);
//set the system time to 21hrs 45min 00sec 16,Feb 2015...does not set RTC, will reset upon powerup

time_t t = now();
long hr = hour(t);
long min = minute(t);
long sec = second(t);
long total = hr * 3600 + min * 60 + sec;
return total;
}

void set_state(const int state[]) {
if (state[0] >= 0 && state[0] <= 1023) Timer1.setPwmDuty(kChan0Pin, state[0]);
if (state[1] >= 0 && state[1] <= 1023) Timer1.setPwmDuty(kChan1Pin, state[1]);
}


// status dzień/noc

String poradnia = "";
String ledonoff = "";

void determine_state() {
if ( ctr >= 0 && ctr < kTurnOn ) { // night
  set_state(kNightState);

  poradnia = "NIGHT/MODE ";        
  digitalWrite(ledEnable,HIGH);
  digitalWrite(ledEnable7,HIGH);
  ledonoff = "LED-OFF";

} else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
int foo[2];
fader(kTurnOn, kNightState, kDayState, foo);
set_state(foo);

   poradnia = "SUNRISE/MODE";              
   digitalWrite(ledEnable, LOW);
   digitalWrite(ledEnable7, LOW);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
set_state(kDayState);

  poradnia = "DAY/MODE";              
  digitalWrite(ledEnable, LOW);
  digitalWrite(ledEnable7, LOW);
  ledonoff = "LED-ON ";

} else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
int foo[2];
fader(kTurnOff, kDayState, kNightState, foo);
set_state(foo);

   poradnia = "SUNSET/MODE";              
   digitalWrite(ledEnable, LOW);
   digitalWrite(ledEnable7, LOW);
   ledonoff = "LED-ON ";

} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
set_state(kNightState);

   poradnia = "NIGHT/MODE";        
   digitalWrite(ledEnable,HIGH);
   digitalWrite(ledEnable7,HIGH);
   ledonoff = "LED-OFF";
  }
}



void setup(void) {

Serial.begin(115200);        
setSyncProvider(RTC.get);
setSyncInterval(120);
Wire.begin();
Timer1.initialize(6666);     // 150Hz PWM
pinMode(kChan0Pin, OUTPUT);    
Timer1.pwm(kChan0Pin, 1023);
pinMode(kChan1Pin, OUTPUT);    
Timer1.pwm(kChan1Pin, 1023);
pinMode(ledEnable,OUTPUT);   // Led control
pinMode(ledEnable7,OUTPUT);

lcd.begin(20, 4);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
//lcd.setBacklightPin(3, HIGH);
lcd.createChar(0, temp);
lcd.createChar(1, wilg);
lcd.createChar(3, stopnie);
lcd.createChar(4, procent);

pinMode(A1, INPUT); //set up analog pin 1 to be input humidity
pinMode(A0, INPUT); //set up analog pin 0 to be input humidity
pinMode(2, OUTPUT); // buzer

pinMode( 4, INPUT_PULLUP );


if (!bme.begin()) {while (1);}

}

void loop() {

unsigned long sek = millis()/1000 ;
if ( (millis()-czas) >= 10000 ){czas = millis();
if (strona == 2){strona = 1;}
else if(strona == 1){strona = 2;}}

ctr = seconds_since_midnight(); // Original code

if ( digitalRead(4) == LOW ){
  
  digitalWrite(ledEnable,HIGH);
  digitalWrite(ledEnable7,HIGH);
  Timer1.pwm(kChan1Pin, 1023);
  Timer1.pwm(kChan0Pin, 1023);
  
  }else{ determine_state();  }

if ( (millis()-odczyt) >= 2000 ){

temperatura = bme.readTemperature() ;
wilgotnosc = bme.readHumidity() ;
cisnienie = bme.readPressure()/100.0F ;

odczyt = millis();}

if ( !ds.search(addr)){ds.reset_search();return;}
if (OneWire::crc8(addr, 7) != addr[7]){return;}

switch (addr[0]) {
  case 0x10:
      type_s = 1;break;
  case 0x28:
      type_s = 0;break;
  case 0x22:
     type_s = 0;break;
  default:
return;
}

ds.reset();
ds.select(addr);
ds.write(0x44, 1);      

present = ds.reset();
ds.select(addr);    
ds.write(0xBE);        

for ( i = 0; i < 9; i++) {data[i] = ds.read();}

int16_t raw = (data[1] << 8) | data[0];

if (type_s) {raw = raw << 3;
if (data[7] == 0x10) {raw = (raw & 0xFFF0) + 12 - data[6];}}

else {byte cfg = (data[4] & 0x60);
  if (cfg == 0x00) raw = raw & ~7;
  else if (cfg == 0x20) raw = raw & ~3;}

celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;

//wilgotnosc start
{
int s1 = analogRead(A0);
int s2 = analogRead(A1); //take a sample
//  Serial.print(s1); Serial.print(" - ");
//  Serial.print(s2); Serial.print(" - ");

if(s1 < 400 || s2 < 400) {
//   Serial.println("Sensor in WATER");
    wilgotnosc1 = "WATER";
    digitalWrite(2, HIGH);
}
else {
if((s1 < 600) || (s2 < 600)) {
   wilgotnosc1 = "Humidity";
   digitalWrite(2, HIGH);
}  
else {
if((s1 < 1000)  || (s2 < 1000)) {
    wilgotnosc1 = "Dry";
    digitalWrite(2, HIGH);
}
else {
    wilgotnosc1 = "OK";
    digitalWrite(2, LOW);
   }
}
}
}
//wilgotność end


switch (strona) {

case 1:

if (lcdx != 1){lcd.clear();lcdx = 1;} //czyszczenie ekranu 1

tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (0, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (10, 0);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
  
}

lcd.setCursor(0,1); //wilgotnosc
lcd.write(byte(4));
lcd.print("=");
lcd.print(wilgotnosc1);  //wilgotnosc

lcd.setCursor (0, 2);
lcd.write(byte(0));
lcd.print("=");
lcd.print(temperatura -1.8, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 2);
lcd.print("P=");
lcd.print(cisnienie, 1);
lcd.print("hPa");

lcd.setCursor (0, 3);
lcd.write(byte(0));
lcd.print("=");
lcd.print(celsius, 1);
lcd.write(byte(3));
lcd.print("C");

lcd.setCursor (9, 3);
lcd.write(byte(1));
lcd.write("=");
lcd.print(wilgotnosc, 1);
lcd.print("%");

break;

case 2:

if (lcdx != 2){lcd.clear();lcdx = 2;} //czyszczenie ekranu 2

//tmElements_t tm;

if (RTC.read(tm)) {

lcd.setCursor (6, 0);
LCDprint2digits(tm.Hour);
lcd.print(':');
LCDprint2digits(tm.Minute);
lcd.print(':');
LCDprint2digits(tm.Second);
lcd.setCursor (5, 1);
lcd.print(tm.Day);
lcd.print('/');
lcd.print(monthName[tm.Month-1]);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
  
}

lcd.setCursor(5,2);
lcd.print(poradnia);        
lcd.setCursor(6,3);
lcd.print(ledonoff);


break;

}}

void LCDprint2digits(int number) {
if (number >= 0 && number < 10) {lcd.write('0');}
lcd.print(number);
}
Ważne aby robić co się lubi albo lubić co się robi .
Arduino UNO, TINY, PRO MINI
Pomoc nagradzamy punktami reputacji Wink
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości