20 кнопок на Uno

Snogg
Offline
Зарегистрирован: 13.03.2017

Подскажите совсем ламеру - как сделать, чтоб Ардуина понимала нажатия как минимум двадцати примитивных кнопок?

И какова максимальная дина проводов от платы до кнопок тогда получится?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Уровень абстрактного "понимания" пока не достигнут даже лучшими образцами Искуственного Интеллекта.

Так что, вынужден Вас расстроить: "...сделать, чтоб понимала", вероятно никак не возможно. Вне зависимости от длины проводов.

Snogg
Offline
Зарегистрирован: 13.03.2017

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

Snogg
Offline
Зарегистрирован: 13.03.2017

wdrakula пишет:

Уровень абстрактного "понимания" пока не достигнут даже лучшими образцами Искуственного Интеллекта.

Уровень ардуинского понимания в виде битового представления "нажата/ненажата" мне необходим и достаточен.

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Snogg пишет:

примитивных кнопок

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Snogg пишет:
Уровень ардуинского понимания в виде битового представления "нажата/ненажата" мне необходим и достаточен.

Можете посмотреть на модули расширения PCF8574/PCF8575. Первый на 8 I/O портов. второй на 16. Таким образом наберете 20 кнопок. Работают по I2C, умеют выдавать сигнал для прерывания при изменении состояния любого I/O - порта.

bizzon
Offline
Зарегистрирован: 29.03.2016

Ну так .. матричная клавиатура 5Х4 -займёт 9 пинов и правильная программа будет понимать одновременно  нажатые кнопки. Или мультиплексоры с достаточным количеством входов - это займёт 6-7 пинов нa ардуине. Много кнопок будет одновременно нажиматься?

Про длину проводов разговор отдельный.

bizzon
Offline
Зарегистрирован: 29.03.2016

sadman41 пишет:

Snogg пишет:
Уровень ардуинского понимания в виде битового представления "нажата/ненажата" мне необходим и достаточен.

Можете посмотреть на модули расширения PCF8574/PCF8575. Первый на 8 I/O портов. второй на 16. Таким образом наберете 20 кнопок. Работают по I2C, умеют выдавать сигнал для прерывания при изменении состояния любого I/O - порта.

Во. Ещё меньше пинов занято будет.

Snogg
Offline
Зарегистрирован: 13.03.2017

sadman41 пишет:

Можете посмотреть на модули расширения PCF8574/PCF8575. Первый на 8 I/O портов. второй на 16. Таким образом наберете 20 кнопок. Работают по I2C, умеют выдавать сигнал для прерывания при изменении состояния любого I/O - порта.

Спасибо, добрый человек! Теперь понял, что искать.

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

Snogg
Offline
Зарегистрирован: 13.03.2017

bizzon пишет:

Много кнопок будет одновременно нажиматься?

Про длину проводов разговор отдельный.

Проект на тему квестов в комнате. Поэтому количество кнопок и одновременность нажатий целиком на совести сценариста.

И, соответственно, длина проводов тоже важна. Надежность распознавания нажатия нужна до 10 метров.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну могу предложить это . Полный скетч здесь. https://yadi.sk/d/cTyiehOG3FhTED

Но там зоточено под нажатие одной кнопки, а остальное это ошибка. Исправите и будет вам счастье. А дальность увеличивется подключением дополнительной цепи на напряжение 12 В, и оптроной развязкой на входа и выхода.

Головной файл здесь 

/* class_do_keys_4х4.ino 
  #1 клавиатура 4x4
           строки->2,3,4,5 выхода
          колонки->6,7,8,9 входа
           {'1','2','3','A'},
           {'4','5','6','B'},
           {'7','8','9','C'},
           {'*','0','#','D'}
  Принцип кода:При нажатии на соответствующую кнопку выполняется соответсвующее действие
*/
//#1 клавиатура 4x4
#include "Cl_do_keys_4x4.h"
void Do1(void) {
  Serial.println("do Func 1");
}
void Do2(void) {
  Serial.println("do Func 2");
}
void Do3(void) {
  Serial.println("do Func 3");
}
void Do4(void) {
  Serial.println("do Func A");
}
void Do5(void) {
  Serial.println("do Func 4");
}
void Do6(void) {
  Serial.println("do Func 5");
}
void Do7(void) {
  Serial.println("do Func 6");
}
void Do8(void) {
  Serial.println("do Func B");
}
void Do9(void) {
  Serial.println("do Func 7");
}
void Do10(void) {
  Serial.println("do Func 8");
}
void Do11(void) {
  Serial.println("do Func 9");
}
void Do12(void) {
  Serial.println("do Func C");
}
void Do13(void) {
  Serial.println("do Func *");
}
void Do14(void) {
  Serial.println("do Func 0");
}
void Do15(void) {
  Serial.println("do Func #");
}
void Do16(void) {
  Serial.println("do Func D");
}
Cl_do_keys_4x4 do_keys_4x4(2, 3, 4, 5, 6, 7, 8, 9,                    // пины для подключения
                           & Do1, & Do2, & Do3, & Do4,    // функции для выполнения при нажатии
                           & Do5, & Do6, & Do7, & Do8,
                           & Do9, & Do10, & Do11, & Do12,
                           & Do13, & Do14, & Do15, & Do16
                          ); // создать клавиатуру 4х4

void setup() {
  Serial.begin(9600);
  do_keys_4x4.setup();
}
void loop() {
  do_keys_4x4.loop();
}

 

Vitali-71
Offline
Зарегистрирован: 25.04.2017

Девченки и мальчишки!!! Доброго всем времемени дня!

Прошу помочь мне разобраться с моим скетчем. Он состоит из:

Arduino Mega 2580, 2 драйвера + 2 шаговых двигателя NEMA 17, матричная клавиатура.

проблема заключается вот в чем. требуется чтобы при нажатии: 

цифры 1 на клавиатуре, двигатель 1 вращался по часовой стрелке.

цифры 2 на клавиатуре, двигатель 1 вращался против часовой стрелке.

цифры 3 на клавиатуре, двигатель 2 вращался по часовой стрелке.

цифры 4 на клавиатуре, двигатель 2 вращался против часовой стрелке.

Но при нажатии любой из перечисленных цифр, двигатели поворачиваются на 1-2 градуса, независимо, нажал ты и отпустил кнопку или нажал и держишь!

 

#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'#', '0', '*', 'D'}
};

byte rowPins[ROWS] = { 26, 27, 28, 29};
byte colPins[COLS] = { 30, 31, 32, 33};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

const int stepPin1 = 39;
const int dirPin1 = 38;
const int stepPin2 = 41;
const int dirPin2 = 40;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode (stepPin1, OUTPUT);
  pinMode (dirPin1,  OUTPUT);
  pinMode (stepPin2, OUTPUT);
  pinMode (dirPin2,  OUTPUT);
  }

void loop() {
  char key = keypad.getKey();
  Serial.print("Key='");
Serial.print(key);
Serial.println("'");
  if (key == '1')
  {
    digitalWrite(dirPin1, HIGH);
    digitalWrite(stepPin1, LOW);
  }
  if (key == '2')
  {
    digitalWrite(dirPin1, LOW);
    digitalWrite(stepPin1, HIGH);
  }
  if (key == '3')
  {
    digitalWrite(dirPin2, HIGH);
    digitalWrite(stepPin2, LOW);
  }
  if (key == '4')
  {
    digitalWrite(dirPin2, LOW);
    digitalWrite(stepPin2, HIGH);
  }
  delayMicroseconds(1000);

if (key == '1')
  {
    digitalWrite(stepPin1, HIGH);
  }
  if (key == '2')
  {
    digitalWrite(stepPin1, LOW);
  }
  if (key == '3')
  {
    digitalWrite(stepPin2, HIGH);
  }
  if (key == '4')
  {
    digitalWrite(stepPin2, LOW);
  }
  delayMicroseconds(1000);
}

скетч этот, в плане двигателей, рабочий 100%!

т.к. есть точно какой же написанный с обычными кнопками. Там все работает как часы!

Прошу помочь разобраться с "матричкой"

bizzon
Offline
Зарегистрирован: 29.03.2016

Титановый велосипед для кнопок? Не годится? Какая разница, как получать данные от кнопок?  Если даже я справился за полдня.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vitali-71, в описании Вашего алгоритма не совсем ясно, как Вы понимаете слово "вращался", и совершенно отсутствует информация о реакции на отпускание кнопок.

Vitali-71
Offline
Зарегистрирован: 25.04.2017

andriano пишет:

Vitali-71, в описании Вашего алгоритма не совсем ясно, как Вы понимаете слово "вращался", и совершенно отсутствует информация о реакции на отпускание кнопок.

"вращался" значит крутится!

а отпустить значит прекратить работу! (вращение)

то есть он должен (мотор) работать только при нажатии кнопки

sadman41
Offline
Зарегистрирован: 19.10.2016

Нажатие и удержание - это разные процессы с точки зрения алгоритма.

Vitali-71
Offline
Зарегистрирован: 25.04.2017

sadman41 пишет:

Нажатие и удержание - это разные процессы с точки зрения алгоритма.

(мотор) должен работать только при удержании кнопки

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vitali-71, в своем скетче Вы реагируете на нажатия, но никак не отслеживаете удержание. Соответственно, скетч и работает: нажали - сделал один шаг, еще раз нажади - еще один.

Vitali-71
Offline
Зарегистрирован: 25.04.2017

andriano пишет:

Vitali-71, в своем скетче Вы реагируете на нажатия, но никак не отслеживаете удержание. Соответственно, скетч и работает: нажали - сделал один шаг, еще раз нажади - еще один.

так, я не знаю как это сделать, поэтому и обращаюсь к вам на форум!!!

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vitali-71, я помог Вам сформулировать (а, вероятно, - и понять) то, что требуется, указал на ошибку, а теперь уж Вы как-то сами. Я не пользуюсь библиотеками, поэтому конкретных указаний, как использовать данную библиотеку, дать не могу. Но направление указал: нужно отслеживать либо удержание кнопки, либо ее отпускание, в зависимости от того, что именно позволяет сделать используемая Вами библиотека. Смотрите, какие там есть команды, разбирайтесь...

Vitali-71
Offline
Зарегистрирован: 25.04.2017

А кто-нибудь может помочь доработать скетч, просто я новичок в этом деле.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, не везет вам. Никого с такой же клавиатурой-библиотекой нет на данный момент на форуме.

Клапауций 555
Offline
Зарегистрирован: 10.03.2018

Vitali-71 пишет:

...просто я новичок...

сбросьте кто его в пропасть - у меня сердце кровью обливается наблюдать сии мучения. О_О

Vitali-71
Offline
Зарегистрирован: 25.04.2017

Клапауций 555 пишет:

Vitali-71 пишет:

...просто я новичок...

сбросьте кто его в пропасть - у меня сердце кровью обливается наблюдать сии мучения. О_О

это легче всего...

Клапауций 555
Offline
Зарегистрирован: 10.03.2018

Vitali-71 пишет:

это легче всего...

ты из гильдии мазохистов? О_О

Vitali-71
Offline
Зарегистрирован: 25.04.2017

Клапауций 555 пишет:

Vitali-71 пишет:

это легче всего...

ты из гильдии мазохистов? О_О

я из тех кто не останавливается на полпути!

nik182
Offline
Зарегистрирован: 04.05.2015

Ну так сделайте подпрограмму которая из будет получать нажатые кнопки и возвращать key.

Клапауций 555
Offline
Зарегистрирован: 10.03.2018

nik182 пишет:
Ну так сделайте подпрограмму которая из будет получать нажатые кнопки и возвращать key.

может, лучше сразу в пропасть? О_О

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Vitali-71, создайте класс для независимой работы ШД. Метод clockwise() - вращать по часовой, anti_clockwise()- вращать против часовой и stop() - остановится. Вот потом ими и управляйте вашей клавиатурой.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Ееееее, Клапауций эволюционировал до таймера ^_^

Vitali-71
Offline
Зарегистрирован: 25.04.2017

qwone, я не знаю как это написать

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Не проверял. Разберетесь отладите и будет вам счастье.

/**/
unsigned long mill; // переменная под millis()
//--------------------------------
class Cl_StepMotor {
  protected:
    byte dirPin, stepPin;
    unsigned long past;
    bool dir;/*0 по часовой 1 против*/
    bool activ = 0; /*0 стоим 1 вращаемся*/
    bool state;/*0 1-й полушаг 1 2-й полушаг*/
    unsigned long interval = 20; /*время полушага в миллисек.*/
  public:
    Cl_StepMotor(byte d, byte s): dirPin(d), stepPin(s) {
    }
    void init() {/*вставить в setup()*/
      pinMode (stepPin, OUTPUT);
      digitalWrite(stepPin, state = LOW);
      pinMode (dirPin,  OUTPUT);
      stop();
    }
    void run() {/*вставить в loop()*/
      if (activ == 0) return;
      if (mill - past >= interval) {
        past = mill;
        digitalWrite(stepPin, state = !state);
      }
    }
    void clockwise() {/*вращать по часовой)*/
      activ = 1;
      dir = 1;
      digitalWrite(dirPin, HIGH);
    }
    void anti_clockwise() {/*вращать против часовой*/
      activ = 1;
      dir = 0;
      digitalWrite(dirPin, LOW);
    }
    void stop() {/*остановить*/
      activ = 0;
    }
};
//---Компоновка-----------------------------
Cl_StepMotor StepMotor1(/*dir Пин*/2,/*step Пин*/3);
Cl_StepMotor StepMotor2(/*dir Пин*/4,/*step Пин*/5);
//---main-----------------------------
void setup() {
  StepMotor1.init();
  StepMotor1.clockwise();/*начать вращать по часовой*/
  StepMotor2.init();
  StepMotor2.clockwise();/*начать вращать по часовой*/
}

void loop() {
  mill = millis();
  StepMotor1.run();
  StepMotor2.run();
}
/*Скетч использует 1070 байт (3%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 39 байт (1%) динамической памяти, оставляя 2009 байт для локальных переменных. Максимум: 2048 байт.
*/

 

Vitali-71
Offline
Зарегистрирован: 25.04.2017

qwone пишет:

Не проверял. Разберетесь отладите и будет вам счастье.

/**/
unsigned long mill; // переменная под millis()
//--------------------------------
class Cl_StepMotor {
  protected:
    byte dirPin, stepPin;
    unsigned long past;
    bool dir;/*0 по часовой 1 против*/
    bool activ = 0; /*0 стоим 1 вращаемся*/
    bool state;/*0 1-й полушаг 1 2-й полушаг*/
    unsigned long interval = 20; /*время полушага в миллисек.*/
  public:
    Cl_StepMotor(byte d, byte s): dirPin(d), stepPin(s) {
    }
    void init() {/*вставить в setup()*/
      pinMode (stepPin, OUTPUT);
      digitalWrite(stepPin, state = LOW);
      pinMode (dirPin,  OUTPUT);
      stop();
    }
    void run() {/*вставить в loop()*/
      if (activ == 0) return;
      if (mill - past >= interval) {
        past = mill;
        digitalWrite(stepPin, state = !state);
      }
    }
    void clockwise() {/*вращать по часовой)*/
      activ = 1;
      dir = 1;
      digitalWrite(dirPin, HIGH);
    }
    void anti_clockwise() {/*вращать против часовой*/
      activ = 1;
      dir = 0;
      digitalWrite(dirPin, LOW);
    }
    void stop() {/*остановить*/
      activ = 0;
    }
};
//---Компоновка-----------------------------
Cl_StepMotor StepMotor1(/*dir Пин*/2,/*step Пин*/3);
Cl_StepMotor StepMotor2(/*dir Пин*/4,/*step Пин*/5);
//---main-----------------------------
void setup() {
  StepMotor1.init();
  StepMotor1.clockwise();/*начать вращать по часовой*/
  StepMotor2.init();
  StepMotor2.clockwise();/*начать вращать по часовой*/
}

void loop() {
  mill = millis();
  StepMotor1.run();
  StepMotor2.run();
}
/*Скетч использует 1070 байт (3%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 39 байт (1%) динамической памяти, оставляя 2009 байт для локальных переменных. Максимум: 2048 байт.
*/

 

Спасибо, вопрос один есть.... а это отдельный скетч, или дполнение к скетчу клавы?

я просто не пойму как и куда ее подключить (клаву)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch... Вот про этот стиль. И подключение рекомендуется похожее. #10  это должно подойти.

Vitali-71
Offline
Зарегистрирован: 25.04.2017

qwone пишет:

http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch... Вот про этот стиль. И подключение рекомендуется похожее. #10  это должно подойти.

Ничего не выходит, а что должно выходить при нажатии на кнопку?