Четыре зоны управления температурой + ШД
- Войдите на сайт для отправки комментариев
Здравствуйте ! Я совсем недавно увлекся ардуинкой, так сказать азы впитываю. Но все больше и больше хочется творить самому, и поэтому я обращаюсь к вам. если у вас есть время повозиться со мной в данном проекте, то я буду очень рад этому. Ну и как положено - с меня причитается!
Проект будет полностью открытым с фото, видео и конечно же кодом !
Творение мое называется экструдер !
У меня есть: "Ардуино мега 2560"
LCD-дисплей + 5 кнопок
четыре EPCOS B57560G104F NTC 100k THERMISTOR
четыре твердотельных реле управление 3в-30в
один драйвер ШД от pololu А4988
и ШД тоже один
Как это должно работать:
четыре зоны со спиральными нагревателями (разные диапазоны температуры на всех спиралях).
Нужно видеть текущую температуру всех четырех датчиков и заданное значение,
ну и соответственно иметь возможность с помощью кнопок задавать температуру для каждой зоны отдельно.
на экране что-то вроде этого "1Т 150°с/160°с" "2Т 200°с./210°"
"3Т 230°с/250°с" "4Т 275°с./280°"
Ну а третьей строкой управление ШД, нужны только обороты.
Я взял готовый похожий скетч и пытаюсь доточить его под свои нужды . Сейчас работаю на тем, чтобы вкрутить в этот скетч свой датчик (EPCOS B57560G104F NTC 100k THERMISTOR). Вроде много чего перечитал, а прикрутить не получается. Может не там читал ?
Ниже прилагаю сам скетч. Заранее благодарю.
001 | // Подключаем библиотеку для работы с шиной OneWire |
002 | // Термометр будет подключен на Pin2 |
003 | #include <OneWire.h> |
004 | OneWire oneWire(2); |
005 |
006 | //Подключаем библиотеку для работы с термометром |
007 | #include <DallasTemperature.h> |
008 |
009 | //Создаем объект sensors, подключенный по OneWire |
010 | DallasTemperature sensors(&oneWire); |
011 |
012 | //Создаем переменные для работы с термометром |
013 | DeviceAddress tempDeviceAddress; //переменная для хранения адреса датчика |
014 | float temp1=0; //переменная для текущего значения температуры |
015 | int setTmp=0; // переменная для заданного значения температуры |
016 |
017 | //Подключаем LCD-дисплей |
018 | #include <LiquidCrystal.h> |
019 | LiquidCrystal lcd(8, 9, 4, 5, 6, 7); |
020 |
021 | //Подсветка управляется через пин D10 |
022 | #define BACKLIGHT_PIN 10 |
023 |
024 | //Создаем переменную для хранения состояния подсветки |
025 | boolean backlightStatus = 1; |
026 |
027 | // Подключаем библиотеку для работы с ARDUINO EEPROM |
028 | //Заданная температура будет храниться по адресу 0 |
029 | #include <EEPROM2.h> |
030 |
031 | //Реле подключено к пину D11 |
032 | #define RELAY_PIN 11 |
033 |
034 | //Объявим переменную для хранения состояния реле |
035 | boolean relayStatus1=LOW; |
036 |
037 | //Объявим переменные для задания задержки |
038 | long previousMillis1 = 0; |
039 | long interval1 = 1000; // интервал опроса датчиков температуры |
040 |
041 | //Аналоговая клавиатура подключена к пину A0 |
042 | #define KEYPAD_PIN A0 |
043 | //Определим значения на аналоговом входе для клавиатуры |
044 | #define ButtonUp_LOW 90 |
045 | #define ButtonUp_HIGH 100 |
046 | #define ButtonDown_LOW 240 |
047 | #define ButtonDown_HIGH 280 |
048 | #define ButtonLeft_LOW 390 |
049 | #define ButtonLeft_HIGH 450 |
050 | #define ButtonRight_LOW 0 |
051 | #define ButtonRight_HIGH 50 |
052 | #define ButtonSelect_LOW 620 |
053 | #define ButtonSelect_HIGH 650 |
054 |
055 | void setup () { |
056 |
057 | //Настроим пин для управления реле |
058 | pinMode(RELAY_PIN,OUTPUT); |
059 | digitalWrite(RELAY_PIN,LOW); |
060 |
061 | //Считаем из постоянной памяти заданную температуру |
062 | setTmp=EEPROM_read_byte(0); |
063 |
064 | //Инициализируем термодатчик и установим разрешающую способность 12 бит (обычно она установлена по умолчанию, так что последнюю строчку можно опустить) |
065 | sensors.begin(); |
066 | sensors.getAddress(tempDeviceAddress, 0); |
067 | sensors.setResolution(12); |
068 | |
069 | //Настроим подсветку дисплея |
070 | pinMode(BACKLIGHT_PIN, OUTPUT); |
071 | digitalWrite(BACKLIGHT_PIN, backlightStatus); |
072 |
073 | //Выведем на дисплей стартовое сообщение на 2 секунды |
074 | lcd.begin(16, 2); |
075 | lcd.setCursor(0, 0); |
076 | lcd.print( "Temp. Controller" ); |
077 | lcd.setCursor(0, 1); |
078 | lcd.print( " v1.0 " ); |
079 | delay(2000); |
080 |
081 | // выведем на дисплей заданное значение температуры на 2 секунды |
082 | lcd.setCursor(0, 1); |
083 | lcd.print( " Set temp: " ); |
084 | lcd.setCursor(12,1); |
085 | lcd.print(setTmp); |
086 | delay(2000); |
087 |
088 | //Очистим дисплей |
089 | lcd.begin(16, 2); |
090 | } |
091 |
092 |
093 |
094 | //Определим функцию для опроса аналоговой клавиатуры |
095 | //Функция опроса клавиатуры, принимает адрес пина, к которому подключена клавиатура, и возвращает код клавиши: |
096 | // 1 - UP |
097 | // 2 - DOWN |
098 | // 3 - LEFT |
099 | // 4 - RIGHT |
100 | // 5 - SELECT |
101 |
102 | int ReadKey( int keyPin) |
103 | { |
104 | int KeyNum=0; |
105 | int KeyValue1=0; |
106 | int KeyValue2=0; |
107 |
108 | //Читаем в цикле аналоговый вход, для подавления дребезга и нестабильности читаем по два раза подряд, пока значения не будут равны. |
109 | //Если значения равны 1023 – значит не была нажата ни одна клавиша. |
110 |
111 | do { |
112 | KeyValue1=analogRead(keyPin); |
113 | KeyValue2=analogRead(keyPin); |
114 | } while (KeyValue1==KeyValue2&&KeyValue2!=1023); |
115 |
116 | //Интерпретируем полученное значение и определяем код нажатой клавиши |
117 | if (KeyValue2<ButtonUp_HIGH&&KeyValue2>ButtonUp_LOW) {KeyNum=1;} //Up |
118 | if (KeyValue2<ButtonDown_HIGH&&KeyValue2>ButtonDown_LOW) {KeyNum=2;} //Down |
119 | if (KeyValue2<ButtonLeft_HIGH&&KeyValue2>ButtonLeft_LOW) {KeyNum=3;} //Left |
120 | if (KeyValue2<ButtonRight_HIGH&&KeyValue2>ButtonRight_LOW) {KeyNum=4;} //Right |
121 | if (KeyValue2<ButtonSelect_HIGH&&KeyValue2>ButtonSelect_LOW) {KeyNum=5;} //Select |
122 |
123 | //Возвращаем код нажатой клавиши |
124 | return KeyNum; |
125 | } |
126 |
127 | //Определим процедуру редактирования заданной температуры |
128 | //Вызывается по нажатию клавиши Select, отображает на дисплее заданную температуру и позволяет изменять ее клавишами Up и Down |
129 |
130 | void setTemperature() { |
131 |
132 | int keyCode=0; |
133 |
134 | //выводим на дисплей заданное значение температуры |
135 | lcd.begin(16,2); |
136 | lcd.setCursor(0, 0); |
137 | lcd.print( " Setting temp " ); |
138 | lcd.setCursor(7, 1); |
139 | lcd.print(setTmp); |
140 |
141 | //Опрашиваем клавиатуру, если нажата клавиша Up увеличиваем значение на 1, если Down – уменьшаем на 1 |
142 | //Если нажаты клавиши Select или Right – цикл опроса прерывается |
143 | //Задержки введены для борьбы с дребезгом, если клавиши срабатывают четко – можно уменьшить время задержек или вообще их убрать |
144 | do { |
145 | keyCode=ReadKey(KEYPAD_PIN); |
146 | if (keyCode==1){setTmp++;delay(200);lcd.setCursor(7, 1);lcd.print(setTmp);} |
147 | if (keyCode==2){setTmp--;delay(200);lcd.setCursor(7, 1);lcd.print(setTmp);} |
148 | } while (keyCode!=5 && keyCode!=4); |
149 | delay(200); |
150 |
151 | //По клавише Select – созраняем в EEPROM измененное значение |
152 | //По клавише Right – восстанавливаем старое значение |
153 | if (keyCode==5) {EEPROM_write_byte(0, setTmp);} |
154 | if (keyCode==4) {setTmp = EEPROM_read_byte(0);} |
155 | } |
156 |
157 | void loop () { |
158 |
159 | //Модуль опроса датчиков и получения сведений о температуре |
160 | //Вызывается 1 раз в секунду |
161 | unsigned long currentMillis1 = millis(); |
162 | if (currentMillis1 - previousMillis1 > interval1) { |
163 | previousMillis1 = currentMillis1; |
164 |
165 | //Запуск процедуры измерения температуры |
166 | sensors.setWaitForConversion( false ); |
167 | sensors.requestTemperatures(); |
168 | sensors.setWaitForConversion( true ); |
169 |
170 | Delay(750) // задержка для обработки информации внутри термометра, в данном случае можно не задавать |
171 |
172 | //Считывание значения температуры |
173 | sensors.getAddress(tempDeviceAddress, 0); |
174 | temp1=sensors.getTempC(tempDeviceAddress); |
175 |
176 | // Вывод текущего значения температуры на дисплей |
177 | lcd.setCursor(0, 0); |
178 | lcd.print( " Current temp " ); |
179 | lcd.setCursor(5, 1); |
180 | lcd.print(temp1); |
181 | // Serial.println(temp1,4); |
182 | } |
183 |
184 | //Проверка условия включения/выключения нагревателя |
185 | if (temp1<setTmp&&relayStatus1==LOW){relayStatus1=HIGH; digitalWrite(RELAY_PIN,HIGH);} |
186 | if (temp1>setTmp&&relayStatus1==HIGH){relayStatus1=LOW; digitalWrite(RELAY_PIN,LOW);} |
187 |
188 | // Опрос клавиатуры |
189 | int Feature = ReadKey(KEYPAD_PIN); |
190 | if (Feature==1 ) {backlightStatus=1;digitalWrite(BACKLIGHT_PIN, backlightStatus);} //Включение подсветки |
191 | if (Feature==2 ) {backlightStatus=0;digitalWrite(BACKLIGHT_PIN, backlightStatus);} //Отключение подсветки |
192 | if (Feature==5 ) {delay(200);setTemperature();} //Переход к редактированию заданной температуры |
193 | } |
//Проверка условия включения/выключения нагревателя
НИже должен идти Ваш код сравнения данных, считанных с делителя на NTC с заданными эталонными значениями. А все, что про Dallas DS18B20 - можно закомментировать. Хотя по-мне, так проще купить (даже по $2) далласовские цифровые термометры.
Не проблема купить, Я не нашел датчиков с диапазоном температуры 0 до 300 г с
//Проверка условия включения/выключения нагревателя
НИже должен идти Ваш код сравнения данных, считанных с делителя на NTC с заданными эталонными значениями.
вот этот код
#define THERMISTORTABLE0 {\
#define THERMISTORTABLE0 {\
Очевидно массив группами по три числа. Что он Вам даст - не очень понятно, хотя может оказаться таблицей пересчета. Для больших температур лучше термопары использовать, а не термосопротивления, вроде бы у них характеристика более линейная.
Хорошо с делителем сегодня вечером разберусь и попробую получить данные для своего датчика .
Ну вот поначалу отчаялся помогать особо некому «да и мне некогда» но ничего русские просто так не сдаются пару дней с бубном шаманские свистопляски с макеткой и скетчем (не одним) вот слепил. «УРА ЗАРАБОТАЛО» да удовольствие незабываемое, многое стало понятней! Если нетрудно посмотрите на то что я слепил ! а то мне еще три датчика как то надо сюда воткнуть может что посоветуете ?
001
/*Моя первая реальная программа SONIC300077!
002
Создана методом научного тыка )) 18,10,2013 22:54
003
*/
004
005
#include <LiquidCrystal.h>
006
#include <math.h>
007
#include <OneWire.h>
008
#include <EEPROM2.h>
009
010
011
float
temp1=0;
//переменная для текущего значения температуры
012
int
setTmp=0;
// переменная для заданного значения температуры
013
014
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//Подключаем LCD-дисплей
015
#define BACKLIGHT_PIN 10 //Подсветка управляется через пин D10
016
boolean backlightStatus = 1;
//Создаем переменную для хранения состояния подсветки
017
018
#define RELAY_PIN 53 //Реле подключено к пину D11
019
boolean relayStatus1=LOW;
//Объявим переменную для хранения состояния реле
020
021
//Аналоговая клавиатура подключена к пину A0
022
#define KEYPAD_PIN A0
023
//Определим значения на аналоговом входе для клавиатуры
024
#define ButtonUp_LOW 130
025
#define ButtonUp_HIGH 150
026
#define ButtonDown_LOW 300
027
#define ButtonDown_HIGH 350
028
#define ButtonLeft_LOW 490
029
#define ButtonLeft_HIGH 520
030
#define ButtonRight_LOW 0
031
#define ButtonRight_HIGH 50
032
#define ButtonSelect_LOW 700
033
#define ButtonSelect_HIGH 780
034
035
void
setup
() {
036
037
//Настроим подсветку дисплея
038
pinMode(BACKLIGHT_PIN, OUTPUT);
039
digitalWrite(BACKLIGHT_PIN, backlightStatus);
040
041
042
//Настроим пин для управления реле
043
pinMode(RELAY_PIN,OUTPUT);
044
digitalWrite(RELAY_PIN,LOW);
045
046
//Считаем из постоянной памяти заданную температуру
047
setTmp=EEPROM_read_byte(0);
048
049
//Выведем на дисплей стартовое сообщение на 2 секунды
050
lcd.begin(20, 4 );
051
lcd.setCursor(0, 0);
052
lcd.print(
"Temp. Controller"
);
053
lcd.setCursor(0, 1);
054
lcd.print(
" v1.0 "
);
055
delay(2000);
056
057
// выведем на дисплей заданное значение температуры на 2 секунды
058
lcd.setCursor(0, 1);
059
lcd.print(
" Set temp: "
);
060
lcd.setCursor(12,1);
061
lcd.print(setTmp);
062
delay(2000);
063
064
//Очистим дисплей
065
lcd.begin(20, 4);
066
}
067
068
double
Thermister(
int
RawADC) {
069
double
Temp;
070
// See <a href="http://en.wikipedia.org/wiki/Thermistor" title="http://en.wikipedia.org/wiki/Thermistor" rel="nofollow">http://en.wikipedia.org/wiki/Thermistor</a> for explanation of formula
071
Temp = log(((10240000/RawADC) - 10000));
072
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
073
Temp = Temp - 273.15;
// Convert Kelvin to Celcius
074
return
Temp;
075
}
076
077
//Определим функцию для опроса аналоговой клавиатуры
078
//Функция опроса клавиатуры, принимает адрес пина, к которому подключена клавиатура, и возвращает код клавиши:
079
// 1 - UP
080
// 2 - DOWN
081
// 3 - LEFT
082
// 4 - RIGHT
083
// 5 - SELECT
084
085
int
ReadKey(
int
keyPin)
086
{
087
int
KeyNum=0;
088
int
KeyValue1=0;
089
int
KeyValue2=0;
090
091
//Читаем в цикле аналоговый вход, для подавления дребезга и нестабильности читаем по два раза подряд, пока значения не будут равны.
092
//Если значения равны 1023 – значит не была нажата ни одна клавиша.
093
do
{
094
KeyValue1=analogRead(keyPin);
095
KeyValue2=analogRead(keyPin);
096
}
while
(KeyValue1==KeyValue2&&KeyValue2!=1023);
097
098
//Интерпретируем полученное значение и определяем код нажатой клавиши
099
if
(KeyValue2<ButtonUp_HIGH&&KeyValue2>ButtonUp_LOW) {KeyNum=1;}
//Up
100
if
(KeyValue2<ButtonDown_HIGH&&KeyValue2>ButtonDown_LOW) {KeyNum=2;}
//Down
101
if
(KeyValue2<ButtonLeft_HIGH&&KeyValue2>ButtonLeft_LOW) {KeyNum=3;}
//Left
102
if
(KeyValue2<ButtonRight_HIGH&&KeyValue2>ButtonRight_LOW) {KeyNum=4;}
//Right
103
if
(KeyValue2<ButtonSelect_HIGH&&KeyValue2>ButtonSelect_LOW) {KeyNum=5;}
//Select
104
105
//Возвращаем код нажатой клавиши
106
return
KeyNum;
107
}
108
109
void
setTemperature() {
110
111
int
keyCode=0;
112
113
//выводим на дисплей заданное значение температуры
114
lcd.begin(20,4);
115
lcd.setCursor(0, 0);
116
lcd.print(
" Setting temp "
);
117
lcd.setCursor(7, 1);
118
lcd.print(setTmp);
119
120
//Опрашиваем клавиатуру, если нажата клавиша Up увеличиваем значение на 1, если Down – уменьшаем на 1
121
//Если нажаты клавиши Select или Right – цикл опроса прерывается
122
//Задержки введены для борьбы с дребезгом, если клавиши срабатывают четко – можно уменьшить время задержек или вообще их убрать
123
do
{
124
keyCode=ReadKey(KEYPAD_PIN);
125
if
(keyCode==1){setTmp++;delay(200);lcd.setCursor(7, 1);lcd.print(setTmp);}
126
if
(keyCode==2){setTmp--;delay(200);lcd.setCursor(7, 1);lcd.print(setTmp);}
127
}
while
(keyCode!=5 && keyCode!=4);
128
delay(200);
129
130
//По клавише Select – созраняем в EEPROM измененное значение
131
//По клавише Right – восстанавливаем старое значение
132
if
(keyCode==5) {EEPROM_write_byte(0, setTmp);}
133
if
(keyCode==4) {setTmp = EEPROM_read_byte(0);}
134
}
135
136
137
void
loop
() {
138
double
temp = Thermister(analogRead(7));
// Read sensor
139
lcd.setCursor(0, 0);
140
lcd.print(
" Current temp "
);
141
lcd.setCursor(5, 1);
142
lcd.print(temp);
143
144
//Проверка условия включения/выключения нагревателя
145
if
(temp<setTmp&&relayStatus1==LOW){relayStatus1=HIGH; digitalWrite(RELAY_PIN,HIGH);}
146
if
(temp>setTmp&&relayStatus1==HIGH){relayStatus1=LOW; digitalWrite(RELAY_PIN,LOW);}
147
148
149
// Опрос клавиатуры
150
int
Feature = ReadKey(KEYPAD_PIN);
151
if
(Feature==1 ) {backlightStatus=1;digitalWrite(BACKLIGHT_PIN, backlightStatus);}
//Включение подсветки
152
if
(Feature==2 ) {backlightStatus=0;digitalWrite(BACKLIGHT_PIN, backlightStatus);}
//Отключение подсветки
153
if
(Feature==5 ) {delay(200);setTemperature();}
//Переход к редактированию заданной температуры
154
}
Я закончил сегодня скетч ! если нетрудно мне нужна оценка , критика и.т.д!!
Вот код:
001
#include <EEPROM2.h>
002
#include <LiquidCrystal.h>
003
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
004
#include <TimerOne.h>
005
//переменная для текущего значения температуры
006
// переменная для заданного значения температуры
007
float
temp1=0;
008
int
setTmp1=0;
009
010
float
temp2=0;
011
int
setTmp2=0;
012
013
float
temp3=0;
014
int
setTmp3=0;
015
016
float
temp4=0;
017
int
setTmp4=0;
018
019
#define RELAY1_PIN 31 //Реле подключено к пину D53
020
boolean relayStatus1=LOW;
//Объявим переменную для хранения состояния реле
021
022
#define RELAY2_PIN 33 //Реле подключено к пину D52
023
boolean relayStatus2=LOW;
//Объявим переменную для хранения состояния реле
024
025
#define RELAY3_PIN 35 //Реле подключено к пину D51
026
boolean relayStatus3=LOW;
//Объявим переменную для хранения состояния реле
027
028
#define RELAY4_PIN 37 //Реле подключено к пину D50
029
boolean relayStatus4=LOW;
//Объявим переменную для хранения состояния реле
030
031
//Аналоговая клавиатура подключена к пину A8
032
#define KEYPAD_PIN A8
033
//Определим значения на аналоговом входе для клавиатуры
034
#define ButtonT1Up_LOW 170
035
#define ButtonT1Up_HIGH 190
036
#define ButtonT1Down_LOW 300
037
#define ButtonT1Down_HIGH 315
038
#define ButtonT2Up_LOW 345
039
#define ButtonT2Up_HIGH 365
040
#define ButtonT2Down_LOW 430
041
#define ButtonT2Down_HIGH 445
042
#define ButtonSelect_LOW 490
043
#define ButtonSelect_HIGH 515
044
#define ButtonT3Up_LOW 670
045
#define ButtonT3Up_HIGH 686
046
#define ButtonT3Down_LOW 690
047
#define ButtonT3Down_HIGH 710
048
#define ButtonT4Up_LOW 735
049
#define ButtonT4Up_HIGH 750
050
#define ButtonT4Down_LOW 790
051
#define ButtonT4Down_HIGH 810
052
#define ButtonRight_LOW 940
053
#define ButtonRight_HIGH 960
054
055
056
// buttons code
057
#define btnRIGHT 0
058
#define btnUP 1
059
#define btnDOWN 2
060
#define btnLEFT 3
061
#define btnSELECT 4
062
#define btnNONE 5
063
064
065
// directions
066
#define FORWARD HIGH
067
#define BACKWARD LOW
068
069
// debounce time (milliseconds)
070
#define DEBOUNCE_TIME 200
071
072
// PINs for Pololu controller
073
#define PIN_STEP 51
074
075
#define PIN_DIR 52
076
077
// lookup table speed - ticks (interrupts)
078
const
int
speed_ticks[] = {-1, 600, 300, 200, 150, 120,100, 86, 75, 67, 60, 55, 50, 46, 43};
079
080
081
int
actual_speed;
082
int
actual_direction;
083
084
int
ticks;
085
int
tick_count;
086
087
int
button;
088
boolean debounce;
089
unsigned
long
previous_time;
090
091
// custom LCD square symbol for progress bar
092
byte
square_symbol[8] = {
093
B11111,
094
B11111,
095
B11111,
096
B11111,
097
B11111,
098
B11111,
099
B11111,
100
B11111,
101
};
102
103
// string constants
104
char
forward_arrow[] =
"->->->"
;
105
char
backward_arrow[] =
"<-<-<-"
;
106
107
108
void
setup
() {
109
110
//Настроим пин для управления реле
111
pinMode(RELAY1_PIN,OUTPUT);
112
digitalWrite(RELAY1_PIN,LOW);
113
114
pinMode(RELAY2_PIN,OUTPUT);
115
digitalWrite(RELAY2_PIN,LOW);
116
117
pinMode(RELAY3_PIN,OUTPUT);
118
digitalWrite(RELAY3_PIN,LOW);
119
120
pinMode(RELAY4_PIN,OUTPUT);
121
digitalWrite(RELAY4_PIN,LOW);
122
123
setTmp1=EEPROM_read_byte(0);
124
setTmp2=EEPROM_read_byte(1);
125
setTmp3=EEPROM_read_byte(2);
126
setTmp4=EEPROM_read_byte(3);
127
128
129
//Выведем на дисплей стартовое сообщение на 2 секунды
130
lcd.begin(20, 4 );
131
lcd.setCursor(0, 0);
132
lcd.print(
" Controller Temp. "
);
133
lcd.setCursor(0, 1);
134
lcd.print(
" OOO Sputnik "
);
135
lcd.setCursor(0, 2);
136
lcd.print(
" v2.2 "
);
137
delay(3000);
138
139
// выведем на дисплей заданное значение температуры на 2 секунды
140
lcd.setCursor(0, 0);
141
lcd.print(
" Set temp1: "
);
142
lcd.setCursor(16,0);
143
lcd.print(setTmp1);
144
145
lcd.setCursor(0, 1);
146
lcd.print(
" Set temp2: "
);
147
lcd.setCursor(16,1);
148
lcd.print(setTmp2);
149
150
lcd.setCursor(0, 2);
151
lcd.print(
" Set temp3: "
);
152
lcd.setCursor(16,2);
153
lcd.print(setTmp3);
154
155
lcd.setCursor(0, 3);
156
lcd.print(
" Set temp4: "
);
157
lcd.setCursor(16,3);
158
lcd.print(setTmp4);
159
160
delay(2000);
161
162
//////////////////////////////
163
// init the timer1, interrupt every 0.1ms
164
Timer1.initialize(100);
165
Timer1.attachInterrupt(timerIsr);
166
167
// init LCD and custom symbol
168
lcd.begin(20, 4);
169
lcd.setCursor(0,3);
170
lcd.createChar(0, square_symbol);
171
172
// pins direction
173
pinMode(PIN_STEP, OUTPUT);
174
pinMode(PIN_DIR, OUTPUT);
175
176
// initial values
177
actual_speed = 0;
178
actual_direction = FORWARD;
179
tick_count = 0;
180
ticks = -1;
181
debounce =
false
;
182
183
digitalWrite(PIN_DIR, actual_direction);
184
updateLCD();
185
}
186
187
188
double
Thermister(
int
RawADC) {
189
double
Temp;
190
double
Temp1;
191
// See <a href="http://en.wikipedia.org/wiki/Thermistor" title="http://en.wikipedia.org/wiki/Thermistor" rel="nofollow">http://en.wikipedia.org/wiki/Thermistor</a> for explanation of formula
192
Temp = log(((10240000/RawADC) - 10000));
193
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
194
Temp = Temp - 273.15;
// Convert Kelvin to Celcius
195
return
Temp;
196
}
197
198
//Определим функцию для опроса аналоговой клавиатуры
199
//Функция опроса клавиатуры, принимает адрес пина, к которому подключена клавиатура, и возвращает код клавиши:
200
// 1 - T1up
201
// 2 - T1Down
202
// 3 - LEFT
203
// 4 - RIGHT
204
// 5 - SELECT
205
// 6 - Ok
206
// 7 - T3up
207
// 8 _ T3down
208
// 9 - T4up
209
int
ReadKey(
int
keyPin)
210
{
211
int
KeyNum=0;
212
int
KeyValue1=0;
213
int
KeyValue2=0;
214
215
//Читаем в цикле аналоговый вход, для подавления дребезга и нестабильности читаем по два раза подряд, пока значения не будут равны.
216
//Если значения равны 1023 – значит не была нажата ни одна клавиша.
217
do
{
218
KeyValue1=analogRead(keyPin);
219
KeyValue2=analogRead(keyPin);
220
}
while
(KeyValue1==KeyValue2&&KeyValue2!=1023);
221
222
//Интерпретируем полученное значение и определяем код нажатой клавиши
223
if
(KeyValue2<ButtonT1Up_HIGH&&KeyValue2>ButtonT1Up_LOW) {KeyNum=1;}
//T1Up
224
if
(KeyValue2<ButtonT1Down_HIGH&&KeyValue2>ButtonT1Down_LOW) {KeyNum=2;}
//T1Down
225
if
(KeyValue2<ButtonT2Up_HIGH&&KeyValue2>ButtonT2Up_LOW) {KeyNum=3;}
//T2Up
226
if
(KeyValue2<ButtonT2Down_HIGH&&KeyValue2>ButtonT2Down_LOW) {KeyNum=4;}
//T2Down
227
if
(KeyValue2<ButtonSelect_HIGH&&KeyValue2>ButtonSelect_LOW) {KeyNum=5;}
//Select
228
if
(KeyValue2<ButtonT3Up_HIGH&&KeyValue2>ButtonT3Up_LOW) {KeyNum=6;}
//T3up
229
if
(KeyValue2<ButtonT3Down_HIGH&&KeyValue2>ButtonT3Down_LOW) {KeyNum=7;}
//T3Down
230
if
(KeyValue2<ButtonT4Up_HIGH&&KeyValue2>ButtonT4Up_LOW) {KeyNum=8;}
//T3up
231
if
(KeyValue2<ButtonT4Down_HIGH&&KeyValue2>ButtonT4Down_LOW) {KeyNum=9;}
//T3Down
232
if
(KeyValue2<ButtonRight_HIGH&&KeyValue2>ButtonRight_LOW) {KeyNum=10;}
//T3Down
233
//Возвращаем код нажатой клавиши
234
return
KeyNum;
235
}
236
237
void
loop
() {
238
239
double
temp1 = Thermister(analogRead(12));
// Read sensor
240
delay(10);
241
lcd.setCursor(0, 0);
242
lcd.print(
"1 "
);
243
//lcd.setCursor(2, 0);
244
lcd.print(temp1);
245
lcd.print(
"/"
);
246
lcd.print(setTmp1);
247
lcd.print(
"* "
);
248
249
250
double
temp2 = Thermister(analogRead(13));
251
delay(10);
252
lcd.setCursor(0, 1);
253
lcd.print(
"2 "
);
254
lcd.print(temp2);
255
lcd.print(
"/"
);
256
lcd.print(setTmp2);
257
lcd.print(
"* "
);
258
259
double
temp3 = Thermister(analogRead(14));
260
delay(10);
261
lcd.setCursor(0, 2);
262
lcd.print(
"3 "
);
263
lcd.print(temp3);
264
lcd.print(
"/"
);
265
lcd.print(setTmp3);
266
lcd.print(
"* "
);
267
268
double
temp4 = Thermister(analogRead(15));
269
delay(10);
270
lcd.setCursor(0, 3);
271
lcd.print(
"4 "
);
272
lcd.print(temp1);
273
lcd.print(
"/"
);
274
lcd.print(setTmp4);
275
lcd.print(
"* "
);
276
277
278
int
Feature = ReadKey(KEYPAD_PIN);
279
if
(Feature==1){setTmp1++;delay(100);lcd.setCursor(8, 0);lcd.print(setTmp1);}
280
if
(Feature==2){setTmp1--;delay(100);lcd.setCursor(8, 0);lcd.print(setTmp1);}
281
if
(Feature==3){setTmp2++;delay(100);lcd.setCursor(8, 1);lcd.print(setTmp2);}
282
if
(Feature==4){setTmp2--;delay(100);lcd.setCursor(8, 1);lcd.print(setTmp2);}
283
if
(Feature==6){setTmp3++;delay(100);lcd.setCursor(8, 2);lcd.print(setTmp3);}
284
if
(Feature==7){setTmp3--;delay(100);lcd.setCursor(8, 2);lcd.print(setTmp3);}
285
if
(Feature==8){setTmp4++;delay(100);lcd.setCursor(8, 3);lcd.print(setTmp4);}
286
if
(Feature==9){setTmp4--;delay(100);lcd.setCursor(8, 3);lcd.print(setTmp4);}
287
288
if
(Feature==5) {EEPROM_write_byte(0,setTmp1);}
289
if
(Feature==5) {EEPROM_write_byte(1,setTmp2);}
290
if
(Feature==5) {EEPROM_write_byte(2,setTmp3);}
291
if
(Feature==5) {EEPROM_write_byte(3,setTmp4);}
292
293
//Проверка условия включения/выключения нагревателя
294
if
(temp1<setTmp1&&relayStatus1==LOW){relayStatus1=HIGH; digitalWrite(RELAY1_PIN,HIGH);}
295
if
(temp1>setTmp1&&relayStatus1==HIGH){relayStatus1=LOW; digitalWrite(RELAY1_PIN,LOW);}
296
if
(temp2<setTmp2&&relayStatus2==LOW){relayStatus2=HIGH; digitalWrite(RELAY2_PIN,HIGH);}
297
if
(temp2>setTmp2&&relayStatus2==HIGH){relayStatus2=LOW; digitalWrite(RELAY2_PIN,LOW);}
298
if
(temp3<setTmp2&&relayStatus3==LOW){relayStatus3=HIGH; digitalWrite(RELAY3_PIN,HIGH);}
299
if
(temp3>setTmp2&&relayStatus3==HIGH){relayStatus3=LOW; digitalWrite(RELAY3_PIN,LOW);}
300
if
(temp4<setTmp2&&relayStatus4==LOW){relayStatus4=HIGH; digitalWrite(RELAY4_PIN,HIGH);}
301
if
(temp4>setTmp2&&relayStatus4==HIGH){relayStatus4=LOW; digitalWrite(RELAY4_PIN,LOW);}
302
303
304
305
306
307
// check if debounce active
308
if
(debounce) {
309
button = btnNONE;
310
if
(millis() > previous_time + DEBOUNCE_TIME) debounce =
false
;
311
}
else
button = read_buttons();
312
313
// if a button is pressed, start debounce time
314
if
(button != btnNONE) {
315
316
previous_time = millis();
317
debounce =
true
;
318
}
319
320
// check which button was pressed
321
switch
(button) {
322
323
case
btnUP:
324
increase_speed();
325
break
;
326
case
btnDOWN:
327
decrease_speed();
328
break
;
329
case
btnLEFT:
330
change_direction(BACKWARD);
331
break
;
332
case
btnRIGHT:
333
change_direction(FORWARD);
334
break
;
335
case
btnSELECT:
336
emergency_stop();
337
break
;
338
}
339
340
// finally update the LCD
341
updateLCD();
342
}
343
344
// increase speed if it's below the max (70)
345
void
increase_speed() {
346
347
if
(actual_speed < 70) {
348
actual_speed += 5;
349
tick_count = 0;
350
ticks = speed_ticks[actual_speed / 5];
351
}
352
}
353
354
// decrease speed if it's above the min (0)
355
void
decrease_speed() {
356
357
if
(actual_speed > 0) {
358
actual_speed -= 5;
359
tick_count = 0;
360
ticks = speed_ticks[actual_speed / 5];
361
}
362
}
363
364
// change direction if needed
365
void
change_direction(
int
new_direction) {
366
367
if
(actual_direction != new_direction) {
368
actual_direction = new_direction;
369
digitalWrite(PIN_DIR, actual_direction);
370
}
371
}
372
373
// emergency stop: speed 0
374
void
emergency_stop() {
375
actual_speed = 0;
376
tick_count = 0;
377
ticks = speed_ticks[actual_speed / 5];
378
}
379
380
// update LCD
381
void
updateLCD() {
382
383
// print first line:
384
// Speed: xxxRPM --> (or <--)
385
lcd.setCursor(14,0);
386
lcd.print(
"R: "
);
387
lcd.print(actual_speed);
388
lcd.print(
"' "
);
389
lcd.setCursor(14,2);
390
lcd.print(
"Speed:"
);
391
392
lcd.setCursor(14,1);
393
if
(actual_direction == FORWARD) lcd.print(forward_arrow);
394
else
lcd.print(backward_arrow);
395
396
// print second line:
397
// progress bar [##### ]
398
// 15 speed steps: 0 - 5 - 10 - ... - 70
399
lcd.setCursor(14,3);
400
lcd.print(
"["
);
401
402
for
(
int
i = 1; i <= 4; i++) {
403
404
if
(actual_speed > (14 * i) - 1) lcd.write(
byte
(0));
405
else
lcd.print(
" "
);
406
}
407
408
lcd.print(
"]"
);
409
}
410
411
// timer1 interrupt function
412
void
timerIsr() {
413
414
if
(actual_speed == 0)
return
;
415
416
tick_count++;
417
418
if
(tick_count == ticks) {
419
420
// make a step
421
digitalWrite(PIN_STEP, HIGH);
422
digitalWrite(PIN_STEP, LOW);
423
424
tick_count = 0;
425
}
426
}
427
428
429
430
431
// read buttons connected to a single analog pin
432
int
read_buttons() {
433
434
int
adc_key_in = analogRead(0);
435
436
if
(adc_key_in > 1000)
return
btnNONE;
437
if
(adc_key_in < 50)
return
btnRIGHT;
438
if
(adc_key_in < 195)
return
btnUP;
439
if
(adc_key_in < 380)
return
btnDOWN;
440
if
(adc_key_in < 555)
return
btnLEFT;
441
if
(adc_key_in < 790)
return
btnSELECT;
442
}