Hardware components | ||||||
![]() |
| × | 3 | |||
![]() |
| × | 5 | |||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
![]() |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 5 | ||||
| × | 18 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
![]() |
| |||||
| ||||||
| ||||||
| ||||||
|
Project Intro:
This project is design for MEGR 3171 Instrumentation UNCC. The purpose of this project is to reduce the movement that the user makes when typing one a keyboard. The intent is that the user experiences and increase is speed and comfort of use.
Project Explanation:
The keyboard uses linear soft-pots to register key strokes that are picked up by set of two Particle Argons. This data is then sent to a third particle argon using particle.publish that will respond to the Argons and also relay the data to a Arduino Lenardo through a Serial1.write(). The purpose of the Arduino is to directly communicate with a computer using a USB. The reason the Particle Argon did not perform this function is due to the keyboard emulation libraries only available to Arduino Lenoardo and like Arduinos.
The keyboard data is uploaded to Thingspeak.com to track the keystroke data. A like to the data is shown:
https://thingspeak.com/channels/880258
The soft-pots are mapped in such a way that there is 6 keys on each soft-pot, and each finger has a designated soft-pot. The layout of the characters from the tip of the senses are as followed with respect to the finger layout:
Thumb: Backspace - Space - Enter - x - y - z
Index: a - b - c - d - e - f
Middle: g - h - i - j - k - l
Ring: m - n - o - p - q - r
Pinky: s - t - u - v - w - Shift
More keys could easily be added, but for this project was just a concept. When the 'shift' is pressed, the letters will then be capitalized.
Project Problems and Critiques:
There are several problems that need to be change in order to make this project run much smoother.
- Use higher quality soft-pot. The soft-pots that were used are not extremely accurate but is just fine for the concept of the product.
- Using only the Arduino. The class project required the use of three Argons but the project would be much better to just use one Arduino.
- The keyboard housing, especially around the soft-pots could have been designed better to improve aesthetics.
void myHandler(const char *event, const char *data) {
String responce = "0";
if (strcmp(data, "0")==0) {}
else if (strcmp(data, "1")==0){
Serial1.write(1);
responce = "10"; }
else if (strcmp(data, "2")==0){
Serial1.write(2);
responce = "10"; }
else if (strcmp(data, "3")==0){
Serial1.write(3);
responce = "10"; }
else if (strcmp(data, "4")==0){
Serial1.write(4);
responce = "10"; }
else if (strcmp(data, "5")==0){
Serial1.write(5);
responce = "10"; }
else if (strcmp(data, "6")==0){
Serial1.write(6);
responce = "10"; }
else if (strcmp(data, "7")==0){
Serial1.write(7);
responce = "10"; }
else if (strcmp(data, "8")==0){
Serial1.write(8);
responce = "10"; }
else if (strcmp(data, "9")==0){
Serial1.write(9);
responce = "10"; }
else if (strcmp(data, "10")==0){
Serial1.write(10);
responce = "10"; }
else if (strcmp(data, "11")==0){
Serial1.write(11);
responce = "10"; }
else if (strcmp(data, "12")==0){
Serial1.write(12);
responce = "10"; }
else if (strcmp(data, "13")==0){
Serial1.write(13);
responce = "10"; }
else if (strcmp(data, "14")==0){
Serial1.write(14);
responce = "10"; }
else if (strcmp(data, "15")==0){
Serial1.write(15);
responce = "10"; }
else if (strcmp(data, "16")==0){
Serial1.write(16);
responce = "10"; }
else if (strcmp(data, "17")==0){
Serial1.write(17);
responce = "10"; }
else if (strcmp(data, "18")==0){
Serial1.write(18);
responce = "5"; }
else if (strcmp(data, "19")==0){
Serial1.write(19);
responce = "5"; }
else if (strcmp(data, "20")==0){
Serial1.write(20);
responce = "5"; }
else if (strcmp(data, "21")==0){
Serial1.write(21);
responce = "5"; }
else if (strcmp(data, "22")==0){
Serial1.write(22);
responce = "5"; }
else if (strcmp(data, "23")==0){
Serial1.write(23);
responce = "5"; }
else if (strcmp(data, "24")==0){
Serial1.write(24);
responce = "5"; }
else if (strcmp(data, "25")==0){
Serial1.write(25);
responce = "5"; }
else if (strcmp(data, "26")==0){
Serial1.write(26);
responce = "5"; }
else if (strcmp(data, "27")==0){
Serial1.write(27);
responce = "5"; }
else if (strcmp(data, "28")==0){
Serial1.write(28);
responce = "5"; }
else if (strcmp(data, "29")==0){
Serial1.write(29);
responce = "5"; }
else if (strcmp(data, "30")==0){
Serial1.write(30);
responce = "5"; }
else {}
Particle.publish("myresponce", responce, PRIVATE);
delay(1000);
}
void setup() {
Serial1.begin(9600);
}
void loop() {
Particle.subscribe("Key_Stroke", myHandler, MY_DEVICES);
delay(1000);
}
void myHandler(const char *event, const char *data) {
if (strcmp(data, "10")==0){
digitalWrite(D7, HIGH);
delay(500);
digitalWrite(D7, LOW);
}
else {
}
}
void setup() {
pinMode(A1, INPUT); // Thumb Finger
pinMode(A2, INPUT); // Index Finger
pinMode(A3, INPUT); // Middle Finger
pinMode(D7, OUTPUT);
}
int arr[30] = {0};
void loop() {
int td = 10;
int t = 50;
int n = 8;
int i = 1;
delay(td);
int thumbfinger = analogRead(A1); // 0 - 4095 range
int thumb = map(thumbfinger, 0, 4095, 0, 7); // 0 - 7 range
delay(td);
int indexfinger = analogRead(A2); // 0 - 4095 range
int index = map(indexfinger, 0, 4095, 0, 7); // 0 - 7 range
delay(td);
int middlefinger = analogRead(A3); // 0 - 4095 range
int middle = map(middlefinger, 0, 4095, 0, 7); // 0 - 7 range
String Data = String(0);
while (i < 19){
if (arr[i]>16){
memset(arr, 0, sizeof(arr));
}
i++;
}
switch(thumb) {
case 0:
Data = String(0);
break;
case 1:
arr[1]++;
if (arr[1] > n+8){
memset(arr, 0, sizeof(arr));
Data = String(1);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 2:
arr[2]++;
if (arr[2] > n+3){
memset(arr, 0, sizeof(arr));
Data = String(2);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 3:
arr[3]++;
if (arr[3] > n){
memset(arr, 0, sizeof(arr));
Data = String(3);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 4:
arr[4]++;
if (arr[4] > n){
memset(arr, 0, sizeof(arr));
Data = String(4);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 5:
arr[5]++;
if (arr[5] > n){
memset(arr, 0, sizeof(arr));
Data = String(5);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 6:
arr[6]++;
if (arr[6] > n){
memset(arr, 0, sizeof(arr));
Data = String(6);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
default:
Data = String(0);
break;
}
switch(index){
case 0:
Data = String(0);
break;
case 1:
arr[7]++;
if (arr[7] > n+8){
memset(arr, 0, sizeof(arr));
Data = String(7);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 2:
arr[8]++;
if (arr[8] > n+3){
memset(arr, 0, sizeof(arr));
Data = String(8);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 3:
arr[9]++;
if (arr[9] > n){
memset(arr, 0, sizeof(arr));
Data = String(9);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 4:
arr[10]++;
if (arr[10] > n){
memset(arr, 0, sizeof(arr));
Data = String(10);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 5:
arr[11]++;
if (arr[11] > n){
memset(arr, 0, sizeof(arr));
Data = String(11);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 6:
arr[12]++;
if (arr[12] > n){
memset(arr, 0, sizeof(arr));
Data = String(12);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
default:
Data = String(0);
break;
}
switch(middle) {
case 0:
Data = String(0);
break;
case 1:
arr[13]++;
if (arr[13] > n+8){
memset(arr, 0, sizeof(arr));
Data = String(13);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 2:
arr[14]++;
if (arr[14] > n+3){
memset(arr, 0, sizeof(arr));
Data = String(14);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 3:
arr[15]++;
if (arr[15] > n){
memset(arr, 0, sizeof(arr));
Data = String(15);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 4:
arr[16]++;
if (arr[16] > n){
memset(arr, 0, sizeof(arr));
Data = String(16);
delay(t);
}
break;
case 5:
arr[17]++;
if (arr[17] > n){
memset(arr, 0, sizeof(arr));
Data = String(17);
delay(t);
}
break;
case 6:
arr[18]++;
if (arr[18] > n){
memset(arr, 0, sizeof(arr));
Data = String(18);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
default:
Data = String(0);
break;
}
Particle.subscribe("res", myHandler, MY_DEVICES);
}
void myHandler(const char *event, const char *data) {
if (strcmp(data, "5")==0){
digitalWrite(D7, HIGH);
delay(500);
digitalWrite(D7, LOW);
}
else {
}
}
void setup() {
pinMode(A1, INPUT); // forth Finger
pinMode(A2, INPUT); // pinky Finger
pinMode(D7, OUTPUT);
}
int arr[30] = {0};
void loop() {
int td = 10;
int t = 50;
int n = 8;
int i = 1;
delay(td);
int fourthfinger = analogRead(A1); // 0 - 4095 range
int fourth = map(fourthfinger, 0, 4095, 0, 7); // 0 - 7 range
delay(td);
int pinkyfinger = analogRead(A2); // 0 - 4095 range
int pinky = map(pinkyfinger, 0, 4095, 0, 7); // 0 - 7 range
String Data = String(0);
while (i < 19){
if (arr[i]>16){
memset(arr, 0, sizeof(arr));
}
i++;
}
switch(fourth) {
case 0:
Data = String (0);
break;
case 1:
arr[1]++;
if (arr[1] > n+8){
memset(arr, 0, sizeof(arr));
Data = String (19);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 2:
arr[2]++;
if (arr[2] > n+3){
memset(arr, 0, sizeof(arr));
Data = String (20);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 3:
arr[3]++;
if (arr[3] > n){
memset(arr, 0, sizeof(arr));
Data = String (21);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 4:
arr[4]++;
if (arr[4] > n){
memset(arr, 0, sizeof(arr));
Data = String (22);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 5:
arr[5]++;
if (arr[5] > n){
memset(arr, 0, sizeof(arr));
Data = String (23);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 6:
arr[6]++;
if (arr[6] > n){
memset(arr, 0, sizeof(arr));
Data = String (24);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
default:
Data = String (0);
break;
}
switch(pinky){
case 0:
Data = String (0);
break;
case 1:
arr[7]++;
if (arr[7] > n+8){
memset(arr, 0, sizeof(arr));
Data = String (25);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 2:
arr[8]++;
if (arr[8] > n+3){
memset(arr, 0, sizeof(arr));
Data = String (26);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 3:
arr[9]++;
if (arr[9] > n){
memset(arr, 0, sizeof(arr));
Data = String (27);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 4:
arr[10]++;
if (arr[10] > n){
memset(arr, 0, sizeof(arr));
Data = String (28);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 5:
arr[11]++;
if (arr[11] > n){
memset(arr, 0, sizeof(arr));
Data = String (29);Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
case 6:
arr[12]++;
if (arr[12] > n){
memset(arr, 0, sizeof(arr));
Data = String (30);
Particle.publish("Key_Stroke", Data, PRIVATE);
delay(1000);
delay(t);
}
break;
default:
Data = String (0);
break;
}
Particle.subscribe("res", myHandler, MY_DEVICES);
}
#include <Keyboard.h>
char enterKey = KEY_LEFT_CTRL;
char backspaceKey = KEY_BACKSPACE;
char shiftKey = KEY_RIGHT_SHIFT;
void setup() {
Serial1.begin(9600);
Keyboard.begin();
}
void loop() {
int t = 50;
int n = 4;
switch (Serial1.read()){
case 0:
break;
case 1:
Keyboard.press(backspaceKey);
Keyboard.release(backspaceKey);
break;
case 2:
Keyboard.print(" ");
break;
case 3:
Keyboard.press(enterKey);
Keyboard.release(enterKey);
break;
case 4:
Keyboard.press('x');
Keyboard.releaseAll();
break;
case 5:
Keyboard.press('y');
Keyboard.releaseAll();
break;
case 6:
Keyboard.press('z');
Keyboard.releaseAll();
break;
case 7:
Keyboard.press('a');
Keyboard.releaseAll();
break;
case 8:
Keyboard.press('b');
Keyboard.releaseAll();
break;
case 9:
Keyboard.press('c');
Keyboard.releaseAll();
break;
case 10:
Keyboard.press('d');
Keyboard.releaseAll();
break;
case 11:
Keyboard.press('e');
Keyboard.releaseAll();
break;
case 12:
Keyboard.press('f');
Keyboard.releaseAll();
break;
case 13:
Keyboard.press('g');
Keyboard.releaseAll();
break;
case 14:
Keyboard.press('h');
Keyboard.releaseAll();
break;
case 15:
Keyboard.press('i');
Keyboard.releaseAll();
break;
case 16:
Keyboard.press('j');
Keyboard.releaseAll();
break;
case 17:
Keyboard.press('k');
Keyboard.releaseAll();
break;
case 18:
Keyboard.press('l');
Keyboard.releaseAll();
break;
case 19:
Keyboard.press('m');
Keyboard.releaseAll();
break;
case 20:
Keyboard.press('n');
Keyboard.releaseAll();
break;
case 21:
Keyboard.press('o');
Keyboard.releaseAll();
break;
case 22:
Keyboard.press('p');
Keyboard.releaseAll();
break;
case 23:
Keyboard.press('q');
Keyboard.releaseAll();
break;
case 24:
Keyboard.press('r');
Keyboard.releaseAll();
break;
case 25:
Keyboard.press('s');
Keyboard.releaseAll();
break;
case 26:
Keyboard.press('t');
Keyboard.releaseAll();
break;
case 27:
Keyboard.press('u');
Keyboard.releaseAll();
break;
case 28:
Keyboard.press('v');
Keyboard.releaseAll();
break;
case 29:
Keyboard.press('w');
Keyboard.releaseAll();
break;
case 30:
Keyboard.press(shiftKey);
Keyboard.release(shiftKey);
break;
default:
break;
}
}
Comments