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

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

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

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

Подключается 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();
}
}
}
Комментарии приветствуются…