#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7); // RS, E, D4, D5, D6, D7 врде так. Взял с сайта для создания своих символов в ячейке для символов
// https://maxpromer.github.io/LCD-Character-Creator/
// https://arduinomaster.ru/platy-arduino/arduino-lcd-keypad-shield/ - здесь хорошо описано про всю плату
// https://ampermarket.kz/base/ex34-lcd-keypad-shield/ - здесь хорошая картинка распиновки (и выходных значений кнопок)
bool engine_operating_mode = 1; // Переключатель Broach/Rewind. Broach соответствует 1
byte str = 0;
bool swiser = 0; //С помощью пина не управляется (подать на выход напряжение), по этому так догадался
//boolean down_flag=0;
boolean flag_heat = 0; //Переменная, отвечающая за состояние нагревателя - идёт подогрев или нет
int heat = 0;
const int St = 60; // Скорость 60 об/мин
float T = 0; // в loop будет вычислена эта переменная температуры, взятая с термистера
short int Ty = 160;short int Sl = 1000;short int Sh = 200; // Мои переменные для теста! //Скорость измеряется в кол-ве шагов за один полный оборот
// пины для подключения контактов STEP, DIR
#define PIN_STEP 3
#define PIN_DIR 2
// https://роботехника18.рф/%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D1%81%D1%82%D0%BE%D1%80/ - отсюда взял схему подключения терморезистора 100 кОм 3950 ntc к Ардуино и программу
// https://radioprog.ru/post/185 - здесь описана формула β-уравнения (и другие вещи: теория и т.д)
// https://robotclass.ru/tutorials/arduino-thermistor-100k/ - ещё одна полезная статья с β-уравнение, но проще чем предыдущая
// https://www.youtube.com/watch?v=B30OhY70N_w - видео, как высчитывать A, B и C коэффициенты для формулы Стейнхарта — Харта
#define B 3950 // B коэффициент
#define RESISTOR 100000 // сопротивление резистора, 100 кОм
#define THERMISTOR 100000 // номинальное сопротивление термистора, 100 кОм
#define NOMINAL 25 // номинальная температура
#define sensor A1
void setup() {
lcd.begin(16,2);
lcd.clear();
// подсветкой экарана на шилде можно управлять через 10 пин командой analogWrite(10, 30); , где 30 - выход ШИМ (Широтно-импульсная модуляция)
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
pinMode(12, OUTPUT); // реле
Serial.begin(9600);
pinMode(sensor, INPUT);
}
void chatter_buttons() { //Дребезг контактов (кнопок)
delay(100);
}
byte key(){ // по идеи (пока ориентируюсь на сайт wokwi), слева направо и сверху вниз (Select,Left, Up, Down, Right, (RST - Reset)): 1 - 719, 2 - 477, 3 - 131, 4 - 305, 5 - 0, ничего не зажато - 1023
// https://www.youtube.com/watch?v=UOreLZaYD5k&t
int val = analogRead(0);
if (val < 100) return 5; // Right
else if (val < 200) return 3; // Up
else if (val < 400) return 4; // Down
else if (val < 600) return 2; // Left
else if (val < 800) return 1; // Select
else return 0;
}
void list(byte str) { //Функция списка экранов
switch(str) {
case 0: //"Status"
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Status");
lcd.setCursor(0, 1);
lcd.print("T=");lcd.print(T);lcd.print("->");
if (flag_heat==0) {
lcd.print("OFF");
}
else
{
lcd.setCursor(15, 0);lcd.print("*");
lcd.setCursor(9, 1);lcd.print(Ty);lcd.print("C");
}
break;
case 1: //"Temp Protazki"
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp broach");
lcd.setCursor(0, 1);
lcd.print("<");lcd.print(Ty);lcd.print("> ");lcd.print("(");lcd.print(T);lcd.print(")");break;
case 2: //"Protazka"
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Speed broach");
lcd.setCursor(0, 1);
lcd.print("<");lcd.print(Sl);lcd.print("> ");break;
case 3: //"Peremotka"
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Speed rewind");
lcd.setCursor(0, 1);
lcd.print("<");lcd.print(Sh);lcd.print("> ");break;
case 4: //Cостояние двигателя
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Engine (ON/OFF)");
lcd.setCursor(0, 1);
if (swiser) {
lcd.print("ON");
}
else {
lcd.print("OFF");
}
break;
case 5: //Режим работы двигателя
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Broach/Rewind");
lcd.setCursor(0, 1);
if (engine_operating_mode) {
lcd.print("Broach");
}
else {
lcd.print("Rewind");
}
break;
}
}
void loop() {
int t = analogRead(sensor);
float tr = 1023.0 / t - 1;
tr = RESISTOR / tr;
Serial.print("R=");
Serial.print(tr);
Serial.print(", t=");
T = 1.0 / (1.0 / (NOMINAL + 273.15) + log(tr / THERMISTOR) / B) - 273.15;
Serial.println(T);
//delay(1000);
if (key() == 0) {
list(str);
//delay(250);
}
if (key() == 4) {//"Down" (key() == 4 && down_flag == 0)
//down_flag = 1;
if (str<5) str+=1;
else str = 0;
list(str);
lcd.print(str);
chatter_buttons();
//if (key()!=4 && down_flag == 1) {
// down_flag = 0;
// }
}
if (key() == 3) {
if (str==0) str=5;
else str -= 1;
list(str);
lcd.print(str);
chatter_buttons();
}
if (key() == 5) {
if (str == 0)
{
flag_heat=!flag_heat;
if (flag_heat)
{
while (T < Ty)
{
digitalWrite(12, HIGH);
T += 1; // для демонстрации
delay(1000); // для демонстрации // убрать после добавления термистера!
loop(); // чтобы во время процесса можно было переключаться между экранами
// дальше if и else if, чтобы во время нагревания, если двигатель работал, он продолжал работать
if (engine_operating_mode and swiser) {
digitalWrite(PIN_DIR, HIGH);
digitalWrite(PIN_STEP, HIGH);
delay(Sl);
digitalWrite(PIN_STEP, LOW);
}
else if (engine_operating_mode==0 and swiser)
{
digitalWrite(PIN_DIR, LOW);
digitalWrite(PIN_STEP, HIGH);
delay(Sh);
digitalWrite(PIN_STEP, LOW);
}
}
digitalWrite(12, LOW);
}
}
else if (str == 1) Ty+=1;
else if (str == 2) Sl+=10;
else if (str == 3) Sh+=10;
else if (str == 4) {
if (swiser == 0) {
swiser = 1;
list(str); // чтобы обновился экран и вместо Off появился On
if (engine_operating_mode)
{
// направление вращения
digitalWrite(PIN_DIR, HIGH);
while (swiser)
{
digitalWrite(PIN_STEP, HIGH);
delay(Sl);
digitalWrite(PIN_STEP, LOW);
loop(); // чтобы во время процесса можно было переключаться между экранами
// ниже просто условие выхода из цикла
if ((key() == 5 or key() == 2) and str == 4) swiser = 0;
}
}
else
{
// направление вращения
digitalWrite(PIN_DIR, LOW);
while (swiser)
{
digitalWrite(PIN_STEP, HIGH);
delay(Sh);
digitalWrite(PIN_STEP, LOW);
loop(); // чтобы во время процесса можно было переключаться между экранами
// ниже просто условие выхода из цикла
if ((key() == 5 or key() == 2) and str == 4) swiser = 0;
}
}
}
else {
swiser = 0;
}
}
else if (str == 5) {
if (engine_operating_mode == 0) engine_operating_mode = 1; else engine_operating_mode = 0;
}
chatter_buttons();
}
if (key() == 2) {
if (str == 0)
{
flag_heat=!flag_heat;
if (flag_heat)
{
while (T < Ty)
{
digitalWrite(12, HIGH);
T += 1; // для демонстрации
delay(1000); // для демонстрации
loop(); // чтобы во время процесса можно было переключаться между экранами
// дальше if и else if, чтобы во время нагревания, если двигатель работал, он продолжал работать
if (engine_operating_mode and swiser) {
digitalWrite(PIN_DIR, HIGH);
digitalWrite(PIN_STEP, HIGH);
delay(Sl);
digitalWrite(PIN_STEP, LOW);
}
else if (engine_operating_mode==0 and swiser)
{
digitalWrite(PIN_DIR, LOW);
digitalWrite(PIN_STEP, HIGH);
delay(Sh);
digitalWrite(PIN_STEP, LOW);
}
}
digitalWrite(12, LOW);
}
}
else if (str == 1) Ty-=1;
else if (str == 2) Sl-=10;
else if (str == 3) Sh-=10;
else if (str == 4) {
if (swiser == 0) {
swiser = 1;
list(str); // чтобы обновился экран и вместо Off появился On
if (engine_operating_mode)
{
// направление вращения
digitalWrite(PIN_DIR, HIGH);
while (swiser)
{
digitalWrite(PIN_STEP, HIGH);
delay(Sl);
digitalWrite(PIN_STEP, LOW);
loop(); // чтобы во время процесса можно было переключаться между экранами
// ниже просто условие выхода из цикла
if ((key() == 5 or key() == 2) and str == 4) swiser = 0;
}
}
else
{
// направление вращения
digitalWrite(PIN_DIR, LOW);
while (swiser)
{
digitalWrite(PIN_STEP, HIGH);
delay(Sh);
digitalWrite(PIN_STEP, LOW);
loop(); // чтобы во время процесса можно было переключаться между экранами
// ниже просто условие выхода из цикла
if ((key() == 5 or key() == 2) and str == 4) swiser = 0;
}
}
}
else {
swiser = 0;
}
}
else if (str == 5) {
if (engine_operating_mode == 0) engine_operating_mode = 1; else engine_operating_mode = 0;
}
chatter_buttons();
}
if (key() == 1) { //Home
if (str==1 && flag_heat==0) {
flag_heat=1;
}
str = 0;
chatter_buttons();
}
delay(250);
}