Nintendo NES controlled drone

Hi @aguy63, welcome to the forum :slight_smile:

Sounds like an interesting project! :slight_smile:

I’m curious what kind of body you’re planning to use - I had a similar thruster setup planned for my StaROV concepts (the project is unfortunately currently on the back-burner).

I’ve formatted your code as a code block, to make it easier to read and understand. You can read more about that in the Formatting a Post/Comment section of the How to Use the Forums post :slight_smile:

In terms of issues with / suggestions for your existing code:

  • it’s generally bad practice to mix action code with reading code, and may cause issues with the reading timings
    • in the readNesController function you’re setting several servo PWM values while reading data from the controller, which should instead be handled elsewhere in the loop, after the controller inputs have been read.
  • I would probably be inclined to replace the clock ticks and data reading section with a loop, to avoid the repeated code, but that does come at the cost of working more explicitly with bit offsets rather than bit names
  • your current code structure means there’s no possibility of mixing motions that use the horizontal thrusters, and using a string of if blocks with no else clauses means only the last pushed relevant button in the sequence is considered
    • if it’s not possible for say up and left to be pressed at the same time then this is functionally irrelevant
    • if that is possible though, it may be worth switching to a mixing approach where two buttons can work together
      • e.g. up + right could have (1900, 1500), or (1700, 1500) if you’re limiting the thrust
  • if you’re happy to get a bit more complex, you could get finer control by keeping track of the ESC PWM values and using the button presses to adjust them over time, rather than having a button press correspond directly to a set of PWMs.
  • setting a timeout for each button press is likely best accomplished by
    1. re-configuring the code to track button press transitions, instead of just whether a button is currently pushed, which requires
      • a new byte for storing the previous state of the buttons, and
      • another new byte for storing whether a button press has occurred and not yet been handled
        • each bit should be cleared when the press is handled, so that a new press within the time limit can refresh the timeout
    2. storing the time for each (relevant) button when it transitions to a press
      • you can get the current time with the millis() function, which requires a new long for every time you want to store
      • you can reduce a bunch of redundancy by grouping together buttons that affect the same thrusters
        • e.g. check for “horizontal command” and “vertical command” events rather than having a timeout for each individual button, since it doesn’t matter if the up button has timed out when you’ve already pressed the down button which has overridden the original up action
    3. checking whether a press has timed out after the latest presses have been determined

Do you want a timeout (whereby you can release a button and the ‘command’ will continue until the timeout), or do you want an immediate ‘stop’ command once no more relevant buttons are being pressed for a given thruster?

Immediate stop is simpler, you can just have variables that start at 1500 each loop iteration, and are overwritten (or modified, if you want to do the mixing approach) by the button states, with the results written to the servos after all the buttons have been checked. If no buttons for a servo are pressed then its result will still be 1500, so the ESC will be commanded to stop.