Matériel:


Schéma :

schéma cablage.JPG


Code :

#include <Wire.h>
#include <Keyboard.h>

#define MCP1_ADDR 0x20
#define MCP2_ADDR 0x21

#define GPIOA 0x12
#define GPIOB 0x13

#define IODIRA 0x00
#define IODIRB 0x01

#define GPPUA 0x0C
#define GPPUB 0x0D

#define DEBOUNCE_MS 40

struct KeyDef {
  uint8_t key;
};

KeyDef keymap[32] = {
  {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'},
  {'9'}, {'0'}, {'q'}, {'w'}, {'e'}, {'r'}, {'t'}, {'y'},
  {'u'}, {'i'}, {'o'}, {'p'}, {'a'}, {'s'}, {'d'}, {'f'},
  {'g'}, {'h'}, {'j'}, {'k'}, {'l'}, {'z'}, {'x'}, {'c'}
};

uint8_t last_state[4] = {0xFF,0xFF,0xFF,0xFF};
unsigned long debounce_time[32];

void mcp_write(uint8_t addr, uint8_t reg, uint8_t val)
{
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();
}

uint8_t mcp_read(uint8_t addr, uint8_t reg)
{
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();

  Wire.requestFrom(addr,(uint8_t)1);

  if(Wire.available())
    return Wire.read();

  return 0xFF;
}

void sendShortcut(uint8_t key)
{
  Keyboard.press(KEY_LEFT_CTRL);
  Keyboard.press(KEY_LEFT_SHIFT);
  Keyboard.press(KEY_LEFT_ALT);
  Keyboard.press(key);

  delay(5);

  Keyboard.releaseAll();
}

void processBank(uint8_t current, uint8_t bank)
{
  unsigned long now = millis();

  for(uint8_t i=0;i<8;i++)
  {
    bool pressed_now = !(current & (1<<i));
    bool pressed_last = !(last_state[bank] & (1<<i));

    uint8_t key_index = bank*8 + i;

    if(pressed_now != pressed_last)
    {
      if(now - debounce_time[key_index] > DEBOUNCE_MS)
      {
        debounce_time[key_index] = now;

        if(pressed_now)
        {
          sendShortcut(keymap[key_index].key);
        }
      }
    }
  }

  last_state[bank] = current;
}

void setup()
{
  Wire.begin();
  Keyboard.begin();

  mcp_write(MCP1_ADDR,IODIRA,0xFF);
  mcp_write(MCP1_ADDR,IODIRB,0xFF);

  mcp_write(MCP2_ADDR,IODIRA,0xFF);
  mcp_write(MCP2_ADDR,IODIRB,0xFF);

  mcp_write(MCP1_ADDR,GPPUA,0xFF);
  mcp_write(MCP1_ADDR,GPPUB,0xFF);

  mcp_write(MCP2_ADDR,GPPUA,0xFF);
  mcp_write(MCP2_ADDR,GPPUB,0xFF);

  last_state[0] = mcp_read(MCP1_ADDR,GPIOA);
  last_state[1] = mcp_read(MCP1_ADDR,GPIOB);
  last_state[2] = mcp_read(MCP2_ADDR,GPIOA);
  last_state[3] = mcp_read(MCP2_ADDR,GPIOB);
}

void loop()
{
  uint8_t m1a = mcp_read(MCP1_ADDR,GPIOA);
  uint8_t m1b = mcp_read(MCP1_ADDR,GPIOB);
  uint8_t m2a = mcp_read(MCP2_ADDR,GPIOA);
  uint8_t m2b = mcp_read(MCP2_ADDR,GPIOB);

  processBank(m1a,0);
  processBank(m1b,1);
  processBank(m2a,2);
  processBank(m2b,3);

  delay(5);
}

Modélisation :

https://www.printables.com/model/1691052-streamdeck-diy