ARDUINO [Модуль оперантного обусловливание - научный проект] робота с LCD и СОМ

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Здравствуйте уважаемые радиолюбители/программисты/инженеры и прочие знатоки темы ардуино. Мы небольшая команда молодых ученых которые работают в области науки о поведение. На данный момент работаем с модуль оперантного обусловливание (это так называемый "Ящик Скиннера", изображение в спойлере).

Полностью разработали код для работы данного устройства, но возникли ряд проблем, а точней:
в устройства есть 7 разных програм, которые запускаються через монитор сом порта и все бы нечего, но данные которые приходят нам, есть в двох форматах (те, которые отображаться в числовых значениях и те, которые в графике). Мы не можем использовать все время мониторинг сом порта ардуино, а для использование специальных програм, необходимо что бы команды посылались тогда через LCD. И это проблема. Не могу найти необходимые примеры, где можно назначить значение посылающие в сом порт к LCD. Увы нету достаточной компетенции в решение данной проблемы.

Вот ниже последняя часть кода, которая отвечает за запуск заданных програм. Вопрос, как сделать что бы данные команды (от 0 до 7) можно было отравить через LCD ?
Буду очень благодарный за помощь (если решение потребует серьезной работы, можем даже оплатить).

C++:
void loop()
{
  if (Serial.available())
  {
    char x = Serial.read();
    int expe = (x - '0');
    if (expe == 0)
    {
      Serial.println("Not yet launched");
    }
    else if (expe == 1)
    {
      Serial << "Training Start:" << "\t" << millis() << "\t" << "100% probability [Training]" << endl;
      train();
    }
    else if (expe == 2) {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " ALL [100%] " << endl;
      restExt(ALL);
    }
    else if (expe == 3)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " FR2" << endl;
      restExt(FR2);
    }
    else if (expe == 4)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FR4" << endl;
      restExt(FR4);
    }
    else if (expe == 5)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "VR" << endl;
      restExt(VR);
    }
    else if (expe == 6)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FI 2 min" << endl;
      FI1(FI);
    }
    else if (expe == 7)
    {
      Serial << "Progressive Ratio" << "\t" << millis() << "\t" << "Ratio" << "\t" << ratio << endl;
      progRat(ratio);
    }
    else
    {
      Serial << "The value " << expe << " is incorrect" << endl;
      // Serial.end ();
    }
  }
}
 
Изменено:
  • Лойс +1
Реакции: chelovek

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,004
406
Москва
wan-derer.ru
@Sudama, LCD это обычно дисплей, т.е. устройство вывода. Непонятно как ты собираешься вводить данные через дисплей.
 
  • Лойс +1
Реакции: chelovek

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Группа молодых учёных или из за рубежа.
Или нам фуфло вешают.
Такое знание Русского языка можно простить только зарубежным молодым учёным, но никак не из России.
Я приношу извинение, так как мы не из России (Прибалтика-Украина), приоритетный язык для работы - исключительно английский.



@Sudama, LCD это обычно дисплей, т.е. устройство вывода. Непонятно как ты собираешься вводить данные через дисплей.
Скорее всего некоректно объяснил. Можно ли привязать кнопки ( к значению которое отправляется на СОМ) с выводом информации на LCD ?
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
Можно ли привязать кнопки ( к значению которое отправляется на СОМ) с выводом информации на LCD ?
Можно всё, практически.
Пока я не совсем понимаю идею. Нужно как то попонятнее.
А там помочь может сможем.
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,695
472
Вот и мне непонятно. При чём тут com? И LCD? Это что, розыгрыш такой? Так неудачно, уважаемые, неудачно.
 

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Учёные, блин. Как же нужно себя любить, чтоб так называть. И никак иначе. Несколько нескромно, не считаете?
Я не знаю почему это так тригерно для Вас, но увы ученый в любой в сфере исследование - это тот, кто заниматься эмпирическими (не всегда, но зачастую) исследованиям, пишет научные публикации и решает поставленные задачи (или получает совершенно новые данные) в ходе исследование на базе академ структуры. Возможно из-за разницы контекста где применяться подобное слово, существует представление, что ученый - это какой то професор или тому подобное, но это не совсем так. Зачастую даже аспиранты (иногда даже студенты) которые работают исключительно с научными методами - уже ученые. Возможно в Росси или где то еще это не так (хотя я сомневаюсь).


@Sudama, Я ж говорю: тач-скрин удобно наверное будет вам https://yadi.sk/i/g4NekSudRbW7VQ
Большое спасибо, попытаюсь разобраться.


Можно всё, практически.
Пока я не совсем понимаю идею. Нужно как то попонятнее.
А там помочь может сможем.
Модуль оперантного обусловливания предназначен для фиксации шейпинга поведения (обусловливанияи поведения). Сам модуль имеет 7 программ. Каждая программа - это целый режим, в котором крыса нажимает на рычаг определенное количество раз, после чего получает корм. Вариация нажима-получения корма отличается от самой программы.

Ниже приведен фрагмент кода который отвечает за программу (несколько из них):
C++:
int ALL[] = {
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
int FR2[] = {
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
};
int FR4[] = {
  0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1
};
int VR [] = {
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
};

int trial00[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}

void setup()

void exeBlockRE(int lista[])
{
  trial = 0;
  Serial << "bloque" << "\t" << "trial"  << "\t" << "PalancaPress" << "\t" << "PalancaRelease" << "\t" << "rewardState" << "\t" << "rewStart" << "\t" << "rewEnd" << "\t" << "trialEnd" << endl;
  while (trial < 40)
  {
    reward = lista[trial];
    digitalWrite(ledPin1, HIGH);
    if (digitalRead(manualDeliveryPin) != 1)
    {
      palancaPress = millis();
      while (digitalRead(manualDeliveryPin) == 0)
      {
        delay(6);
      }
      palancaRelease = millis();
      if (reward == 1)
      {
        servo.write(servoServe);
        rewStart = millis();
        delay(500);
        servo.write(servoRest);
        rewEnd = millis();
        digitalWrite(ledPin2, HIGH);
        delay(2000);
        digitalWrite(ledPin2, LOW);
      }
      else if (reward == 0)
      {
        rewStart = millis();
        delay(500);
        rewEnd = millis();
      }
    
      trialEnd = millis();
      Serial << bloque << "\t" << trial + 1  << "\t" << palancaPress << "\t" << palancaRelease << "\t" << reward << "\t" << rewStart << "\t" << rewEnd << "\t" << trialEnd << endl;
      trial++;
      reward = lista[trial];
    }
  }
  Serial << "End of Block" << endl;
  digitalWrite(ledPin1, LOW);
  luceo();
}
Каждая программа имеет свое значение от 0 до 7. Чтобы запустить программу эксперимента нужно ввести (отправить) это значение в COM. Нам нужно привязать кнопки к этим значениям. То есть чтобы при нажиме кнопки отправляли команды на com порт без ручного ввода через терминалы
C++:
void loop()
{
  if (Serial.available())
  {
    char x = Serial.read();
    int expe = (x - '0');
    if (expe == 0)
    {
      Serial.println("Not yet launched");
    }
    else if (expe == 1)
    {
      Serial << "Training Start:" << "\t" << millis() << "\t" << "100% probability [Training]" << endl;
      train();
    }
    else if (expe == 2) {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " ALL [100%] " << endl;
      restExt(ALL);
    }
    else if (expe == 3)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " FR2" << endl;
      restExt(FR2);
    }
    else if (expe == 4)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FR4" << endl;
      restExt(FR4);
    }
    else if (expe == 5)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "VR" << endl;
      restExt(VR);
    }
    else if (expe == 6)
    {
      Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FI 2 min" << endl;
      FI1(FI);
    }
    else if (expe == 7)
    {
      Serial << "Progressive Ratio" << "\t" << millis() << "\t" << "Ratio" << "\t" << ratio << endl;
      progRat(ratio);
    }
    else
    {
      Serial << "The value " << expe << " is incorrect" << endl;
      // Serial.end ();
    }
  }
}
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
@Sudama, Т.е. Вам нужна железка. В которой можно задать программу командой по COM порту или нажав нужную кнопку?
Зачем LCD? Отображать номер программы? Для такого устройства LCD наверное лишнего будет.
Достаточно или один семисегментный индикатор или 10 светодиодов.
 
  • Лойс +1
Реакции: Sudama

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Если я правильно понял им нужно заменить подключение по ком порту к компу на что то, что могло бы выдавать 10 команд и как то показывать какая команда выполняется.
 
  • Лойс +1
Реакции: Sudama

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Если я правильно понял им нужно заменить подключение по ком порту к компу на что то, что могло бы выдавать 10 команд и как то показывать какая команда выполняется.
Именно, вот написали код, но пока что не работает коректно.

