Зима, холода - вот что может сподвигнуть человека, который ни разу не видел даже, что такое программирование.
- Войдите на сайт для отправки комментариев
Прошу прощения сразу, если что-то где-то коряво. Решил сделать автоматический подсос на машинку, машинка старенькая ауди 80 с карбюратором от ВАЗа. вот настроил карбюратор, чтобы работал отменно, подумал, а почему бы не автоматизировать заслонку, когда-то год назад слышал про автозапуск на ардуино. Думаю, мне не светит, потом решил изучить программирование, хотя бы немножко, чтобы выполнять какие-нибудь цели интересные) ну думаю для этого и программируют так-то))) и что-то начало получаться, сначала подправил код, взятый тут https://sites.google.com/site/hobbyarduino/project-updates/arduhome/car-start на автозапуск, чтобы и глушить можно было, и не было произвольных запусков или остановок программы старта, если немного передержал сигнал с телефона, его приложу во втором сообщении ,пальцами еще не щупал, ардуинка никак с китая не придет, уже второй раз заказываю, на алиэкспрессе, хотя у магазина в основном все положительные отзывы, и заказов много. Ну это ладно, пустили слезу, пока все тестирую в протеусе. сСелал там эмулятор ардуино, так сказать. Благо чуть-чуть в электротехнике разбираюсь, ну, в общем, неделя моих упорных изучений и получилось!!! Сначала была идея с ПИД регулятором и сервоприводом, а потом подумал, почему бы не взять двигатель обычный для управления заслонки. таких много валяется, сварочным аппаратом пользуюсь, сделаю красивый кроншейн все будет не хуже сервы))) и вот в общем что получилось.
П.С. код полностью рабочий, но если покажите где можно упростить, буду рад!
int con1 = 7; // концевик полностью открытой заслонки
int con2 = 4; // концевик полностью закрытой заслонки
int temp = A3; // датчик температуры
int rpm = A4; // датчик оборотов(датчик хола)
int out1 = 5; //выход на любой мотор
int out2 = 6; // выход на любой мотор
int rpm2 = 0; // переменная для рассчета оборотов
void setup()
{
Serial.begin(9600);
// объявляем входом
pinMode(con1, INPUT); // подтяжку к минусу реализуем аппаратно резистором в 10кОм
pinMode(temp, INPUT);
pinMode(rpm, INPUT);
pinMode(con2, INPUT); // подтяжку к минусу реализуем аппаратно резистором в 10кОм
// объявляем выходом
pinMode(out1, OUTPUT);
digitalWrite(out1, LOW);
pinMode(out2, OUTPUT);
digitalWrite(out2, LOW);
}
void loop()
// сама программа
{
rpm2 = (analogRead(rpm)*2); // делаем рассчет температуры, что бы удобнее было потом прописывать в градусах
if ((analogRead(temp) <= 30) && (rpm2 > 100)) // если температура меньше 30 и двигатель не заглушен то управлять первым режимом управления моторчиком
{
chek_serva();// первая программа управления моторчиком
}
else if ((analogRead(temp) <= 60) && (rpm2 > 100))// если температура меньше 60 и двигатель не заглушен то управлять первым режимом управления моторчиком
{
chek_serva2();// вторая программа управления моторчиком
}
else //если ни одно не верно то запускаем программу управления по температуре
{
chek_temp(); // программа управления по температуре
}
// тут ми считываем показания с датчиков что бы настроить под машину задержки нам не мешают, даже помогают, что бы моторчик бешано не крутился постоянно
Serial.print("temp");
Serial.println(analogRead(temp));
Serial.print("rpm");
Serial.println(rpm2);
delay(1000);
}
void chek_serva()// первая программа управления моторчиком
{
if(rpm2 >= 1500) // если обороты больше 1500 то провернуть моторчик с небольшой задержкой в одну сторону( сами выберете в какую)
{
digitalWrite(out1, HIGH);
delay(50);
digitalWrite(out1, LOW);
}
else if ((rpm2 <= 1200)&&(digitalRead(con2)==0)) // если обороты больше 1200 то провернуть моторчик в обратную сторону
{
digitalWrite(out2, HIGH);
delay(50);
digitalWrite(out2, LOW);
}
}
void chek_serva2() // вторая программа управления моторчиком аналогичная только для диапазона от 1300 до 1100( потому что двигатель более менее уже устоялся.
{
if(rpm2 >= 1300)
{
digitalWrite(out1, HIGH);
delay(50);
digitalWrite(out1, LOW);
}
else if ((rpm2 <= 1100)&&(digitalRead(con2)==0))
{
digitalWrite(out2, HIGH);
delay(50);
digitalWrite(out2, LOW);
}
}
void chek_temp() // сюда попадаем если двигатель заглушен
{
if ((digitalRead(con1) ==0) && (analogRead(temp) > 60)) // если концевик еще не включен(т.е. если заслонка еще не <ОТКРЫЛАСЬ> полностью) а температура <БОЛЬШЕ> 60градусов то <ОТКРЫВАЕМ> на максимум заслонку
{
digitalWrite(out1, HIGH);
delay(100);
digitalWrite(out1, LOW);
}
else if ((digitalRead(con2) ==0) && (analogRead(temp) <60) ) // если концевик еще не включен(т.е. если заслонка еще не <ЗАКРЫЛАСЬ> полностью) а температура <МЕНЬШЕ> 60градусов то <ЗАКРЫВАЕМ> на максимум заслонку
{
digitalWrite(out2, HIGH);
delay(100);
digitalWrite(out2, LOW);
}
}
измененый автозапуск(моих коментариев нет) прошу прощения, какие были коментарии у автора те и оставил
//v 22 //Настройки unsigned long ENGINE_WARM_TIME = 1200000; //В миллисекундах время работы мотора после запуска 1200000 миллисекунд = 20 минут int ENGINE_START_MAX_TIME = 4; //В секундах масимальное время работы стартера типично 3 -10 сек // select pins for input const int hand_brake_in = 3; //d3 adruino Контакт стояночного тормоза "-" const int start_in = 4; //d4 adruino Сигнал команды на старт от мобильного телефона вибра звонка const int sharging_in = 5; //d5 adruino const int sharging_on = 0; // 0 когда во время работы генератора или от датчика давления масла на этом входе низкое состояние , 1 когда на лампе генератора при работе генератора высокое состояние const int hand_brake_on = 0; // 0= поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1= датчик ручника в поднятом состоянии выдает высокий уровень напряжения // select pins for output const int starter_out = 6; //d6 adruino реле стартера const int engine_out = 7; //d7 adruino зажигание const int secpower_out = 8; //d8 цепи вторичного питания печка, фары итд const int status_out = 9; //d9 светодиод статуса системы горит = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей //светодиод подключать с этого пина на массу // variable for actual mode int actual_mode = 0; // 2 engine started int left_start_try = 0; // переменная для хранения остатка числа попыток запуска unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок unsigned long last_stop_time = 0; void setup() { //---- настройка входов и выходов контроллера -------------- // init selected pins pinMode(hand_brake_in, INPUT); // enable input //digitalWrite(hand_brake_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо pinMode(start_in, INPUT); // enable input //digitalWrite(start_in, LOW); //pullup resustor enable pinMode(sharging_in, INPUT); // enable input //digitalWrite(sharging_in, HIGH); //generator LOW normaly // init outputs pinMode(starter_out, OUTPUT); // enable output digitalWrite(starter_out, LOW); //set digital 0 pinMode(engine_out, OUTPUT); // enable output digitalWrite(engine_out, LOW); //set digital 0 pinMode(secpower_out, OUTPUT); // enable output digitalWrite(secpower_out, LOW); //set digital 0 pinMode(status_out, OUTPUT); // enable output digitalWrite(status_out, LOW); //set digital 0 //---- конец настройки входов и выходов контроллера -------------- } void loop() { //---- собственно это и есть весь код программы -------------- if (actual_mode < 2 ) //если двигатель не запущен check_start(); //Управляем режимом запуска //код условия обязательно включать в фигурные скобки если должно быть выполнено несколько инструкций, в данном случае одна, поэтому скобки опущены else // иначе { check_for_shutdown(); //Управляем режимом ожидания окончания прогрева } //но хорошая привычка фигурные скобки ставить всегда set_status_led(); //независимо от режима Управляем светодиодом статуса //------------------конец основного кода ----------------- } //---- а дальше идут используемые функции и подфункции -------------- void check_start() { if (digitalRead(start_in) == 1 && left_start_try == 0 ) // 1 is command for start - 1 значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска { if (millis() > last_stop_time+12000) { left_start_try = 3; // указываем что нужно попытаться трижды запустить движок } } if ( left_start_try > 0) { digitalWrite(engine_out, HIGH); //включаем зажигание digitalWrite(secpower_out, HIGH); //включаем печку фары итд delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление, все датчики включились if (digitalRead(hand_brake_in) != hand_brake_on ) //без ручника не делаем запуск { do_shutdown(); actual_mode = 2; // заканчиваем попытки запустить движок left_start_try = 0; //без ручника другие попытки бесполезны return; } if (digitalRead(sharging_in) != sharging_on ) // проверяем что генератор не работает { do_start(); // пытаемся запустить движок left_start_try = left_start_try - 1 ; //уменьшаем число попыток if (left_start_try == 0 ) actual_mode = 2; // заканчиваем попытки запустить движок } // конец проверки что ручник стоит а генератор не работает } } // конец процедуры старта void do_start() { //тут будет запуск движка // digitalWrite(engine_out, HIGH); //включаем зажигание // digitalWrite(secpower_out, HIGH); //включаем печку фары итд // delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление digitalWrite(secpower_out, LOW); //выключаем печку фары итд //----------------------------------------------------------------------------------- цикл стартера digitalWrite(starter_out, HIGH); //включаем стартер for (int secs=0; secs <= ENGINE_START_MAX_TIME ; secs++) // { delay(1000); // и продолжаем его держать включенным 1 секунду if (digitalRead(sharging_in) == sharging_on) //если зарядка пошла то break; // прерываем цикл } //----------------------------------------------------------------------------------- digitalWrite(starter_out, LOW); //отключаем стартер if (digitalRead(sharging_in) == sharging_on) //еще раз смотрим что зарядка пошла { actual_mode = 2; //Запоминаем что движок запущен last_start_time = millis(); // запоминаем время запуска движка } else { digitalWrite(engine_out, LOW); //выключаем зажигание чтбы разблокировать реле стартера digitalWrite(secpower_out, LOW); //выключаем печку фары итд delay(5000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление } } void check_for_shutdown() { //сюда мы попадаем когда контроллер считает что движок работает if (digitalRead(sharging_in) != sharging_on ) //проверяем что движок случайно не заглох do_shutdown(); else digitalWrite(secpower_out, HIGH); //включаем печку фары итд if ((digitalRead(hand_brake_in) != hand_brake_on) || (digitalRead(start_in) == 1) && (millis() > last_start_time+12000)) //проверяем что если злодеи сняли с ручника то глушим мотор { do_shutdown(); left_start_try =0; // и больше не заводим last_start_time = 0; last_stop_time = millis(); } //тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время if (actual_mode != 0 ) //значит не выключили заглохший двигатель только что { // милисекунды в ардуино обнуляются каждые 49 суток // для того чтобы в случае если запуск произошел в течении последних 20 минут до обнуления мотор не молотил еще 49 суток // нужно обнулить и время старта, при этом мотор максимум будет прогреваться вдвое больше обычного if (millis() < last_start_time) { last_start_time = 0; } if (millis() > last_start_time+ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева { do_shutdown(); left_start_try =0; // и больше не заводим } } } void do_shutdown() { digitalWrite(secpower_out, LOW); //выключаем печку фары итд digitalWrite(engine_out, LOW); //вырубаем зажигание actual_mode = 0; // движок выключили запомним это last_start_time = 0; // ну и забудем о том что он был включен delay(1000); } void set_status_led() { if (digitalRead(hand_brake_in) != hand_brake_on ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту { digitalWrite(status_out, LOW); return; //прерываем выполнение функции } if (actual_mode == 2) //Движок запущен status_led_flash(); // показываем с какой попытки был прошлый запуск else digitalWrite(status_out, HIGH); // постоянное свечение - показываем что готов к следующему запуску } void status_led_flash() { static unsigned long big_interval = 0; static unsigned long flash_interval = 0; unsigned long flash_count = 0; flash_count = 3 - left_start_try; //сколько раз мигать //1 секндный интервал if (millis() > flash_interval + 1000L) flash_interval = millis() ; //задаем счетчие от 0 до 1 секунды //задаем 6 секунд if (millis() > big_interval + 6000L) { big_interval = millis() ; //задаем счетчие от 0 до 10секунд flash_interval = big_interval; } if (millis() < big_interval + flash_count * 1000L) // делим 6 секндный интервал на два периода, в первый мигаем количество раз соответствующее числу израсходованных попыток { //мигает if (millis() > flash_interval + 500L) digitalWrite(status_out, HIGH); else digitalWrite(status_out, LOW); } else { // негорит digitalWrite(status_out, LOW); //set digital 0 } }???