Есть скетч хочу добавить сон/просыпание по нажатию кнопок

mihail_v
Offline
Зарегистрирован: 03.01.2017

Есть скетч, для блока контроллера лаборатрного БП.

Есть силовой трансформатор с группой выходных обмоток 1-2-4-8-16-32-64 вольта, с семью реле переключающими эти обмотки. Еще имеется три реле 1 - включение силового трансформатора по сети 220 вольт, включение выодного напряжения AC|DC не стабилизированного и реле подключения программируемого модуля DC, фактически подключаемого к обмотке 32 вольта.

Органы управления 3 кнопки включения общее, и 2 соответвующих выходов, регулировка выходного напряжения валкодером, и на программируемом модуле (он законченная конструкция).

#include <Encoder.h>

// Плата nano ATmega328

// входа
const int power_main_in = 7; // (D4) кнопка включения силового питания
const int power_AC_in = 8; // (D5) кновка включение выхода AC|DC не стабилизированного
const int power_DC_in = 9; // (D6) кнопка влючения программируемого бодуля DC
const int enc_a = 5; // (D2) энкодер
const int enc_b = 6; // (D3) энкодер

// выхода
const int power_main_out = 12; // (D9) реле вкл силового т-ра
const int power_AC_out = 26; // (A7) реле вкл выходов AC|DC
const int power_DC_out = 11; // (D8) реле вкл. питания DC модуля
const int volt_1 = 19; // A0  реле коммутации вторичных обмоток силового тр-ра
const int volt_2 = 20; // A1
const int volt_4 = 21; // A2
const int volt_8 = 22; // A3
const int volt_16 = 23; // A4
const int volt_32 = 24; // A5
const int volt_64 = 25; // A6

Encoder myEnc(enc_a, enc_b);

const byte delitel = 4; // делитель для валкодера чтобы один целчек соотвтевовал изменению на 1 единицу 

boolean power_main = false; // храним состояние реле 
boolean power_AC = false;
boolean power_DC = false;

boolean a = true;
boolean b = true;
boolean c = true;
boolean a_last = true;
boolean b_last = true;
boolean c_last = true;
boolean a_state = true;
boolean b_state = true;
boolean c_state = true;

long oldPosition  = -999;

long voltage = 0; // счетчик напряжения 
byte volt = 0; // четчик напряжения приведенный к диапазону
unsigned long de_time = 50; // Время антидребезга
unsigned long counter_a = 0;
unsigned long counter_b = 0;
unsigned long counter_c = 0;

void setup() {
  // put your setup code here, to run once:

pinMode (power_main_in, INPUT_PULLUP);
pinMode (power_AC_in, INPUT_PULLUP);
pinMode (power_DC_in, INPUT_PULLUP);
pinMode (enc_a, INPUT_PULLUP);
pinMode (enc_b, INPUT_PULLUP);

pinMode (power_main_out, OUTPUT);
pinMode (power_AC_out, OUTPUT);
pinMode (power_DC_out, OUTPUT);
pinMode (volt_1, OUTPUT);
pinMode (volt_2, OUTPUT);
pinMode (volt_4, OUTPUT);
pinMode (volt_8, OUTPUT);
pinMode (volt_16, OUTPUT);
pinMode (volt_32, OUTPUT);
pinMode (volt_64, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

// Обработка кнопки вкл силового питания
a = digitalRead (power_main_in);


// антидребезг
if (a != a_last) 
  {
    counter_a = millis();
  }
if ((millis()- counter_a) > de_time) 
 {
  if (a != a_state) 
   {a_state = a;
     
     // обработка нажатия кнопки
     
     if (a_state = false) { power_main = !power_main; }
      if (power_main = false)  // если питание силового тр-ра отключили
       {
         power_DC = false;
         power_AC = false;
         voltage = 0;
         volt = 0;
         voltwrite; // запись побитно заначения напряжения на соответвующие выводы
         digitalWrite (power_AC_out, power_AC);
         digitalWrite (power_DC_out, power_DC);
       }
       digitalWrite (power_main_out, power_main); // 
   }
 }

a_last = a;
 
if (power_main = true)  // если силовое питание 220 включено, то проверяем другие органы управления
 {

    // Энкодер
    long newPosition = myEnc.read();
    if (newPosition != oldPosition) 
      {
        oldPosition = newPosition;
        voltage = voltage + newPosition/delitel;
    
        if (voltage < 0)
         {
          voltage =0;
         }
        if (voltage > 127)
         {
        voltage = 127;
          }

      volt = byte (voltage); //
      voltwrite; // запись побитно заначения напряжения на соответвующие выводы
    
      } 


     // обработка кнопки включения не регилируемого AC|DC
     b = digitalRead (power_AC_in);

      if (b != b_state) 
        {
          counter_b = millis();
        }
      if ((millis()- counter_b) > de_time) 
        {
          if (b != b_state) 
            {
              b_state = b;
              if (b_state = false) { power_AC = !power_AC; }
              digitalWrite (power_AC_out, power_AC);
            }
        }

      b_last = b;

      // обработка кнопки включения программиремого DC
      c = digitalRead (power_DC_in);

      if (c != c_state) 
        {
          counter_c = millis();
        }
      if ((millis()- counter_c) > de_time) 
        {
          if (c != c_state) 
            {
              c_state = c;
              if (c_state = false) { power_DC = !power_DC; }
              digitalWrite (power_DC_out, power_DC);
             }
        }

      c_last = c;
 
 }


 } // конец основного цикла

void voltwrite() // запись побитно заначения напряжения на соответвующие выводы
 {
    digitalWrite (volt_1, bitRead (volt,0));
    digitalWrite (volt_2, bitRead (volt,1));
    digitalWrite (volt_4, bitRead (volt,2));
    digitalWrite (volt_8, bitRead (volt,3));
    digitalWrite (volt_16, bitRead (volt,4));
    digitalWrite (volt_32, bitRead (volt,5));
    digitalWrite (volt_64, bitRead (volt,6));
 }

1 . есть ошибки, пока проверить не могу плата приедет через несколько недель

2. хочу ввести режим сна, т.е. сконфигирировались заснули, задели органы управления, любой из пяти пинов поснулись, пошли пахать по программе, скажем пару секунд(?) затем обратно засыпаем.

Посмотрел нужно использовать прерывания, 1-я проблема в андруно внешние прерывания можно задействовать только на 2-пинах, nano mega328 аппаратно позволяет задействовать на любом пине порта, смотрел сторонние библиотеки на пока не понял что нужно. 

Меня интересует порт D (PD2-PD6), в прерывании обработка нажатия не нужна, только проснуться и передать управление на loop. Подскажите :)

 

 

 

 

 

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
mihail_v
Offline
Зарегистрирован: 03.01.2017

Дв я видел эту библиотеку, слишком сложно. Мне не нужна обработка конкетного пина, надо только проснуться от определенных выводов.

mihail_v
Offline
Зарегистрирован: 03.01.2017

Вот поковырялся, что еще забыл?

 

#include <avr/sleep.h>

ISR(PCINT2_vect)
{
    // null
}


void setup() {
  // put your setup code here, to run once:

PCICR |= (1<<2); // разрешаем INT16-23
PCMSK2 |= (1<<PCINT18) | (1<<PCINT19) | (1<<PCINT20) | (1<<PCINT21) | (1<<PCINT22); // маска INT18-22

}

unsigned long couter_w = 0;
const unsigned long timewalkup = 2000;

void loop() {
cli();

// тут код обработки


if ((millis() - couter_w) > timewalkup)  
 {
   couter_w = millis();
   set_sleep_mode (SLEEP_MODE_PWR_DOWN);
   sleep_enable();
   sei ();
   sleep_cpu();
   sleep_disable();
  }
}