Created
December 30, 2020 09:36
-
-
Save dentex/98e6c38dd6b1af2cc13558d9303c3a0e to your computer and use it in GitHub Desktop.
Arduino sketch to Zoom in/out view and increase/decrease brush size in Krita, using a Digispark ATtiny85 board
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Kritary - Krita Rotary Zoom and Brush Size Controller | |
* [Using a Digispark (ATtiny85) and a rotary encoder] | |
* | |
* Copyright (C) 2020 Samuele RINI <samuele.rini76 [AT] gmail.com> | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
* | |
* | |
* | |
* | |
* ###################################################################################### | |
* Realized adapting and modifing the two amazing pieces | |
* of code, [1] and [2], as noted below: | |
* ###################################################################################### | |
* | |
* | |
* | |
* | |
* ##### | |
* # 1 # -------------------------------------------------------------------------------- | |
* ##### | |
* | |
* ===== T H E K N O B ===== | |
* Media Controller Mk III | |
* ----- By Frank Lumien ----- | |
* www.lumien.se | |
* =========================== | |
* Arduino code by: | |
* IAmOrion aka James Tanner | |
* =========================== | |
* | |
* Version 2.0 | |
* Changes in this fork | |
* FUNCTIONS -------------------- | |
* Turn knob left: Volume down "-" to zoom out | |
* Turn knob right: Volume up "+" to zoom in | |
* Press knob: Play & Pause (alternating) zoom reset | |
* Press and turn knob left: Previous track decrease brush size | |
* Press and turn knob right: Next track increase brush size | |
* | |
* Note: You can change all of these functions, see Settings.h for more. | |
* | |
* PINOUT, Digispark to KY-040 | |
* P0 to CLK | |
* P2 to DT | |
* P5 to SW // RESET disabled | |
* VIN to GND // reversed | |
* GND to +5V // reversed | |
* Note: The position of these pins may depend on your board and encoder. | |
* If you have already soldered or if The Knob doesn’t behave as expected, | |
* you can adjust the pin settings in Settings.h | |
* | |
* CONNECTING | |
* See https://digistump.com/wiki/digispark/tutorials/connecting for how | |
* to connect, get drivers and add set up Arduino for the Digispark bord. | |
* | |
* Set board to "Digispark (Default - 16.5Mhz)" | |
* | |
* COMPILING | |
* Get the Trinket library from https://github.com/adafruit/Adafruit-Trinket-USB/tree/master/TrinketHidCombo | |
* When compiling you will likely get warning messages related to the Trinket | |
* library. This is normal and does not mean that something is wrong. As long | |
* as the compilation finishes, you are good to go. | |
* | |
* ##### | |
* # 2 # -------------------------------------------------------------------------------- | |
* ##### | |
* | |
* TinyMultimediaController - Multimedia controller using a Digispark | |
* (ATtiny85) and a rotary encoder | |
* | |
* Copyright (C) 2018 Costin STROIE <[email protected]> | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#include "DigiKeyboard.h" | |
//Pin settings | |
#define encoderPinA 2 // DT -- (volume DOWN) | |
#define encoderPinB 0 // CLK - (volume UP) | |
#define encoderButton 5 | |
#define ROTARY_LED 1 | |
// LED stuff | |
bool ledLight = false; // Status flag for the LED (on or off) | |
unsigned long ledTimeout = 0UL; // The time when the LED will turn off | |
unsigned long ledDelay = 30UL; // Time delay after which the LED turns off | |
// Function settings. To change any of the functions, replace | |
// the MMKEY_* commands with any of the examples below. | |
// all actions will be done with the | |
// LEFT CONTROL modifier, in the sketch | |
#define LEFT_ACTION 0x38 // "-" | |
#define LEFT_ACTION_MODE1 KEY_8 | |
#define RIGHT_ACTION 0x30 // "+" | |
#define RIGHT_ACTION_MODE1 KEY_9 | |
#define BUTTON_ACTION_SINGLE KEY_0 | |
#define TRINKET | |
#include <avr/power.h> | |
#define LATCHSTATE 3 | |
int buttonState = LOW, lastButtonState = LOW; | |
long lastDebounceTime = 0, debounceDelay = 50; | |
int _position = 0, _positionExt = 0; | |
int8_t _oldState; bool btnPressed=false, btnReleased=false, pressedRotary=false; | |
byte bitLed = _BV(ROTARY_LED); | |
const int8_t encoderStates[] = { | |
0, -1, 1, 0, | |
1, 0, 0, -1, | |
-1, 0, 0, 1, | |
0, 1, -1, 0 | |
}; | |
void setup() { | |
if (F_CPU == 16000000) clock_prescale_set(clock_div_1); | |
pinMode(encoderPinA, INPUT); | |
pinMode(encoderPinB, INPUT); | |
pinMode(encoderButton, INPUT); | |
digitalWrite(encoderPinA, HIGH); | |
digitalWrite(encoderPinA, HIGH); | |
digitalWrite(encoderButton, LOW); | |
_oldState = 3; | |
// Set the LED pin to output and flash it longer | |
pinMode(ROTARY_LED, OUTPUT); | |
ledOn(); | |
ledTimeout += ledDelay; | |
// this is generally not necessary but with some older systems it seems to | |
// prevent missing the first character after a delay: | |
DigiKeyboard.sendKeyStroke(0); | |
DigiKeyboard.delay(250); | |
} | |
/** | |
Send a media keypress | |
@param key the key code to send | |
*/ | |
void keySend(byte key/* , byte mod */) { | |
// Turn the LED on | |
ledOn(); | |
// Send the key | |
DigiKeyboard.sendKeyStroke(key, MOD_CONTROL_LEFT); | |
} | |
/* | |
Turn the LED on and set the timeout | |
*/ | |
void ledOn() { | |
if (!ledLight) { | |
ledLight = true; | |
PORTB |= bitLed; | |
} | |
ledTimeout = millis() + ledDelay; | |
} | |
/* | |
Check the timeout and turn the LED off | |
@param nowMillis cached millis() | |
*/ | |
void ledOff(unsigned long nowMillis) { | |
if (ledLight and (nowMillis > ledTimeout)) { | |
ledLight = false; | |
PORTB &= ~bitLed; | |
} | |
} | |
void loop() { | |
// Keep the time | |
unsigned long nowMillis = millis(); | |
static int pos = 0; | |
tick(); | |
int newPos = getPosition(); | |
if (pos != newPos) { | |
if (newPos < pos) { | |
if (!btnPressed) { | |
keySend(LEFT_ACTION); | |
} else { | |
pressedRotary=true; | |
keySend(LEFT_ACTION_MODE1); | |
} | |
} | |
else if (newPos > pos){ | |
if (!btnPressed) { | |
keySend(RIGHT_ACTION); | |
} else { | |
pressedRotary=true; | |
keySend(RIGHT_ACTION_MODE1); | |
} | |
} | |
pos = newPos; | |
} | |
int reading = digitalRead(encoderButton); | |
if (reading != lastButtonState) { | |
lastDebounceTime = millis(); | |
} | |
if ((millis() - lastDebounceTime) > debounceDelay) { | |
if (reading != buttonState) { | |
buttonState = reading; | |
if (buttonState == HIGH) { | |
btnPressed=true; | |
} else if (buttonState == LOW){ | |
btnReleased=true; | |
} | |
} | |
} | |
lastButtonState = reading; | |
if (btnPressed == true && btnReleased ==true && pressedRotary ==false) { | |
keySend(BUTTON_ACTION_SINGLE); | |
btnPressed=false;btnReleased=false; | |
} else if (btnPressed == true && btnReleased == true && pressedRotary == true) { | |
//RELEASED_AFTER_HELD_ROTATION | |
btnPressed=false;btnReleased=false;pressedRotary=false; | |
} | |
// Turn the LED off, if timed out | |
ledOff(nowMillis); | |
} | |
int getPosition() { | |
return _positionExt; | |
} | |
void setPosition(int newPosition) { | |
_position = ((newPosition<<2) | (_position & 0x03)); | |
_positionExt = newPosition; | |
} | |
void tick(void) { | |
int sig1 = digitalRead(encoderPinA); | |
int sig2 = digitalRead(encoderPinB); | |
int8_t thisState = sig1 | (sig2 << 1); | |
if (_oldState != thisState) { | |
_position += encoderStates[thisState | (_oldState<<2)]; | |
if (thisState == LATCHSTATE) | |
_positionExt = _position >> 2; | |
_oldState = thisState; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment