Управление «E-stim 2B» с помощью «Arduino UNO»

Добавить какой-то свой хитрый режим стимуляции непосредственно в E-Stim 2B нельзя, но используя Arduino это ограничение можно обойти. В E-Stim 2B предусмотрена возможность управления командами извне, и не важно откуда команды исходят, от подключённого через интерфейсный кабель компьютера или присоединенной платы Arduino. В статье приводится полноценный ардуиновский скетч «модифицирующий» встроенный в стимулятор режим «Step».

В E-Stim 2B в режиме стимуляции Step уровень стимуляции нарастает постепенно до значения (границы), установленного ручкой настройки (условно «громкость»), после чего стимуляция спадает до нуля и процесс плавного нарастания повторяется вновь.

Внешний вид E-stim 2B
Внешний вид E-stim 2B

К недостаткам режима Step можно отнести то, что через несколько циклов нервы привыкают к установленному уровню стимуляции и требуется поднятие границы. Установить новый уровень, до которого будет нарастать стимуляция, можно только ручкой настройки, автоматический сдвиг верхней границы с течением времени в режиме Step не предусмотрен.

Power Level стимулятора установлен в H
Power Level стимулятора установлен в H

При подключении Arduino с предлагаемый скетчем к E-Stim 2B, произойдёт автоматическая установка настройки Power Level в H, выберется режим Step, опция Pulse Feel будет установлена на 65 единиц.

Стимулятор в режиме Step, Pulse Feel - 65
Стимулятор в режиме Step, Pulse Feel — 65

Теперь, если повернуть «громкость» стимуляции канала A хотя бы на 1%, начнется автоматическое увеличение «громкости» — верхней границы, до которой плавно нарастает стимуляция. Причём, чем больше текущее значение «громкости», тем медленнее будет двигаться граница. Граница отодвигается всегда с шагом 1, только временной промежуток будет увеличиваться.

Плата Arduino UNO и разъём mini-jack TRS 3,5 мм
Плата Arduino UNO и разъём mini-jack TRS 3,5 мм

Подключается Arduino UNO к стимулятору через разъём джек (mini-jack TRS 3,5 мм). Распайка разъёма джек с цветными проводами приводится в статье «Интерфейсный кабель для «E-Stim 2B» из конвертера UART USB-TTL с AliExpress». Желтый провод (Ring у джека) надо соединить с пином — 0, оранжевый (Tip у джека) – с пином 1, чёрный (Sleeve у джека) – с GND платы Arduino UNO.

Скачать скетч полностью можно внизу этого поста.

Если не понятно, что делается в скетче, то отсылаю к статьям:

Теперь некоторые пояснения к назначению процедур скетча.

Процедура SendCommand служит для посыла в E-Stim 2B команды. Каждая отправка команды сопровождается морганием встроенного в плату Arduino UNO светодиода. После отправки команды, ожидается ответ от прибора E-Stim 2B. Если вдруг прибор не ответил на поданную команду (например был случайно выдернут соединительный кабель), то светодиод останется зажжённым сигнализируя об ошибке.


void  SendCommand(String S) {

  digitalWrite(LED_BUILTIN, HIGH); //Зажигаем светодиод
  
  while (Serial.available()) Serial.read(); //Очищаем буфер порта
  
  Serial.print(S); //Отправляем команду
  Serial.print("\r"); //CR - возврат каретки
  
  delay(50); //Ждем для стабильности. Минимум 20.

  EStimRead(); //Считываем и парсим ответ на команду.

  if ( EStimERR == false){ // Если нет ошибки, то
      digitalWrite(LED_BUILTIN, LOW); //гасим светодиод
  }
  
}

Процедура EStimRead получает ответ от E-Stim 2B и разбирает его на составные части. Ответ состоит из девяти элементов, отделяемых двоеточием. Завершается ответ символом переноса строки. Если ответ не соответствует формату, то EStimRead выставит флаг ошибки EStimERR.


void EStimRead() {

    String S = "";
    
    int charCount = 0; //Счетчик символов в блоке
    int blockCount = 0; //Счетчик блоков данных

    EStimERR = false; //Флаг ошибки получения данных с EStim
    
    while (Serial.available() ) {
      char inByte = Serial.read(); //Считанный символ (один байт)
    
      if ( (inByte == 58) or (inByte == 10) ) { //58 - двоеточие,
                               //10 - перенос строки LF (признак конца)
          blockCount++;

          if ( blockCount > 9 ){ //Если слишком много разделяющих
                                        // двоеточий (блоков)
            break; //значит ошибка, выходим из цикла
          }
          
          EStimReadVar(S, blockCount);
          S = "";
          charCount = 0;   
          
      } else {
          
          charCount++;

          if ( charCount > 5 ){ //Может быть не больше 5 символов в блоке
            EStimERR = true;
            break; //иначе ошибка, выходим из цикла
          }

          S = S + inByte;  
      }
      
    }

    if ( blockCount < 9 ){ // Должно быть 9 блоков
      EStimERR = true;
    }
}

Процедура EStimReadVar вспомогательная, используется в EStimRead. EStimReadVar заполняет соответствующие глобальные переменные данными из полученного ответа.

void EStimReadVar(String &S, int &blockCount) { 

  switch (blockCount) {
  case 1:
      POW = S.toInt();
      break;
  case 2:
      A = S.toInt() / 2;
      break;
  case 3:
      B = S.toInt() / 2;
      break;
  case 4:
      C = S.toInt() / 2;
      break;
  case 5:
      D = S.toInt() / 2;
      break;
  case 6:
      M = S.toInt();
      break;
  case 7:
      U = S;
      break;
  case 8:
      N = S.toInt();
      break;
  case 9:
      VER = S;
      break;
  }

}

Процедура Timer проверяет пора ли сдвигать границу, и если пора, то сдвигает её на 1.

void Timer() { 

  if( millis()-time > SetTime) // Проверка таймера
  {
    
    if ( EStimERR == false ){ // Если нет ошибки, то 
                                 // увеличиваем текущий уровень
      int i = A + 1;
      String S = "A" + String(i);

      SendCommand(S);
      
      time = millis();
    }
    
  }

}

Скачать скетч для Arduino UNO

Комментарии приветствуются…

Добавить комментарий

Все поля обязательны к заполнению. Ваш e-mail не будет опубликован