C++:
const int buttonPinNext = 2;     // Кнопка для перехода к следующей команды
const int buttonPinPrev = 3;    // Кнопка для перехода к предыдущей команды
const int buttonPinSelect = 4;      // Кнопка для выбора нынешней команды

const char chars[] = {'0','1','2','3','4','5','6','7'};// индекс команд


void setup()

 lcd.init();
  lcd.backlight();

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Select command:");
  lcd.setCursor(0, 1);
  lcd.print("0");
 
 
 
  Serial.begin(9600);

  pinMode(buttonPinNext, INPUT);
  pinMode(buttonPinPrev, INPUT);
  pinMode(buttonPinSelect, INPUT);
  charsSize = sizeof(chars);


void loop() {
  buttonStateNext = digitalRead(buttonPinNext);
  buttonStatePrev = digitalRead(buttonPinPrev);
  buttonStateSelect = digitalRead(buttonPinSelect);
 
  //next char
  if (buttonStateNext == HIGH) {
    charindex++;
    if(charindex == charsSize){
      charindex = 0;
    }
    // change char
    lcd.print(chars[charindex]);
    lcd.setCursor(0, 1);
    
  }
 
  //Move to prev char
  if (buttonStatePrev == HIGH) {
     charindex--;
    if(charindex < 0){
      charindex = charsSize-1;
    }
    // change char
    lcd.print(chars[charindex]);
    lcd.setCursor(0, 1);
  }
 
 
  //select
  if (buttonStateSelect == HIGH) {
    
    int expe = (chars[charindex] - '0');
    
    switch(expe){
      
      case 0:
        Serial.println("Not yet launched");
        break;
        
      case 1:
        Serial << "Training Start:" << "\t" << millis() << "\t" << "100% probability [Training]" << endl;
        train();
        break;
        
      case 2:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " ALL [100%] " << endl;
        restExt(ALL);
        break;
        
      case 3:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " FR2" << endl;
        restExt(FR2);
      
        break;
      case 4:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FR4" << endl;
        restExt(FR4);
        break;
        
      case 5:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "VR" << endl;
        restExt(VR);
        break;
        
      case 6:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FI 2 min" << endl;
        FI1(FI);
        break;
        
      case 7:
        Serial << "Progressive Ratio" << "\t" << millis() << "\t" << "Ratio" << "\t" << ratio << endl;
        progRat(ratio);
        break;
      
    }
     default {
      Serial << "The value " << expe << " is incorrect" << endl;
      // Serial.end ();
    }
    
  }
  delay(170);
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
@Sudama,
Ну кнопки так не работают как написано...

Берем средне загруженную ардуину и полчим 50к циклов в секунду. Быстрое нажатие на кнопку будет 0.2 секунды,значит за одно нажатие при таком раскладе переменная следующего шага может увеличиться на 10 000, а не на 1.

А можно вопрос, кто писал код?
 
  • Лойс +1
Реакции: Sudama

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Еще немного покопались в коде и все вроде работает. Но есть одно но. Сам пин срабатывает как кнопка, когда в нем просто контакт (без соединения), когда подключена кнопка, она тоже автоматически срабатывает.

C++:
const int buttonPinNext = 2;     
const int buttonPinPrev = 3;     
const int buttonPinSelect = 4; 


// initialize the pushbutton pin as an input:
  pinMode(buttonPinNext, INPUT);
  pinMode(buttonPinPrev, INPUT);
  pinMode(buttonPinSelect, INPUT);
 
   digitalRead(buttonPinNex,LOW);
   digitalWrite(buttonPinPrev, LOW);
   digitalWrite(buttonPinSelec, LOW);

C++:
void loop() {
  buttonStateNext = digitalRead(buttonPinNext);
  buttonStatePrev = digitalRead(buttonPinPrev);
  buttonStateSelect = digitalRead(buttonPinSelect);
 
  Serial << "buttonStateNext:" << "\t" << buttonStateNext << endl;
  Serial << "buttonStatePrev:" << "\t" << buttonStatePrev << endl;
  Serial << "buttonStateSelect:" << "\t" << buttonStateSelect << endl;
 
 
  //next char
  if (buttonStateNext == HIGH) {
    charindex++;
    if(charindex == charsSize){
      charindex = 0;
    }
    // change char
    lcd.print(chars[charindex]);
    lcd.setCursor(0, 1);
    
  }
 
  //Move to prev char
  if (buttonStatePrev == HIGH) {
     charindex--;
    if(charindex < 0){
      charindex = charsSize-1;
    }
    // change char
    lcd.print(chars[charindex]);
    lcd.setCursor(0, 1);
  }
 
 
  //select
  if (buttonStateSelect == HIGH) {
    
    int expe = (chars[charindex] - '0');
    
    switch(expe){
      
      case 0:
        Serial.println("Not yet launched");
        break;
        
      case 1:
        Serial << "Training Start:" << "\t" << millis() << "\t" << "100% probability [Training]" << endl;
        train();
        break;
        
      case 2:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " ALL [100%] " << endl;
        restExt(ALL);
        break;
        
      case 3:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << " FR2" << endl;
        restExt(FR2);
      
        break;
      case 4:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FR4" << endl;
        restExt(FR4);
        break;
        
      case 5:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "VR" << endl;
        restExt(VR);
        break;
        
      case 6:
        Serial << "Resistance to Extintion Start:" << "\t" << millis() << "\t" << "FI 2 min" << endl;
        FI1(FI);
        break;
        
      case 7:
        Serial << "Progressive Ratio" << "\t" << millis() << "\t" << "Ratio" << "\t" << ratio << endl;
        progRat(ratio);
        break;
      
      default:
        Serial << "The value " << expe << " is incorrect" << endl;
        // Serial.end ();
        break;
    
    }
  }
 
  delay(1500);
 
 
}
Вот значение без любого подключение к пинам кнопки:

1596388814622.png


А вот значение когда в пин под номером 4 вставлен контакт (не кнопка):
1596388915153.png
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
Вам уже писали, что так не делается. Но Вы гнёте свою линию.
Вам написали в личку, с чего нужно начать.
Вы не слушаете. С такими людьми я не работаю. Вы из тех, что ставят лошадь позади телеги.
Так что прощайте.
 
  • Лойс +1
Реакции: Sudama и PiratFox

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
Вам уже писали, что так не делается. Но Вы гнёте свою линию.
Вам написали в личку, с чего нужно начать.
Вы не слушаете. С такими людьми я не работаю. Вы из тех, что ставят лошадь позади телеги.
Так что прощайте.
Да большое спасибо за помощь, но решение найдено.
Второй абзац в данном описание и был нашей ошибкою. Именно Ваш совет сделать схему как раз и помог. Подвели 3 резистора по 10кОМ и все работает нормально.

1596407163160.png
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630
@Sudama, на будущее - дискретные кнопки лучше делать с обратной логикой, то есть не подавать на них +vcc через кнопку, а наоборот - прижимать кнопкой вход на землю.
Соответственно setup будет выглядеть так
C++:
const int buttonPinNext = 2;    
const int buttonPinPrev = 3;    
const int buttonPinSelect = 4;


// initialize the pushbutton pin as an input:
  pinMode(buttonPinNext, PULLUP_INPUT);
  pinMode(buttonPinPrev, PULLUP_INPUT);
  pinMode(buttonPinSelect, PULL_INPUT);
Ну и соответственно читать нужно состояние пина LOW, а не HIGH.
Это и схему упрощает, резисторы не нужны, и помехозащищённость выше.
 
  • Лойс +1
Реакции: Sudama и b707_2

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,265
944
58
Марий-Эл
Это и схему упрощает, резисторы не нужны, и помехозащищённость выше.
Резисторы нужны по любому. Те, что на кристалле могут иметь сопротивление от 20 до 50 КОм. А это очень много.
Чаще всего глюки с кнопками из за пренебрежения этим правилом.
 
  • Лойс +1
Реакции: Sudama

Sudama

✩✩✩✩✩✩✩
2 Авг 2020
7
1
t.me
@Sudama, на будущее - дискретные кнопки лучше делать с обратной логикой, то есть не подавать на них +vcc через кнопку, а наоборот - прижимать кнопкой вход на землю.
Соответственно setup будет выглядеть так
C++:
const int buttonPinNext = 2;   
const int buttonPinPrev = 3;   
const int buttonPinSelect = 4;


// initialize the pushbutton pin as an input:
  pinMode(buttonPinNext, PULLUP_INPUT);
  pinMode(buttonPinPrev, PULLUP_INPUT);
  pinMode(buttonPinSelect, PULL_INPUT);
Ну и соответственно читать нужно состояние пина LOW, а не HIGH.
Это и схему упрощает, резисторы не нужны, и помехозащищённость выше.
Большое спасибо,
kostyamat и Эдуард Анисимов, ваши советы полностью решили проблему, все работает коректно.