5-битный способ связи?
Хорошо, я работаю над проектом, в котором я хочу, чтобы несколько переключателей создавали "код" для определения дальнейших действий. По сути, это 5-битный процесс связи, который создаст выходные данные с 32-битным диапазоном результатов от 00000 до 11111.
Я тестирую метод с тремя переключателями, поэтому, если первый и третий переключатели работают/включены, он будет показывать 101. Второй и третий, 011 и т.д. Я недостаточно сведущ, чтобы знать, есть ли здесь лучший метод, но есть ли лучший способ сделать это?
// Определите используемые контакты
int pin_switch = 10;
int pin_switch2 = 11;
int pin_switch3 = 12;
// создать int для 3-значного кода
int code = 000;
void setup()
{
Serial.begin(9600);
pinMode(pin_switch, INPUT);
pinMode(pin_switch2, INPUT);
pinMode(pin_switch3, INPUT);
}
void loop()
{
if pin_switch == HIGH;
{code += 100;}
if pin_switch2 == HIGH;
{code += 10;}
if pin_switch3 == HIGH;
{code += 1;}
Serial.print(code);
// operate based on code output
if code == 101;
{do 101 stuff}
if code == 001
{do 001 stuff}
// сбросить код для следующего цикла, чтобы числа не продолжали расти
code = 000;
}
@Mulcch, 👍-1
Обсуждение2 ответа
Было бы удобнее и меньше печатать, если бы вы поместили все свои контакты переключателя в массив. Таким образом, вы можете обойти его, чтобы настроить порты и прочитать их, а не копировать/вставлять "один и тот же" код снова и снова.
Расчет полученного кода представляет собой классический цикл "сдвиг и добавление". Я поместил как десятичную версию, которую вы, кажется, хотите, так и более "обычную" двоичную версию во фрагменте ниже.
Идея такого рода цикла заключается в следующем:
- начните с пустого (нулевого) кода
- умножьте код на 10 (или один раз сдвиньте влево для двоичного кода)
- считайте переключатель, добавьте 1 к коду, если он ВЫСОКИЙ
- вернитесь к шагу 2, если есть еще переключатели.
Значение уже прочитанных переключателей "сдвигается" на один слот влево перед чтением следующего переключателя, в результате чего получается нужный вам код.
Порядок, в котором вы перечисляете порты в массиве, важен: первый порт в массиве изменит крайнюю левую (самую значимую) цифру/бит в коде.
const uint8_t switch_pin[] = { 10, 11, 12 };
const uint8_t num_switches = sizeof(switch_pin)/sizeof(switch_pin[0]);
void setup() {
// Установить все контакты переключателя в режим ввода
for (uint8_t i = 0; i < num_switches; ++i) {
pinMode(switch_pin[i], INPUT);
}
Serial.begin(9600);
}
void loop() {
int code = 0;
// Считать каждый переключатель и вычислить код
for (uint8_t i = 0; i < num_switches; ++i) {
// Если код должен быть в десятичной системе счисления
code = code * 10;
code += digitalRead(switch_pin[i]);
/* Для двоичной версии код должен быть длиной всего 8 бит:
code <<= 1;
code |= digitalRead(switch_pin[i]);
*/
}
// Делайте что-нибудь с кодом
Serial.println(code);
delay(200);
}
О, спасибо, Мэт, я думаю, что Сдвиг и Добавление-это терминология, которой мне не хватало! Я думаю, что я действительно хочу перейти на двоичный код, я думаю, что расширю это до пяти переключателей, чтобы аспект переключения упрощал это в моем представлении. Глядя на ваш код здесь: код <<= 1; Как бы я изменил и добавил для других частей кода? Приор выведет 010, верно? Мне бы просто нужно было сделать <<<=1; И <<= 1, чтобы получить 110? Спасибо вам за помощь., @Mulcch
Если " код равен 1010,
код <<= 1 (это то же самое, что " код = код << 1
) приведет к "10100" (сдвиньте влево, вставьте ноль справа). Код |= 1;
будет "заполнять" последнюю позицию до " 10101.
код |= 0;` ничего не даст., @Mat
К сожалению, ваш код повсюду. Вы должны использовать синтаксис C/C++, чего вы не делаете. Кроме того, вы на самом деле не читаете никаких данных.
если утверждения выглядят так:
if(condition){ my_code(); }
if(pin_switch == ВЫСОКИЙ)
(исправленный синтаксис) всегда будет ложным, таккак pin_switch
имеет значение10
. Это просто номер контакта. Чтобы действительно прочитать номер контакта, вам нужно использоватьdigitalRead()
следующим образом:if(digitalRead(pin_switch) == HIGH)
или даже проще
if(digitalRead(pin_switch))
Похоже, что вы хотите манипулировать битами с
помощью кода += 100;
, но компилятор принимает числа как десятичные. Таким образом, вы добавляете 100 вкод
. Пожалуйста, изучите побитовые операторы. Также: вы действительно можете записывать числа в двоичном или шестнадцатеричном формате, используя0b101
или0xF3
соответственно (значения здесь являются лишь примерами). Это также означает, чтокод int = 000;
совпадает скодом int = 0;
.
Чтобы построить 3-значный код из входных данных, вы можете собрать их вместе с помощью побитовых операторов:
code = (digitalRead(pin_switch3) << 2) | (digitalRead(pin_switch2) << 1) | digitalRead(pin_switch);
В зависимости от вашего используемого Arduino и используемых контактов, вы можете сделать это еще проще. Контакты сортируются по портам. Каждый порт имеет специальный регистр функций, в котором хранится текущее состояние контактов. Вы можете замаскировать любые нежелательные контакты и изменить число, чтобы оно было правильно обосновано. Например: На выводах Uno и Nano от 2 до 7 принадлежат PORTD. Таким образом, если вы используете контакты от 2 до 4 для своих 3 переключателей, вы можете получить код, такой как:
code = (PIND & 0b00011100) >> 2;
Это немного сложнее понять, но это поможет вам позже, когда вы будете больше заниматься Arduino.
Для принятия решения о том, какое действие следует выполнить на основе кода, обычно проще использовать оператор случая переключения:
switch(code){
case 0b101:
do_something();
break;
case 0b011:
do_something_else();
break;
}
Спасибо! Да, мой код был поспешно собран из примера, чтобы протестировать метод. Действительно ценю направление здесь, я буду больше копаться в побитовых операторах!, @Mulcch
@Mulcch ой, исправлена небольшая ошибка. Я использовал "PORTD` вместо "PIND". Первый используется для установки выходного состояния вывода, второй отражает текущее входное состояние., @chrisl
Спасибо, что поймали! Я не уверен, что пойду по этому пути, но действительно полезно знать об этом., @Mulcch
- Шестнадцатеричное/Байтовое реверсирование и преобразование
- LSB/MSB и shiftOut
- Использование массивов, двоичных данных и битового чтения
- Изменение одного бита в байтовом массиве
- Arduino статус бита
- Как управлять выводом регистров сдвига по отдельности побитово
- Вывести 2 числа, хранящиеся в 24-битном формате, в десятичном формате.
- Замените digitalWrite выборочной побитовой операцией.
Примечание: не записывайте начальные нули в десятичном числе на C или C++ (или на множестве других языков) - числа будут рассматриваться как восьмеричные, а не десятичные, что очень редко бывает тем, что вам нужно., @Mat