So I have made a little code on my arduino Uno.
The goal is to use one button to cicle through some numbers and send the number to computer over USB as a keyboard.
The purpose is to trigger some movie clips in previously mapped software.
So you click the button once, nr 1 is sent to PC and the first clip is played. You press the button second time nr 2 is sent to PC and the second clip is played.
The code is here and if I use Serial monitor, it works correct symbols are shown. But if I convert the devise into HID, Windows shows some random CTRL+ALT stuff and controls. I don't really understand what is wrong. Could anyone help me?
My PC winXP recognises the Arduino as a HID. So there should not be a problem.
USB table is here. http://www.usb.org/developers/devclass_docs/Hut1_11.pdf
uint8_t buf[8] = {
0 }; /* Keyboard report buffer */
const byte switchPin = A0;
// switch is connected to pin A0
byte ledPin = 13; // led on pin 13
byte buttonPresses = 0; // how many times the button has been pressed
byte lastPressCount = 0; // to keep track of last press count
void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
digitalWrite(switchPin, HIGH); // set pullup resistor
Serial.begin(9600); // Set up serial communication at 9600bps
delay(200);
}
void loop(){
if (digitalRead(switchPin) == LOW) // check if button was pressed
{
buttonPresses++; // increment buttonPresses count
delay(600); // debounce switch
}
if (buttonPresses == 10) buttonPresses = 0; // rollover every 10th press
if (lastPressCount != buttonPresses) // only do output if the count has changed
{
Serial.print ("Button press count = "); // out to serial
Serial.println(buttonPresses, DEC);
if(buttonPresses == 0)
{
buf[0] = 39; // 0
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 1)
{
buf[0] = 30; // 1
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 2)
{
buf[0] = 31; // 2
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 3)
{
buf[0] = 32; // 3
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 4)
{
buf[0] = 0;
buf[2] = 0x21; // 4
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 5)
{
buf[0] = 34; // 5
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 6)
{
buf[0] = 35; // 6
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 7)
{
buf[0] = 36; // 7
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 8)
{
buf[0] = 37; // 8
Serial.write(buf, 8); // Send keypress
releaseKey();
}
else if(buttonPresses == 9)
{
buf[0] = 38; // 9
Serial.write(buf, 8); // Send keypress
releaseKey();
}
lastPressCount = buttonPresses; // track last press count
}
}
void releaseKey()
{
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Release key
delay(200);
}
I assume that you have all the tools to do this project. You have both .hex files, the one for HID and the one for serial converter. I also assume you have the programming software to switch between the two fuctions so you can easily go back and forth between Serial converter and HID.
After up update the firmware on the serial interface controller, does it appear as an HID device on your computer?
In HID mode, what is the interface baud rate? Are you sure that it is 9600 and not something higher?
You know that you can do
pinMode(switchPin, INPUT_PULLUP);
instead of
pinMode(switchPin, INPUT); // Set the switch pin as input
digitalWrite(switchPin, HIGH); // set pullup resistor
You might want to try something VERY simple like:
Press the button - say "Hello World"
Release the button - say "Goodbye World"
if (digitalRead(switchPin) == LOW) // check if button was pressed
{
buttonPresses++; // increment buttonPresses count
delay(600); // debounce switch
}
You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.
You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.
A 600 millisecond delay is not debouncing.
But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don't want to allow the button being pressed that frequently.
I will try to send text to confirm if the connection works.
Oh I tried this code. Its a random Key/ Random Delay. And this worked.
But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don’t want to allow the button being pressed that frequently.
It seems to me like you want to count once for each switch press, regardless of how long the switch is held down. If that isn’t what you want, forget I said anything.
Still, the 600 millisecond delay is not for debouncing, so your comment is wrong.
But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don't want to allow the button being pressed that frequently.
That means you're debouncing the user, not the switch. If you use the state change detection approach you only act when the state of the switch changes. The user could hold it down for minutes and it will only count once. When you simply check the state of the switch you increment the counter every time it checks, if the switch is pressed. Your work around is the long delay giving the user time to release the switch. This is debouncing the user. I used to do that until I figured it out.
Good point.
I will get to it once I have some hope to get the counter thing working.
So here is a code that works.
It sends a R each time I press the button. A0 is pulled low with resistor and goes high once the button is pressed.
/*
*
*/
//9.Aprill, 2000
uint8_t buf[8] = {
0 }; /* Keyboard report buffer */
const int button = A0; // Button input pin
int ButtonState = LOW; //
int val = 0; // button value
void setup()
{
Serial.begin(9600);
pinMode(button, INPUT);
delay(200);
}
void loop()
{
val = digitalRead(button); // read the button
delay(300); // wait, to reduce noise (debouncing stuff)
if (val == HIGH) // continue if the button is pressed
{
buf[2] = 0x15; // Letter R
Serial.write(buf, 8); // Send keypress
releaseKey();
}
}
void releaseKey()
{
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Release key
}
The next step would be to get the thing sending other letters or numbers (I actually need nubers from 0 to 9)
I was first thinking to program a counter. And use If/else if functions to send different numbers to PC.
I also found out that if I use Serial.print in the code and switch to Arduino keyboard, the thing will go nuts.
PaulS:
You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.
served:
so Why it should not be counted when its low?
PaulS was drawing your attention to the difference between a transition from HIGH to LOW vs. a LOW state.