Проблемы со стабильностью работы

Тема в разделе "Arduino & Shields", создана пользователем kirilikyzzz, 7 июн 2019.

  1. kirilikyzzz

    kirilikyzzz Нуб

    Был сделан прибор для общения и обучения слепо-глухонимых. Состоит из обычной клавиатуры PS/2, LCD 1602, самодельной клавиатуры на 7 кнопок(подключенных через i2c), тактильного дисплея(представляет собой устройство из 6 пар катушек, 6 ВЧ диодами, соединённых параллельно каждой паре катушек и 6 поднимаемыми ими штырей) и платы с ардуиной во главе. Фото ниже. В последствии экран и клавиатура ps/2 были подключены через PS/2 разъемы, а не через обычные штырьевые, но сути это не меняет. Питание системы осуществляется через DC-DC преобразователь. Первая линия питания с неизмененными 9 вольтами с DC-DC идут на каскад транзисторов, включенных в режиме ключа, и питают тактильный дисплей. Вторая линия идет на Arduino где стабилизируется до 5 вольт и питает оставшиеся компанеты.

    Код писался и адаптировался соответственно из разных частей непроффесионалами, пожелания по улучшению принимаются. Есть 2 версии, с массивами и без. Тут привожу с массивами. Без в ссылке ниже.

    Работает все так. Человек пишет на клавиатуре ps/2, текст выводится побуквено на тактильный дисплей и полностью на ЛСД экран. Тоже самое в обратном направлении. Слепо-глухонемой человек набирает на своей клавиатуре текст и он выводится на тактильный дисплей(Для проверки написанного) и на ЛСД экран.

    И вот какая проблема. Без тактильного дисплея все работает стабильно и быстро. Набираешь текст на одной из клавиатур и он тут же выводится на экран. Но. Как только подключаешь тактильный дисплей начинаются проблемы с клавиатурой PS/2. Вместо нужных букв выводятся другие, клавиатура не реагирует на нажатия, происходят зависания. При этом с самоделкой на 7 кнопок все хорошо, все буквы четко и правильно выводятся.

    Сначала грешили на питание, но просадок и проблем не нашли. Возможно код? Без массивов работа чуть лучше, но проблема не исчезает, да и почему тогда без тактильного дисплея все работает отлично? В общем мы пока в тупике. То ли клавиатура отказывается в паре робить, то ли катушки поле создают и все ломают и необходимо все экранировать дополнительно. Уповаем на мудрые советы форумчан. Надеюсь проблема понятна.

    Видео с примером проблемной работы
    https://vk.com/im?sel=152090993&z=video152090993_456239092/137ce12a044bec08bb
    Видео с нормальной работой без тактильного дисплея
    https://vk.com/im?sel=152090993&z=video152090993_456239093/c6eca5f6ddd84a1202
    Ссылка на вторую версию кода без массивов.
    https://yadi.sk/d/15MImTH5sCboKw

    Код (C++):
    #include <LCD_1602_RUS.h>
    #include <PS2Keyboard.h>
    #include <Wire.h>
    #include <LCD_1602_RUS.h>
    #define ADDR_KBRD 0x27

    LCD_1602_RUS lcd(0x3F,16,2);

    const int DataPin = 2;
    const int IRQpin =  3;
    int i;
    int j;
    int pins[6] = {4, 5, 6, 7, 8, 9};

    String str;
    byte dio_in;
    bool b;
    bool key[7];

    PS2Keyboard keyboard;
    int bCount = 0;

    String LCD_array[33] = {"А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П",
    "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я"};

    String S7_keyboard[33] = {"115", "113", "5", "65", "67", "83", "51", "69", "18", "101", "32", "114", "112", "98",
    "66", "82", "96", "80", "100", "68", "50", "97", "81", "99", "64", "19", "34", "16", "36", "4", "37", "17", "33"};

    int PS_keyboard[33] = {102, 44, 100, 117, 108, 116, 96, 59, 112, 98, 113, 114, 107, 118, 121, 106,
    103, 104, 99, 110, 101, 97, 91, 119, 120, 105, 111, 93, 115, 109, 39, 46, 122};

    byte Taktor_array[33] = {B00000001, B00000011, B00111010, B00011011, B00011001, B00010001, B00100001, B00011010, B00110101,
    B00001010, B00101111, B00000101, B00000111, B00001101, B00011101, B00010101, B00001111, B00010111, B00001110, B00011110,
    B00100101, B00001011, B00010011, B00001001, B00011111, B00110001, B00101101, B00110111, B00101110, B00111110, B00101010, B00110011, B00101011};

    void setup() {

      lcd.init();                  // Инициализация экрана
      lcd.backlight();             // Включаем подсветку

    Wire.begin();
    Wire.beginTransmission(ADDR_KBRD);
    Wire.endTransmission();
     
      delay(1000);
      keyboard.begin(DataPin, IRQpin);
      Serial.begin(9600);
      Serial.println("Keyboard Test:");
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
      pinMode(7, OUTPUT);
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
    }
     
    void loop() {
      if (keyboard.available()) {
        char c = keyboard.read();
        if (c == PS2_ENTER) {
          Serial.println();
          lcd.setCursor( 15, 0);
           lcd.print("-");
             lcd.setCursor( 0, 1);
        } else if (c == PS2_TAB) {
                 digitalWrite(pins[0],  LOW);
                 digitalWrite(pins[1],  LOW);
                 digitalWrite(pins[2],  HIGH);
                 digitalWrite(pins[3],  HIGH);
                 digitalWrite(pins[4],  HIGH);
                 digitalWrite(pins[5],  HIGH);
                  lcd.print("=");
        } else if (c == PS2_ESC) {
          Serial.print("[ESC]");
        } else if (c == PS2_PAGEDOWN) {
          Serial.print("[PgDn]");
        } else if (c == PS2_PAGEUP) {
          Serial.print("[PgUp]");
        } else if (c == PS2_LEFTARROW) {
          Serial.print("[Left]");
        } else if (c == PS2_RIGHTARROW) {
          Serial.print("[Right]");
        } else if (c == PS2_UPARROW) {
          Serial.print("[Up]");
        } else if (c == PS2_DOWNARROW) {
          Serial.print("[Down]");
        } else if (c == PS2_DELETE) {
               lcd.clear();
                lcd.setCursor( 0, 0);
        } else         if (c == 32)
               {
                 digitalWrite(pins[0],  LOW);
                 digitalWrite(pins[1],  LOW);
                 digitalWrite(pins[2],  LOW);
                 digitalWrite(pins[3],  LOW);
                 digitalWrite(pins[4],  LOW);
                 digitalWrite(pins[5],  LOW);
                  lcd.print(" ");}
          for (int i=0; i<33; i++)
          {
            if (c == PS_keyboard[i])
      {
      lcd.print(LCD_array[i]);
        for (int j=0; j<6; j++)
      {
      Serial.print(bitRead(Taktor_array[i], j));
      digitalWrite(pins[j], bitRead(Taktor_array[i], j));
                      }
               }
          }
      }

    Wire.requestFrom(ADDR_KBRD,1);
    while (!Wire.available());
    byte dio_in = Wire.read(); //читаем состояние портов PCF8574P

    str=String(dio_in, DEC);
    //Serial.println(str);
      for (int i=0; i<33; i++)
      {  
        if (str == S7_keyboard[i])
      {
      lcd.print(LCD_array[i]);
          delay(500);
      for (int j=0; j<6; j++)
      {
                                                              // Serial.print(bitRead(Taktor_array[i], j));
      digitalWrite(pins[j], bitRead(Taktor_array[i], j));
      }
       }  
    }
    }
     

    Вложения:

  2. b707

    b707 Гуру

    kirilikyzzz - да как же этому коду работать, если у вас при считывании данных с I2C клавиатуры после каждого считанного символа задержка полсекунды? конечно оно будет постоянно тормозить и зависать
    Я не вполне понимаю, как у вас эта тактильная клавиатура устроена и зачем там задержка. Попробуйте ее либо убрать совсем, либо уменьшить, скажем. до 20-50 мс (речь о строке delay(500) примерно десятая строка от конца кода
     
    Daniil и BAR__MEN нравится это.
  3. Daniil

    Daniil Гуру

    Да, когда объединяете много устройств delay опасен в неумелых руках - в setup еще простительно, эта процедура выполняется 1 раз при включении, а вот в loop появляются проблемы.
    А while (!Wire.available()); тоже может повесить программу - отвиснет только при нажатии. Нужно понять логику, чего вы тут хотите сделать.
    Видео в вк, судя по всему, ограничено в доступе - не посмотреть.
     
  4. kirilikyzzz

    kirilikyzzz Нуб

    Видео загрузил на Диск, теперь должно работать
    Неправильная работа: https://yadi.sk/i/NCtnoAsrP11WGw
    Нормальная работа без тактора: https://yadi.sk/i/e9pLnAeGAGZIUA

    while (!Wire.available()); Используеться только потому, что это единственный способ(который нашли), чтобы подключить самодельную 7ми символьную клавиатуру. Других не знаем к сожалению.

    Логика проста. Обычный человек набирает текст на PS/2, команды передается в ардуину и от туда на ЛСД экран и тактильный дисплей и тоже самое наоборот. Тактильный дисплей односимвольный, поэтому выглядит так. Человек нажал кнопку на клавиатуре, этаже буква вывелась на тактильный дисплей и на экран, нажал следующую, на тактильном дисплее поднялась другая буква, а лсд записалась в следующую позицию, пока не заполняться обе строки. Надеюсь на видео будет понятно.

    С делеем мы пробовали разные варианты, и убирали и добавляли. Не сказал бы что есть какие то ощутимые изменения.
     
  5. kirilikyzzz

    kirilikyzzz Нуб

    Эта задержка введена специально. Из за особенности работы клавиатуры для слепого. Ардуина постоянно считывает её состояние, то есть в порт постоянно приходит её состояние, наверно раз 5-10 в секунду. Дело в том, что слепо-глухонемой, набирает на 6 верхних кнопках определенную комбинацию и нижней клавишей подтвержлает её отправку. Если делей слишком маленький, ниже 200 точно, то при удержании кнопки отправки чуть дольше, вместо 1 буквы, вылетает сразу 2-6 на лсд, в зависимости от долготы нажатия. т.к. ардуина все время считывает состояние и очень быстро. Как вариант замедлить это считывание, но как я не знаю. Надеюсь понятно объяснил.
     
  6. Daniil

    Daniil Гуру

    Я вижу 2 варианта:
    1. Если не хочется думать над кодом, то взять 2ую ардуинку, обмениваться буквами с 1ой по uart. 2ая будет работать "глупо" с задержками только с тактором.
    2. Подумать над кодом. Заходить в обработку трактора не по while (в данном случае этот вайл вам стопорит выполнения кода), а через if.
    Если что-то есть, то обработать.
    + delay тут вводит тупую задержку, она не помогает ничем. Т.к. пользователь нажал кнопку, while сработал и всё. Больше данные не считываются/проверяются/обрабатываются.