Compare commits
6 Commits
6acee37a7f
...
771c135cd2
Author | SHA1 | Date |
---|---|---|
radex | 771c135cd2 | |
radex | efc318c99a | |
radex | 7c9323c9b8 | |
radex | 63f57df758 | |
radex | a9e21296c8 | |
radex | c8f72826d1 |
|
@ -1,6 +1,7 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "encoder.h"
|
||||
|
||||
/*
|
||||
|
||||
|
@ -12,21 +13,72 @@ When rotated clockwise, CLK changes before DT; when rotated counter-clockwise, D
|
|||
|
||||
*/
|
||||
|
||||
#define SW_DEBOUNCE_MS 10
|
||||
|
||||
bool previousClk = false;
|
||||
bool previousDt = false;
|
||||
|
||||
void setupEncoder() {
|
||||
pinMode(CLK_PIN, INPUT);
|
||||
pinMode(DT_PIN, INPUT);
|
||||
pinMode(SW_PIN, INPUT_PULLUP);
|
||||
|
||||
// save initial state
|
||||
previousClk = digitalRead(CLK_PIN);
|
||||
previousDt = digitalRead(DT_PIN);
|
||||
}
|
||||
|
||||
void demoEncoder() {
|
||||
bool previousPressed = false;
|
||||
unsigned long lastChangeAt = 0;
|
||||
|
||||
SwitchEvent handleSwitch() {
|
||||
bool isPressed = !digitalRead(SW_PIN);
|
||||
|
||||
// only handle change
|
||||
if (isPressed == previousPressed) {
|
||||
return SWITCH_NONE;
|
||||
}
|
||||
|
||||
// debounce
|
||||
unsigned long now = millis();
|
||||
if (now - lastChangeAt < SW_DEBOUNCE_MS) {
|
||||
return SWITCH_NONE;
|
||||
}
|
||||
|
||||
// save state
|
||||
previousPressed = isPressed;
|
||||
lastChangeAt = now;
|
||||
|
||||
// return event
|
||||
return isPressed ? SWITCH_PRESSED : SWITCH_RELEASED;
|
||||
}
|
||||
|
||||
EncoderEvent handleEncoder() {
|
||||
bool clk = digitalRead(CLK_PIN);
|
||||
bool dt = digitalRead(DT_PIN);
|
||||
bool sw = digitalRead(SW_PIN);
|
||||
|
||||
Serial.print("CLK: ");
|
||||
Serial.print(clk);
|
||||
Serial.print(" DT: ");
|
||||
Serial.print(dt);
|
||||
Serial.print(" SW: ");
|
||||
Serial.println(sw);
|
||||
// only handle change
|
||||
if (clk == previousClk && dt == previousDt) {
|
||||
return ENCODER_NONE;
|
||||
}
|
||||
|
||||
// TODO: Do we need to debounce encoder?
|
||||
|
||||
// clockwise pattern:
|
||||
// clk: 1001 1001
|
||||
// dt: 1100 1100
|
||||
// counter-clockwise pattern:
|
||||
// clk: 1100 1100
|
||||
// dt: 1001 1001
|
||||
EncoderEvent event = ENCODER_NONE;
|
||||
if (clk == dt) {
|
||||
event = clk == previousClk ? ENCODER_CLOCKWISE : ENCODER_COUNTER_CLOCKWISE;
|
||||
}
|
||||
|
||||
// save state
|
||||
previousClk = clk;
|
||||
previousDt = dt;
|
||||
|
||||
// return event
|
||||
return event;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
typedef uint8_t SwitchEvent;
|
||||
#define SWITCH_NONE 0
|
||||
#define SWITCH_PRESSED 1
|
||||
#define SWITCH_RELEASED 2
|
||||
|
||||
typedef int8_t EncoderEvent;
|
||||
#define ENCODER_NONE 0
|
||||
#define ENCODER_CLOCKWISE 1
|
||||
#define ENCODER_COUNTER_CLOCKWISE -1
|
||||
|
||||
void setupEncoder();
|
||||
void demoEncoder();
|
||||
|
||||
SwitchEvent handleSwitch();
|
||||
EncoderEvent handleEncoder();
|
||||
|
|
|
@ -2,9 +2,34 @@
|
|||
#include <Wire.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "debug.h"
|
||||
|
||||
PCF8574 kbd(KBD_I2C_ADDR, &Wire);
|
||||
|
||||
/*
|
||||
Keyboard layout:
|
||||
|
||||
row/col 0 1 2 3
|
||||
|
||||
0 1 2 3 A
|
||||
1 4 5 6 B
|
||||
2 7 8 9 C
|
||||
3 * 0 # D
|
||||
|
||||
Keys, in order:
|
||||
123A 456B 789C *0#D
|
||||
*/
|
||||
|
||||
typedef uint8_t Key;
|
||||
|
||||
const char *allKeys = "123A456B789C*0#D";
|
||||
#define KEY_NONE 255
|
||||
const uint8_t digits[16] =
|
||||
{ 1, 2, 3, KEY_NONE,
|
||||
4, 5, 6, KEY_NONE,
|
||||
7, 8, 9, KEY_NONE,
|
||||
KEY_NONE, 0, KEY_NONE, KEY_NONE};
|
||||
|
||||
bool setupKeyboard() {
|
||||
if (!kbd.begin()) {
|
||||
Serial.println("Could not initialize keyboard");
|
||||
|
@ -18,10 +43,74 @@ bool setupKeyboard() {
|
|||
return true;
|
||||
}
|
||||
|
||||
Key getPressedKey();
|
||||
uint8_t getPressedDigit(Key key);
|
||||
|
||||
#define KBD_COL_MASK 0b11110000
|
||||
#define KBD_ROW_MASK 0b00001111
|
||||
|
||||
void demoKeyboard() {
|
||||
kbd.write8(0b11110000); // first 4 bits are columns, low when pressed
|
||||
// kbd.write8(0b00001111); // last 4 bits are rows, low when pressed
|
||||
int x = kbd.read8();
|
||||
Serial.print("Keyboard: ");
|
||||
Serial.println(x, BIN);
|
||||
auto key = getPressedKey();
|
||||
if (key != KEY_NONE) {
|
||||
Serial.print("Key pressed: ");
|
||||
Serial.print(allKeys[key]);
|
||||
|
||||
auto digit = getPressedDigit(key);
|
||||
if (digit != KEY_NONE) {
|
||||
Serial.print(", digit: ");
|
||||
Serial.print(digit);
|
||||
} else {
|
||||
Serial.print(" (Not a digit)");
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pressed key or KEY_NONE if no key is pressed
|
||||
*
|
||||
* NOTE: Only one key can be pressed at a time;
|
||||
* if multiple keys are pressed, the result is undefined
|
||||
*/
|
||||
Key getPressedKey() {
|
||||
// check pressed column
|
||||
// first 4 bits are columns, low when pressed
|
||||
kbd.write8(KBD_COL_MASK);
|
||||
|
||||
uint8_t cols = kbd.read8();
|
||||
if (cols == KBD_COL_MASK) {
|
||||
return KEY_NONE;
|
||||
}
|
||||
|
||||
uint8_t colState = ~(cols >> 4);
|
||||
uint8_t colPressed = 0;
|
||||
if (colState & 0b1000) colPressed = 0;
|
||||
else if (colState & 0b0100) colPressed = 1;
|
||||
else if (colState & 0b0010) colPressed = 2;
|
||||
else if (colState & 0b0001) colPressed = 3;
|
||||
else fatal();
|
||||
|
||||
// check pressed row
|
||||
// last 4 bits are rows, low when pressed
|
||||
kbd.write8(KBD_ROW_MASK);
|
||||
|
||||
uint8_t rowState = ~kbd.read8();
|
||||
uint8_t rowPressed = 0;
|
||||
if (rowState & 0b1000) rowPressed = 0;
|
||||
else if (rowState & 0b0100) rowPressed = 1;
|
||||
else if (rowState & 0b0010) rowPressed = 2;
|
||||
else if (rowState & 0b0001) rowPressed = 3;
|
||||
else fatal();
|
||||
|
||||
// return key
|
||||
return (rowPressed * 4) + colPressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pressed digit or KEY_NONE if the key is not a digit
|
||||
*/
|
||||
uint8_t getPressedDigit(Key key) {
|
||||
if (key == KEY_NONE) return KEY_NONE;
|
||||
return digits[key];
|
||||
}
|
||||
|
|
|
@ -22,12 +22,19 @@ void setup() {
|
|||
}
|
||||
|
||||
void loop() {
|
||||
tick();
|
||||
// tick();
|
||||
|
||||
debugScanI2C();
|
||||
demoScreen();
|
||||
// debugScanI2C();
|
||||
// demoScreen();
|
||||
// demoKeyboard();
|
||||
// demoEncoder();
|
||||
|
||||
delay(200);
|
||||
if (auto event = handleSwitch()) {
|
||||
tick();
|
||||
Serial.println(event == SWITCH_PRESSED ? "Pressed" : "Released");
|
||||
}
|
||||
|
||||
if (auto event = handleEncoder()) {
|
||||
tick();
|
||||
Serial.println(event == ENCODER_CLOCKWISE ? "Clockwise" : "Counter-clockwise");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue