Помощь с кодом (ввод 2х символов, конвертация в 16ричную систему)
- Войдите на сайт для отправки комментариев
Добрый день,
Прошу подсобить с кодом, ломал голову не получается решить задачу, пока сложновата для моих знаний.
Устройство пульт. ИК передачик. Клавиатура 3х4.
Задача: При вводе с клавиатуры значения от 1 до 100 передать это число в 16 виде в функцию которая формирует посылку на отправку.
А именно включили пульт, он ждет команду, набираем 35, число конвертируется в 16 систему исчисления и подставляется в эту команду вместо этого значения: fire (0x80, 0x01, 0xE8);
#include <Keypad.h> // Библиотека матричной клавиатуры
#include "Adafruit_NeoPixel.h" // Подключаем библиотеку Adafruit NeoPixel. Светодиод
#define IR_PIN 2 // ПИН ИК Диода
#define BTN_PIN 3 // ПИН TSOP
#define LED_PIN 4 // ПИН LED
#define LED_COUNT 1 // Указываем, какое количество светодиодов у нашей ленты.
int LevelMenu = 1; // Уровень меню
const byte ROWS = 4; //четыре строки на клавиатуре
const byte COLS = 3; //три столбца на клавиатуре
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {10, 9, 8, 7}; //подключить к выводам строк клавиатуры
byte colPins[COLS] = {13, 12, 11}; //подключить к выводам столбцов клавиатуры
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pinMode(IR_PIN, OUTPUT);
pinMode(BTN_PIN, INPUT);
digitalWrite(BTN_PIN, HIGH);
Serial.begin(9600);
Serial.println("Ready...");
strip.begin();
strip.show();
}
void loop() {
char key = keypad.getKey();
MenuLED(LevelMenu, 1);
if (LevelMenu == 1) {
switch (key) {
case '1':
Serial.println("+1 Live");
fire (0x80, 0x01, 0xE8);
MenuLED2();
break;
case '#':
LevelMenu++;
break;
case '*':
LevelMenu = 3;
break;
}
}
else if (LevelMenu == 2) {
switch (key) {
case '#':
LevelMenu++;
break;
case '*':
LevelMenu--;
break;
}
}
else if (LevelMenu == 3) {
switch (key) {
case '#':
LevelMenu = 1;
break;
case '*':
LevelMenu--;
break;
}
}
}
//-------------------------------------------------
// Отработка светодиодом какое меню запущено
//-------------------------------------------------
void MenuLED (int Var, unsigned int ShowDelay)
{
if (Var == 1) {
strip.setPixelColor(0, strip.Color(10, 0, 0));
strip.show();
delay(ShowDelay);
}
else if (Var == 2) {
strip.setPixelColor(0, strip.Color(0, 10, 0));
strip.show();
delay(ShowDelay);
}
else if (Var == 3) {
strip.setPixelColor(0, strip.Color(0, 0, 10));
strip.show();
delay(ShowDelay);
}
}
//-------------------------------------------------
// Отработка светодиодом прерывание
//-------------------------------------------------
void MenuLED2 ()
{
strip.setPixelColor(0, strip.Color(0, 0, 0));
strip.show();
delay(200);
}
//-------------------------------------------------
// Отработка выстрела
//-------------------------------------------------
void fire (int sendByte1, int sendByte2, int sendByte3) {
sendHeader();
sendByte(sendByte1);
sendByte(sendByte2);
sendByte(sendByte3);
}
прошу прощения если нимешал кашу :)
PS: Не очень понятно, как отрабатывать число 100. С первой десяткой в принципе понятно можно просто ввести 01, 02 ... а со 100 не очень понятно, хотелось бы что бы отрабатывал число без дополнительных нажатий в виде * или #, так как эти клавиши задействованы на переход между меню ...
Сделайте Serial.println(0x80) и вы сильно удивитесь...
Прошу прощения, отвлекли, забыл добавить вместо какого значения :)
Значение 0x01 заменить на то что введено с клавиатуры, конвертированное в 16ричную систему исчисления: fire (0x80, 0x01, 0xE8);
Сделайте Serial.println(0x80) и вы сильно удивитесь...
Спасибо
Могу предположить что он сразу конвертирует в нужную систему :), нет под рукой ардуинки ... тогда остается вторая часть вопроса, организовать сбор 2х значных чисел и передача в функцию корректно...
А именно включили пульт, он ждет команду, набираем 35, число конвертируется в 16 систему исчисления и подставляется в эту команду вместо этого значения: fire (0x80, 0x01, 0xE8);
не очень понятно, зачем для этого конвертировать число в 16-ричный вид. Компьютеру все равно, в каком виде число.
Функция которая отрабатывает и отправляет ИК посылку работает только с числами в этом формате :(
Функция которая отрабатывает и отправляет посылку работает только с числами в этом формате :(
Поверьте дидам - вашей функции всё равно, дадите вы ей на вход 0x20 или 32.
Функция которая отрабатывает и отправляет ИК посылку работает только с числами в этом формате :(
БРЕД - код этой таинственной функции приведен в вашем же скетче, там ясно видно, что она принимает целые числа: void fire (int sendByte1, int sendByte2, int sendByte3)
Поймите - шестнадцитиричные числа - это просто вид записи числа, число от этого другим не становится. Это как текст, набран он фонтом Вердана или Сансерифом - все тот же текст.
Что бы не мудрить, весь код ниже ...
#include <Keypad.h> // Библиотека матричной клавиатуры #include "Adafruit_NeoPixel.h" // Подключаем библиотеку Adafruit NeoPixel. Светодиод #define IR_PIN 2 // ПИН ИК Диода #define BTN_PIN 3 // ПИН TSOP #define LED_PIN 4 // ПИН LED #define LED_COUNT 1 // Указываем, какое количество светодиодов у нашей ленты. #define CARRIER_INTERVAL 4 // Относится к генерации ИК посылки #define MLT_SPACE_INTERVAL 600 // Относится к генерации ИК посылки #define MLT_HEADER_CYCLES 162 // Относится к генерации ИК посылки #define MLT_BIT0_CYCLES 36 // Относится к генерации ИК посылки #define MLT_BIT1_CYCLES 78 // Относится к генерации ИК посылки int LevelMenu = 1; // Уровень меню const byte ROWS = 4; //четыре строки на клавиатуре const byte COLS = 3; //три столбца на клавиатуре char keys[ROWS][COLS] = { {'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}, {'*', '0', '#'} }; byte rowPins[ROWS] = {10, 9, 8, 7}; //подключить к выводам строк клавиатуры byte colPins[COLS] = {13, 12, 11}; //подключить к выводам столбцов клавиатуры Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); void setup() { pinMode(IR_PIN, OUTPUT); pinMode(BTN_PIN, INPUT); digitalWrite(BTN_PIN, HIGH); Serial.begin(9600); Serial.println("Ready..."); strip.begin(); strip.show(); } void loop() { char key = keypad.getKey(); MenuLED(LevelMenu, 1); if (LevelMenu == 1) { switch (key) { case '1': Serial.println("+1 Live"); fire (0x80, 0x01, 0xE8); MenuLED2(); break; case '#': LevelMenu++; break; case '*': LevelMenu = 3; break; } } else if (LevelMenu == 2) { switch (key) { case '1': Serial.println("10%"); fire (0xA5, 0x0A, 0xE8); MenuLED2(); break; case '#': LevelMenu++; break; case '*': LevelMenu--; break; } } else if (LevelMenu == 3) { switch (key) { case '1': Serial.println("StormTrooper"); fire (0xA8, 0x01, 0xE8); MenuLED2(); break; case '#': LevelMenu = 1; break; case '*': LevelMenu--; break; } } } //------------------------------------------------- // Отработка светодиодом какое меню запущено //------------------------------------------------- void MenuLED (int Var, unsigned int ShowDelay) { if (Var == 1) { strip.setPixelColor(0, strip.Color(10, 0, 0)); strip.show(); delay(ShowDelay); } else if (Var == 2) { strip.setPixelColor(0, strip.Color(0, 10, 0)); strip.show(); delay(ShowDelay); } else if (Var == 3) { strip.setPixelColor(0, strip.Color(0, 0, 10)); strip.show(); delay(ShowDelay); } } //------------------------------------------------- // Отработка светодиодом прерывание //------------------------------------------------- void MenuLED2 () { strip.setPixelColor(0, strip.Color(0, 0, 0)); strip.show(); delay(200); } //------------------------------------------------- // Отработка выстрела //------------------------------------------------- void fire (int sendByte1, int sendByte2, int sendByte3) { sendHeader(); sendByte(sendByte1); sendByte(sendByte2); sendByte(sendByte3); } void sendHeader() { sendPulse(MLT_HEADER_CYCLES); delayMicroseconds(MLT_SPACE_INTERVAL); } void sendByte(byte x) { for (int i = 0; i < 8; i++) { if (x & 0x80) { sendPulse(MLT_BIT1_CYCLES); } else { sendPulse(MLT_BIT0_CYCLES); } x = x << 1; delayMicroseconds(MLT_SPACE_INTERVAL); } } void sendPulse(int cycles) { for (int i = 0; i < cycles; i++ ) { digitalWrite(IR_PIN, HIGH); delayMicroseconds(CARRIER_INTERVAL); digitalWrite(IR_PIN, LOW); delayMicroseconds(CARRIER_INTERVAL); } }Что бы не мудрить, весь код ниже ...
И что? посмотрите заголовок функции в строке 155. Или для вас это тарабарская грамота?
Все команды которые которые отправляются мне известны только в таком формате
fire (0x80, 0x01, 0xE8), т.е. 8001E8
Все команды которые которые отправляются мне известны только в таком формате
fire (0x80, 0x01, 0xE8), т.е. 8001E8
продолжаете УПОРНО тупить? - вам видно это нравится... ну как хотите... Можете цифры еще в римскую нотацию перевести...
Согласен, передаем в целых числах. Буду подтягивать мат.часть ) в части типов данных.
Но давайте отвлечемся от типов данных, и поможем мне во второй части вопроса ...
Но давайте отвлечемся от типов данных, и поможем мне во второй части вопроса ...
Ввод чисел по принципу как в тв-пульте. Ввводите 2 и делаете паузу - получаете вторую программу , вводите 2 и потом быстро 3 - получаете 23-ю. "100". если это единственное трехзначное число - я бы выкинул, слишком много мороки из-за одного числа. Вместо 100 вариантов. всегда можно обойтись 99-ю :)
b707, хорошо "100" можно пренебречь.
Тогда прошу помочь с рабочим кодом по вводу 2х чисел ... Спасибо
b707, хорошо "100" можно пренебречь.
Тогда прошу помочь с рабочим кодом по вводу 2х чисел ... Спасибо
"100" можно заменить на "00". кстати. Насчет кода - сами пробовали что-нибудь писать?
"Игра в одни ворота" тут не принята.
Пробовал, не заработало, стер :) ... могу что то попробовать написать, если не заработает прислать код, но это будет позже :)
... с 00 отличная идея!
У вас в коде куча delay с таким кодом толком клавиатуру не считать. Если нажать во время delayнажатие проигнорируется.
У вас в коде куча delay с таким кодом толком клавиатуру не считать. Если нажать во время delayнажатие проигнорируется.
EnTeen, Penni прав, чтобы нормально опрашивать клавиатуру, полный "оборот" loop() не должен быть больше 10-20мс. А у вас там полно задержек по 200мс, причем вроде как даже по несколько за цикл. С таким кодом затевать работу с кнопками бессмысленно.
Да, пересоберу код на millis. Вопрос а разве loop ходит по функциям которые не вызваны? просто все задержки в основном сидят в обработке светодиодов и по сути можно вообще оттуда убрать ... это тоже попробую сделать.
У вас menuLED сразу секунду задержку добавляет. Если выполнять так как написано в первом сообщении, то еще можно легкой кровью отделаться. Крутитесь в лупе и сканируете клавиатуру. если * или # переходите по меню. Если нажата цифра то крутимся, например 2 секунды и считываем все нажатия (если они были). Т.е. определили что нажата цифра, запоминаете время начала сканирования и в переменную типа байт кладете key-48. Если считана еще одна цифра за эти две секунды то переменную умножаете на 10 и прибавляете key-48, если и еще одна цифра (это если надо больше 100) то снова умножаете на 10 и прибавляете key-48, но это уже в байт может не влезть. Как две секунды вышло у вас в переменной будет нужное число.
Penni, спасибо
Подсмотрел в другой ветке и вроде все получается логично, программа не выдала ошибок ... будет под рукой ардуинка попробую зашить.
Прошу посмотреть верное ли решение. я потом по факту ещё отпишусь что все нормально ...
int data=0; // инициализация переменной для ввода 2х значного числа boolean first=true; // инициализация переменной для ввода 2х значного числа void setup() { pinMode(IR_PIN, OUTPUT); pinMode(BTN_PIN, INPUT); digitalWrite(BTN_PIN, HIGH); Serial.begin(9600); Serial.println("Ready..."); strip.begin(); strip.show(); } void loop() { char key = keypad.getKey(); MenuLED(LevelMenu, 1); if (LevelMenu == 1) { if (key) { if (first) { first = false; if (isDigit(key)) { data = data * 10 + key - 48; } } } else if (!first) { first = true; } switch (data) { case '1': Serial.println("+1 Live"); fire (0x80, data, 0xE8); MenuLED2(); break;