Всем привет дорогие читатели и всем тем кто хоть как-то интересуется микро электроникой.
Ну опять прошло не мало времени и Я создал очередную безделушку думаю вам она понравится. Ну что-же начнем все по порядку.
Идея первоначально заключалась в том чтоб сделать экономней расход воды в ванной и чтоб когда я принимал ванную температура воды была нужная мне и чтоб вода не набиралась слишком много. И не мало важны момент чтоб время в ванной было определенным..
Задачка стояла не из легких но я справился)))
Начнем: первоначально нам понадобится датчик я использовал ds18b20
Схема подключения простейшая
Она состоит из трех проводной линии, два крайних это питание а третий это линия данных. Линия данных «подтянута » к 5 В. Сопротивлением 4.7 кОм. У меня была плата Arduino Mega.
Для того чтобы получать данные с датчика, как было сказано ранее, используеться протокол 1-wire. Датчик можно подключить к любому выводу Arduino, но предварительно нужно указать в коде программы с каким именно выводом мы имеем дело. В нашем мы подключаем к выводу.
линию данных, D;
плюс питания, VCC;
минус питания, GND.
Линия данных используется для обмена информацией между контроллером и датчиком. Данный датчик использует протокол 1-Wire. Информация о температуре датчика хранится в оперативной памяти, состоящей из слова длиной 9 байт.
Для того чтобы измерить температуру с помощью цифрового датчика ds18b20 и Arduino нам нужно сделать следующее:
Сначала собрать схему;
Скачать библиотеку OneWire;
Открыть готовый пример в среде Arduino;
Наслаждаться показаниями датчика.
После того как подключили все заливаем скетч:
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}
И вот у нас уже есть система тепературы.. но тепрь нам нужна сделать подачу горячей и холодной воды да так чтоб в ванной была определенная температура, да так чтоб набралась она для определенной температуры.
для этого начинаем писать скетч:
#include <OneWire.h>
#include <DallasTemperature.h>
#define SWITCH_PIN 2
#define LED_PIN 13
#define OUTPUT_PIN 7
#define ONE_WIRE_BUS 10
boolean lastButton = LOW; //прошлое состояние кнопки
boolean currentButton = LOW; //нынешнее состояние кнопки
boolean Stop0n = false; // флаг режима «стоп» было ledOn
float now_temp; //переменная нынешняя температура
float now_motion; // это где применяется?
int max_temp = 26; // уставка по максим температуре датчика
int min_temp = 25; // уставка по минимальной температуре датчика я бы поставил так! Чисто на время наладки!
void setup()
{
pinMode (SWITCH_PIN, INPUT);
pinMode (LED_PIN, OUTPUT);
pinMode (OUTPUT_PIN, OUTPUT);
Serial.begin(9600);
sensors.begin();
}
void loop()
{
currentButton = digitalRead(SWITCH_PIN); // читаем состояние кнопки
{
Stop0n = !LOW; // то инвертируем какую-то переменную Stop0n
if (Stop0n == true) { Serial.println("Vkluchen rezhim STOP");}
if (Stop0n == false) {Serial.println("Termostat ON");}
delay(1000); // обязательная пауза для борьбы с дребезгом в 1 секунду
}
//_____ Далее работа термостата
sensors.requestTemperatures();
now_temp = sensors.getTempCByIndex(0);// то читаем температуру из датчика
Serial.print("Temp: ");
Serial.println(now_temp);
delay(1000);
if (Stop0n==false)
{ // Если режим стоп не активирован работаем по термостату
if (now_temp > max_temp ) // превышение температуры
{
Serial.println("Temperatua max – LED_PIN ON");
digitalWrite(LED_PIN, HIGH);
}
else { digitalWrite(LED_PIN, LOW); }
if (now_temp < min_temp ) // понижение температуры
{
Serial.println("Temperatua min – OUTPUT_PIN ON ");
digitalWrite(OUTPUT_PIN, HIGH);
}
else { digitalWrite(OUTPUT_PIN, LOW); }
}
else { //если блокировка включена то погасить выходы
digitalWrite(LED_PIN, LOW) ;
digitalWrite(OUTPUT_PIN, LOW);
}
}
В данном скетче показано что к второму пину на ардуине подключен вывод замыкатель "для остановки воды"
к 13 и 7 пину подключены электронные клапаны я использовал http://www.rosarmatrade.com/published/publicdata/ROSARMATWARSTM/attachments/SC/products_pictures/Электромагнитные-клапаны_enl.jpg
ну и к десятому пину подсоединен датчик температуры ds18b20.
С этим все..
Теперь берем семи сигментный индикатор подключаем его к ардуине. Распиновка у всех разная поэтому схему не выкладываю, по трудитесь и поищите в интернете "гугл вам в помощь"
Пишем скетч таймера:
int digit1 = 11; //PWM Display pin 1
int digit2 = 10; //PWM Display pin 2
int digit3 = 9; //PWM Display pin 6
int digit4 = 6; //PWM Display pin 8
//Pin mapping from Arduino to the ATmega DIP28 if you need it
//http://www.arduino.cc/en/Hacking/PinMapping
int segA = A1; //Display pin 14
int segB = 3; //Display pin 16
int segC = 4; //Display pin 13
int segD = 5; //Display pin 3
int segE = A0; //Display pin 5
int segF = 7; //Display pin 11
int segG = 8; //Display pin 15
int start_num=30; // Number to countdown from
unsigned long time;
void setup() {
pinMode(segA, OUTPUT);
pinMode(segB, OUTPUT);
pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT);
pinMode(segE, OUTPUT);
pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);
pinMode(digit1, OUTPUT);
pinMode(digit2, OUTPUT);
pinMode(digit3, OUTPUT);
pinMode(digit4, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
//long startTime = millis();
if((millis()/1000) < start_num){
displayNumber(start_num -(millis()/1000));
}
else {
// reached zero, flash the display
time=millis();
while(millis() < time+200) {
displayNumber(0); // display 0 for 0.2 second
}
time=millis();
while(millis() < time+200) {
lightNumber(10); // Turn display off for 0.2 second
}
}
//while( (millis() - startTime) < 2000) {
//displayNumber(1217);
//}
//delay(1000);
}
//Given a number, we display 10:22
//After running through the 4 numbers, the display is left turned off
//Display brightness
//Each digit is on for a certain amount of microseconds
//Then it is off until we have reached a total of 20ms for the function call
//Let's assume each digit is on for 1000us
//If each digit is on for 1ms, there are 4 digits, so the display
//is off for 16ms.
//That's a ratio of 1ms to 16ms or 6.25% on time (PWM).
//Let's define a variable called brightness that varies from:
//5000 blindingly bright (15.7mA current draw per digit)
//2000 shockingly bright (11.4mA current draw per digit)
//1000 pretty bright (5.9mA)
//500 normal (3mA)
//200 dim but readable (1.4mA)
//50 dim but readable (0.56mA)
//5 dim but readable (0.31mA)
//1 dim but readable in dark (0.28mA)
void displayNumber(int toDisplay) {
#define DISPLAY_BRIGHTNESS 500
#define DIGIT_ON HIGH
#define DIGIT_OFF LOW
long beginTime = millis();
for(int digit = 4 ; digit > 0 ; digit--) {
//Turn on a digit for a short amount of time
switch(digit) {
case 1:
digitalWrite(digit1, DIGIT_ON);
break;
case 2:
digitalWrite(digit2, DIGIT_ON);
break;
case 3:
digitalWrite(digit3, DIGIT_ON);
break;
case 4:
digitalWrite(digit4, DIGIT_ON);
break;
}
//Turn on the right segments for this digit
lightNumber(toDisplay % 10);
toDisplay /= 10;
delayMicroseconds(DISPLAY_BRIGHTNESS);
//Display digit for fraction of a second (1us to 5000us, 500 is pretty good)
//Turn off all segments
lightNumber(10);
//Turn off all digits
digitalWrite(digit1, DIGIT_OFF);
digitalWrite(digit2, DIGIT_OFF);
digitalWrite(digit3, DIGIT_OFF);
digitalWrite(digit4, DIGIT_OFF);
}
while( (millis() - beginTime) < 10) ;
//Wait for 20ms to pass before we paint the display again
}
//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay) {
#define SEGMENT_ON LOW
#define SEGMENT_OFF HIGH
switch (numberToDisplay){
case 0:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_ON);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_OFF);
break;
case 1:
digitalWrite(segA, SEGMENT_OFF);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_OFF);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_OFF);
digitalWrite(segG, SEGMENT_OFF);
break;
case 2:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_OFF);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_ON);
digitalWrite(segF, SEGMENT_OFF);
digitalWrite(segG, SEGMENT_ON);
break;
case 3:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_OFF);
digitalWrite(segG, SEGMENT_ON);
break;
case 4:
digitalWrite(segA, SEGMENT_OFF);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_OFF);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_ON);
break;
case 5:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_OFF);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_ON);
break;
case 6:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_OFF);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_ON);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_ON);
break;
case 7:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_OFF);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_OFF);
digitalWrite(segG, SEGMENT_OFF);
break;
case 8:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_ON);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_ON);
break;
case 9:
digitalWrite(segA, SEGMENT_ON);
digitalWrite(segB, SEGMENT_ON);
digitalWrite(segC, SEGMENT_ON);
digitalWrite(segD, SEGMENT_ON);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_ON);
digitalWrite(segG, SEGMENT_ON);
break;
case 10:
digitalWrite(segA, SEGMENT_OFF);
digitalWrite(segB, SEGMENT_OFF);
digitalWrite(segC, SEGMENT_OFF);
digitalWrite(segD, SEGMENT_OFF);
digitalWrite(segE, SEGMENT_OFF);
digitalWrite(segF, SEGMENT_OFF);
digitalWrite(segG, SEGMENT_OFF);
break;
}
}
И вуаля у нас все готово.. наслаждаемся и не забываем оставлять комментарии.