Skip to content

Instantly share code, notes, and snippets.

@Grezzo
Last active December 11, 2015 15:00
Show Gist options
  • Save Grezzo/8c3ca525834b40a5cf57 to your computer and use it in GitHub Desktop.
Save Grezzo/8c3ca525834b40a5cf57 to your computer and use it in GitHub Desktop.
/*
* Monitor-Auto-Rotate v1
*
* Sketch that will change display orientation by using usb keyboard emultaion to
* press Ctrl+Alt+Up-Arrow or Ctrl+Alt+Right-Arrow (which are the default hotkeys
* to rotate the display on windows systems with Intel graphics drivers) when it
* senses (using a reed switch and a magnet) that the monitor has been physically
* rotated.
*
* Requires updating the Arduino's atmega8u2 USB firmware so that it can emulate
* a USB keyboard (this stops you from being able to upload sketches, so you must
* upoad the sketch before changing the firmware)
*
* USB HID firmware can be downloaded from:
* http://hunt.net.nz/users/darran/weblog/b3029/Arduino_UNO_Keyboard_HID_version_03.html
*
* The circuit:
* Reed switch attached from pin 12 to GND
* Magnet should pull reed switch closed when monitor is in portrait position
*/
#define KEY_LEFT_CTRL 0b00000001
#define KEY_LEFT_ALT 0b00000100
#define KEY_UP_ARROW 82
#define KEY_LEFT_ARROW 80
const int switchPin = 12; // the number of the pushbutton pin
int switchState; // the current reading from the switch pin
int lastSwitchState; // the previous reading from the switch pin
long lastDebounceTime = 0; // the last time the switch pin was toggled
long debounceDelay = 50; // the debounce time
uint8_t buf[8] = {0}; /* Keyboard report buffer */
void setup() {
pinMode(switchPin, INPUT_PULLUP);
Serial.begin(9600);
}
void sendKeyPress(byte modifier, byte key) {
buf[0] = modifier;
buf[2] = key;
Serial.write(buf, 8); // Send keypress
delay(100); //Give host time to read keypress
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Release key
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(switchPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastSwitchState) {
// reset the debouncing 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 (reading != switchState) {
switchState = reading;
if (switchState == HIGH) {
//Send hotkey for normal (landscape) orientation
sendKeyPress(KEY_LEFT_CTRL + KEY_LEFT_ALT, KEY_UP_ARROW);
//Serial.println("SEND UP");
} else {
//Send hotkey for portrait orientation
sendKeyPress(KEY_LEFT_CTRL + KEY_LEFT_ALT, KEY_LEFT_ARROW);
//Serial.println("SEND LEFT");
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastSwitchState:
lastSwitchState = reading;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment