Код на суд общественности :)

bsdshneg
Offline
Зарегистрирован: 21.10.2014

Добрый день ВСЕЕЕМ!!!!)))))

Парни, а возможно и девушки, я не программист, а всего лишь админ, поэтому прошу не закидывать меня не свежими продуктами, а посоветовать как можно "оптимизировать" или изменить код, который я наваял ... как бы при 32 килобайтах памяти можно было бы не заморачиваться, но всё же, хочется изначально делать всё правильно, а не клепать какашкокод, поэтому представлю Вам следующее

#include <Bounce.h> // библиотека подавления дребезга

#define wind_pin 7 // пин омывателя лобовухи
#define washer_pin 8  // пин омывателя фар
#define washer_led_pin 9 // пин светодиода состояния
#define state_led_pin 10 // пин светодиода состояния

Bounce bouncer = Bounce( wind_pin,5 ); 
Bounce orientation = Bounce( wind_pin, 50 );

int awake; // Are we awake based on our current orientation?

int blink_delay = 1000; // частота моргания светодиода

int wash_count = 0; // устанавливаем количество омываний стекла
int max_count = 4; // количество омываний стекла для срабатывания омывателя фар
int wash_time = 2000; // время работы омывателя фар
int count_time = 3000; // время в течение которого омыватель стекла должен отработать Х раз
int wind_wash_time = 2500; // время непрерывного омывания стекла до срабатывания омывателя фар (с поправкой на задержку считывания)
int duration = 0; // будем считать сколько по времени идёт омывание стекла
int enable_washer = 0; // идентификатор включённого омывателя фар
int push = 0; // идентификатор "нажатости кнопки"

unsigned long previousMillis = 0; // цикл считывания омывателя стекла
unsigned long previousLedMillis = 0; // моргающий светодиод
unsigned long previousWindWashMillis = 0; // длительное омывание стекла
unsigned long previousWasherMillis = 0; // омывание фар

void setup() {

  pinMode(wind_pin, INPUT); // ставим пин омывателя лобовухи на вход
  digitalWrite(wind_pin, HIGH); // подтягиваем резистор
  pinMode(washer_pin, OUTPUT); // пин омывателя фар на выход
  pinMode(state_led_pin, OUTPUT); // пин светодиода на выход
  pinMode(washer_led_pin, OUTPUT); // пин светодиода омывателя на выход
  digitalWrite(state_led_pin, LOW); // светодиод потушен
  digitalWrite(washer_led_pin, LOW); // светодиод потушен

  awake = orientation.read(); // читаем состояние "кнопки"
  
}

void loop() {

  unsigned long currentMillis = millis();

  orientation.update();

  // #########################################################################################
  
  // проверяем "кнопку" на нажатость
  if ( orientation.read() != awake && orientation.duration() > 500 ) {

    awake = orientation.read();

    if ( !awake ) {

      previousWindWashMillis  = currentMillis; // если нажата, то начинаем считать время
      push = 1;

    } 
    
    if ( awake && push == 1 ) {

      duration = currentMillis - previousWindWashMillis; // если отпущена, то смотрим, сколько была нажата по времени
      push = 0;
      
    }
    
  }

  // #########################################################################################
  
  

  if ( bouncer.update() ) { // считываем обновление статуса

    if (wash_count == 0) { // если не было срабатываний, то запускаем таймер

      previousMillis = currentMillis;
        
    }

    if(currentMillis - previousMillis <= count_time) { // если с момента первого срабатывания не прошло заданное время, то плюсуем срабатывания
      
      //если считано значение 1
      if ( bouncer.read() == LOW) {
          
        wash_count++;
          
      }

    } else { // иначе обновляем статусы

      wash_count = 0;
      previousMillis = currentMillis;
        
    }
      
  }
    
  

  // #########################################################################################

  if (wash_count >= max_count or duration >= wind_wash_time) { // если количество срабатываний или долгое нажатие, то говорим, что надо помыть фары и обнуляем счётчики

    enable_washer = 1;
    previousWasherMillis = currentMillis;

  }

  // #########################################################################################

  if(currentMillis - previousWasherMillis <= wash_time && enable_washer == 1) { // если нужно помыть фары и время "помойки" ещё не вышло - моем, включаем светодиод и сводим статусы на 0
    
    digitalWrite(washer_pin, HIGH);
    digitalWrite(washer_led_pin, HIGH);
    wash_count = 0;
    duration = 0;
      
  } else { // если время вышло - вырубаем и говорим, что усё помыто )))
      
    digitalWrite(washer_pin, LOW);
    digitalWrite(washer_led_pin, LOW);
    enable_washer = 0;
    
  }

  // #########################################################################################
    
  if(currentMillis - previousLedMillis >= blink_delay) { // моргаем светодиодом, говоря, что мы работаем )))

    previousLedMillis = currentMillis;
    digitalWrite(state_led_pin, !digitalRead(state_led_pin));
    
  }

}

Что тут происходит, да и вообще что это:

1. Это будет контроллер омывателя фар

2. Принцип работы следующий:

- При четырёхкратном срабатывании омывателя лобовухи в течение 3-ёх секунд с момента первого нажатия или при длительном срабатывании (3 сек) включается омыватель фар и работает 2 секунды ... из переменных думаю всё понятно.

 

Вот собственно и всё )))))

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Общество в шоке. Ибо не всем понятно накой в этом процессе мк? Тоесть код можно опттмизировать до нуля, мк прибить гвоздем на капот.

bsdshneg
Offline
Зарегистрирован: 21.10.2014

Пардоньте великодушно))))))

Atmega328p

А на капот - дорого ... я знаю не по наслышке!)))

Arhat109
Offline
Зарегистрирован: 26.05.2015

Поздравляю. Нормально писанный и хорошо документированный код. Тоже предпочитаю перебеть с комментами, чем недобздеть. :)

Разве что в проверках условий (но это вам виднее по логике работы), при нескольких "И" в одной проверке, первым ставить то, которое срабатывает реже (чаще ложно чем истинно) И проще в реализации. Дело в том, что в "И" если первое условие НЕ выполнилось, то остальное компилятор и НЕ проверяет, ибо "нафиг не надо".

Пример: if( callFunc() && varName>0 ) -- если переставить наоборот, то вычисления функции (вызов) не будет если значение переменной меньше или равно нулю. Вызывать функцию (метод) всегда дороже, чем проверить значение.

Для проверок собранных по ИЛИ, точно также но только вперед надо выставлять то, что быстрее ИСТИННО и проще в вычислении. Потому что если первая проверка дает истину, то опять же дальше проверять нечего.

Как-то так. :)

Arhat109
Offline
Зарегистрирован: 26.05.2015

Ну и ещё. С целью уменьшения размера, поищите в Сети библиотеки, заменяющие типовые digitalWrite() однокомандным кодом. Их есть и предостаточно. Особенно для вашего случая, когда номера пинов лежат в константах препроцессора.

bsdshneg
Offline
Зарегистрирован: 21.10.2014

Спасибо за советы! Условия сейчас переделаю, а библиотеку где-то видел такую .. попробую с ней )))

Radjah
Offline
Зарегистрирован: 06.08.2014

CyberLib называется. Гуглится на раз.

bsdshneg
Offline
Зарегистрирован: 21.10.2014

Да да, она меня и заинтересовала как-то)))