For enhancing the sense of movement in VR, a custom vibrotactile module has been developed with out-of-the-box components including an Arduino board. The vibrotactile module can function as a valuable feedback modality for promoting induced illusions relying on the sensorimotor contingencies between perception and action, useful in motor-imagery training in BCI.
This module is composed by three main components:
- Arduino board
- Vibrating motors
- Cylindrical tubes
1. Arduino board setup:
For connecting the Arduino board with the motors (see figure 1(a)), the following components are needed:
- 1N4001 Diode
- 0.1µF ceramic capacitor
- 1KΩ Resistor
- 2N2222 NPN Transistor
- USB Connector
![]() Figure 1 (a): Circuit schematic for 1 motor |
![]() Figure 1 (b): Complete circuitry for 6 motors |
2. Vibrating tubes
– For installing the motors inside the tubes, a 3D printed case has been designed (STL model) in order to accommodate the motor before inserted inside the tube (see figure 2).
![]() Figure 2 (a): 3D model of the motor casing |
![]()
Figure 2 (b): Motor inserted inside the 3D printed case |
– Cylindrical tubes act as grasping objects for simulating the rows movement. For our setup, a pair of carton based tubed had been used with 12cm of length, 3cm diameter and 0.5cm of thickness (see figure 3).
![]() Figure 3 (a): Cylindrical tube schematic with dimensions |
![]() Figure 3 (b): Complete tube with motor installed |
3. Technical specifications
Vibrating Motor Specs
|
|
Arduino Mega 2560
Microcontroller | ATmega2560 | ![]() |
Operating Voltage | 5V | |
Input Voltage (recommended) | 7-12V | |
Input Voltage (limit) | 6-20V | |
Digital I/O Pins | 54 (of which 15 provide PWM output) | |
Analog Input Pins | 16 | |
DC Current per I/O Pin | 20 mA | |
DC Current for 3.3V Pin | 50 mA | |
Flash Memory | 256 KB of which 8 KB used by bootloader | |
SRAM | 8 KB | |
EEPROM | 4 KB | |
Clock Speed | 16 MHz | |
Length | 101.52 mm | |
Width | 53.3 mm | |
Weight | 37 g |
Finally, upload the following code to the Arduino board for controlling the motors through NeuRow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
String str; int values[2][6]; int power = 0; int hand = 0; int finger = 0; void setup() { Serial.begin(9600); Serial.flush(); //clears any possible left over information } void loop() { if(Serial.available() > 0) { str = Serial.readStringUntil(';'); power = str.toInt(); str = Serial.readStringUntil(';'); hand = str.toInt(); str = Serial.readStringUntil(';'); finger = str.toInt(); values[hand][finger] = power; } for(int i = 0; i <2; i++) { for(int j = 0; j < 6; j++) { analogWrite(i*6+j+2, values[i][j]); } } } |