Замена #define и #if...#endif на опрос входов МК

User MTU
Offline
Зарегистрирован: 24.03.2012

Добрый день.

 

Есть скетч, котрый компилируется под разное железо, путем выбора нужного режима. При этом выводы МК конфигурируются по-разному:

#define VALUE_1    1                         
#define VALUE_2    2      
#define VALUE_3    3  
#define VALUE_TYPE VALUE_1 //в зависимости от конфигурации железа, выбираем нужное значение VALUE_1...VALUE_3
                    
const uint8_t PresetNum = 3;

// в зависимости от выбранного VALUE_1...VALUE_3 объявляем нужный вывод МК
#if VALUE_TYPE == VALUE_1
  const uint8_t pinControl = 3;    
#elif VALUE_TYPE == VALUE_2
  const uint8_t pinControl = A3;    
#elif VALUE_TYPE == VALUE_3
  const uint8_t pinControl = A0;                                                             
#endif



void setup() {  
  
#if VALUE_TYPE == VALUE_3
  for (int pin = 0; pin < PresetNum; pin++) pinMode(pinControl+pin, INPUT); //потому что нужны подряд А0...А2, и к + питания не подтягивать
#else
  pinMode(pinControl, INPUT);
#endif

#if VALUE_TYPE == VALUE_1
  attachInterrupt(digitalPinToInterrupt(pinControl), func, CHANGE);
#endif
}



void loop() {

 #if VALUE_TYPE == VALUE_1
   digitalRead(pinControl);
 #elif VALUE_TYPE == VALUE_2
   analogRead(pinControl);
 #elif VALUE_TYPEE == VALUE_3
   for (int pin = 0; pin < PresetNum; pin++) digitalRead(pinControl+pin)); 
 #endif
}



#if VALUE_TYPE == VALUE_1
  void func() {
    digitalRead(pinControl);
    // и дальше куча вычислений полученного с входа
  }
#endif

Из этого кода убрано "лишнее", но структура сохранена именно так.

С подходом к конфигурированию в скетче есть неудобство - надо иметь 3 версии прошивки+лазить что-то перепрошивать.

Есть идея заменить конфигурирование через #define на аналог dip-переключателей, благо свободные выводы МК есть. При этом, в зависимости от состояния переключателей, нужный режим будет подобран автоматически, при включении МК.

Попытка модификации скетча:

#define VALUE_1    1                         
#define VALUE_2    2      
#define VALUE_3    3  
#define VALUE_TYPE VALUE_1 //в зависимости от конфигурации железа, выбираем нужное значение VALUE_1...VALUE_3
                    
const uint8_t PresetNum = 3;

// в зависимости от выбранного VALUE_1...VALUE_3 объявляем нужный вывод МК
#if VALUE_TYPE == VALUE_1
//  const uint8_t pinControl = 3;    
#elif VALUE_TYPE == VALUE_2
  const uint8_t pinControl = A3;    
#elif VALUE_TYPE == VALUE_3
  const uint8_t pinControl = A0;                                                             
#endif



void setup() {  
  pinMode (10, INPUT_PULLUP); //попробуем заменить VALUE_1
  pinMode (11, INPUT_PULLUP);
  pinMode (12, INPUT_PULLUP);

  if (digitalRead (10)) {
    const uint8_t pinControl = 3; //и уберем эту строку из #if ...    
  }
  
#if VALUE_TYPE == VALUE_3
  for (int pin = 0; pin < PresetNum; pin++) pinMode(pinControl+pin, INPUT); //потому что нужны подряд А0...А2, и к + питания не подтягивать
#else
  pinMode(pinControl, INPUT);
#endif

//#if VALUE_TYPE == VALUE_1
  If (digitalRead (10)) {
  attachInterrupt(digitalPinToInterrupt(pinControl), func, CHANGE);
//#endif
}
}



void loop() {

 #if VALUE_TYPE == VALUE_1
   digitalRead(pinControl);
 #elif VALUE_TYPE == VALUE_2
   analogRead(pinControl);
 #elif VALUE_TYPEE == VALUE_3
   for (int pin = 0; pin < PresetNum; pin++) digitalRead(pinControl+pin)); 
 #endif
}



//#if VALUE_TYPE == VALUE_1
  If (digitalRead (10) {
  void func() {
    digitalRead(pinControl);
    // и дальше куча вычислений полученного с входа
  }
//#endif
  }

В итоге модификаций, появляется ошибка на строке 46 - не объявлена переменная pinControl

Скорее всего будет и ошибка по функции func.

Вопрос к общественности - решение такой проблемы реально, или без серьезного перелопачивания всего и вся затея бесперспективная?

Где можно посмотреть на аналогичные примеры?

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

вместо 12 строки (и 14)

и value определено или нет? 10 строку раскомментировтаь

#define pinControl A3

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Вполне реализуемо.
Понадобится всего 2 пина.
Value определить как переменную.
В setup делать проверку.
Типа такой:
Value=1+digitalRead(pin1)+digitalRead(pin2);
В итоге на выходе переменная будет принимать значения от 1 до 3.
Ну и дальше уже в зависимости от этого значения реализовывать в коде

Kakmyc
Offline
Зарегистрирован: 15.01.2018

В исходном коде нужно учитывать, что "пины сподряд А0...А2" ,это пины 14,15,16

User MTU
Offline
Зарегистрирован: 24.03.2012

Спасибо за наводки в нужные стороны! Получилось.

 

В итоге код с отказом от #define и # if... работающий как надо, и без ошибок в общем алгоритме железяки вышел такой:

const uint8_t PresetNum = 3;

uint8_t pinControl;


void setup() {  
  pinMode (10, INPUT_PULLUP); 
  pinMode (11, INPUT_PULLUP);

// аналог VALUE_1
  if (digitalRead (10) && digitalRead (11)) {
    pinControl = 3;   
  }

//аналог VALUE_2
  if (!digitalRead (10) && digitalRead (11)) {
    pinControl = A3;
  }  

//аналог VALUE_3
  if (!digitalRead (10) && !digitalRead (11)) {
    pinControl = A0;   
  }


  if (!digitalRead (10) && !digitalRead (11)) {
    for (int pin = 0; pin < PresetNum; pin++) pinMode(pinControl+pin, INPUT); //потому что нужны подряд А0...А2, и к + питания не подтягивать
  }
    else
    {
      pinMode(pinControl, INPUT);
    }


  if (digitalRead (10) && digitalRead (11)) {
    attachInterrupt(digitalPinToInterrupt(pinControl), func, CHANGE);
  }
}



void loop() {

 if (digitalRead (10) && digitalRead (11)) {
   digitalRead(pinControl);
 }
  else if (!digitalRead (10) && digitalRead (11)) {
   analogRead(pinControl);
  }
  else if (!digitalRead (10) && !digitalRead (11)) {
   for (int pin = 0; pin < PresetNum; pin++) digitalRead(pinControl+pin); 
  }
}



  void func() {
    digitalRead(pinControl);
    // и дальше куча вычислений полученного с входа
  }

Может кому пригодится из новичков. По идее в, 16 строке подкорректировав условие, можно получить еще одну комбинацию (всего возможно 4-е по 2-м джамперам (dip-переключателям)). Но по факту уложился в требуемые 3. Теперь поставил нужный режим, нажал сброс и железяка работает в другом алгоритме без плясок с перепрошивкой.

sadman41
Offline
Зарегистрирован: 19.10.2016
uint8_t option = (digitalRead(11) << 1) | digitalRead(10);

switch (option){
   case B00000000:
   ...
   break;

   case B00000001:
   ...
   break;

   case B00000010:
   ...
   break;

   case B00000011:
   ...
   break;
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

sadman41 пишет:

uint8_t option = (digitalRead(11) << 1) | digitalRead(10);

switch (option){
   case B00000000:
   ...
   break;

   case B00000001:
   ...
   break;

   case B00000010:
   ...
   break;

   case B00000011:
   ...
   break;
}

 

Разделом ошибся,
Видно же, что ему нужно от максимально функционального кода нужно перейти к максимально внятному

mixail844
Offline
Зарегистрирован: 30.04.2012
Kakmyc пишет:
Вполне реализуемо. Понадобится всего 2 пина. Value определить как переменную. В setup делать проверку. Типа такой: Value=1+digitalRead(pin1)+digitalRead(pin2); В итоге на выходе переменная будет принимать значения от 1 до 3. Ну и дальше уже в зависимости от этого значения реализовывать в коде
 
а вот тут ,кмк, есть место для бага : 
 как вы отличите когда Value = 2  , стало в следствиие 1 + digitalRead(pin1) или стало в следствиие 1 + digitalRead(pin2)  ? 
 
кмк ,правильней Value = 2 * digitalRead(pin2) + digitalRead(pin1);
Izvekoff
Offline
Зарегистрирован: 02.03.2020

mixail844 пишет:

Kakmyc пишет:
Вполне реализуемо. Понадобится всего 2 пина. Value определить как переменную. В setup делать проверку. Типа такой: Value=1+digitalRead(pin1)+digitalRead(pin2); В итоге на выходе переменная будет принимать значения от 1 до 3. Ну и дальше уже в зависимости от этого значения реализовывать в коде
 
а вот тут ,кмк, есть место для бага : 
 как вы отличите когда Value = 2  , стало в следствиие 1 + digitalRead(pin1) или стало в следствиие 1 + digitalRead(pin2)  ? 
 
кмк ,правильней Value = 2 * digitalRead(pin2) + digitalRead(pin1);

а если и далее расширяться то Value = 4*digitalRead(pin3)+2 * digitalRead(pin2) + digitalRead(pin1);  ;-)))

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Никак, и нет тут бага.
Все тупо до безумия.
Нет перемычек, вариант 1, одна перемычка(пофигу где) вариант 2, две перемычки, вариант 3.

Гриша
Offline
Зарегистрирован: 27.04.2014

Kakmyc пишет:
Никак, и нет тут бага. Все тупо до безумия. Нет перемычек, вариант 1, одна перемычка(пофигу где) вариант 2, две перемычки, вариант 3.

собрано по ИЛИ; исключающее ИЛИ; И... а вам предложили дешифратор.