带有 Arduino 的字母数字电话键盘

Posted

技术标签:

【中文标题】带有 Arduino 的字母数字电话键盘【英文标题】:Alpha-numeric Telephone Keypad with Arduino 【发布时间】:2017-03-20 12:48:52 【问题描述】:

我正在尝试制作一个电容式触摸键盘来接收用户的输入,并输出由该输入生成的字符串。每个 pad 返回其值,第一个为 1,第二个为 2,第三个为 4、8、16,直到 2^12。 (如果触摸了多个键,它们的 id 会相加,但这不会发生。)

假设您正在使用旧的诺基亚手机给朋友发信息,您按 2 两次输入“b”,按三次 9 输入“y”。我需要这样的代码。

我最大的障碍是我对 C 的了解非常有限,到目前为止我所做的一切都很顺利,偶尔会打嗝,但这远远超出了我的知识范围。

这是我当前的代码,它不是很漂亮,但这是我目前的尝试。

//import all packages
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <Adafruit_MPR121.h>
#include <Adafruit_NeoPixel.h>
#include <SPI.h>
//define pins for OLED display
#define sclk SCK
#define mosi MOSI
#define dc   A1
#define cs   A2
#define rst  A3
//define pins for indicator lights
#define neo_pin A4
//define basic colours
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0 
#define WHITE           0xFFFF
//create the screen
Adafruit_SSD1351 screen = Adafruit_SSD1351(cs, dc, mosi, sclk, rst);
//create the cap. sensor
Adafruit_MPR121 cap = Adafruit_MPR121();
//initialize the variables used by the cap. sensor
uint16_t lastTouched = 0;
uint16_t currTouched = 0;
int delayPress = -1;
int buttonIndex = 0;
int padTouched = 0;
//create the neopixel indicator light
Adafruit_NeoPixel indicator = Adafruit_NeoPixel(1, neo_pin, NEO_GRB + NEO_KHZ800);
//initialize functional variables
char string[32];
//level 0 functions
void flash(int dly = 100)

  digitalWrite(13,HIGH);
  delay(dly);
  digitalWrite(13,LOW);
  delay(dly);

void flashIndicator(int dly = 100)

  setColour(255,255,255);
  delay(dly);
  setColour(0,0,0);
  delay(dly);

void setColour(int r, int g, int b)

  indicator.setPixelColor(0,r,g,b);
  indicator.show();

void resetDrawText(char *text,uint16_t textColour = WHITE, uint16_t backColour = BLACK)

  screen.fillScreen(backColour);
  screen.setCursor(0,0);
  screen.setTextColor(textColour);
  screen.print(text);

void drawText(char *text,uint16_t textColour = WHITE)

  screen.setCursor(0,0);
  screen.setTextColor(textColour);
  screen.print(text);


//component startup functions (level 1)
void startIndicator()

  indicator.begin();
  indicator.setBrightness(64);
  setColour(0,0,0);
  setColour(0,255,0);

void startCap()

  cap.begin(0x5A);

void startScreen()

  screen.begin();
  screen.fillScreen(BLACK);


void setup() 
  // start all components
  startIndicator();
  startCap();
  startScreen(); 
  Serial.begin(9600);
  Serial.println("init");
  setColour(255,0,255);


void keyIn()

  flashIndicator(100);
  flashIndicator(100);

  char catChar[] = " ";
  Serial.println("pad index");
  Serial.println(currTouched);
  switch (currTouched)
  
    case 1:
    catChar[1] = "A";
    break;

    case 2:
    catChar[1] = "B";
    break;

    case 4:
    catChar[1] = "C";
    break;
  
  //Serial.println("char group");
  //Serial.println(catGroup);


  //strcpy(catChar, catGroup);
  //char catChar = catGroup[buttonIndex];
  Serial.println("new char");
  Serial.println(catChar);

  strcat(string, catChar);
  drawText(string);
  Serial.println("draw text");
  Serial.println(string);
  delayPress = -1;
  buttonIndex = 0;
  padTouched = 0;


