-
Notifications
You must be signed in to change notification settings - Fork 2
5. How it Works
The overall design includes three distinct components which had to be integrated together to form a final working system.
-
Creating the waveform using the Due The waveform creation takes input values received from the bluetooth module and uses those values to build an array of voltage samples to write out as the stimulation signal. These configuration values are listed below.
int pulse_frequency = 40; // Frequency of the voltage peaks during stimulation. int rise_time = 20; // Adjusts the rising ramp of the output waveform. Used to control comfort. int max_current = 100; // Determines the magnitude of the output waveform. int decay_coeff = 100; // Dictates the voltage fall-off after waveform has reached peak value.Once these values are received and bounds checks are performed, it is a simple job of using the Arduino's DAC to output the required voltages.
-
Using gyroscope values Analyzing the gyroscope values actually proved to be one of the more difficult components of the project. The gyroscope is placed on the outside edge of the users leg near the top of the tibialis anterior muscle. We then read in the angular velocity of your leg about your left-right axis. This data, as opposed to other axes or acceleration, was the most clear and useful during our design phase (graphs of the output can be seen on our poster). Once we receive data real time, we calculate the derivative and use the combination of these two values to find points of interest in a person's walking pattern. In particular, we find when the foot begins to swing forward, when the foot is swinging at maximum angualar velocity and also when the foot stops swinging forward. Once the Arduino identifies these two points, we can lock onto the user's walking pattern and notify the waveform generator when to output the signal.
-
Interfacing with Bluetooth applications
Before the FES device can be connected to, it has to be paired to the Android or Windows device. This is handled by the operating system.
The Android application is a simple static application with text entry boxes for each of the adjustable parameters and two buttons, one for setting up Bluetooth and the other for sending the user-entered parameters. When the app is opened, only the "Setup Bluetooth" button is enabled. When the user clicks the setup button, the app retrieves (from the operating system) and searches through the currently paired Bluetooth devices. When the HC-06 chip is found, the app begins the connection process using
android.bluetoothfunctions. Any error during the connection process results in an error message appearing on screen with suggested troubleshooting steps.After the connection process has completed, the "Setup Bluetooth" button is disabled and the text entry boxes and send button are enabled. The text entry boxes are limited to numerical input. When the user enters their desired values and hits send, any decimal places are truncated to avoid having to unnecessarily send decimals. Each of the values is then validated to ensure that the user has entered reasonable values. For example, the code for validating pulse frequency:
if (values[0] < PULSE_FREQUENCY_MIN || values[0] > PULSE_FREQUENCY_MAX) { dataIsValid = false; addErrorMessage("Pulse frequency should be in the range " + PULSE_FREQUENCY_MIN + " to " + PULSE_FREQUENCY_MAX + " hertz."); }
If the user's input passes the data validation, the values are then saved into the apps
SharedPreferences. This allows the app to remember the currently set values; when the app is opened, the currently saved values are loaded.Next, the application transforms the data into a form suitable for transmission. Due to the HC-06 Bluetooth chip being character-based, it interprets the data it receives as ASCII character codes. To minimize the amount of data being sent, the user's values are changed to base-78 values between ASCII codes 48 and 126:
private String getMessage(int[] values) { StringBuilder stringBuilder = new StringBuilder(); for(int value : values) { if(value > 78) { int firstDigitValue = value / 78; int secondDigitValue = value % 78; stringBuilder.append((char) (firstDigitValue + 48)); stringBuilder.append((char) (secondDigitValue + 48)); } else { stringBuilder.append("0"); stringBuilder.append((char) (value + 48)); } } return stringBuilder.toString(); }
The data can then be passed to the proper Bluetooth functions to transmit the data, with a small toast message appearing if the data is sent successfully or an error message if not:
private void sendData(String message) { byte[] messageBuffer = message.getBytes(); try { mOutStream.write(messageBuffer); Toast toast = Toast.makeText(MainActivity.this, "Data sent", Toast.LENGTH_SHORT); toast.show(); } catch (IOException messageException) { addErrorMessage("Message sending error. Make sure that the FES device is powered and paired to your Android device, then restart the app and FES device."); } }
The Windows application is functionally identical, and is programmed almost identically except that the Bluetooth functionality is handled by the BlueCove JSR-82 Bluetooth library.
On the Arduino, the bytes that are sent are simply read in using Serial and interpreted into values:
// Get the bytes int i = 0; while (i < 8) { info = Serial.read(); if (info != -1) { val[i] = info - 48; i++; } } // Get the values from the bytes temp[0] = val[0] * 78 + val[1]; temp[1] = val[2] * 78 + val[3]; temp[2] = val[4] * 78 + val[5]; temp[3] = val[6] * 78 + val[7];
The same data validation that is applied by the applications is then also applied on the Arduino to ensure that there were no errors or data corruption during transmission.
The combination of the above components results in the following circuit:
