Использование прерываний и микросхемы-дешифратора

Lictor
Offline
Зарегистрирован: 01.10.2015

Начитался статей наподобие http://avrproject.ru/publ/kak_podkljuchit/kogda_ne_khvataet_nog_chast_1_deshifrator_4_16/2-1-0-12

собрал эту схему, написал код

byte massa = B0;

const int buttonPin1 = 10;     // номер выхода управление дешифратором
const int buttonPin2 = 11;     // номер выхода управление дешифратором
const int buttonPin3 = 12;     // номер выхода управление дешифратором
const int buttonPin4 = 13;     // номер выхода управление дешифратором

int knopf ;   //переменная состояния кнопки

const int buttonPin = 2;     // номер входа прерывания

unsigned long previousMillis ; // для таймеров

void setup() {

  attachInterrupt(0, blink, FALLING ); // прерывание по 2 пину при переходе с высокого на низкий уровень

  Serial.begin(9600); //монитор порта

  pinMode(buttonPin1, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin2, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin3, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin4, OUTPUT);   //инициализация вывода управления дешифратором

  pinMode(buttonPin, INPUT);    //вход на атмеге с дешифратора (клавиатура)
}
void loop() {

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > 10) {
   Serial.println(knopf); // тестовая строка
    previousMillis = currentMillis;
    if ( massa <= B1111 ) {
      digitalWrite( 10, bitRead( massa , 0 ));
      digitalWrite( 11, bitRead( massa , 1 ));
      digitalWrite( 12, bitRead( massa , 2 ));
      digitalWrite( 13, bitRead( massa , 3 ));
   /*    Serial.print(digitalRead(buttonPin1));  //тестовая строка состояний пинов на входе в дешифратор.
         Serial.print(digitalRead(buttonPin2));
         Serial.print(digitalRead(buttonPin3));
         Serial.println(digitalRead(buttonPin4)); */
      massa = massa + 1;
      if ( massa > B1111 ) {
        massa = B0;
      }
    }
  }
}

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
  if ( massa == B1111 ) {
    knopf = 0 ;
  }
  if ( massa == B0111 ) {
    knopf = 15 ;
  }
  if ( massa == B1011 ) {
    knopf = 14 ;
  }
  if ( massa == B0011 ) {
    knopf = 13 ;
  }
  if ( massa == B1101 ) {
    knopf = 12 ;
  }
  if ( massa == B0101 ) {
    knopf = 11 ;
  }
  if ( massa == B1001 ) {
    knopf = 10 ;
  }
  if ( massa == B0001 ) {
    knopf = 9 ;
  }
  if ( massa == B1110 ) {
    knopf = 8 ;
  }
  if ( massa == B0110 ) {
    knopf = 7 ;
  }
  if ( massa == B1010 ) {
    knopf = 6 ;
  }
  if ( massa == B0010 ) {
    knopf = 5 ;
  }
  if ( massa == B1100 ) {
    knopf = 4 ;
  }
  if ( massa == B0100 ) {
    knopf = 3 ;
  }
  if ( massa == B1000 ) {
    knopf = 2 ;
  }
  if ( massa == B0000 ) {
    knopf = 1 ;
  }
}

 

Вроде все должно работать, но у меня такое ощущение, что прерывание работает не так, как я думал: при нажатии на кнопку оно присваевает значение переменной knopf, но при повтороном нажатии на кнопку оно его меняет на некоторое другое. И так с каждой кнопкой. Не могу понять, почему так происходит(

Lictor
Offline
Зарегистрирован: 01.10.2015

Строку 8 изменил на 

volatile int knopf ;

не полегчало

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

Теперь сделай для 1 строки так же.

42 строка: massa++

В 34-37 вместо bitread лучше использовать сдвиг.

И не вижу гашение дребезга.

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

Ну, во-первых, давайте сначала упростим код. Например, Ваша длинющая функция blink() полностью эквивалента вот такой маленькой:

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
	static const PROGMEM int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
	knopf = res[massa];
}

