I have created two sketches for the Pro Micro, one sends media control messages to VLC Player over USB while the other sends page-up and page-down commands to MS Word over USB. They both verify and work as designed. The problem occurs when I combine them into one sketch for the Pro Micro where they share a 6 button foot-switch and USB connection.
When I try to verify the sketch I get the error message as follows.
Arduino: 1.8.13 (Windows 7), Board: "SparkFun Pro Micro, ATmega32U4 (5V, 16 MHz)"
In file included from c:\users\mac\documents\arduino\libraries\hid-project\src\hid-apis\KeyboardAPI.h:29:0,
from c:\users\mac\documents\arduino\libraries\hid-project\src\hid-apis\defaultkeyboardapi.h:27,
from C:\Users\mac\Documents\Arduino\libraries\HID-Project\src/SingleReport/BootKeyboard.h:30,
from C:\Users\mac\Documents\Arduino\libraries\HID-Project\src/HID-Project.h:50,
from F:\Technical\Arduino\page_media_control_A\page_media_control_A.ino:6:
c:\users\mac\documents\arduino\libraries\hid-project\src\keyboardlayouts\improvedkeylayouts.h:54:21: note: #pragma message: Using default ASCII layout for keyboard modules
#pragma message "Using default ASCII layout for keyboard modules"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from F:\Technical\Arduino\page_media_control_A\page_media_control_A.ino:5:0:
C:\Users\mac\Documents\Arduino\libraries\Keyboard\src/Keyboard.h:54:27: error: expected identifier before numeric constant
#define KEY_RETURN 0xB0
^
c:\users\mac\documents\arduino\libraries\hid-project\src\keyboardlayouts\improvedkeylayouts.h:103:5: note: in expansion of macro 'KEY_RETURN'
KEY_RETURN = 40, // Alias
^~~~~~~~~~
C:\Users\mac\Documents\Arduino\libraries\Keyboard\src/Keyboard.h:54:27: error: expected '}' before numeric constant
#define KEY_RETURN 0xB0
Multiple libraries were found for "Keyboard.h"
^
Used: C:\Users\mac\Documents\Arduino\libraries\Keyboard
Not used: C:\Program Files (x86)\Arduino\libraries\Keyboard
c:\users\mac\documents\arduino\libraries\hid-project\src\keyboardlayouts\improvedkeylayouts.h:103:5: note: in expansion of macro 'KEY_RETURN'
KEY_RETURN = 40, // Alias
^~~~~~~~~~
C:\Users\mac\Documents\Arduino\libraries\Keyboard\src/Keyboard.h:54:27: error: expected unqualified-id before numeric constant
#define KEY_RETURN 0xB0
^
c:\users\mac\documents\arduino\libraries\hid-project\src\keyboardlayouts\improvedkeylayouts.h:103:5: note: in expansion of macro 'KEY_RETURN'
KEY_RETURN = 40, // Alias
^~~~~~~~~~
In file included from c:\users\mac\documents\arduino\libraries\hid-project\src\hid-apis\KeyboardAPI.h:29:0,
from c:\users\mac\documents\arduino\libraries\hid-project\src\hid-apis\defaultkeyboardapi.h:27,
from C:\Users\mac\Documents\Arduino\libraries\HID-Project\src/SingleReport/BootKeyboard.h:30,
from C:\Users\mac\Documents\Arduino\libraries\HID-Project\src/HID-Project.h:50,
from F:\Technical\Arduino\page_media_control_A\page_media_control_A.ino:6:
c:\users\mac\documents\arduino\libraries\hid-project\src\keyboardlayouts\improvedkeylayouts.h:521:1: error: expected declaration before '}' token
};
^
exit status 1
Error compiling for board SparkFun Pro Micro.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I do get the pragma message when verifying the media control sketch, but it seems to be informational only as the sketch verifies and runs properly. Something about having the HID-Project and Keyboard libraries together in one sketch causes a problem that causes the message about duplicate Keyboard libraries that does not occur when the page control sketch doesn't contain the media control statements. Code follows.
// page_media_control_A
// Mark Chambers 8/27/2023
// for Pro Micro
#include <Keyboard.h>
#include <HID-Project.h>
// constants won't change
const int pgup = 2;
const int pgdn = 3;
const int play = 4;
const int halt = 5;
const int rew = 6;
const int fwd = 7;
// variables will change
int pgupState; // the current reading from the input pins
int pgdnState;
int playState;
int haltState;
int rewState;
int fwdState;
int lastPgupState = HIGH; // the previous reading from the input pins
int lastPgdnState = HIGH;
int lastPlayState = HIGH;
int lastHaltState = HIGH;
int lastRewState = HIGH;
int lastFwdState = HIGH;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(pgup, INPUT_PULLUP);
pinMode(pgdn, INPUT_PULLUP);
pinMode(play, INPUT_PULLUP);
pinMode(halt, INPUT_PULLUP);
pinMode(rew, INPUT_PULLUP);
pinMode(fwd, INPUT_PULLUP);
Keyboard.begin();
Consumer.begin();
}
void loop() {
// read the state of the page up switch into a local variable:
int readingPgup = digitalRead(pgup);
// If the page up switch state changed, due to noise or pressing:
if (readingPgup != lastPgupState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingPgup != pgupState) {
pgupState = readingPgup;
// only send page up if the new button state is LOW
if (pgupState == LOW) {
Keyboard.write(0xD3); // page up, 0xD3, 211
}
}
}
// read the state of the page down switch into a local variable:
int readingPgdn = digitalRead(pgdn);
// If the page down switch state changed, due to noise or pressing:
if (readingPgdn != lastPgdnState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingPgdn != pgdnState) {
pgdnState = readingPgdn;
// only send page down if the new button state is LOW
if (pgdnState == LOW) {
Keyboard.write(0xD6); // page down, 0xD6, 214
}
}
}
// read the state of the play switch into a local variable:
int readingPlay = digitalRead(play);
// If the play switch state changed, due to noise or pressing:
if (readingPlay != lastPlayState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingPlay != playState) {
playState = readingPlay;
// only send play if the new button state is LOW
if (playState == LOW) {
Consumer.write(MEDIA_PLAY_PAUSE);
}
}
}
// read the state of the stop switch into a local variable:
int readingHalt = digitalRead(halt);
// If the stop switch state changed, due to noise or pressing:
if (readingHalt != lastHaltState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingHalt != haltState) {
haltState = readingHalt;
// only send stop if the new button state is LOW
if (haltState == LOW) {
Consumer.write(MEDIA_STOP);
}
}
}
// read the state of the jump back switch into a local variable:
int readingRew = digitalRead(rew);
// If the jump back switch state changed, due to noise or pressing:
if (readingRew != lastRewState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingRew != rewState) {
rewState = readingRew;
// only send jump back if the new button state is LOW
if (rewState == LOW) {
Consumer.write(MEDIA_PREVIOUS);
}
}
}
// read the state of the jump forward switch into a local variable:
int readingFwd = digitalRead(fwd);
// If the jump forward switch state changed, due to noise or pressing:
if (readingFwd != lastFwdState) {
// reset the debounce timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (readingFwd != fwdState) {
fwdState = readingFwd;
// only send jump forward if the new button state is LOW
if (fwdState == LOW) {
Consumer.write(MEDIA_NEXT);
}
}
}
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastPgupState = readingPgup;
lastPgdnState = readingPgdn;
lastPlayState = readingPlay;
lastHaltState = readingHalt;
lastRewState = readingRew;
lastFwdState = readingFwd;
}
Any guidance you can provide will be much appreciated.
Thanks, Mark