带 Arduino 的字母数字电话键盘
Alpha-numeric Telephone Keypad with Arduino
我正在尝试制作一个电容式触摸键盘来接收用户的输入,并输出由该输入生成的一串字符。每个填充 returns 它的值,第一个是 1,第二个是 2,第三个是 4、8、16,直到 2^12。 (如果触摸了多个键,它们的id会相加,但不会发生这种情况。)
假设您正在使用旧诺基亚 phone 并向朋友输入消息,您按 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);
}
请随时要求清楚,如果您知道解决方案,请解释每行和语句的作用,以便我对语言有一些了解。
这演示了字母数字键盘键入的概念:
const int max_delay_between_keys = 300; // Time in milliseconds to allow between keypresses
String text = "";
char current_char = '[=10=]';
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
我正在尝试制作一个电容式触摸键盘来接收用户的输入,并输出由该输入生成的一串字符。每个填充 returns 它的值,第一个是 1,第二个是 2,第三个是 4、8、16,直到 2^12。 (如果触摸了多个键,它们的id会相加,但不会发生这种情况。)
假设您正在使用旧诺基亚 phone 并向朋友输入消息,您按 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);
}
请随时要求清楚,如果您知道解决方案,请解释每行和语句的作用,以便我对语言有一些了解。
这演示了字母数字键盘键入的概念:
const int max_delay_between_keys = 300; // Time in milliseconds to allow between keypresses
String text = "";
char current_char = '[=10=]';
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