Добавить какой-то свой хитрый режим стимуляции непосредственно в 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(); } } }
Комментарии приветствуются…