Arduino TDCS Super Simples. Transcranial Direct Current Stimulator (tDCS) DIY

About: Estudante de Ciência da Computação na Univap | Portfólio: https://github.com/MateusAquino/

Para fazer este tDCS você precisará apenas de um arduino, resistor, capacitor e alguns cabos

Componentes

  1. Arduino
    • Pino D13 como saída PWM (pode ser alterado).
    • Pino A0 como entrada analógica (para feedback de corrente).
    • Pino GND apenas para GND.
  2. Resistor (~470 Ω, mas provavelmente entre 300-1000 Ω funciona, você precisará alterar no código fonte)
  3. Capacitor (220 μF). Serve para estabilizar os pulsos do PWM.
  4. Eletrodos de Esponja (Use água salina para molhá-lo).

Como funciona

O Arduino calcula a corrente padrão (pode ser alterado) que passará pelo seu cérebro apenas por mudar a voltagem de saída. Você também pode alterar o valor do target_mA pelo serial CLI (Console).

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Saiba Mais

Você deve ler mais sobre tDCS primeiro. Não é aprovado pelo FDA e pode ser prejudicial a sua saúde, principalmente se você não sabe nada sobre os efeitos colaterais, precauções e dentre outros...

Step 2: Monte O Circuito Abaixo

Não se esqueça das esponjas com água salina!

Step 3: Instale O Código No Seu Arduino

Lembre-se de alterar as configurações e parametros na área de HARDWARE PARAMS e CONFIGURABLE PARAMS.

Você também deve alterar o boud rate do Serial para: 115200 para poder ver o resultado.

Para executar comandos, troque o No Line Ending para Carriage Return.

O código fonte + tutorial também podem ser encontrados no repositório: https://github.com/MateusAquino/tDCS_arduino_simplest

Código:

const String ver = "2.0m";
//HARDWARE PARAMS const int analogInPin = A0; // Entrada do Analógico const int analogOutPin = 13; // Saida D13 padrão float maxOutV = 5.0; // A voltagem de saída PWM padrão do Arduino [V] float maxRefInV = 1.1; // Referencia à voltagem analógica [V] float R = 470.0; // Resistencia da corrente [Ohm]

//CONFIGURABLE PARAMS bool plotter = false; // Defina: true, caso esteja usando o Serial plotter bool putty = false; // Defina: true, caso esteja usando o PuTTT (pode ser alterado no CLI) int maxmin = 30; // Tempo (em minutos) necessário para desligar [Min] float target_mA = 2.73; // Essa é a corrente que passará pelo seu cérebro!!! [mA] float epsilon_mA = 0.03; // Diferença máxima entre a corrente real e o target_mA (Não altere caso não saiba o que está fazendo!)

//INIT GLOBALS int state = 1; /* -1 - Cérebro não identificado 0 - Voltagem sendo alterada para definir a corrente padrão 1 - Tudo certo. Você esta na corrente definida -10 - Voltagem desligada */ float outV = maxOutV; // Voltagem int debounced_state = 0; int zeros_len = 0; float smoothed_mA=0;

String commandString = ""; //for CLI

//FEEDBACK HELPERS float computeOutVoltage(float V, float new_mA){ if(abs(new_mA-target_mA)maxOutV){ state = -1; // resistência muito alta -> cérebro não encontrado? return maxOutV; //return maxOutV/5.0; // para segurança } state = 0; return 0.1*new_V+0.9*V; //return new_V; }

int convertVtoOutputValue(float V){ return constrain(int(V/maxOutV*255), 0, 255); }

float sensorValue2mA(int sensorValue){ float sensorVoltage = sensorValue/1023.0*maxRefInV; float sensor_mA = sensorVoltage/R*1000.0; return sensor_mA; }

int debounced_state_compute(int state){ if(state < 0) { zeros_len = 0; return state; } if(state == 1){ zeros_len = 0; return 1; } if(debounced_state == 0){ return 0; } if(state == 0){ zeros_len++; if(zeros_len>5) return 0; } return 1; }

unsigned long start, endc; void process_feedback(){ int sensorValue = analogRead(analogInPin); float new_mA = sensorValue2mA(sensorValue); smoothed_mA = 0.2*new_mA+0.8*smoothed_mA; float V = outV; outV = computeOutVoltage(V, new_mA); analogWrite(analogOutPin, convertVtoOutputValue(outV)); debounced_state = debounced_state_compute(state); // Exibir informações no CLI endc = (millis()-start)/1000; String tv = "[", ttm = "mA/", tsm = "V, ", ts = "mA] | Estado: ", h = " | Tempo: ", s = ":", leadM = "", leadS = "", plotT = "Target: ", plotmA = "\tSmoothed MA: ", plotMin = "\tMin: ", tempo; unsigned long tmin = endc/60-((endc/60)%1); // Formatação if (endc%60<10) leadS = "0"; if (tmin<10) leadM = "0"; if (endc%60==0) tempo = leadM + tmin + s + "00 "; else tempo = leadM + tmin + s + leadS + endc%60 + " "; if (debounced_state>=0) ts = ts + "+"; // Parar automaticamente if (tmin>maxmin) stop_device(); String txt; if (plotter) txt = plotT + target_mA + plotMin + "0" + plotmA + smoothed_mA; else txt = tv + V + tsm + smoothed_mA + ttm + target_mA + ts + debounced_state + h + tempo; if (putty) Serial.print("\r\e[?25l" + txt); else Serial.println(txt);

// wait 2 milliseconds before the next loop // for the analog-to-digital converter to settle // after the last reading: delay(5); }

void stop_device(){ state = -10; analogWrite(analogOutPin, 0); clearAndHome(); Serial.println("Sessão tDCS interrompida"); Serial.println("------------------------"); help(); }

//CLI HELPERS void clearAndHome() { Serial.write(27); Serial.print("[2J"); // limpa a tela Serial.write(27); // ESC Serial.print("[H"); // \r if (!putty) for (int i = 0; i<=30; i++) Serial.println(""); }

void help(){ Serial.println("tDSC arduino, ver "+ver); Serial.println("'?' - ajuda"); Serial.println("'max_time ' - atualiza o tempo máximo (em minutos)"); Serial.println("'target_mA ' - atualiza o target (mA)"); Serial.println("'epsilon_mA ' - atualiza o epsilon_mA (mA)"); Serial.println("'R ' - atualiza a resistência do hardware (Ohm)"); Serial.println("'putty ' - muda a formatação de saída pro PuTTY"); Serial.println("'stop' - para a estimulação"); Serial.println("'restart' - inicia/reinicia a estimulação & o timer"); Serial.println("'continue' - continua a estimulação"); Serial.print("\n\rEstado:\n\r * max_time: "); Serial.print(maxmin); Serial.print(" minutos\n\r * target_mA: "); Serial.print(target_mA); Serial.print(" mA\n\r * epsilon_mA: "); Serial.print(epsilon_mA); Serial.print(" mA\n\r * R: "); Serial.print(R); Serial.println(" Ohms"); }

bool parse_param(String &cmdString){ int spacePos = cmdString.indexOf(' '); if(spacePos<=0) return false; String command = cmdString.substring(0, spacePos); String fval = cmdString.substring(spacePos+1); if(command=="putty") if (fval=="true"){ putty = true; return true; }else if (fval=="false"){ putty = false; return true; } float val = fval.toFloat(); if(command=="target_mA"){ if(val<=0.0 or val>100.0){ return false; } target_mA = val; clearAndHome(); help(); }else if(command=="epsilon_mA"){ if(val<=0.0 or val>0.3){ return false; } epsilon_mA = val; clearAndHome(); help(); }else if(command=="R"){ R = val; clearAndHome(); help(); }else if(command=="max_time"){ maxmin = val; clearAndHome(); help(); }else{ return false; } return true; }

//SETUP AND MAIN LOOP void setup() { Serial.begin(115200); analogReference(INTERNAL); //1.1 V Serial.print("Sessão iniciada!"); start = millis(); } void loop(){ if(state!=-10){ process_feedback(); } if (Serial.available() > 0){ char v = Serial.read(); if (byte(v) == 13){ // Carriage return bool accepted = true; if (commandString == "?" || commandString == "stop"){ stop_device(); }else if (commandString == "restart"){ clearAndHome(); state = -1; outV = maxOutV/5.0; start = millis(); accepted = false; }else if (commandString == "continue"){ clearAndHome(); state = -1; outV = maxOutV/5.0; accepted = false; }else{ bool ok = parse_param(commandString); if(!ok){ clearAndHome(); help(); accepted = false; Serial.println("Comando desconhecido: '" + commandString + "'"); } } commandString = ""; if (accepted){ clearAndHome(); help(); Serial.println("Ok!"); } }else{ commandString+=v; if(state==-10){ Serial.print(v); } } } }

Step 4: Uma UI Personalizada

Para melhor acompanhamento e segurança, utilize a ferramenta PuTTY, e defina no código fonte:

putty = true

Recomendações de definições:

  • Window
    • 61 Colunas e 20 Linhas
    • Display scrollbar desativado
  • Window > Appearance
    • Fonte: Lucida Console, 28px

Step 5: Dúvidas?

Para abrir a guia de ajuda, digite:

?

e pressione [ENTER]

OBS:
Caso o Estado seja:

-1 -> Cérebro não identificado (corrente aberta)
+0 -> Ajustando voltagem
+1 -> Tudo certo, tDCS funcionando

Be the First to Share

    Recommendations

    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    Discussions