Во-вторых, если есть сомнения в том, что присваивается переменной - её нужно печатать и смотреть. Вывод в сериал внутри оработчика прерывания само по себе плохо и в окончательной программе этого быть не должно, но для отладки поставьте и посмотрите.

КОгда сделаете, если останутся непонятки, выложите свежий код и лог того, что печаталось с пояснениями, что нажимали.

И ещё: в данном компиляторе с опциями по умолчанию всё работет как надо, но я всё же не советовал бы Вам так использовать двоичные константы. Начинайте их с нуля. Т.е. вместо B1111, пишите B01111. Разницы никакой, но зато есть гарантия что шибко умный компилятор не развернёт Вашу константу в отрицательное число.

Lictor
Offline
Зарегистрирован: 01.10.2015

Radjah пишет:

Теперь сделай для 1 строки так же.

42 строка: massa++

В 34-37 вместо bitread лучше использовать сдвиг.

И не вижу гашение дребезга.

 

добавил volatile и для первой строки. Изменил massa на massa++. Касаемо  bitread  я проверял, она рабтает отлично: я делал вывод в монитор порта состояний выводов, замечаний не было. Поэтому пока трогать не буду. 

По поводу защиты от дребезга, а есть ли смысл? при смене уровня сигнала даже если и будет дребезг, просто прерывание вызовется несколько раз, но переменная knopf все равно должна приравниваться к одному и тому же числу. (я его сделаю, но потом, мне кажется, что проблема все таки не в дребезге).

 

Не полегчало. Все равно knopf принимает рандомные значения.  при задержке нажатия кнопки и (иногда) при повторном значении

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Ну, во-первых, давайте сначала упростим код. Например, Ваша длинющая функция blink() полностью эквивалента вот такой маленькой:

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
	static const PROGMEM int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
	knopf = res[massa];
}

Во-вторых, если есть сомнения в том, что присваивается переменной - её нужно печатать и смотреть. Вывод в сериал внутри оработчика прерывания само по себе плохо и в окончательной программе этого быть не должно, но для отладки поставьте и посмотрите.

КОгда сделаете, если останутся непонятки, выложите свежий код и лог того, что печаталось с пояснениями, что нажимали.

И ещё: в данном компиляторе с опциями по умолчанию всё работет как надо, но я всё же не советовал бы Вам так использовать двоичные константы. Начинайте их с нуля. Т.е. вместо B1111, пишите B01111. Разницы никакой, но зато есть гарантия что шибко умный компилятор не развернёт Вашу константу в отрицательное число.

 

исправил функцию blink на Ваш вариант. Касаемо лога, сделал так:

volatile byte massa = B0;

const int buttonPin1 = 10;     // номер выхода управление дешифратором
const int buttonPin2 = 11;     // номер выхода управление дешифратором
const int buttonPin3 = 12;     // номер выхода управление дешифратором
const int buttonPin4 = 13;     // номер выхода управление дешифратором

volatile int  knopf ;   //переменная состояния кнопки

const int buttonPin = 2;     // номер входа прерывания

unsigned long previousMillis ; // для таймеров

void setup() {

  attachInterrupt(0, blink, FALLING ); // прерывание по 2 пину при переходе с выского на низкий уровень

  Serial.begin(9600); //монитор порта

  pinMode(buttonPin1, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin2, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin3, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin4, OUTPUT);   //инициализация вывода управления дешифратором

  pinMode(buttonPin, INPUT);    //вход на атмеге с дешифратора (клавиатура)
}
void loop() {

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > 10) {
 //  Serial.println(knopf); // тестовая строка
    previousMillis = currentMillis;
    if ( massa <= B01111 ) {
      digitalWrite( 10, bitRead( massa , 0 ));
      digitalWrite( 11, bitRead( massa , 1 ));
      digitalWrite( 12, bitRead( massa , 2 ));
      digitalWrite( 13, bitRead( massa , 3 ));
   /*    Serial.print(digitalRead(buttonPin1));  //тестовая строка состояний пинов на входе в дешифратор.
         Serial.print(digitalRead(buttonPin2));
         Serial.print(digitalRead(buttonPin3));
         Serial.println(digitalRead(buttonPin4)); */
      massa++ ;
      if ( massa > B01111 ) {
        massa = B0;
      }
    }
  }
}

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
knopf = res[massa];
Serial.println(knopf); // тестовая строка
}

вгрузил и запустил монитор порта. Там было следующее

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
512
0
0
0
512
0
0
0
512
0
0
512
0
0
0
512
0
0
512

Что мы тут видим, нули вначале появляются при нажатии кнопки и если ее зажать. При нажатии второй кнопки появляется число 512, если же ее зажать то выводятся еще три нуля. Затем 512 и все вновь. 

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

Вторая кнопка? o_0

У тебя же в лупе идет щелканье выходами из изменение massa, а в прерывании вывод в порт числа из массива по индексу massa.

Замени еще в 25 строке INPUT на INPUT_PULLUP, чтобы вход Маяк не ловил. :)

 

Lictor
Offline
Зарегистрирован: 01.10.2015

Radjah пишет:

Вторая кнопка? o_0

У тебя же в лупе идет щелканье выходами из изменение massa, а в прерывании вывод в порт числа из массива по индексу massa.

Замени еще в 25 строке INPUT на INPUT_PULLUP, чтобы вход Маяк не ловил. :)

 

 

Эээ, ну да, вторая и третья, и четвертая... Я же говорил, что собрал схему из http://avrproject.ru/publ/kak_podkljuchit/kogda_ne_khvataet_nog_chast_1_deshifrator_4_16/2-1-0-12

она там на последней картинке. Касаемо пуллапа, то вход через резистор в 10кОм подянут к плюсу. Хотя не спорю, можно просто прописать пуллап и убрать резистор. Но пока не заработает оригинальная схема, мне бы не хотелось, что-либо в ней менять.

 

Касаемо работы программы, я думаю, что она работает так:

каждые 10 милисекунд происходит изменение переменной massa, потом она разделяется на биты и биты записываются в сосотояние выводов. Соответственно микросхема-дешифратор выдает на одной из 16 ножек-выходов низкое напряжение. Повторюсь, каждые 10 милисекунд состояние меняется. Если же мы нажимаем кнопку, то до тех пор, пока massa не образует комбинацию такую, что на выходе дешифратора с нажатой кнопкой не образуется низкий сигнал прерывание происходить не будет, т.к обычное состояние выводов дешифратора высокое. Как только эта комбинация достигнута, программа прерывается, в прерывании переменной knopf присваивается значение из массива соответствующее текущему значению massa. Но в примере из интернета другая логика работы программы. 

 

Убрал резистор, использовал внутренню подтяжку к плюсу. В серийном порте получил следующее:

512
0
0
0
512
0
0
0
512
0
0
0
769
0
769
0
769
0
769
0
769

при нажатии на 1 кнопку 512 и если удерживать то три нуля, потом зацикливается, при нажатии на вторую 769 и один ноль, потом зацикливается. Откуда там такие числа??? 

 

вывод в порт написал так 

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
knopf = res[massa], 10;
 Serial.println(knopf); // тестовая строка
}

 

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

Lictor пишет:

исправил функцию blink на Ваш вариант. Касаемо лога, сделал так:

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
knopf = res[massa];
Serial.println(knopf); // тестовая строка
}

Что мы тут видим, ...

Нет, так не пойдёт - ничего мы тут не видим. Надо и massa печатать. Как-нибудь так:

void blink() {
   static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
   Serial.print("knopf="); Serial.print(knopf);
   knopf = res[massa];
   Serial.print(" ::: massa="); Serial.print(massa);
   Serial.print(" >>> knopf="); Serial.println(knopf);
}

Теперь Вы будете видеть какой была knopf в момент прерывания, какой была massa и как поменялась knopf. Тогда Вы сможете что-то понять.

Почему все новички так любят работать вслепую? :))))

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Lictor пишет:

исправил функцию blink на Ваш вариант. Касаемо лога, сделал так:

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
knopf = res[massa];
Serial.println(knopf); // тестовая строка
}

Что мы тут видим, ...

Нет, так не пойдёт - ничего мы тут не видим. Надо и massa печатать. Как-нибудь так:

void blink() {
   static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2,10, 6, 14, 4, 12, 8, 0};
   Serial.print("knopf="); Serial.print(knopf);
   knopf = res[massa];
   Serial.print(" ::: massa="); Serial.print(massa);
   Serial.print(" >>> knopf="); Serial.println(knopf);
}

Теперь Вы будете видеть какой была knopf в момент прерывания, какой была massa и как поменялась knopf. Тогда Вы сможете что-то понять.

Почему все новички так любят работать вслепую? :))))

 

 

Потому что когда не видно - не страшно)

слегка исправил Ваш пример 

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2, 10, 6, 14, 4, 12, 8, 0};
Serial.print("knopf="); Serial.print(knopf, 10);

   knopf = res[massa];

   Serial.print(" ::: massa="); Serial.print(massa, 2);

   Serial.print(" >>> knopf="); Serial.println(knopf, 10);

}

получил следующее

knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0
knopf=0 ::: massa=100 >>> knopf=0
knopf=0 ::: massa=1000 >>> knopf=0

как я вижу, прерывание вызывается в любой момент, т.е. оно почему-то не ждет перепада уровня, а прсто работает неограниченно от 1 перепада? Откуда оно вообще такие числа как 512 берет??? это может не десятичная система???

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

del

Lictor
Offline
Зарегистрирован: 01.10.2015

Radjah пишет:

LOW = !HIGH

Что не так?

 

но прерывание же у меня вызывается как 

 attachInterrupt(0, blink, FALLING );

где FALLING  именно перепад, именно с HIGH  на LOW, а не постоянное состояние.

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

Подключение еще проверь. Питание дешифратора, наличие соплей. Просто так пин на землю коротиться не должен.

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

Пожалуйста. уберите двойки и десятки из всех принтов.

Дайте полный скетч (текущую версию) и лог Seriala обязательно с самого начала. Я посмотрю.

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

Lictor пишет:

оно почему-то не ждет перепада уровня, а прсто работает неограниченно от 1 перепада? 

Это называется "дребезг" или сопли в схеме, что в принципе одно и тоже.

Ладно, сделайте то, что я просил - будем думать где она 512 берёт.

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

Кстати,

byte massa = B0;

тоже нужно сделать volatile

Lictor
Offline
Зарегистрирован: 01.10.2015

текущий скетч

volatile byte massa = B0;

const int buttonPin1 = 10;     // номер выхода управление дешифратором
const int buttonPin2 = 11;     // номер выхода управление дешифратором
const int buttonPin3 = 12;     // номер выхода управление дешифратором
const int buttonPin4 = 13;     // номер выхода управление дешифратором

volatile int  knopf ;   //переменная состояния кнопки

const int buttonPin = 2;     // номер входа прерывания

unsigned long previousMillis ; // для таймеров

void setup() {

  attachInterrupt(0, blink, FALLING ); // прерывание по 2 пину при переходе с высокого на низкий уровень

  Serial.begin(9600); //монитор порта

  pinMode(buttonPin1, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin2, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin3, OUTPUT);   //инициализация вывода управления дешифратором
  pinMode(buttonPin4, OUTPUT);   //инициализация вывода управления дешифратором

  pinMode(buttonPin, INPUT_PULLUP);    //вход на атмеге с дешифратора (клавиатура)
}
void loop() {

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > 10) {
 //  Serial.println(knopf); // тестовая строка
    previousMillis = currentMillis;
    if ( massa <= B01111 ) {
      digitalWrite( 10, bitRead( massa , 0 ));
      digitalWrite( 11, bitRead( massa , 1 ));
      digitalWrite( 12, bitRead( massa , 2 ));
      digitalWrite( 13, bitRead( massa , 3 ));
  /*     Serial.print(digitalRead(buttonPin1));  //тестовая строка состояний пинов на входе в дешифратор.
         Serial.print(digitalRead(buttonPin2));
         Serial.print(digitalRead(buttonPin3));
         Serial.println(digitalRead(buttonPin4)); */
      massa++ ;
      if ( massa > B01111 ) {
        massa = B0;
      }
    }
  }
}

void blink() { //прерывание по нажатию кнопки, присвоение значения нажатой кнопки
 static const PROGMEM  int res[] = {1, 9, 5, 13, 3, 11, 7, 15, 2, 10, 6, 14, 4, 12, 8, 0};
Serial.print("knopf="); Serial.print(knopf);

   knopf = res[massa];

   Serial.print(" ::: massa="); Serial.print(massa);

   Serial.print(" >>> knopf="); Serial.println(knopf);

}

лог 

при нажатии (при нажатии и удержании) на кнопку:


knopf=0 ::: massa=12 >>> knopf=769
knopf=769 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=12 >>> knopf=769
knopf=769 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=12 >>> knopf=769
knopf=769 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=12 >>> knopf=769
knopf=769 ::: massa=10 >>> knopf=0
knopf=0 ::: massa=12 >>> knopf=769

при нажатии на дргую кнопку


knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=2 >>> knopf=0
knopf=0 ::: massa=4 >>> knopf=0
knopf=0 ::: massa=8 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=2 >>> knopf=0
knopf=0 ::: massa=4 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=2 >>> knopf=0
knopf=0 ::: massa=4 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=2 >>> knopf=0
knopf=0 ::: massa=4 >>> knopf=0
knopf=0 ::: massa=8 >>> knopf=0
knopf=0 ::: massa=8 >>> knopf=0
knopf=0 ::: massa=0 >>> knopf=512
knopf=512 ::: massa=2 >>> knopf=0
knopf=0 ::: massa=4 >>> knopf=0
knopf=0 ::: massa=10 >>> knopf=0

фото. что бы все могли убедиться, что аппаратно схема правильная:

и да, пока кнопка не нажата, лог пустой и ни чем не заполняется.

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

Уберите PROGMEM  из строки 51 и скажите поменялся ли лог (так же ли там всё время 0 и 512 или нет).

Lictor
Offline
Зарегистрирован: 01.10.2015

после того как убрал

кнопка первая

knopf=0 ::: massa=8 >>> knopf=2
knopf=2 ::: massa=0 >>> knopf=1
knopf=1 ::: massa=2 >>> knopf=5
knopf=5 ::: massa=4 >>> knopf=3
knopf=3 ::: massa=0 >>> knopf=1
knopf=1 ::: massa=2 >>> knopf=5
knopf=5 ::: massa=4 >>> knopf=3
knopf=3 ::: massa=8 >>> knopf=2
knopf=2 ::: massa=8 >>> knopf=2
knopf=2 ::: massa=0 >>> knopf=1
knopf=1 ::: massa=2 >>> knopf=5
knopf=5 ::: massa=4 >>> knopf=3
knopf=3 ::: massa=0 >>> knopf=1
knopf=1 ::: massa=2 >>> knopf=5
knopf=5 ::: massa=4 >>> knopf=3
knopf=3 ::: massa=8 >>> knopf=2
knopf=2 ::: massa=0 >>> knopf=1
knopf=1 ::: massa=2 >>> knopf=5

кнопка вторая 


knopf=6 ::: massa=12 >>> knopf=4
knopf=4 ::: massa=10 >>> knopf=6
knopf=6 ::: massa=10 >>> knopf=6
knopf=6 ::: massa=12 >>> knopf=4
knopf=4 ::: massa=10 >>> knopf=6
knopf=6 ::: massa=12 >>> knopf=4
knopf=4 ::: massa=11 >>> knopf=14
knopf=14 ::: massa=12 >>> knopf=4
knopf=4 ::: massa=10 >>> knopf=6
knopf=6 ::: massa=12 >>> knopf=4

 

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

Так, уже лучше. Значения присваиваются правильные. Т.е. knopf изменяется так, как и должна.

То, что на одно нажатие вываливается много прерываний - следствие дребезга или неверной схемы. 

Ещё какие-то вопросы остались? Что-то ещё непонятно? Знаете, как от дребезга избавиться?

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Так, уже лучше. Значения присваиваются правильные. Т.е. knopf изменяется так, как и должна.

То, что на одно нажатие вываливается много прерываний - следствие дребезга или неверной схемы. 

Ещё какие-то вопросы остались? Что-то ещё непонятно? Знаете, как от дребезга избавиться?

Про дребезг догадываюсь, но с удовольствием выслушаю Ваш вариант. 

Спасибо за помощь

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

Про дребезг - вот здесь самое лучшее, что я видел. Можно сказать "энциклопедия боьбы с дребезгом" и программно, и аппаратно - http://www.eng.utah.edu/~cs5780/debouncing.pdf

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Про дребезг - вот здесь самое лучшее, что я видел. Можно сказать "энциклопедия боьбы с дребезгом" и программно, и аппаратно - http://www.eng.utah.edu/~cs5780/debouncing.pdf

 

премного благодарен, когда я перенес с макетки на плату с пайкой, оно заработало  отлично, дело действительно было то ли в дребезге, то ли где-то что-то отходило. 

Lictor
Offline
Зарегистрирован: 01.10.2015

Обнаружил следующую фичу:

я писал про задваивание значений, сперва одно, потом другое. Кажись я понял в чем дело, это не дребезг, просто обращаясь к массиву со значениями knopf он переводит massa в десятичную систему, а там 010 и 10 одинаково равно 2 в десятичной. Видимо тсюда и идет задваивание. Такое возможно?

так как в логе видно при зажатии кнопки (massa в двоичной ситеме)

knopf=0 ::: massa=1000 >>> knopf=2
knopf=2 ::: massa=1 >>> knopf=9
knopf=9 ::: massa=10 >>> knopf=5
knopf=5 ::: massa=100 >>> knopf=3
knopf=3 ::: massa=1000 >>> knopf=2

и еще мне кажется, что он читает байты справа налево...

 

при зажатии следующей кнопки видим другое 

knopf=1 ::: massa=1000 >>> knopf=2
knopf=2 ::: massa=1010 >>> knopf=6
knopf=6 ::: massa=1100 >>> knopf=4
knopf=4 ::: massa=0 >>> knopf=1

 

хотя на некоторых пинах все работает превосходно


knopf=12 ::: massa=1101 >>> knopf=12
knopf=12 ::: massa=1101 >>> knopf=12
knopf=12 ::: massa=1101 >>> knopf=12
knopf=12 ::: massa=1101 >>> knopf=12
knopf=12 ::: massa=1101 >>> knopf=12
knopf=12 ::: massa=1101 >>> knopf=12

 

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

 

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

Никто никого никуда не переводит. Все числа хранятся одинаково - их представления в разных системах - только для Вас, чтобы Вы читали - хранится всё одинаково.

Там он тупо использует massa в качестве индекса и берёт число из массива.

Нетникакой мистики, не забивайте себе голову. Следующие строки абсолютно идентичны:

a = 9;

a = 011;

a = b01001;

Абсолютно! Нет никакой разницы.

Lictor
Offline
Зарегистрирован: 01.10.2015

вероятно прерывание, вызываемое в любой момент, прерывает запись состояний выводов атмеги. И не смотря на то, что масса уже задана, выводы находятся еще не в том состоянии, в котором должны, что и вызывает множественные переключения (которые, кстати, всегда одни и те  же). Т.е. сперва срабатывает одно ложное состояние, потом второе и .т.п. Так же это может быть связано с тем, что выводы записываются по очереди, а не одновременно, что и вызывает некий набор промежуточных состояний.

 

Тогда как Вам такая версия?