Урок 18 собственная версия библиотеки сканирования матрицы кнопок

Обсуждение и вопросы по урокам Ардуино
Вадим Анатольевич
Сообщения: 7
Зарегистрирован: 19 сен 2018, 08:58

Урок 18 собственная версия библиотеки сканирования матрицы кнопок

Сообщение Вадим Анатольевич » 05 окт 2018, 18:09

Уважаемые коллеги. Выношу на Ваш суд собственную версию библиотеки сканирования матрицы кнопок. Основная идея сканирования матрицы и работы алгоритма была подсказана Ярославом в комментариях к уроку. Основным принципам написания программ, таким как использование параллельных вычислений, создание классов размещения их в библиотеке я научился у Эдуарда, по предыдущим урокам, за которые я, как и многие здесь безмерно ему благодарен.
Отличительные особенности библиотеки:
1 горизонтальные и вертикальные выводы клавиатуры подключаются к пинам контроллера без диодов и разгрузочных резисторов.(Алгоритм опроса подробно описан в коментариях)
2 команды оперирующие портами процессора приведенные в примере Ярослава не используются, что делает код платформенно независимым
и предотвращает появление багов при использовании библиотеки в сложных программах.
3 программу переработана для использования в параллельном процессе.(Как ее использовать подробно описано в комментариях)


/*
Matrix.h - библиотека для цифровой обработки сигналов контактов матрицы кнопок
размерностью 4 ряда на 4 строки параллельным процессом


В параллельном процессе должен регулярно вызываться один из методов:
void scanSt; // метод проверки ожидание стабильного состояния сигнала

В результате формируются признаки:

- при стабильном изменении состояния матрицы flagChangeState= true
- при нажатии на одну из кнопок flagClick= true


Объект типа Matrix при создании имеет параметры:
- номер выводов, к которым подключены горизонтальные и вертикальные выводы матрицы
- время обработки сигнала (умножается на период вызова метода scanSt())

Matrix matrix1(9, 10, 11, 12, 4, 5, 6, 7, 50); // создание объекта для матрицы кнопок,
горизонтальные линии которой подключены к пинам (9, 10, 11, 12), а вертикальные к пинам (4, 5, 6, 7)
с временем фильтрации 100 мс (при цикле 2 мс)

Библиотека разработана Аксениным Вадимом с использованием принципов и методики изложенной Калининым Эдуардом
на сайте http://mypractic.ru
*/

// проверка, что библиотека еще не подключена
#ifndef Button_h // если библиотека Button не подключена
#define Button_h // тогда подключаем ее

#include "Arduino.h"

class Matrix {

public:
byte oldCod; //предыдущий скан код клавиатуры
boolean flagChangeState; //флаг устойчивого изменения состояния матрицы
boolean flagClick; //флаг нажатия одной из кнопок
void scanSt(); //метод сканирования матрицы
//конструктор ввода номеров вертикальных и горизонтальных пинов и количества циклов подтверждения
Matrix (byte verticalPin1, byte verticalPin2, byte verticalPin3, byte verticalPin4, byte horizontalPin1, byte horizontalPin2, byte horizontalPin3, byte horizontalPin4,byte numAckn);

private:
byte _oldSumBits; //предыдущее количество нажатых кнопок
byte _cod; //текущий скан код клавиатуры
byte _timeCount; //счетчик числа сканирования клавиатуры
byte _verticalPins[4]; //выводы вертикальных линий
byte _horizontalPins[4]; //выводы горизонтальных линий
byte _numAckn; //количество циклов подтверждения неизменно состояния матрицы
short int _i; //индекс циклов
boolean _tmp; //временный результат
byte _sumBits; //сумма битов при текущем сканировании

};

#endif

//-------------------------------------------------------------------------------------------------------------------------------------------------
//Matrix.cpp
/*
Matrix.h - библиотека для цифровой обработки сигналов контактов матрицы кнопок
размерностью 4 ряда на 4 строки параллельным процессом


В параллельном процессе должен регулярно вызываться один из методов:
void scanSt; // метод проверки ожидание стабильного состояния сигнала

В результате формируются признаки:

- при стабильном изменении состояния матрицы flagChangeState= true
- при нажатии на одну из кнопок flagClick= true


Объект типа Matrix при создании имеет параметры:
- номер выводов, к которым подключены горизонтальные и вертикальные выводы матрицы
- время обработки сигнала (умножается на период вызова метода scanSt())

Matrix matrix1(9, 10, 11, 12, 4, 5, 6, 7, 50); // создание объекта для матрицы кнопок,
горизонтальные линии которой подключены к пинам (9, 10, 11, 12), а вертикальные к пинам (4, 5, 6, 7)
с временем фильтрации 100 мс (при цикле 2 мс)

Библиотека разработана Аксениным Вадимом с использованием принципов и методики изложенной Калининым Эдуардом
на сайте http://mypractic.ru
*/

#include "Arduino.h"
#include "Matrix.h"

//-------------------------------------------------------------------------конструктор класса Matrix
Matrix::Matrix(byte verticalPin1, byte verticalPin2, byte verticalPin3, byte verticalPin4, byte horizontalPin1, byte horizontalPin2, byte horizontalPin3, byte horizontalPin4,byte numAckn) {
// загрузка массивов выводов
_verticalPins[0]= verticalPin1; _verticalPins[1]= verticalPin2; _verticalPins[2]= verticalPin3; _verticalPins[3]= verticalPin4; _horizontalPins[0]= horizontalPin1; _horizontalPins[1]= horizontalPin2; _horizontalPins[2]= horizontalPin3; _horizontalPins[3]= horizontalPin4;
// и количества подтверждений состояния
_numAckn= numAckn;

oldCod=0xff; //матрица заполнена единицами все кнопки не нажаты
_oldSumBits=16; //сумма ненажатых кнопок
}

//----------------------------------------------------------------------метод сканирования матрицы кнопок
void Matrix::scanSt(){

_sumBits=0; //обнулить сумму битов скан кода
_cod=0; //текущий скан код

// чтение строк в старшие четыре бита сканкода считываются значения вертикальных пинов
for (_i=0; _i<=3; _i++){
pinMode(_verticalPins[_i],INPUT_PULLUP); //вертикальные пины объявляем входами и подключаем подтягивающие резисторы благодаря чему при разомкнутых кнопках на входе логическая единица 5В
pinMode(_horizontalPins[_i],OUTPUT); //горизонтальные пины настраиваем как выходы
digitalWrite(_horizontalPins[_i],LOW); //низкий потенциал на все выходы при замыкании кнопок потенциал входа = потенциалу выхода = логическому нулю
}
for (_i=3; _i>=0; _i--){
_cod=_cod<<1; //сдвигаем байт кода влево на один бит
_tmp=digitalRead(_verticalPins[_i]); //читаем вход
_cod|=_tmp; //заносим его в текущий бит кода
_sumBits=_tmp+_sumBits; //суммируем биты сканкода
}

// чтение столбцов младшие четыре бита сканкода
for (_i=0; _i<=3; _i++){
pinMode(_horizontalPins[_i],INPUT_PULLUP); //В этой части кода горизонтальные и вертикальные пины меняются ролями значения горизонтальных пинов считываются в младшие четыре бита скан кода
pinMode(_verticalPins[_i],OUTPUT);
digitalWrite(_verticalPins[_i],LOW);
}
for (_i=3; _i>=0; _i--){
_cod=_cod<<1;
_tmp=digitalRead(_horizontalPins[_i]);
_cod|=_tmp;
_sumBits=_tmp+_sumBits; //суммируем биты сканкода
}

//ниже блок анализа скан кода и формирования флагов связи с параллельными процессами
if (_cod==oldCod) _timeCount=0; //если код не изменился сбросить счетчик
_timeCount++; //иначе увеличиваем счетчик на единицу

if (_timeCount>=_numAckn){ //если скан код после последнего изменения подтвержден заданное количество раз то
if(_sumBits<_oldSumBits){ //сравнить сумму битов в нем с предыдущей
flagClick=true; //если она меньше значит одна из кнопок была нажата
}

_timeCount=0; //сбросить счетчик
flagChangeState=true; //установить флаг изменения состояния матрицы
oldCod=_cod; //запомнить скан код для последующего сравнения
_oldSumBits=_sumBits; //запомнить сумму битов скан кода для последующего сравнения
}
}

//------------------------------------------------------------------------------------------------------------------------------------------------
//тестовая программа

//* Программа sketch_18 урока
//* Подключена матрица кнопок
//* При нажатии кнопок формируется уникальный код размером в байт
//* Код выводится через UART в монитор Arduino в бинарном виде
//* При нажатии кнопки звучит короткий звуковой сигнал

#include<MsTimer2.h>
#include<Matrix.h>


Matrix matrix1(9, 10, 11, 12, 4, 5, 6, 7, 50); //создаем объект matrix1

void setup(){
MsTimer2::set(2,timerInterupt); //каждые две милисикунды запускаем синхронный процесс
MsTimer2::start();
Serial.begin(9600); // инициализируем порт, скорость 9600 //настраиваем частоту работы порта UART
pinMode(8,OUTPUT); //к восьмому пину подключен активный динамик
}

void loop() {
if(matrix1.flagChangeState==true){ //если состояние клавиатуры изменилось
Serial.println(matrix1.oldCod,BIN); //вывести в порт код клавиатуры
matrix1.flagChangeState=false;} //сбросить флаг
if(matrix1.flagClick==true){ //если произошло событие нажатия кнопки
digitalWrite(8,HIGH); //короткий звуковой сигнал
delay(30);
digitalWrite(8,LOW);
matrix1.flagClick=false;} //сбросить флаг
}

//------------------------------------------------------------------------обработчик прерывания по времени
void timerInterupt(){
matrix1.scanSt(); //считать состояния матрицы клавиш
}


Вернуться в «Уроки Ардуино»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 4 гостя