Looking for assistance improving my bionic arm controller

I am working on developing an open-source bionic arm. I have been familiar with programming in other languages as a hobby over the years, but I am still relatively new to Arduino. As such, I can get a fairly solid IF/THEN routine figured out, and the math for handling variables to do what I want, but my shortcoming is in knowing the best way to achieve that in Arduino. My current program works somewhat, but it still has a few strange behaviors, and I'm sure I have written it in a clunky way clinging to what few statements I know how to program with, when there may be much cleaner ways to do so.

This is my first draft of it, but it mostly functions, but not tuned in yet. This is intended for use on an Arduino Mega 2560, using two myoelectric muscle sensor boards (one on the hand "closing" and another on the "opening" muscle groups). The goal is to get as much functionality as possible out of it, yet keeping the interface easy to use. I am sorry this program isn't all commented up yet, so I will try to describe the functionality in this write-up here.

Currently, my friend has a professional-made prosthesis which uses myoelectric sensors picking up his closing and opening muscles, but to switch between grip control and wrist rotation motor control, he has to tense both muscle groups at once for a few seconds, which isn't easy and takes time, and no indicator light shows the mode switch status so he has to try and then run it for a moment to see whether the hand or the wrist responds.

On this arm we are building, the wrist rotation is biological muscle movement, with the prosthesis from the forearm outward being fitted to and rotating with the end of my friend's arm that he can still twist on its rotation axis. This saves needing to motorize it, makes use of muscle functionality he still has, and naturally will provide a wrist rotation that is more natural and has the feel of forces involved, and can be done simultaneous to any opening/closing muscle movement.

Several modes exist for our arm, separated into two Tiers. One is grip modes, the other is accessories. When my friend rotates his arm to its limit (past a "palm up" position) there is a limit switch that gets pressed. When the program sees that this limit switch is pressed, an LED lights up to show that Mode Select is active, and also an LED shows up for which type of Tier 1 grip is active, and which type of Tier 2 grip is active. As soon as Mode Select is activated, it swaps whether Tier 1 or Tier 2 is active, enabling a very fast movement between being in Tier 1 grip mode, twisting the wrist for a moment to bump the Mode Select switch and come back, and now being in Tier 2 wrist flexion control. After moving the wrist, twist-bump-untwist we're back in Tier 1 grip mode.

There are several types of grip modes in Tier 1. There is a whole-hand grip which has the thumb and index finger synchronizing their potentiometer values during travel (yet to be tuned in to working right). A pinch grip mode does the same, but instantly closes the middle ring and pinky fingers until their pots read closed positions. Gesture mode closes everything initially, and then reads a muscle "close" command to give a thumbs-up, or reads the muscle "open" command to point the index finger. There is another gesture that activates if both "open" and "close" muscle groups are tensed. Another grip mode is rock/paper/scissors, which will mostly just serve as a bit of a tech demo, and operates similar to the gesture mode. The last Tier 1 grip mode is "gun grip", which for operating anything with a trigger such as a squirting bottle, waits until the first muscle "close" and then clamps down all fingers except the index, and then keeps a light pressure on them while the index finger is the one responding to the muscle open/close values. Switching modes resets the grip to being open again.

For Tier 2, the first mode controls the wrist flexion motor. We finally got the right belt drive components ordered, and it works GREAT. I am so happy that this wrist ended up working exactly like we intended, where it uses a geneva mechanism to have three indexing positions (straight, + and - 60 degrees) where the cam locks the wrist so there is no risk of back-driving the motor or stripping gears under load. When wrist flexion is the active mode, muscle closing and opening runs the motor forward or reverse. The second mode for Tier 2 controls a laser and flashlight embedded in the back of the hand (aiming the way the fingers extend when flat), with the muscle close being a toggle on / off for the laser, and muscle open being the toggle on / off for the flashlight. The last mode in Tier 2 is lock, which simply puts all motors to neutral.

To switch modes, the arm is rotated until the Mode Select button is active, the LED is visible for Mode Select, and the LED's for Tier 1 and Tier 2 are also visible. Each tensing of the "close" muscle advances the currently active Tier to its next mode, so if you are in full-hand grip and want pinch grip, you would twist your arm to bounce Mode Select once (goes into Tier 2) and then would bring it back and hold it on Mode Select (now in Tier 1 again) and now closing the arm muscle would show the LED change in the Tier 1 row to now be indicating that pinch grip mode is activated. If you wanted to go to higher modes, you would stay in Mode Select and repeatedly give momentary squeezes of the closing muscle. To get back to full-hand grip, a momentary squeeze of the opening muscle resets to the first mode in Tier 1. If you were in Tier 2, cycling modes, this would work the same (opening resets to the first mode of Tier 2 then). When just switching between Tier 1 and Tier 2 by bumping Mode Select, whatever type of Tier 1 or Tier 2 mode was active will stay what it goes back to - so you could turn on the laser, switch to grip mode, and then later Mode Select brings you back to laser/flashlight mode, not the first Tier 2 mode (wrist flexion) unless you tense muscles open while the Mode Select button was active.

The goal is to make it as intuitive and quick / easy to change as possible, and allows us to custom-tune the operation per the user feedback. With my friend's current prosthesis, a big issue is that the feedback loop on control system changes is very slow, sort of "I hope this works for you, otherwise let us know and we can do things differently in a few years on the next arm". By keeping this using Arduino that anyone can reprogram, it can be modified any time by anyone who knows what they're doing. Making the program open-source (along with the arm design, and using your hand design) creates a complete open-source system that anyone can modify and improve on.

I apologize that I have not completed the commenting throughout the program. I intend to, but I wanted to post what I have so far so I could start to get some feedback on it. Thank you for your time.

Code in following message due to size limits.

The code is too big, sorry, I guess I will have to post it as an attachment.

Hand_program.zip (7.27 KB)

It certainly seems that arrays would be useful.

You have a lot of global variables that probably do not need to be global.

    if (mode == 11)  {                         // whole hand grip

So, why not

#define WHOLE_HAND_GRIP 11

if(mode == WHOLE_HAND_GRIP)

Making the code self-documenting means that the comments can't get out of date.

I'd prefer to see a lot more functions. If you create a function called wholeHandGrip() and one called
pinchGrip(), and the user has a problem with the whole hand grip part of the program, there is no need to look at pinchGrip() to determine what the problem is.

Thanks for the help, that should help me group the modes better and will make the program more clear and concise. I will do some work on the program, and add more comments, and eventually will post the updated version.