I am working on a binary keyboard that uses 8 buttons, one button for each bit in the ASCII code. I've set it up to where it reads the button states and turns that into a string of 8 0's and 1's. The problem I am having is converting that string into it's ASCII code and printing to Serial.
For example something like this:
stringOne = "01000001"; // for A
//convert stringOne somehow
Serial.write(B01000001); // prints A to serial
Here is my full code if that helps any. It's not done yet, still working on the conversion issue, but any suggestions for how to optimize my code or any other ideas is also appreciated.
// left hand
const int buttonPin1 = 2; // the number of the button and its pin assignment
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int buttonPin4 = 5;
// right hand
const int buttonPin5 = 6;
const int buttonPin6 = 7;
const int buttonPin7 = 8;
const int buttonPin8 = 9;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;
int buttonState7 = 0;
int buttonState8 = 0;
String stringOne;
void setup()
{
Serial.begin(9600); // Start a serial connection at 9600 baud
// Sets the pins 2-10 as INPUT
pinMode(buttonPin1, INPUT); // button 1
pinMode(buttonPin2, INPUT); // button 2
pinMode(buttonPin3, INPUT); // button 3
pinMode(buttonPin4, INPUT); // button 4
pinMode(buttonPin5, INPUT); // button 5
pinMode(buttonPin6, INPUT); // button 6
pinMode(buttonPin7, INPUT); // button 7
pinMode(buttonPin8, INPUT); // button 8
}
void loop()
{
//Read the state of the buttons
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
buttonState5 = digitalRead(buttonPin5);
buttonState6 = digitalRead(buttonPin6);
buttonState7 = digitalRead(buttonPin7);
buttonState8 = digitalRead(buttonPin8);
//Turn button states into a binary string
stringOne = ""; //resets the string on each loop
stringOne.concat(buttonState1); //concats each binary value of the buttons
stringOne.concat(buttonState2);
stringOne.concat(buttonState3);
stringOne.concat(buttonState4);
stringOne.concat(buttonState5);
stringOne.concat(buttonState6);
stringOne.concat(buttonState7);
stringOne.concat(buttonState8);
Serial.write(); //Send the ASCII character to serial
}
Thanks aarondc. Your code is definitely a lot cleaner and more efficient. I learned quite a bit looking at your code, only it doesn't work. It compiles and uploads fine but does not print the binary or the characters. It will print an ASCII block thing after the binary only if I hold down the first button. Two blocks if I hold down the first two, three for the first three, etc. Nothing for any combination.
It looks like this for buttons 1-3.
The below is based on the IDE example code to see various outputs.
// zoomkat 5-28-13 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later
String readString;
void setup() {
Serial.begin(9600);
Serial.println("serial test 0021"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
delay(2); //delay to allow byte to arrive in input buffer
byte c = Serial.read();
//char c = Serial.read();
// print it out in many formats:
//Serial.println(c); // print as an ASCII-encoded decimal
Serial.println(c, DEC); // print as an ASCII-encoded decimal
Serial.println(c, HEX); // print as an ASCII-encoded hexadecimal
Serial.println(c, OCT); // print as an ASCII-encoded octal
Serial.println(c, BIN); // print as an ASCII-encoded binary
Serial.println();
readString += c;
}
if (readString.length() >0) {
Serial.println("Decimal values of bytes sent");
Serial.println(readString);
Serial.println("Done!");
Serial.println();
readString="";
}
}
Hmm, i tried implementing your code Aarondc and asciiValue seems to only return a 0 or a 1.
Also, I am not sure what you mean about the "0b". Perhaps if you could post a more complete code. Still pretty new to the Arduino and probably in over my head.
Sometimes (ok, always) it pays to KISS and do baby steps first. Don't try to finish the project. Do the first, smallest piece possible, and then slowly increase the complexity. Get rid of all your pins and reads and everything. Pretend you already have the data, and see if you can output it.
I see a lot of people with little coding experience jumping into the deep end with their projects, trying to finish it in one go. I've been programming a long time and never do that - ever. I always get the basic in/out working, then the processing.
Try this - and don't add anything (ie pin reading) until you get it working.
You chose the button pins nicely for doing PINx reading. You could have done it with just PIND if you could have used pins 0-7 instead of 2-9. But that would interfere with Rx and Tx.
Actually, it occurs to me that I did all those bits backwards. You might have to change all the shifted values to be the other way around.
Anyway, is that what you're looking for, or did you really want to convert the String to binary?
byte asciiCode = 0;
for (byte i = 0; i < 8; ++i)
asciiCode = asciiCode * 2 + stringOne.charAt(i) - '0';
Sorry for jumping in a bit late, but I think it would be easier to write the binary number by accessing the bits directly of an input buffer bit. No bit shifting needed.
I'd offer something like this: (note, I'm typing this in on my Transformer so it is untested and uncompiled and may have syntax errors and/or typos)
// Single byte input buffer
byte inputByte;
// Array of bytes for keyboard pin numbers
byte inputBits[] {2, 3, 4, 5, 6, 7, 8, 9}; // May need to reverse the order of these if the byte is backwards...
void setup()
{
Serial.begin(115200); // Change to your favorite baudrate
for (byte i = 0; i < 8; i++)
{
pinMode(inputBits[i], INPUT);
}
}
void loop()
{
keyboardInput();
Serial.print(F("Keyboard input is: 0b")); // Habit I've started putting diagnostic print strings within the F() macro to not waste precious SRAM on diagnostics...
Serial.println(inputByte,BIN); // let println do the hard work of converting the byte into binary notation ASCII
delay(100); // delay for this example so not to spam the SerialMonitor...
}
// Here is the magic. See http://arduino.cc/en/Reference/BitWrite for documentation on bitWrite()
void keyboardInput()
{
// No need to initialize the inputByte variable to anything because the following loop will positively write something to each and every bit.
for (int i = 0; i < 8; i++)
{
bitWrite(inputByte, i, digitalRead(inputBits[i])); // taking a bit of a shortcut here, hopefully the return of digitalRead() will work here
}
}
Serial.write(asciiCode); //Send the ASCII character to serial
}
It outputs an ASCII character to the serial although it appears it is out of order. For example it gives the character " ' " for the relative buttons of "01100110" which ideally should be "l". Is it a bit shifting issue?
I'm looking into the other code posted as I can. Getting late.
Serial.write(asciiCode); //Send the ASCII character to serial
}
It outputs an ASCII character to the serial although it appears it is out of order. For example it gives the character " ' " for the relative buttons of "01100110" which ideally should be "l". Is it a bit shifting issue?
I'm looking into the other code posted as I can. Getting late.
Yeah, getting late here too. But I'm not sure if this would actually work. AFAIK, digitalRead() returns a boolean value which the compiler handles as a byte. The boolean value FALSE I'm pretty sure is stored as 0b00000000, but I'm not sure how the boolean value TRUE is stored. Is it simply 1 (0b00000001), or is it 255 (as an unsigned char, which is 0b11111111, or -1 as a signed char). The above code would work if TRUE is stored as value 1, but would break for any other non-zero value being stored (all non-zero values evaluate to TRUE).
Also, if my mind isn't falling asleep on me, isn't 0b01100110 equivalent to 0x66? If so, according to an ASCII table I looked up, that should evaluate to the ASCII character 'f'.
How would 0b01100110 expose this type of error? It's a palindrome, so bit order isn't important. I'm not sure what the expected character (not binary number) is supposed to be a lower-case L (l), or a vertical bar (|) because of the display font. So, let's look at the reverse of both:
Lower-case L on the ASCII table is 0x6C, or 0b01101100. The bit reverse (or whatever the correct term is) would be 0b00110110 or 0x36 which is the ASCII character '6'. Not what he got...
Vertical bar on the ASCII table is 0x7C, or 0b01111100. The bit reverse would be 0b00111110 or 0x3E which is the ASCII character '>'. Again, not what he got...
So none of the three cases would a simple bit reversal give an apostrophe (which is 0x27 or 0b00100111). The apostrophe's bit reversal would be 0b11100100 or 0xE4, which should be the Greek letter sigma on the extended ASCII chart (the symbol commonly used for arithmetic sums).
Thanks TanHadron. That finally did it....Mostly. I can get some characters to output correctly. I think it may be a problem with my protoboard after all of that button mashing last night. Going to check the connections and see if that helps any. At least now I see the answer to my original problem.