Планировщик включений и выключения пк иммитируя нажатие кнокпи питания с помощью реле.
- Войдите на сайт для отправки комментариев
Чт, 23/06/2016 - 23:16
Данный код был написанн за один вечер... Пожалуйста прошу оценить (выслушаю любую критику) и показать на мои ошибки или же как лучше можно было бы сделать. Это первое, что написал для ардуины сам (до этого только лампочкой поморгал для проверки). До этого кодил на делфи и то толко две программы т.к. была острая нужда в них... Код использует RTC часы и реле...
/* * Планировщик включений и выключения пк иммитируя нажатие кнокпи питания с помощью реле. * Цель: Включение и выключение компьютера в определенный момент времени. * Макет работы: программа читает из EEPROM-а 4 байта (кодируют задания): 1-ый байт (FF - не запланированно, 00 - включает каждый день в определенное время, 01 -выключает каждый день в определенное время, 02 - включает в определенный день недели в определенное время, * 03 - выключает в определенный день недели в определенное время, 04 - включает в определенный день(1-31) в определенное время, 05 - выключает в определенный день(1-31) в определенное время), 2-ой байт и 3-ий байт отвечает за время - часы и минуты соответственно, * 4-ый байт отвечает за день (если от 1 до 31 то показвает число, если от 32 до 38 то день недели (32- пн, 33-вт ... 37 -сб, 38 -вс)). * Далее програма переходит на следущие задание читая следущие 4 байта и так далее, пока не появится не запланированное задание (1 байт = FF). * @ Код был написан Aleksnfsl5 в 23.06.2016 используя различные примеры работ с библиотеками. */ #include <EEPROM.h> #include <TimeLib.h> #include <Wire.h> #include <DS1307RTC.h> int sensorValue = 0; int incomingByte = 0; int address; byte value; String Bytes; const int Relay = 12; // подключенно реле const int analogInPin = A0; // мониторинг состояния пк (включен или выключен) по напряжению usb порта. void setup() { Serial.begin(115200); while (!Serial) ; pinMode(Relay, OUTPUT); pinMode(13, OUTPUT); setSyncProvider(RTC.get); // получаем время из RTC if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); } void loop() { digitalWrite(Relay, HIGH); //Поднимаем питание - размыкаем реле //запись EEPROM с помощью данных полученных через Serial do { // начинаем цикл чтения serial incomingByte = Serial.read(); // читаем байт Bytes = String (incomingByte, HEX); // преобразуем if (Bytes != "ffff"){ // проверяем стоп-байт это ли? EEPROM.write(address, incomingByte); // если нет то продолжаем работу! address = address + 1; }; } while (Bytes != "ffff"); // Выполняем цикл пока не появится стоп-байт. EEPROM.write(address-1, 0xFF); // Удаляем лишний байт, который появляется всегда перед стоп-байтом. address = 0; // Конец записи EEPROM sensorValue = analogRead(analogInPin); // определяем включен ли компьютер (проверяем напряжение на usb-порте) value = EEPROM.read(address); String typeon; typeon = String (value, DEC); // определяем тип задания if (typeon == "255"){ //если нет задания переходим в начало! address = 0; }else{ //если же задание есть определяем его тип! if (sensorValue == 1023){ //задания по выключению пк digitalWrite(13, LOW); // индикация if(typeon == "1"){ timetrue(); }; // каждый день в определенное время if(typeon == "3"){ weekdaydec(); }; // в определенный день недели в определенное время if(typeon == "5"){ daydec(); }; // в определенный день в определенное время }else{ //задания по включению пк digitalWrite(13, HIGH); // индикация if(typeon == "0"){ timetrue(); }; // каждый день в определенное время if(typeon == "2"){ weekdaydec(); }; // в определенный день недели в определенное время if(typeon == "6"){ daydec(); }; // в определенный день в определенное время }; address = address + 4; // переход на следущее задание. }; }; void timetrue(){ String timeon = ""; // время выполнения задания String realtime = ""; // реальное время value = EEPROM.read(address + 1); timeon = String (value , DEC); realtime = String (hour() , DEC); if (timeon == realtime){ // сравниваем сначала часы value = EEPROM.read(address + 2); timeon = String (value , DEC); realtime = String (minute() , DEC); if (timeon == realtime){ // затем минуты digitalWrite(Relay, LOW); //Поднимаем питание - замыкаем реле delay(1200); }; }; }; void weekdaydec(){ String Realweekdays; // Реальный день недели String Weekdays; // День недели выполнения задания Realweekdays = String (weekday()+ 31, DEC); value = EEPROM.read(address + 3); Weekdays = String (value, DEC); if( Realweekdays == Weekdays) { timetrue(); }; }; void daydec(){ String Realdays; // Реальный день String days; // День выполнения задания Realdays = String (day(), DEC); value = EEPROM.read(address + 3); days = String (value, DEC); if( Realdays == days) { timetrue(); }; };
Зачем использовать реле? Достаточной одной оптопары. И потом компьютер как бэ это сказать – выключается простым скриптом, или вашей программой. А вообще «грешно» выключать компьютер. В настройках БИОС можно задать время автоматического включения.
1. у меня лично глючит эта опция
2. не возможно выставить более одной даты (в программе же большое кол-во заданий на включение и выключение)
3. оптопары не оказалось под рукой, ибо живу в городке в котором и о понятии магазине радиодеталей и не слышали...
4. комп лень вечно держать включенным.
5. Так как я владелец usb модема и тарифа с опцией ночной безлимит ( с 1 ночи и до 8 утра по местному времени траффик не учитывается) то качать ночью что либо для меня сущий ад, а так все включается автоматически и выключается в заданное время без участия человека
6. по поводу выключения компа с помощью скрипта - пользовался им! Но как альтернативу добавил в код... Тем более невозможно написать мультиплатформенный скрипт.
Некоторые из пунктов и сподвигли меня на написание этой программы
Можно узнать, для чего Вы каждый раз, перед сравнением, преобразуете целые числа в строки?
Прежде чем читать Serial хорошо бы проверить, что в него что-то поступило, т. е.:
Обоснованность применения цикла do while кажется сомнительной.
Если не ошибаюсь, конструкция:
нужна только для плат типа Leonardo.
Прошу учесть тот факт, что впервые пишу под arduino и не знаю некоторых особенностей, поэтому решил узнать какие есть недостатки в моем коде и что бы сдалели люди с опытом на моем месте!!!
Использование цикла дает мне возможность в начале записать все байты, а только потом идти на проверку заданий! Конструкцию типа Serial.available() > 0 не стал использовать по причине того, что я сам ищу стоп-байт и если он попался, то перестаю выполнять цикл, т.е. я заменил Serial.available() > 0 своей конструкцией. Да и в цикле do .. while конструкция Serial.available() > 0 срабатывала не так как мне нужно!
А по поводу while (!Serial); я посмотрел что используется во всех примерах, но строка не была прокомментированна ни в одном из них :(... Вот за это спасибо я учту на будущее!