Hi everyone,
I am a new user of Arduino (my first time using it). I am working on programming a keyboard for MD patients. I have only 16 inputs to map 26 keys, and so I thought about a sticky shift concept:
A sticky shift works like this. You press a key that activates the sticky shift. This activates a secondary set of key definitions. When the second key is pressed, the key mappings revert back to the original. The concept is similar to phone keyboards where after typing a period (to end a sentence) often the shift key will automatically activate giving you temporary access to capital letters for the start of the next sentence.
However, I am having trouble implementing the idea.
Would appreciate any suggestions and orientation.
Before you get into sticky keys, you might want to read about keyboard/button matrices.
up to this point, I have managed to connect the sensors (Force sensor) with my Arduino and written a basic code that encodes 16 letters. This is an example of code for two sensors:
#include <Keyboard.h>
const int threshold = 800;
int up4 = 0;
int down4 = 0;
int right4 = 0;
int left4 = 0;
int up5 = 0;
int down5 = 0;
int right5 = 0;
int left5 = 0;
int yellow4= A0; // down
int white4 = A1;//left
int red4 = A2;//up
int blue4 = A3;//right
int yellow5=A4;//down
int white5= A5;//left
int red5= A6;//up
int blue5 = A7;//right
void setup()
{
pinMode(red4, INPUT);
pinMode(blue4, INPUT);
pinMode(white4, INPUT);
pinMode(yellow4, INPUT);
pinMode(red5, INPUT);
pinMode(blue5, INPUT);
pinMode(white5, INPUT);
pinMode(yellow5, INPUT);
Serial.begin(9600);
Keyboard.begin();
}
void loop()
{
int up4 = analogRead(red4);
int right4 = analogRead(blue4);
int down4 = analogRead(yellow4);
int left4 = analogRead(white4);
int up5 = analogRead(red5);
int right5 = analogRead(blue5);
int down5=analogRead(yellow5);
int left5 = analogRead(white5);
if (right4>threshold & up4<threshold & down4<threshold & left4<threshold){
Serial.println("right4");
Keyboard.write('L');
delay(300);
Keyboard.releaseAll();
}
if (right5>threshold & up5<threshold & down5<threshold & left5<threshold){
Serial.println("right5");
Keyboard.write('Y');
delay(300);
Keyboard.releaseAll();
}
if (right4<threshold & up4>threshold & down4<threshold & left4<threshold){
Serial.println("up4");
Keyboard.write('M');
delay(300);
Keyboard.releaseAll();
}
if (right5<threshold & up5>threshold & down5<threshold & left5<threshold){
Serial.println("up5");
Keyboard.write('R');
delay(300);
Keyboard.releaseAll();
}
if (right4<threshold & up4<threshold & down4>threshold & left4<threshold){
Serial.println("down4");
Keyboard.write('N');
delay(300);
Keyboard.releaseAll();
}
if (right5<threshold & up5<threshold & down5>threshold & left5<threshold){
Serial.println("down5");
Keyboard.write('Z');
delay(300);
Keyboard.releaseAll();
}
if (right4<threshold & up4<threshold & down4<threshold & left4>threshold){
Serial.println("left4");
Keyboard.write('O');
delay(300);
Keyboard.releaseAll();
}
if (right5<threshold & up5<threshold & down5<threshold & left5>threshold){
Serial.println("left5");
Keyboard.write('P');
delay(300);
Keyboard.releaseAll();
}
}
MD as in muscular dystrophy? What about a button on a table or attached to a pedal depending on how the user is able to interact that "activates" the secondary set of key definitions? Would a momentary off-on-off (or on-off-on and use the internal pullup resistor in setup() which reverses the logic) work for you?
So
#include <Keyboard.h>
const int threshold = 800;
int up4 = 0;
int down4 = 0;
int right4 = 0;
int left4 = 0;
int up5 = 0;
int down5 = 0;
int right5 = 0;
int left5 = 0;
int yellow4 = A0; // down
int white4 = A1;//left
int red4 = A2;//up
int blue4 = A3;//right
int yellow5 = A4; //down
int white5 = A5; //left
int red5 = A6; //up
int blue5 = A7;//right
const int userPedal = 2;
int pedalState;
void setup() {
pinMode(userPedal, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // initialize LED key set indicator to, say, on
pedalState == HIGH; //initialize to key set A
}
void loop() {
if (digitalRead(userPedal) == LOW) {
delay(10); // read again below
pedalState = digitalRead(userPedal); // stabilize first read, this will debounce button in basic way
while (pedalState == LOW) {
digitalWrite(LED_BUILTIN, LOW);
keyDefsB();
}
}
if (digitalRead(userPedal) == HIGH) {
delay(10);
pedalState = digitalRead(userPedal);
while (pedalState == HIGH) {
digitalWrite(LED_BUILTIN, HIGH);
keyDefsA();
}
}
}
void keyDefsA() {
int up4 = analogRead(red4);
int right4 = analogRead(blue4);
int down4 = analogRead(yellow4);
int left4 = analogRead(white4);
int up5 = analogRead(red5);
int right5 = analogRead(blue5);
int down5 = analogRead(yellow5);
int left5 = analogRead(white5);
if (right4 > threshold & up4 < threshold & down4 < threshold & left4 < threshold) {
Serial.println("right4");
Keyboard.write('L');
delay(300);
Keyboard.releaseAll();
}
if (right5 > threshold & up5 < threshold & down5 < threshold & left5 < threshold) {
Serial.println("right5");
Keyboard.write('Y');
delay(300);
Keyboard.releaseAll();
}
if (right4<threshold & up4>threshold & down4 < threshold & left4 < threshold) {
Serial.println("up4");
Keyboard.write('M');
delay(300);
Keyboard.releaseAll();
}
if (right5<threshold & up5>threshold & down5 < threshold & left5 < threshold) {
Serial.println("up5");
Keyboard.write('R');
delay(300);
Keyboard.releaseAll();
}
if (right4 < threshold & up4<threshold & down4>threshold & left4 < threshold) {
Serial.println("down4");
Keyboard.write('N');
delay(300);
Keyboard.releaseAll();
}
if (right5 < threshold & up5<threshold & down5>threshold & left5 < threshold) {
Serial.println("down5");
Keyboard.write('Z');
delay(300);
Keyboard.releaseAll();
}
if (right4 < threshold & up4 < threshold & down4<threshold & left4>threshold) {
Serial.println("left4");
Keyboard.write('O');
delay(300);
Keyboard.releaseAll();
}
if (right5 < threshold & up5 < threshold & down5<threshold & left5>threshold) {
Serial.println("left5");
Keyboard.write('P');
delay(300);
Keyboard.releaseAll();
}
}
void keyDefsB() {
// whatever your secondary set is
}
(this compiled for me with Due(Programming port) selected as I know that board supports this library)
Thank you!
I want to try this, however, can any sensor be used as a pullup_input?
You need a global or a static variable to hold a mode indicating if sticky keys is active or not. Below is to give you the idea.
void loop()
{
static bool stickykeyActive = false;
if(digitalRead(stickykeyButtonPin) == ISPRESSED)
{
stickykeyActive = true;
}
if(any of the buttons pressed)
{
if(stickykeyActive == true)
{
send alternate key
stickykeyActive = false;
}
else
{
send normal key
}
}
}
I have never tried the INPUT_PULLUP with anything other than a pushbutton, but I think its a 20k resistor value so however you use that, I suppose it would work. Take a look at this, explains better than I could:
https://www.arduino.cc/en/Tutorial/Foundations/DigitalPins
Any sensor that has an active pull down (low impedance switch to ground) can. Most don't, they have a sink-source digital level signal.
Never really thought about this. Learn something every day!
Is there any way to know if my sensor has n active pull down?
this is my sensor : Force Sensor Interlink
Data Sheet : https://media.digikey.com/pdf/Data%20Sheets/Interlink%20Electronics.PDF/4-Zone_Mouse_Sensor_RevB.pdf
That device has no active circuitry or switches, just an internal resistor array. So you need to interface it to a circuit that responds to resistance changes. I guess you could find a way to interface it to the analog input pins.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.