Минимизация цифрового входного кода
Я создаю устройство, которое может умножать аналоговый входной сигнал относительно выбранного усиления с цифровых входов. Здесь я использовал два цифровых входа (из которых я могу иметь четыре выбора), но я планирую добавить еще два входа (тогда я могу иметь 16 выборов). Я сделал код с операторами if else, есть ли более короткий способ сделать это? или код становится огромным.
вот код:
#define sensor A0
#define resetPin 3
#define measurePin 2
#define k1 3
#define k2 4
float A = 0;
float J = 0;
int resetstatus = 0;
int measurestatus = 0;
void setup() {
Serial.begin(9600);
pinMode(sensor,INPUT);
pinMode(resetPin,INPUT_PULLUP);
pinMode(measurePin,INPUT_PULLUP);
pinMode(k1,INPUT_PULLUP);
pinMode(k2,INPUT_PULLUP);
Serial.println("INITIALAIZING");
delay(3000);
Serial.println("Ready to begin");
delay(200);
}
void loop()
{
resetstatus = digitalRead(resetPin);
measurestatus = digitalRead(measurePin);
if(resetstatus == LOW)
{
reset();
delay(200);
}
if(measurestatus == LOW)
{
if(digitalRead(k1 == LOW) && digitalRead(k2 == LOW))
{
J = 1.0;
measure();
delay(50);
}
else if(digitalRead(k1 == LOW) && digitalRead(k2 == HIGH))
{
J = 2.0;
measure();
delay(50);
}
else if(digitalRead(k1 == HIGH) && digitalRead(k2 == LOW))
{
J = 3.0;
measure();
delay(50);
}
if(digitalRead(k1 == HIGH) && digitalRead(k2 == HIGH))
{
J = 4.0;
measure();
delay(50);
}
}
}
void measure()
{
A = analogRead(sensor);
float sumA = A * J;
Serial.println(sumA);
}
void reset()
{
Serial.println("reset");
}
У меня возникла проблема с выводом этого кода (Я использую потенциометр для подачи на Arduino аналогового значения)
Я не знаю, почему вывод показывает 993 и 3972 в каждом цикле. Может кто-нибудь объяснить?
@Peouse Dutta, 👍0
4 ответа
Лучший ответ:
Я создал код с операторами if else. Есть ли более короткий способ сделать это?
j = 1 + (digitalRead(k1) | (digitalRead(k2) << 1) | (digitalRead(k3) << 2) | (digitalRead(k3) << 3));
или
j = 1 + digitalRead(k1) + 2*digitalRead(k2) + 4*digitalRead(k3) + 8*digitalRead(k4)
Не знаю, почему вывод показывает 993 и 3972 в каждом цикле. Может кто-нибудь объяснить?
напечатанные значения неверны из-за ошибки, указанной в ответе Ника
Это неправильно:
if(digitalRead(k1 == LOW)
Вы имеете в виду:
if(digitalRead(k1) == LOW
То же самое касается и многих других мест в вашем коде.
Я создал код с операторами if else. Есть ли более короткий способ сделать это? в противном случае код становится огромным.
Да, есть способ упрощения. Как уже заметил @Juraj, в этом частном случае его можно даже выразить как двоичное представление:
if(digitalRead(k1) == LOW && digitalRead(k2) == LOW)
{
J = 1.0;
measure();
delay(50);
}
else if(digitalRead(k1) == LOW && digitalRead(k2) == HIGH)
{
J = 2.0;
measure();
delay(50);
}
else if(digitalRead(k1) == HIGH && digitalRead(k2) == LOW)
{
J = 3.0;
measure();
delay(50);
}
if(digitalRead(k1) == HIGH && digitalRead(k2) == HIGH)
{
J = 4.0;
measure();
delay(50);
}
То, что вы здесь делаете, представляет собой следующую схему:
- прочитать состояние кнопок
- в зависимости от того, какие комбинации кнопок нажаты, присвойте
J
разное значение
Мы можем обобщить эту концепцию «получить значение J для определенной комбинации кнопок», выполнив следующие действия:
- объединить все «состояния кнопок» в одно уникальное число
- найти соответствующее значение
J
Если мы назовем состояния кнопок ввода «k1» и «k2», то увидим следующую логику:
| k1 | k2 | J |
| 0 | 0 | 1.0 |
| 0 | 1 | 2.0 |
| 1 | 0 | 3.0 |
| 1 | 1 | 4.0 |
Мы просто объединяем входные данные кнопок в одну битовую строку «k1|k2» и видим
| (k1,k2) | J |
| 00 | 1.0 |
| 01 | 2.0 |
| 10 | 3.0 |
| 11 | 4.0 |
Если мы перепишем двоичные индексы в десятичные числа:
| (k1,k2) | J |
| 0 | 1.0 |
| 1 | 2.0 |
| 2 | 3.0 |
| 3 | 4.0 |
Итак, мы видим, что можем использовать это число (k1,k2) как индекс от 0 до 3, чтобы получить значение J как таковое:
//Объединить все нажатия кнопок в одно число
//использование битовых сдвигов
int index = (digitalRead(k2) << 1) | digitalRead(k1);
//Все используемые значения J в правильном порядке
const float J_values[] = {
1.0f, 2.0f, 3.0f, 4.0f
};
//получить правильное значение J
J = J_values[index];
//измерение и задержка
measure();
delay(50);
Это заменяет все ваши 4 оператора if-else
и делает то же самое.
Теперь, если вы добавите больше входов, вы можете просто расширить способ построения индексного номера и вашего массива J_values
. Запишите "таблицу функций" для нужных вам значений J
, как указано выше, создайте строки битов, упорядочите индексы в порядке возрастания и запишите значения массива соответственно.
Ссылки:
- https://www.cprogramming.com/tutorial/bitwise_operators.html
- https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitshiftleft/
Подключите все 4 контакта к одному порту, затем выполните чтение порта. Допустим, вы использовали D2,3,4,5. Затем переключатели = (PIND && 0b00111100) >> 2;
затем переключатели = от 0 до 15, и вы можете сделать ветвление на этом.
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату