Repo for Hand-Powered Hand!
Code is uploaded separately to the transmitting (Nano) and receiving (Mega) microcontroller.
The final design included two separate microcontrollers: an ATmega328P on the Arduino Nano on the user side to take the flex sensor readings, and an ATmega2560 on the Arduino Mega on the mechanical side to translate the sensor data into hand motion. The two microcontrollers communicated wirelessly with a pair of nRF24L01 modules.
Sensing Glove Flex sensors were mounted inside of the fingers of a glove for the user to wear to measure the degree to which each finger was being bent. Each of the five flex sensors was then connected to a distinct ADC pin on the Arduino Nano. The operating principle of a flex sensor is that it decreases in resistance in response to the decreasing length as it is bent. The input value from each of the five ADC pins used was then read and stored in turn. The resolution of the ADC value was decreased from 10-bit to 8-bit by an integer division by a factor of four in order for the set of values for the hand to be sent out as a packet of five 8-bit values. Each flex sensor was placed in series with a 47kΩ resistor in a voltage dividing circuit, where the node between the two was the input to the ADC. The sensors and board were powered by a 9V battery in order to make the glove portable. The components were then placed neatly into a small box which was attached to a wristband for the user to strap on in addition to the glove to create a smoother user experience. A picture of the sensing glove is shown in Figure 1.
Mechanical Hand Five servo motors, one for each finger, with an accompanying LED were mounted on a 3D printed hand. The fingers were constructed to each have two joints—one at the base of the finger and the other near the center. Fishing line was used to attach the arm of the motors to each finger just above the second joint in order to pull the fingers down as the motors turned. Rubber bands were used on the back of the fingers in order to pull them straight when at rest and provide the tension for intermediate finger positions while motors pulled to bend them. The servo motors were connected to the OCnB pins of the Arduino Mega and their positions were set with PWM. Each finger was one its own timer, so scaling the OCRnB value to produce the duty cycle in phase correct PWM mode corresponding to the sensor input accurately set the position of each motor.
Upon receipt of the 5 byte packet of values from the flex sensors, the values for each finger were first compared with the values received in the previous packet. If the most recently received value for a given finger was under the threshold of three units away from the old value, no change of the corresponding motor’s position was made. However if the difference exceeded the threshold, the flex sensor input was mapped to a duty cycle value for the motor. Since each of the flex sensors returned slightly different values depending on the degree to which each of the fingers was bent, the scaling from input values to duty cycle depended in the minimum and maximum ADC values received from each flex sensor corresponding to when the fingers were completely bent and completely straight, mapped to a continuous range from the minimum to the maximum duty cycle of the servo motors that would produce a change in position. The input values for the bent and straight positions of each finger were determined experimentally and defined outside of the mapping function. After the duty cycle values were determined, the most recently received ADC values were saved as the old values for the next cycle.
The LEDs for each finger were also controlled based on the difference between the previously received flex sensor values and the most recently received flex sensor values. If the difference was above the threshold, the LED was turned on. If the difference was below the threshold, the LED was turned off. Thus, the LED was on when the fingers were in motion and off otherwise. A picture of the mechanical hand is shown in Figure 2.
Wireless Communication A pair of nRF24L01 transceiver modules was used to facilitate wireless communication between the two microcontrollers. They use the 2.4 GHz band and it can operate with baud rates from 250 kbs up to 2 Mbps. They can use 125 different channels which gives a possibility to have a network of 125 independently working modems in one place. For this project, only one channel was chosen since one module was used to communicate with another. Each channel can have up to 6 addresses and only one address was used, again for the same reason. To communicate with each other, the transmitter and receiver module must have the same channel and data rate, as well as the address, which functions as a type of unique identification code. Generally, transmission works in the following manner - the transmitter sends data packets to the receiver using a predefined channel and data rate, and the receiver receives the packets and sends an acknowledgement back to the transmitter to confirm that the data was received successfully.
The nRF24L01 modules are a very popular choice for wireless communication when using the Arduino and is the reason why they are used for this project. Their low power consumption makes them quite popular - they only use around 12 mA during transmission, which is even lower than a single LED. Their operating voltage is 3.3 V and they were connected to the 3.3 V pins on the Arduino.
One of the RF modules was connected to each microcontroller. The module on the Arduino Nano worked as a transmitter to send the input values from the flex sensors, while the module on the Arduino Mega worked as a receiver to respond to the sensor input values. Using this form of wireless communication, the mechanical hand could be controlled all the way from the other side of the lab over thirty feet away. SPI was used to pass information between each transceiver and its respective microcontroller.