STM32 마이크로 컴퓨터 보드에 48 키보드 구현

13128 단어 STM32키보드
이런 것을 만들었습니다.



2017년의 AVTOKYO의 배지를 2017년에 만들었습니다만, 이번에는 거기에 키보드를 만들어 보았다.

원래, 에니그마 암호기를 실장한 마이크로컴퓨터 보드를 만들까라고 생각하고 있어, 그 때문에 키보드를 원한다.

검토


  • QWERTY 키보드를 원합니다
  • 터치 패널 방식
  • → 비용
  • 터치패드 방식
    - 유전 방식
    - 저항 방식
  • 기계 키

  • 터치패널 방식으로 매트릭스를 만들고 싶었지만 아무래도 좋은 해결책을 할 수 없었다.
    결과, 메카 키를 채용.
    이 때문에, 물리 스위치를 기판 상에 실장하지 않으면 안 된다.

    매트릭스 키보드





    특수 키는 다음 12개 키를 지원합니다.

    ESC SPACE TAB
    CTRL CAPS
    BS ENTER 기호 ↑↓←→

    숫자 10 + 알파벳 26 + 특수 키 12

    매트릭스 방식



    이번에는 14개의 신호선으로 컨트롤하기로 했다.

    1x13 13 키
    2x12 24 키
    3x11 33 키
    4x10 40 키
    5x9 45 키
    6x8 48 키
    7x7 49 키

    48 키보드 매트릭스를 6x8로 생각했습니다.




    49 키보드도 7x7로 생각할 수 있습니다만, 아직 나에게는 너무 이르렀다.

    롤오버



    동시에 최대 3개의 키를 누르면 ok



    3 키 롤오버

    동시에 최대 2개의 키를 누른다.



    2 키 롤오버

    2 키 롤오버 이상을 실현하면 다이오드가 필요

    이번에는 키트로 만드는 것을 생각해 부품 점수를 줄이고 싶다.
    따라서 인접한 키를 잘못 눌러도 가능한 한 간섭하지 않도록 배열을 고안했다.



    기타
  • STM32 오픈 드레인으로 구동
  • 저항은 표면
  • 49 키는 키보드 컨트롤러 아래에 있고 조이 패드 키는 키보드 컨트롤러 아래에 없습니다.

  • 테스트 프로그램


    
    // AVTokyo2019Badge-m0
    // keyboard test
    #include "EEPROM.h"
    
    #include <SPI.h>
    #include <Wire.h>
    // #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306_STM32.h>
    
    #define PAGE_SIZE 0x400
    #define MEM_START 0x8000000
    
    #define OLED_MOSI  PA7
    #define OLED_CLK   PA5
    #define OLED_DC    PA6
    #define OLED_CS    PA4
    #define OLED_RESET PA3 
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
    
    
    #define BUTTONA PA0
    #define BUTTONB PC14
    #define BUTTONUP PB5
    #define BUTTONDOWN PB6
    
    
    
    #define KEYX0 PB1
    #define KEYX1 PA2
    #define KEYX2 PA1
    #define KEYX3 PC15 // PC15 source is 0mA (Use Open Drain mode)
    #define KEYX4 PB9
    #define KEYX5 PB4
    
    #define KEYY0 PB3
    #define KEYY1 PA10
    #define KEYY2 PA9
    #define KEYY3 PA8
    #define KEYY4 PB15
    #define KEYY5 PB14
    #define KEYY6 PB13
    #define KEYY7 PB12
    
    
    #define NUMFLAKES 10
    #define XPOS 0
    #define YPOS 1
    #define DELTAY 2
    
    #define LOGO16_GLCD_HEIGHT 16 
    #define LOGO16_GLCD_WIDTH  16
    
    
     int i,counter=0;
    #define LED  PC13
    #define BOARD_BUTTON_PIN PB10 
    #define COPY_PIN PA8
    #define PWM_PIN0  PB0  // TIMER3
    #define PWM_PIN1  PB1  // TIMER3
    
    int keyY[8]={KEYY0,KEYY1,KEYY2,KEYY3,KEYY4,KEYY5,KEYY6,KEYY7};
    int keyX[6]={KEYX0,KEYX1,KEYX2,KEYX3,KEYX4,KEYX5};
    
    static const unsigned char PROGMEM logo16_glcd_bmp[] =
    { B00000000, B0000000,
      B00000011, B11100000,
      B00001101, B11110000,
      B00011011, B11111000,
      B00110011, B11111100,
      B01111110, B11111110,
      B11111110, B11111111,
      B11110011, B10011111,
      B11111111, B11111111,
      B11001101, B01110011,
      B01111011, B10100110,
      B00111111, B11111100,
      B00011111, B11111000,
      B00001100, B11110000,
      B00000111, B01100000,
      B00000011, B11000000 };
    
    #if (SSD1306_LCDHEIGHT != 64)
    #error("Height incorrect, please fix Adafruit_SSD1306.h!");
    #endif
    
    char readbuffer[255];
    char checksumstr[3]={'A','A',0};
    char namestr[5]={'A','A','A',0};
    String temp;
    char menustr[5][20] = { 
      "   keyboard    ",
      "   keycheck    ",
      "   keydisp     ",
      "    credit     ",
      "factory reset  "
      };
    
    long av=500;
    
    void testdrawchar(void) {
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
    
      for (uint8_t i=0; i < 168; i++) {
        if (i == '\n') continue;
        display.write(i);
        if ((i > 0) && (i % 21 == 0))
          display.println();
      }    
      display.display();
    }
    
    void testdrawcircle(void) {
      for (int16_t i=0; i<display.height(); i+=2) {
        display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
        display.display();
      }
    }
    
    
    int menu(void){
        int menuitem,j;
        int exitflag=0;
        int namey=30;
        int maxitem=5;
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0,10);  
        display.print("AV");
        display.setTextSize(1);
        display.print(" = ");
        display.print(av);
    
        while ( exitflag != 1 ){
    
          delay(200);
          if ( 1==digitalRead(BUTTONDOWN))
            {
              menuitem=menuitem+1;
            }
          if ( 1==digitalRead(BUTTONUP))
            {
              menuitem=menuitem-1;
            }
          if ( 1==digitalRead(BUTTONB))
            {
              exitflag=1;
            }
          if ( maxitem < menuitem  ) { menuitem = 0; }
          if ( 0 > menuitem  ) { menuitem =maxitem; }
          display.setCursor(0,30);  
          display.setTextSize(1);
          for ( j = 0; j<maxitem+1 ; j++ ){
            display.setCursor(24,20+j*(8*1+1));  
            if ( j == menuitem ) {
               display.setTextColor(BLACK,WHITE);
            } else {
               display.setTextColor(WHITE,BLACK);       
            }
            display.println(menustr[j]);
          }
          display.display();
        }
      return(menuitem);
    }
    
    
    
    int credit(void){
        int menuitem,j;
        int exitflag=0;
        int namey=30;
        int maxitem=5;
        display.clearDisplay();
        display.setTextSize(1);
        display.setTextColor(WHITE);
        display.setCursor(0,0);  
        display.println("    -   credit   -");
        display.display();
        while ( exitflag != 1 ){
    
          delay(200);
          if ( 1==digitalRead(BUTTONB))
            {
              exitflag=1;
            }
          display.setCursor(0,10);  
          display.setTextSize(1);
          display.println("This is OSHW.");
          display.println("License:Public Domain");
          display.println("Powered By AVTOKYO");
          display.println("        &");
          display.println("LowLevelStudySociety");
          display.println("nodrinknohack proj.");
          display.display();
        }
      return(menuitem);
    }
    
    
    
    int buttunwait(int wait){
    
       int exitflag=0;
        for ( int  i= 0;( i < wait*10 )&&  (exitflag != 1); i++ ){
       // display.println(j);
    
          delay(100);
          if ( 1==digitalRead(BUTTONB)||1==digitalRead(BUTTONDOWN)||1==digitalRead(BUTTONUP) )
            {
              exitflag=1;
            }
        }    
        while ( 1==digitalRead(BUTTONB)||1==digitalRead(BUTTONDOWN)||1==digitalRead(BUTTONUP) )
            {
              delay(100);
            }
    
    }
    
    int keyboard(void)
    {
    
        int menuitem,i,j;
        int exitflag=0;
        int namey=30;
        int maxitem=5;
        int keyx=0;
        int keyy=0;
    
        while ( exitflag != 1 ){
          display.clearDisplay();
          display.setTextSize(1);
          display.setTextColor(WHITE);
          display.setCursor(0,0);  
          display.println("    -   keyboard   -");
          display.display();
    
    
          delay(200);
          if ( 1==digitalRead(BUTTONB))
              {
                exitflag=1;
              }
          keyx=-1;
          keyy=0;
          digitalWrite(KEYX0,1);
          digitalWrite(KEYX1,1);
          digitalWrite(KEYX2,1);
          digitalWrite(KEYX3,1);
          digitalWrite(KEYX4,1);
          digitalWrite(KEYX5,1);
          for ( int x=0; x<6;x++){
            digitalWrite(keyX[x],0);
            int key=0;
            if ( 0==digitalRead(KEYY0)) key+=1;
            if ( 0==digitalRead(KEYY1)) key+=2;
            if ( 0==digitalRead(KEYY2)) key+=4;
            if ( 0==digitalRead(KEYY3)) key+=8;
            if ( 0==digitalRead(KEYY4)) key+=16;
            if ( 0==digitalRead(KEYY5)) key+=32;
            if ( 0==digitalRead(KEYY6)) key+=64;
            if ( 0==digitalRead(KEYY7)) key+=128;
            if ( 0 != key )
             keyx=x;  
            keyy += key;
            digitalWrite(keyX[x],1);
          }
          display.setTextSize(1);
          display.setCursor(0,10);
          display.print("This is Keyboard.");
          display.display();
          display.setTextSize(1);
          display.setCursor(0,30);  
          display.setTextColor(WHITE,BLACK);
    
          display.print(keyx);
          display.print("  ");
          display.print(keyy);
          display.display();
          delay(200);
    
        }
      return(menuitem);
    
    }
    
    int keycheck(void)
    {
    
        int menuitem,i,j;
        int exitflag=0;
        int namey=30;
        int maxitem=5;
        int keyx=0;
        int keyy=0;
    
        while ( exitflag != 1 ){
          display.clearDisplay();
          display.setTextSize(1);
          display.setTextColor(WHITE);
          display.setCursor(0,0);  
          display.println("    -   keycheck   -");
          keyx=0;
          keyy=0;
          digitalWrite(KEYX0,1);
          digitalWrite(KEYX1,1);
          digitalWrite(KEYX2,1);
          digitalWrite(KEYX3,1);
          digitalWrite(KEYX4,1);
          digitalWrite(KEYX5,1);
          for ( int x=0; x<6;x++){
            digitalWrite(keyX[x],0);
            int key=0;
            for ( int y=0; y<8;y++){
              if ( 0==digitalRead(keyY[y])){ display.print(1);} else {display.print(0);}
              display.print(" ");
            }
            display.println();
            digitalWrite(keyX[x],1);
            delay(10);
          }
          display.display();
          delay(200);
          if ( 1==digitalRead(BUTTONB))
              {
                exitflag=1;
              }
    
        }
      return(menuitem);
    
    }
    
    int keydisp(void)
    {
    
        int menuitem,i,j;
        int exitflag=0;
        int namey=30;
        int maxitem=5;
        int keyx=0;
        int keyy=0;
    
        while ( exitflag != 1 ){
          display.clearDisplay();
          display.setTextSize(1);
          display.setTextColor(WHITE);
          display.setCursor(0,0);  
          display.println("    -   keydisp   -");
          keyx=0;
          keyy=0;
          digitalWrite(KEYX0,1);
          digitalWrite(KEYX1,1);
          digitalWrite(KEYX2,1);
          digitalWrite(KEYX3,1);
          digitalWrite(KEYX4,1);
          digitalWrite(KEYX5,1);
          for ( int x=0; x<6;x++){
            digitalWrite(keyX[x],0);
            int key=0;
            for ( int y=0; y<8;y++){
              if ( 0==digitalRead(keyY[y])){ display.print(1);} else {display.print(0);}
              display.print(" ");
            }
            display.println();
            digitalWrite(keyX[x],1);
            delay(10);
          }
          display.display();
          delay(200);
          if ( 1==digitalRead(BUTTONB))
              {
                exitflag=1;
              }
    
        }
      return(menuitem);
    
    }
    
    void action()
    {
      int state=  digitalRead(BOARD_BUTTON_PIN);
      // digitalWrite(PWM_PIN0,state);
      if (HIGH == state ){
       Timer3.pause();
      Timer3.setCount(0);
      Timer3.refresh();
       } else {
        Timer3.resume();
      }
    }
    
    void setup()   {                
    
    
      // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
      display.begin(SSD1306_SWITCHCAPVCC);
      // init done
    
      // Show image buffer on the display hardware.
      // Since the buffer is intialized with an Adafruit splashscreen
      // internally, this will display the splashscreen.
      display.display();
      delay(1000);
    
      disableDebugPorts();  // for use  PA15/PB3/PB4
      pinMode(BUTTONUP,INPUT_PULLDOWN);
      pinMode(BUTTONDOWN,INPUT_PULLDOWN);
      pinMode(BUTTONB,INPUT_PULLDOWN);
      pinMode(BUTTONA,INPUT_PULLDOWN);
    
      pinMode(KEYX0,OUTPUT_OPEN_DRAIN);
      pinMode(KEYX1,OUTPUT_OPEN_DRAIN);
      pinMode(KEYX2,OUTPUT_OPEN_DRAIN);
      pinMode(KEYX3,OUTPUT_OPEN_DRAIN);
      pinMode(KEYX4,OUTPUT_OPEN_DRAIN);
      pinMode(KEYX5,OUTPUT_OPEN_DRAIN);
    
      pinMode(KEYY0,INPUT_PULLUP);
      pinMode(KEYY1,INPUT_PULLUP);
      pinMode(KEYY2,INPUT_PULLUP);
      pinMode(KEYY3,INPUT_PULLUP);
      pinMode(KEYY4,INPUT_PULLUP);
      pinMode(KEYY5,INPUT_PULLUP);
      pinMode(KEYY6,INPUT_PULLUP);
      pinMode(KEYY7,INPUT_PULLUP);
    
      Serial.begin(2400);
      Serial3.begin(2400);
      delay(100);
    
    
      Timer3.pause();
      Timer3.setPrescaleFactor(947);   // システムクロック 72MHzを10kHzに分周
      Timer3.setOverflow(2);      // wave width = 2 ( 2 * 72MHz / 947 = 38Khz)
      pwmWrite(PWM_PIN0, 1);       // pulse width = 1 (1/2 duty 50%)
      pwmWrite(PWM_PIN1, 1);      // pulse width = 1 (1/2 duty 50%)
    
      Timer3.setCount(1);
      Timer3.refresh();
        Timer3.resume();
     //   Timer3.resume();
     delay(100);
      Timer3.pause();
      Timer3.setCount(0);
      Timer3.refresh();
    
        Serial.println("start ...");
      delay(100); 
    
    
      display.clearDisplay();
      display.setTextSize(1);
      display.setCursor(0,0);  
      display.setTextColor(WHITE,BLACK);
    
    
    
    }
    
    void loop() {
        // text display tests
      int menucode=0;
      // nameentry();
      menucode=menu();
      if ( 0 == menucode ){
        keyboard();
      }
      if ( 1 == menucode ){
        keycheck();
      }
      if ( 2 == menucode ){
        keydisp();
      }
      if ( 3 == menucode ){
        credit();
      }
    
    
    }
    

    좋은 웹페이지 즐겨찾기