if/else в digitalRead не выполняется в части else

Я новичок в C++, но раньше хорошо владел BASIC (2 десятилетия назад, лол). Я создаю перистальтический дозатор, который позволяет вам вводить желаемые мл на клавиатуре 4х4, а затем при нажатии кнопки «заполнить» он дозирует нужные мл через перистальтику.

Я все еще рисую/печатаю перистальтический корпус и все такое, но тем временем я хочу выполнить как можно больше кода. Он еще не завершен, но одна из функций, которую я хочу, чтобы дозатор имел, — это кнопка «ЗАПРАВКА/ПРОМЫВКА».

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

Обходной путь: сделать эту кнопку кнопкой включения/выключения. Итак, нажмите один раз, насос включится, нажмите еще раз, насос выключится. Поскольку насос еще не распечатан, я использовал встроенный светодиод в качестве тестера кодирования (отсюда и LED_BUILTIN).

Проблема в том, что в ходе исследования я понял, что мне понадобится оператор if/else. Когда кнопка нажата (в данном случае кнопка «a»), она считывает статус LED_BUILTIN, и если он ВЫСОКИЙ, он выключается, а если НИЗКИЙ, он включается.

Но часть «if» работает, она включает, а часть «else» — нет. Когда светодиод уже горит и нажата кнопка «а», он остается включенным и не перезаписывается на НИЗКИЙ.

Код ниже, есть какие-нибудь советы?

#include <KeypadShield.h>

KeypadShield keypad;

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

char Data[15];
byte data_count = 0;

int x;

char customKey;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  keypad.begin();
  lcd.begin(20,4); 
    lcd.setCursor(4,0);
    lcd.print("Let's Fill!");
    lcd.setCursor(4,1);
    lcd.print("Designed by");
    lcd.setCursor(4,2);
    lcd.print("JP");
    lcd.setCursor(5,3);
    lcd.print("2019 v1.0");

    delay (2000);

    lcd.clear();

    lcd.setCursor(1,0);
    lcd.print("Enter volume in mL");
    lcd.setCursor(3,1);
    lcd.print("on keypad then");
    lcd.setCursor(5,2);
    lcd.print("press DONE");
    lcd.setCursor(0,3);
    lcd.print("mL:");
}

void softReset()
{
asm volatile ("  jmp 0");
}

void loop() 
{
    customKey = keypad.getNextKeypress();

    if (customKey) 
    {
      if (customKey == 'a') 
      {
        if (digitalRead(LED_BUILTIN == LOW)) 
        {
          digitalWrite(LED_BUILTIN, HIGH);
          lcd.clear();
          lcd.setCursor(5,1);
          lcd.print("FLUSHING");
        } 
        else
        {
          digitalWrite(LED_BUILTIN, LOW);
          lcd.clear();
          lcd.setCursor(1,0);
          lcd.print("Enter volume in mL");
          lcd.setCursor(3,1);
          lcd.print("on keypad then");
          lcd.setCursor(5,2);
          lcd.print("press DONE");
          lcd.setCursor(0,3);
          lcd.print("mL:");
        }
      }

      if (customKey == 'd')
      {
       softReset();
      }

      if (customKey != 'p' && customKey != 'a' && customKey != 'b' && customKey != 'c' && customKey != 'd' && customKey != 's')
      {
        Data[data_count] = customKey; // сохраняем символ в массив данных
        lcd.setCursor(data_count+3,4); // перемещаем курсор, чтобы показать каждый новый символ
        lcd.print(Data[data_count]); // печатаем символ в указанном курсоре
        data_count++; // увеличиваем массив данных на 1 для сохранения нового символа, а также отслеживаем количество введенных символов
        x = atoi (Data); //конвертируем строку в целое число 'x' для использования в уравнениях
      }

     if (customKey == 'p')
      {
       lcd.clear();
       lcd.setCursor(7,0);
        lcd.print(x);
        lcd.setCursor(Data[data_count]+13,0);
        lcd.print("mL");
        lcd.setCursor(0,1);
        lcd.print("FILL --> fill");
        lcd.setCursor(0,2);
        lcd.print("RESET --> change mL");
        lcd.setCursor(0,3);
        lcd.print("FLUSH --> finish");

      }
    }
};

, 👍0

Обсуждение

digitalRead(LED_BUILTIN) == LOW переместите ). (вы читаете светодиод?), @Juraj

Святая ворона... спасибо, Юрай. Мозговой пердеж тут же... это решило проблему! И да, сейчас светодиод — это всего лишь заполнитель для моего перистальтического насоса (как только я закончу чертить и распечатать корпус). Я просто использую его, чтобы убедиться, что все работает. Еще раз спасибо!, @Jay

насос можно прочитать?, @Juraj

@Юрай, я думал, что смогу прочитать, включен или нет насос, или какой-то вариант этой концепции., @Jay

случайно в Uno вы прочтете последнее установленное состояние контакта, но лучше иметь переменную состояния, @Juraj

Вы можете удалить ';' в самом конце эскиза. Если вы не знаете всех последствий мягкого сброса, то не стоит его использовать. Мы не используем его по уважительной причине. Когда микроконтроллер Arduino Uno включен, все находится в выключенном состоянии. Это означает, что никакие внутренние части (таймеры, контроллеры шины и т. д.) не нужно инициализировать. Вот почему его так легко использовать для небольших проектов и для платы Arduino. При мягком сбросе вы продолжаете работу с начала кода. Если что-то было не так и находится в неправильном состоянии, то программный сброс может усугубить ситуацию., @Jot


1 ответ


7

(Хех... еще до того, как я увидел код, я догадался, что ты это сделал...)

Вы сравниваете номер контакта, а не результаты digitalRead(), а затем передаете результаты этого сравнения в digitalRead():

if (digitalRead(LED_BUILTIN == LOW))

Должно быть написано:

if (digitalRead(LED_BUILTIN) == LOW)

Обратите внимание на порядок скобок: LED_BUILTIN передается в digitalRead(), а затем результат вызова этой функции сравнивается со значением LOW.

,

Спасибо Маженко! Большой мозговой пердеж с моей стороны... но это решило проблему. хаха. Тратите так много времени на поиск больших проблем, что самые маленькие остаются прямо у вас под носом..., @Jay

@Джей Абсолютно. Это называется «Кодовая слепота»., @Majenko