Hello all! I am making a USB media controller with an Arduino Pro Micro. It uses 2 rotary encoders, one for "Volume" and one for page scrolling "Scroll". I am using a laptop touchpad for mouse cursor movement along with 2 tactile momentary switches for "Next " track and "Previous" track. Everything works well until I start moving the volume encoder a few clicks or the scroll encoder. The rest of the loop stops responding and I can then only change volume or scroll. Media play/ pause (connected to press switch on encoder) along with Next, Previous and all mouse functions will no longer function. If I reset the Arduino and don't touch the encoders, all other functions work properly (Mouse, Next track, Previous and Play/Pause). When I print any int to the serial monitor, the monitor halts when an Interrupt Service Routine is triggered. I'm sure it is something I have overlooked. Any assistance is greatly appreciated, thank you in advance!
// Download the HID and FAST LED Library before compiling
#include <HID-Project.h>
#include <HID-Settings.h>
#include "PS2Mouse.h"
#define DATA0 3 // To Encoder Data 0 - Interrupt Pin Volume
#define DATA1 2 // To Encoder Data 1 - Interrupt Pin Volume
#define DATA2 1 // To Encoder Data 0 - Interrupt Pin Scroll
#define DATA3 0 // To Encoder Data 1 - Interrupt Pin Scroll
#define MUTE 7 // To Touch Switch Data pin Mute
#define NEXT 6 // To Touch Switch Data pin Mute
#define PAUSE 8 // To Touch Switch Data pin Mute
#define PREVIOUS 5 // To Touch Switch Data pin Mute
PS2Mouse PS2mouse(10, 9); // 9,10 Mouse data and clock pins
int oldData0 = 0, oldData1 = 0, oldButtonState = 0, oldButtonState1 = 0, oldButtonState2 = 0, oldButtonState3 = 0; // To store the state of encoder
int oldData2 = 0, oldData3 = 0;
int val;
int b;
void setup() {
PS2mouse.begin();
pinMode(MUTE, INPUT);
pinMode(DATA0, INPUT);
pinMode(DATA1, INPUT);
pinMode(DATA2, INPUT);
pinMode(DATA3, INPUT);
pinMode(NEXT, INPUT);
pinMode(PREVIOUS, INPUT);
pinMode(PAUSE, INPUT);
digitalWrite(DATA0, HIGH);
digitalWrite(DATA1, HIGH);
digitalWrite(DATA2, HIGH);
digitalWrite(DATA3, HIGH);
digitalWrite(NEXT, HIGH);
digitalWrite(PREVIOUS, HIGH);
digitalWrite(PAUSE, HIGH);
attachInterrupt(digitalPinToInterrupt(DATA0), volume, CHANGE);
attachInterrupt(digitalPinToInterrupt(DATA1), volume, CHANGE);
attachInterrupt(digitalPinToInterrupt(DATA2), scroll, CHANGE);
attachInterrupt(digitalPinToInterrupt(DATA3), scroll, CHANGE);
delay(3000);
Consumer.begin();
}
void loop() {
{
uint8_t stat;
int x, y;
PS2mouse.getPosition(stat, x, y);
Mouse.move(x * 5, -y * 5, 0);
if (bitRead(stat, 0) == 1) {
Mouse.press();
}
else {
Mouse.release();
}
}
//MEDIA_NEXT right
int newButtonState1 = digitalRead(NEXT);
if (oldButtonState1 != newButtonState1) {
// If it did and the new button state is 1 (button pressed down)
if (newButtonState1 == 1) {
// See HID Project documentation for more Consumer keys
Consumer.write(MEDIA_NEXT);
}
oldButtonState1 = newButtonState1;
}
//MEDIA_PREVIOUS Left
int newButtonState2 = digitalRead(PREVIOUS);
if (oldButtonState2 != newButtonState2) {
// If it did and the new button state is 1 (button pressed down)
if (newButtonState2 == 1) {
// See HID Project documentation for more Consumer keys
Consumer.write(MEDIA_PREVIOUS);
}
oldButtonState2 = newButtonState2;
}
//Media PAUSE PLAY
int newButtonState3 = digitalRead(PAUSE);
if (oldButtonState3 != newButtonState3) {
// If it did and the new button state is 1 (button pressed down)
if (newButtonState3 == 1) {
val = 0;
Serial.println("Count reset!");
// See HID Project documentation for more Consumer keys
Consumer.write(MEDIA_PLAY_PAUSE);
;
}
oldButtonState3 = newButtonState3;
}
}
void scroll() // Encoder Interrupt Function
{
//Initalise Timer
TIMSK1 |= (1 << TOIE1);
TCCR1A &= (~(1 << WGM10)) & (~(1 << WGM11));
TCCR1B &= (~(1 << WGM12)) & (~(1 << WGM13));
TCCR1B |= (1 << CS12) | (1 << CS10);
TCCR1B &= (~(1 << CS11));
TCNT1 = 0;
int newData2 = digitalRead(DATA2);
int newData3 = digitalRead(DATA3);
if (newData2 != oldData2 || newData3 != oldData3) {
// Check both data pins and check if the state changed
// compared to the last cycle
if (!oldData2 && !oldData3 && !newData2 && newData3) {
Mouse.move(0, 0, 1);
}
if (!oldData2 && !oldData3 && newData2 && !newData3) {
Mouse.move(0, 0, -1);
}
oldData2 = newData2;
oldData3 = newData3;
}
}
void volume() // Encoder Interrupt Function
{
//Initalise Timer
TIMSK1 |= (1 << TOIE1);
TCCR1A &= (~(1 << WGM10)) & (~(1 << WGM11));
TCCR1B &= (~(1 << WGM12)) & (~(1 << WGM13));
TCCR1B |= (1 << CS12) | (1 << CS10);
TCCR1B &= (~(1 << CS11));
TCNT1 = 0;
int newData0 = digitalRead(DATA0);
int newData1 = digitalRead(DATA1);
if (newData0 != oldData0 || newData1 != oldData1) {
// Check both data pins and check if the state changed
// compared to the last cycle
if (!oldData0 && !oldData1 && !newData0 && newData1) {
Consumer.write(MEDIA_VOLUME_DOWN);
}
if (!oldData0 && !oldData1 && newData0 && !newData1) {
Consumer.write(MEDIA_VOLUME_UP);
}
oldData0 = newData0;
oldData1 = newData1;
}
}
ISR(TIMER1_OVF_vect) {
b = 16;
TCNT1 = 0;
TCCR1B &= ~(1 << CS12);
TCCR1B &= ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
}