void loop() 
  currTouched = cap.touched();

  if ((currTouched > 0) and (not currTouched == lastTouched))
  
    Serial.println("pad touched");
    Serial.println(currTouched);
    flashIndicator(200);
    if ((padTouched == currTouched) or (padTouched == 0))
    
    delayPress = 50;

    buttonIndex++;
    if (buttonIndex > 2)
    
        buttonIndex = 0;
    
    Serial.println("button index");
    Serial.println(buttonIndex);
    
    else if (not currTouched == 0)
    
    keyIn();
    
    padTouched = currTouched;
  
  if (delayPress > 0)
  
    delayPress--;
  
  else if (delayPress == 0)
   
    keyIn();
  
  lastTouched = currTouched;

  flash(50);//delay(100);

请随时要求澄清,如果您知道解决方案,请解释每行和语句的作用,以便我可以深入了解该语言。

【问题讨论】:

【参考方案1】:

这演示了字母数字键盘输入的概念:

const int max_delay_between_keys = 300; // Time in milliseconds to allow between keypresses

String text = "";
char current_char = '\0';
int last_pressed = -1;
int times_pressed = 0;
int time_last_pressed = 0;

char lookup_value(int key, int count) 
    const char* const characters[12] = "1", "abc2", "def3", "ghi4", "jkl5", "mno6", "pqrs7", "tuv8", "wxyz9", "*", "0 ", "#"; //Change this to match the characters on your keypad.
    const char* sequence = characters[key];
    return sequence[count % strlen(sequence)];


String process_keystream(int key_code) 
    int new_time = millis();
    bool time_over = (new_time - time_last_pressed > max_delay_between_keys);

    time_last_pressed = new_time;

    key_code = log((float)key_code) / log(2.0) - 1;
    if (key_code == last_pressed && !time_over) 
        times_pressed += 1;
    
    else 
        if (last_pressed != -1) 
            text += current_char;
        

        last_pressed = key_code;
        times_pressed = 0;
    
    current_char = lookup_value(key_code, times_pressed);

    return text + current_char;


void setup() 
  // put your setup code here, to run once:
  Serial.begin(115200);

  // Serial.println() is what you'd send to your screen.
  Serial.println(process_keystream(16)); // Pressed the 4 key
  Serial.println(process_keystream(16)); // Pressed the 4 key
  Serial.println(process_keystream(8));  // Pressed the 3 key
  Serial.println(process_keystream(8));  // Pressed the 3 key
  Serial.println(process_keystream(32)); // Pressed the 5 key
  Serial.println(process_keystream(32)); // Pressed the 5 key
  Serial.println(process_keystream(32)); // Pressed the 5 key
  delay(500);                            // Wait a while so the current letter is set.
  Serial.println(process_keystream(32)); // Pressed the 5 key
  Serial.println(process_keystream(32)); // Pressed the 5 key
  Serial.println(process_keystream(32)); // Pressed the 5 key
  Serial.println(process_keystream(64)); // Pressed the 6 key
  Serial.println(process_keystream(64)); // Pressed the 6 key
  Serial.println(process_keystream(64)); // Pressed the 6 key


void loop() 
  // put your main code here, to run repeatedly:


结果:

g
h
hd
he
hej
hek
hel
helj
helk
hell
hellm
helln
hello

【讨论】:

谢谢!刚刚查看了代码,它比我的混乱 xD 更有意义。

以上是关于带有 Arduino 的字母数字电话键盘的主要内容,如果未能解决你的问题,请参考以下文章

隐藏键盘返回按钮

Arduino UNO通过电容的直接检测实现简易触摸开关

Arduino与Proteus仿真实例-4x4矩阵键盘驱动仿真

用于 MDTextField 的带有 Kivy / KivyMD 的数字键盘

根据具有 Character 类的字母,用数字替换字符串中的字母

IOS中国际电话无模式