Debounce please help

I know you all probably hate this kind of question but I've googled and tried and tried but I'm just getting nowhere. I've already bricked two pro micros with bad code so any help would be REALLY appreciated.

I got this code from an instructables. I built the project and it does work but I'm getting double triggers. Here's the project Instructables Project As far as I can tell the person who posted it has abandoned his account and there's no other way to contact him that I can see.

I know the tinest bit about coding, I've found several libraries that are supposed to help with debouncing but as much as I struggle to understand this code I can't make heads nor tails out of it. I'm trying to teach myself C but it's slow going...

I'm just looking for the easiest way to debounce this code. Possibly using this Library? I don't know... Any help would be really appreciated.

#include <Keyboard.h>

// Board Arduino Micro. Port Arduino Micro
// These are used as indices to other arrays
enum {
  UP,
  RIGHT,
  DOWN,
  LEFT,
  A,
  Z,
  X,
  S,
  SELECT,
  START,
  // Number of keys
  NUM_KEYS,
};

// Maps button index to digital pin
const int PINS[] = {
  2,  // UP
  3,  // RIGHT
  4,  // DOWN
  5,  // LEFT
  14, // A
  10, // Z
  16, // X
  15, // S
  9,  // SELECT
  8,  // START
};

// Maps button to keyboard key
const char KEYS[] = {
  KEY_UP_ARROW,    // UP
  KEY_RIGHT_ARROW, // RIGHT
  KEY_DOWN_ARROW,  // DOWN
  KEY_LEFT_ARROW,  // LEFT
  'a',             // A
  'z',             // Z
  'x',             // X
  's',             // S
  KEY_RETURN,      // SELECT
  ' ',             // START
};

// Store previous state of keys
bool STATES[NUM_KEYS];

// Left and right LED pins
#define LED0 7
#define LED1 6

// Initialize
void setup() {
  Keyboard.begin();
  for (int i = 0; i < NUM_KEYS; i++) {
    pinMode(PINS[i], INPUT_PULLUP);
    STATES[i] = digitalRead(PINS[i]);
  }
  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);
}

// Main loop
void loop() {
  bool state;
  // Flash LEDs
  const unsigned long t = millis();
  digitalWrite(LED0, (t / 1000) % 2 == 0 ? HIGH : LOW);
  digitalWrite(LED1, (t / 1000) % 2 == 0 ? LOW : HIGH);
  // Process each key
  for (int i = 0; i < NUM_KEYS; i++) {
    state = digitalRead(PINS[i]);
    if (STATES[i] != state) {
      if (state == LOW) {
        Keyboard.press(KEYS[i]);
      } else {
        Keyboard.release(KEYS[i]);
      }
      STATES[i] = state;
    }
  }
}

A few points…

Unless we can see how your processors are connected, it’s quite unlikely you’ve bricked them.

Starting a post with Instructables and ‘doesn’t work’ in the same sentence, isn’t unusual.

[quote="lastchancename, post:2, topic:1152119, full:true"]
Unless we can see how your processors are connected, it’s quite unlikely you’ve bricked them. [/quote]

Well they were findable in the Arduino IDE before I uploaded the code and they don't work and are unfindable after I uploaded the the code. I googled around and found that they can be bricked. I found that there is a possible way to reset them using a jump wire but I wasn't able to make that work.

Actually the code and the project does work. The buttons double trigger a lot though. That's why I'm trying to debounce them...

@harold_3gy6 try this Poor Man's method:

    if (STATES[i] != state) {
      if (state == LOW) {
        Keyboard.press(KEYS[i]);
      } else {
        Keyboard.release(KEYS[i]);
      }
      delay(20);    // poor man's debounce
      STATES[i] = state;
    }

If bouncing is actually all that's wrong, this will fix it. I can't test it, but my way of doing seems to tell me there is something else wrong somewhere. Perhaps I damaged your sketch removing the Keyboard object .I'll look for a bit.

Edit: I hacked again and successfully removed the Keyboard object and references to it, the delay(20); however crude will fix the problem and there may be no other problem. I did not look beyond the bouincing.

I don't like using this method at all, but just to see if that is the problem, see if this is a fix.

Then worry about proper debouncing. Or not. :expressionless:

a7

Yes. So... either you didn't do it right, or the recipe is wrong or you have a pro micro that does not have the bootloader that repsonds to that method.

Post a link to the method you found.

Say exactly what Arduino board you have - is it a genuine anything or a cheap clone or what?

a7

I'm sorry, it looks to my very uneducated eye that all you did was add the delay(20); above the STATES line. How did you remove the keyboard object? I don't mean to sound ungrateful, I'm very appreciative of your help. I'm Just trying to understand what you mean.

[quote="alto777, post:5, topic:1152119"]
Post a link to the method you found.[/quote]

I'm pretty sure this is the method I tried. I think the fault lies with me. I couldn't get the timing right between uploading the empty sketch and shorting out the pins. After like, 5 times, I got frustrated and gave up.

https://www.shellhacks.com/arduino-pro-micro-reset-restore-bootloader/

It is a cheap clone I got off of Aliexpress link This is the exact board I ordered.

Yes, and that's all you have to try.

To test my fix, I needed to run your code. But I do not have a pro micro handy.

To run the essence of your logic, which would exhibit the bouncing and verify to my satisfaction any fix I created, I needed to take out the keyboard stuff.

No include file, no begin keyboard, no calls to the keyboard methods.

I placed print statements where the keyboard stuff was so I can still see you press and release buttons, they don't actually do anything but print.

Just Hacking 1.01.

I just put the delay() into your original code in the exact same place as it was in my hacked version and posted those few lines, which still had the keyboard stuff.


Now since you are using a clone, you'll have to look a bit further on the brick thing.

Follow the recipe slavishly. I've had to do that, and it is a bit tricky with all that pressure and stuff.

If you are convinced you are doing exactly what should work, and it doesn't, it may be the cheap counterfeit has a boot loader that does not respond to a double tap on the reset line.

On that part of your problem, I can say no more at this time, sry.

a7

No it's cool. I get it :slight_smile:

Sorry it's taken me so long to get back to you. I had to remake the controller board. Then I had a couple of other issues to iron out.

Anyways, I uploaded the code and your change helps a lot. Will the poor man's method work long term?

Sry, forgot to respond immediately.

That technique will work as a long term solution. It will be no trouble at all until you start to need the time it spends wastes, by then you'll have other things to learn, and it can be replaced by a more sophisticate method.

So for now, and maybe for this project, it is entirely adequate. And can be used with no apologies.

a7

Awesome, thank you so much for your help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.