I am making an keyboard with 5 buttons to control some Aplications on my computer.
Now i want to configure witch button, sends witch Character.
So i decided to use the serial control.
Now i just want to send an text string like: A,B,C,D,E
so button 1 is A
button 2 is B....
i wrote this code but its not working..
can anybody help me please?
/*
Keyboard control
by T.H. de Bruijn
Can be used to trigger Qlab..
*/
#include <EEPROM.h>
//define witch pins to use
const int button1 = 12;
const int button2 = 10;
const int button3 = 8;
const int button4 = 6;
const int button5 = 4;
//give some state value
int prevStateButton1 = HIGH;
int prevStateButton2 = HIGH;
int prevStateButton3 = HIGH;
int prevStateButton4 = HIGH;
int prevStateButton5 = HIGH;
//extra delay filter
const int DELAY = 250;
void setup() {
//setup the pin modes(inputs)
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
pinMode(button5, INPUT);
//Start the serial com
Serial.begin(9600);
//first some delay before starting the keyboard session
delay(10000);
//start Keyboard
Keyboard.begin();
delay(1000);
}
void loop() {
//read the buttons
int StateButton1 = digitalRead(button1);
int StateButton2 = digitalRead(button2);
int StateButton3 = digitalRead(button3);
int StateButton4 = digitalRead(button4);
int StateButton5 = digitalRead(button5);
//First check if there is an serial command
if (Serial.available() > 0) {
char CharButton1 = Serial.parseInt();
char CharButton2 = Serial.parseInt();
char CharButton3 = Serial.parseInt();
char CharButton4 = Serial.parseInt();
char CharButton5 = Serial.parseInt();
EEPROM.write(11, CharButton1);
EEPROM.write(12, CharButton2);
EEPROM.write(13, CharButton3);
EEPROM.write(14, CharButton4);
EEPROM.write(15, CharButton5);
}
//Check if the button is changed, if so.. execute
if ((StateButton1 != prevStateButton1) && (StateButton1 == HIGH)) {
Keyboard.write(EEPROM.read(11));
//delay filter
delay(DELAY);
}
else if ((StateButton2 != prevStateButton2) && (StateButton2 == HIGH)) {
Keyboard.write(EEPROM.read(12));
//delay filter
delay(DELAY);
}
else if ((StateButton3 != prevStateButton3) && (StateButton3 == HIGH)) {
Keyboard.write(EEPROM.read(13));
//delay filter
delay(DELAY);
}
else if ((StateButton4 != prevStateButton4) && (StateButton4 == HIGH)) {
Keyboard.write(EEPROM.read(14));
//delay filter
delay(DELAY);
}
else if ((StateButton5 != prevStateButton5) && (StateButton5 == HIGH)) {
Keyboard.write(EEPROM.read(15));
//delay filter
delay(DELAY);
}
// save the current state of the buttons
prevStateButton1 = StateButton1;
prevStateButton2 = StateButton2;
prevStateButton3 = StateButton3;
prevStateButton4 = StateButton4;
prevStateButton5 = StateButton5;
}
There are 5 buttons attached to the arduino micro.
each of these buttons can send an keyboard character( by using the keyboard lib).
I want to use the EEPROM & serial to change the Character for each button.
So the idea is that when i send the serial command: A,d,W,e,E
the Character A is written in EEPROM adr 11
the Character d is written in EEPROM adr 12
the Character W is written in EEPROM adr 13
ect..
I know how to make it work for just 1 EEPROM adress and when i am sending just 1 character by serial command:
The way to eat an elephant is one bite at a time...you're trying to swallow it whole. Break it down into pieces; of which your first task seems to be reading input. Try something like the following:
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("In setup(), start...");
}
void loop() {
char inChar;
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
inChar = Serial.read();
inChar = toupper(inChar); // Make everything uppercase
switch (inChar) {
case '\n': // Ignore newline
break;
case 'A':
Serial.println("Got an A");
// Put what you want to do as a function call here:
// ProcessButtonA();
break;
case 'B':
Serial.println("Got a B");
// Put what you want to do as a function call here:
// ProcessButtonB();
// Do for rest of them...
break;
case 'C':
Serial.println("Got a C");
break;
case 'D':
Serial.println("Got a D");
break;
case 'E':
Serial.println("Got an E");
break;
default:
Serial.println("I shouldn't be here.");
break;
}
}
}
Instead of hard-coding "11" as the eeprom address, use a variable and after the write do a ++ to increment it... The next write will be properly advanced. The total number of writes will be the starting address (initializer) - current variable value.
So the idea is that when i send the serial command: A,d,W,e,E
Why would you be calling Serial.parseInt() multiple times to read that data? There is not an int in sight.
Well i was just looking for some examples on the site and found this example: http://arduino.cc/en/Tutorial/ReadASCIIString
here they are sending 3 value's separated by comma's by serial.
what i want to do is sending 5 characters separated by comma's.
the difference between this is that in the example they are using values(0-255).
And I want to use characters.
the difference between this is that in the example they are using values(0-255).
Which need to be converted to ints. Hence, the parseInt() calls. That is NOT what you want to do, so why are you calling parseInt() anyway?
If you want to read one character, use read(), not parseInt().
Of course, parseInt() manages the waiting for serial data, and causes skipping over the commas. Those are tasks you will need to perform.
Ok, but i am not sending just one character, im sending an string(A,B,C,D,E) so when i do serial.read() it wil output A,B,C,D,E.
then i need to read the first char(A) of the string and outputing it in the EEPROM.
Then i need to read the 2th char(B) of the string and outputting it in the next EEPROM address.
Ok, but i am not sending just one character, im sending an string(A,B,C,D,E)
Each piece is one character. Why not make life easy for yourself. Stop sending the commas. Do nothing until there are 5 or more characters to read, and read 5 characters?
Get rid of the String class completely.
if(Serial.available() >= 5)
{
char stuff[5];
for(byte i=0; i<5; i++)
{
stuff[i] = Serial.read();
}
// Do something with the 5 characters in stuff
}
@Paul: I've noticed in situations such as these you present the solution above while I seem to see it as something like:
int charsRead;
char buff[10];
if (Serial.available() > 0) {
charsRead = Serial.readBytesUntil('\n', buff, 9); // Read to newline or 9 chars max
buff[charsRead] = '\0'; // It's now a string...
// Do whatever
}
I know you're careful in your code and that you have a reason for not using this approach. What am I missing?
Your method handles the data as being sent, but then needs to parse the data. Ignoring the odd positions in the array is a form of parsing. Your method requires sending twice as much data as mine. Your method requires sending a carriage return but not a line feed.
But, if speed is not an issue (and it probably isn't), and the parsing is trivial (as in this case), and the serial monitor is sending the data, your method is just as good as mine.