forked from wirtz/BALibrary
parent
5c4be4bc2a
commit
10818bcd78
@ -0,0 +1,67 @@ |
||||
#define TGA_PRO_REVB |
||||
#define TGA_PRO_EXPAND_REV2 |
||||
|
||||
#include "BAGuitar.h" |
||||
|
||||
using namespace BALibrary; |
||||
|
||||
// Create physical controls for Expansion Board, 2 switches, 3 pots, 0 encoders, 2 LEDs
|
||||
BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, 0, BA_EXPAND_NUM_LED); |
||||
|
||||
void setup() { |
||||
delay(100); |
||||
Serial.begin(57600); |
||||
delay(500); // long delay to wait for Serial to init
|
||||
|
||||
// put your setup code here, to run once:
|
||||
Serial.println("Calibrating POT1"); |
||||
Potentiometer::Calib pot1Calib = Potentiometer::calibrate(BA_EXPAND_POT1_PIN); |
||||
if (pot1Calib.min == pot1Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } |
||||
|
||||
Serial.println("\nCalibrating POT2"); |
||||
Potentiometer::Calib pot2Calib = Potentiometer::calibrate(BA_EXPAND_POT2_PIN); |
||||
if (pot2Calib.min == pot2Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } |
||||
|
||||
Serial.println("\nCalibrating POT3"); |
||||
Potentiometer::Calib pot3Calib = Potentiometer::calibrate(BA_EXPAND_POT3_PIN); |
||||
if (pot3Calib.min == pot3Calib.max) { Serial.println("\n!!! The knob didn't appear to move. Are you SURE you're turning the right knob? !!!"); } |
||||
|
||||
// Create the controls using the calib values
|
||||
controls.addPot(BA_EXPAND_POT1_PIN, pot1Calib.min, pot1Calib.max, pot1Calib.swap); |
||||
controls.addPot(BA_EXPAND_POT2_PIN, pot2Calib.min, pot2Calib.max, pot2Calib.swap); |
||||
controls.addPot(BA_EXPAND_POT3_PIN, pot3Calib.min, pot3Calib.max, pot3Calib.swap); |
||||
|
||||
// Add the pushbuttons
|
||||
controls.addSwitch(BA_EXPAND_SW1_PIN); |
||||
controls.addSwitch(BA_EXPAND_SW2_PIN); |
||||
|
||||
// Setup the LEDs
|
||||
controls.addOutput(BA_EXPAND_LED1_PIN); |
||||
controls.setOutput(BA_EXPAND_LED1_PIN, 0); |
||||
controls.addOutput(BA_EXPAND_LED2_PIN); |
||||
controls.setOutput(BA_EXPAND_LED2_PIN, 0); |
||||
|
||||
Serial.println("DONE SETUP! Try turning knobs and pushing buttons!\n"); |
||||
|
||||
} |
||||
|
||||
void loop() { |
||||
// put your main code here, to run repeatedly:
|
||||
float value; |
||||
for (unsigned i=0; i<BA_EXPAND_NUM_POT; i++) { |
||||
if (controls.checkPotValue(i, value)) { |
||||
Serial.println(String("POT") + (i+1) + String(" new value: ") + value); |
||||
} |
||||
} |
||||
|
||||
// Check pushbuttons
|
||||
for (unsigned i=0; i<BA_EXPAND_NUM_SW; i++) { |
||||
if (controls.isSwitchToggled(i)) { |
||||
Serial.println(String("Button") + (i+1) + String(" pushed!")); |
||||
controls.toggleOutput(i); |
||||
} |
||||
} |
||||
|
||||
delay(10); |
||||
|
||||
} |
@ -0,0 +1,113 @@ |
||||
#include <MIDI.h> |
||||
|
||||
#define TGA_PRO_REVB |
||||
#define TGA_PRO_EXPAND_REV2 |
||||
|
||||
#include "BAGuitar.h" |
||||
|
||||
using namespace midi; |
||||
using namespace BAEffects; |
||||
using namespace BALibrary; |
||||
|
||||
AudioInputI2S i2sIn; |
||||
AudioOutputI2S i2sOut; |
||||
BAAudioControlWM8731 codec; |
||||
|
||||
//#define USE_EXT // uncomment this line to use External MEM0
|
||||
|
||||
#ifdef USE_EXT |
||||
// If using external SPI memory, we will instantiance an SRAM
|
||||
// manager and create an external memory slot to use as the memory
|
||||
// for our audio delay
|
||||
ExternalSramManager externalSram; |
||||
ExtMemSlot delaySlot; // Declare an external memory slot.
|
||||
|
||||
// Instantiate the AudioEffectAnalogDelay to use external memory by
|
||||
/// passing it the delay slot.
|
||||
AudioEffectAnalogDelay analogDelay(&delaySlot); |
||||
#else |
||||
// If using internal memory, we will instantiate the AudioEffectAnalogDelay
|
||||
// by passing it the maximum amount of delay we will use in millseconds. Note that
|
||||
// audio delay lengths are very limited when using internal memory due to limited
|
||||
// internal RAM size.
|
||||
AudioEffectAnalogDelay analogDelay(200.0f); // max delay of 200 ms.
|
||||
#endif |
||||
|
||||
AudioFilterBiquad cabFilter; // We'll want something to cut out the highs and smooth the tone, just like a guitar cab.
|
||||
|
||||
// Simply connect the input to the delay, and the output
|
||||
// to both i2s channels
|
||||
AudioConnection input(i2sIn,0, analogDelay,0); |
||||
AudioConnection delayOut(analogDelay, 0, cabFilter, 0); |
||||
AudioConnection leftOut(cabFilter,0, i2sOut, 0); |
||||
AudioConnection rightOut(cabFilter,0, i2sOut, 1); |
||||
|
||||
//////////////////////////////////////////
|
||||
// SETUP PHYSICAL CONTROLS
|
||||
//////////////////////////////////////////
|
||||
BAPhysicalControls controls(BA_EXPAND_NUM_SW, BA_EXPAND_NUM_POT, 0); |
||||
|
||||
int loopCount = 0; |
||||
|
||||
void setup() { |
||||
delay(100); |
||||
Serial.begin(57600); // Start the serial port
|
||||
delay(100); |
||||
|
||||
// Setup the controls
|
||||
controls.addSwitch(BA_EXPAND_SW1_PIN); |
||||
controls.addSwitch(BA_EXPAND_SW2_PIN); |
||||
controls.addPot(BA_EXPAND_POT1_PIN,
|
||||
|
||||
// Disable the codec first
|
||||
codec.disable(); |
||||
AudioMemory(128); |
||||
|
||||
// Enable the codec
|
||||
Serial.println("Enabling codec...\n"); |
||||
codec.enable(); |
||||
|
||||
// If using external memory request request memory from the manager
|
||||
// for the slot
|
||||
#ifdef USE_EXT |
||||
Serial.println("Using EXTERNAL memory"); |
||||
// We have to request memory be allocated to our slot.
|
||||
externalSram.requestMemory(&delaySlot, 500.0f, MemSelect::MEM0, true); |
||||
#else |
||||
Serial.println("Using INTERNAL memory"); |
||||
#endif |
||||
|
||||
// Besure to enable the delay. When disabled, audio is is completely blocked
|
||||
// to minimize resources to nearly zero.
|
||||
analogDelay.enable();
|
||||
|
||||
// Set some default values.
|
||||
// These can be changed using the controls on the Blackaddr Audio Expansion Board
|
||||
analogDelay.bypass(false); |
||||
analogDelay.mix(0.5f); |
||||
analogDelay.feedback(0.0f); |
||||
|
||||
//////////////////////////////////
|
||||
// AnalogDelay filter selection //
|
||||
// Uncomment to tryout the 3 different built-in filters.
|
||||
//analogDelay.setFilter(AudioEffectAnalogDelay::Filter::DM3); // The default filter. Naturally bright echo (highs stay, lows fade away)
|
||||
//analogDelay.setFilter(AudioEffectAnalogDelay::Filter::WARM); // A warm filter with a smooth frequency rolloff above 2Khz
|
||||
//analogDelay.setFilter(AudioEffectAnalogDelay::Filter::DARK); // A very dark filter, with a sharp rolloff above 1Khz
|
||||
|
||||
// Setup 2-stages of LPF, cutoff 4500 Hz, Q-factor 0.7071 (a 'normal' Q-factor)
|
||||
cabFilter.setLowpass(0, 4500, .7071); |
||||
cabFilter.setLowpass(1, 4500, .7071); |
||||
} |
||||
|
||||
void loop() { |
||||
|
||||
if (loopCount % 524288 == 0) { |
||||
Serial.print("Processor Usage, Total: "); Serial.print(AudioProcessorUsage()); |
||||
Serial.print("% "); |
||||
Serial.print(" analogDelay: "); Serial.print(analogDelay.processorUsage()); |
||||
Serial.println("%"); |
||||
} |
||||
loopCount++; |
||||
|
||||
|
||||
} |
@ -0,0 +1,19 @@ |
||||
// To give your project a unique name, this code must be
|
||||
// placed into a .c file (its own tab). It can not be in
|
||||
// a .cpp file or your main sketch (the .ino file).
|
||||
|
||||
#include "usb_names.h" |
||||
|
||||
// Edit these lines to create your own name. The length must
|
||||
// match the number of characters in your custom name.
|
||||
|
||||
#define MIDI_NAME {'B','l','a','c','k','a','d','d','r',' ','A','u','d','i','o',' ','T','G','A',' ','P','r','o'} |
||||
#define MIDI_NAME_LEN 23 |
||||
|
||||
// Do not change this part. This exact format is required by USB.
|
||||
|
||||
struct usb_string_descriptor_struct usb_string_product_name = { |
||||
2 + MIDI_NAME_LEN * 2, |
||||
3, |
||||
MIDI_NAME |
||||
}; |
@ -0,0 +1,148 @@ |
||||
/**************************************************************************//**
|
||||
* @file |
||||
* @author Steve Lascos |
||||
* @company Blackaddr Audio |
||||
* |
||||
* BAPhysicalControls is a general purpose class for handling an array of |
||||
* pots and switches. |
||||
* |
||||
* @copyright 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/>.
|
||||
*****************************************************************************/ |
||||
#ifndef __BAPHYSICALCONTROLS_H |
||||
#define __BAPHYSICALCONTROLS_H |
||||
|
||||
#include <vector> |
||||
#include <Encoder.h> |
||||
#include <Bounce.h> |
||||
|
||||
namespace BALibrary { |
||||
|
||||
class DigitalOutput { |
||||
public: |
||||
DigitalOutput(uint8_t pin) : m_pin(pin) {} |
||||
void set(int val); |
||||
void toggle(void); |
||||
|
||||
private: |
||||
uint8_t m_pin; |
||||
int m_val = 0; |
||||
}; |
||||
|
||||
class Potentiometer { |
||||
public: |
||||
struct Calib { |
||||
unsigned min; |
||||
unsigned max; |
||||
bool swap; |
||||
}; |
||||
Potentiometer(uint8_t pin, unsigned minCalibration, unsigned maxCalibration) |
||||
: m_pin(pin), m_swapDirection(false), m_minCalibration(minCalibration), m_maxCalibration(maxCalibration) {} |
||||
|
||||
Potentiometer(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection) |
||||
: m_pin(pin), m_swapDirection(swapDirection), m_minCalibration(minCalibration), m_maxCalibration(maxCalibration) {} |
||||
|
||||
bool getValue(float &value); |
||||
int getRawValue(); |
||||
void adjustCalibrationThreshold(float thresholdFactor); |
||||
static Calib calibrate(uint8_t pin); |
||||
|
||||
private: |
||||
uint8_t m_pin; |
||||
bool m_swapDirection; |
||||
unsigned m_minCalibration; |
||||
unsigned m_maxCalibration; |
||||
unsigned m_lastValue = 0; |
||||
unsigned m_lastValue2 = 0; |
||||
}; |
||||
|
||||
constexpr bool ENCODER_SWAP = true; |
||||
constexpr bool ENCODER_NOSWAP = false; |
||||
|
||||
class RotaryEncoder : public Encoder { |
||||
public: |
||||
RotaryEncoder(uint8_t pin1, uint8_t pin2, bool swapDirection = false, int divider = 1) : Encoder(pin1,pin2), m_swapDirection(swapDirection), m_divider(divider) {} |
||||
|
||||
int getChange(); |
||||
void setDivider(int divider); |
||||
|
||||
private: |
||||
bool m_swapDirection; |
||||
int32_t m_lastPosition = 0; |
||||
int32_t m_divider; |
||||
}; |
||||
|
||||
/// Specifies the type of control
|
||||
enum class ControlType : unsigned { |
||||
SWITCH_MOMENTARY = 0, ///< a momentary switch, which is only on when pressed.
|
||||
SWITCH_LATCHING = 1, ///< a latching switch, which toggles between on and off with each press and release
|
||||
ROTARY_KNOB = 2, ///< a rotary encoder knob
|
||||
POT = 3, ///< an analog potentiometer
|
||||
UNDEFINED = 255 ///< undefined or uninitialized
|
||||
}; |
||||
|
||||
class BAPhysicalControls { |
||||
public: |
||||
BAPhysicalControls() = delete; |
||||
BAPhysicalControls(unsigned numSwitches, unsigned numPots, unsigned numEncoders = 0, unsigned numOutputs = 0); |
||||
~BAPhysicalControls() {} |
||||
|
||||
/// add a rotary encoders to the controls
|
||||
/// @param pin1 the pin number corresponding to 'A' on the encoder
|
||||
/// @param pin2 the pin number corresponding to 'B' on the encoder
|
||||
/// @param swapDirection When true, reverses which rotation direction is positive, and which is negative
|
||||
/// @param divider optional, for encoders with high resolution this divides down the rotation measurement.
|
||||
/// @returns the index in the encoder vector the new encoder was placed at.
|
||||
unsigned addRotary(uint8_t pin1, uint8_t pin2, bool swapDirection = false, int divider = 1); |
||||
|
||||
/// add a switch to the controls
|
||||
/// @param pin the pin number connected to the switch
|
||||
/// @param intervalMilliseconds, optional, specifies the filtering time to debounce a switch
|
||||
/// @returns the index in the switch vector the new switch was placed at.
|
||||
unsigned addSwitch(uint8_t pin, unsigned long intervalMilliseconds = 10); |
||||
|
||||
/// add a pot to the controls
|
||||
/// @param pin the pin number connected to the wiper of the pot
|
||||
/// @param minCalibration the value corresponding to lowest pot setting
|
||||
/// @param maxCalibration the value corresponding to the highest pot setting
|
||||
unsigned addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration); |
||||
|
||||
/// add a pot to the controls
|
||||
/// @param pin the pin number connected to the wiper of the pot
|
||||
/// @param minCalibration the value corresponding to lowest pot setting
|
||||
/// @param maxCalibration the value corresponding to the highest pot setting
|
||||
/// @param swapDirection reverses the which direction is considered pot minimum value
|
||||
/// @param range the pot raw value will be mapped into a range of 0 to range
|
||||
unsigned addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection); |
||||
unsigned addOutput(uint8_t pin); |
||||
void setOutput(unsigned index, int val); |
||||
void toggleOutput(unsigned index); |
||||
int getRotaryAdjustUnit(unsigned index); |
||||
bool checkPotValue(unsigned index, float &value); |
||||
bool isSwitchToggled(unsigned index); |
||||
|
||||
private: |
||||
std::vector<Potentiometer> m_pots; |
||||
std::vector<RotaryEncoder> m_encoders; |
||||
std::vector<Bounce> m_switches; |
||||
std::vector<DigitalOutput> m_outputs; |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // BALibrary
|
||||
|
||||
|
||||
#endif /* __BAPHYSICALCONTROLS_H */ |
@ -0,0 +1,220 @@ |
||||
/*
|
||||
* BAPhysicalControls.cpp |
||||
* |
||||
* This file provides a class for handling physical controls such as |
||||
* switches, pots and rotary encoders. |
||||
* |
||||
* 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 "BAPhysicalControls.h" |
||||
|
||||
// These calls must be define in order to get vector to work on arduino
|
||||
namespace std { |
||||
void __throw_bad_alloc() { |
||||
Serial.println("Unable to allocate memory"); |
||||
abort(); |
||||
} |
||||
void __throw_length_error( char const*e ) { |
||||
Serial.print("Length Error :"); Serial.println(e); |
||||
abort(); |
||||
} |
||||
} |
||||
|
||||
namespace BALibrary { |
||||
|
||||
BAPhysicalControls::BAPhysicalControls(unsigned numSwitches, unsigned numPots, unsigned numEncoders, unsigned numOutputs) { |
||||
if (numSwitches > 0) { |
||||
m_switches.reserve(numSwitches); |
||||
} |
||||
if (numPots > 0) { |
||||
m_pots.reserve(numPots); |
||||
} |
||||
if (numEncoders > 0) { |
||||
m_encoders.reserve(numEncoders); |
||||
} |
||||
if (numOutputs > 0) { |
||||
m_outputs.reserve(numOutputs); |
||||
} |
||||
|
||||
} |
||||
|
||||
unsigned BAPhysicalControls::addRotary(uint8_t pin1, uint8_t pin2, bool swapDirection, int divider) { |
||||
m_encoders.emplace_back(pin1, pin2, swapDirection, divider); |
||||
pinMode(pin1, INPUT); |
||||
pinMode(pin2, INPUT); |
||||
return m_encoders.size()-1; |
||||
} |
||||
|
||||
unsigned BAPhysicalControls::addSwitch(uint8_t pin, unsigned long intervalMilliseconds) { |
||||
m_switches.emplace_back(pin, intervalMilliseconds); |
||||
pinMode(pin, INPUT); |
||||
return m_switches.size()-1; |
||||
} |
||||
|
||||
unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration) { |
||||
m_pots.emplace_back(pin, minCalibration, maxCalibration); |
||||
return m_pots.size()-1; |
||||
} |
||||
|
||||
unsigned BAPhysicalControls::addPot(uint8_t pin, unsigned minCalibration, unsigned maxCalibration, bool swapDirection) { |
||||
m_pots.emplace_back(pin, minCalibration, maxCalibration, swapDirection); |
||||
return m_pots.size()-1; |
||||
} |
||||
|
||||
unsigned BAPhysicalControls::addOutput(uint8_t pin) { |
||||
m_outputs.emplace_back(pin); |
||||
pinMode(pin, OUTPUT); |
||||
return m_outputs.size()-1; |
||||
} |
||||
|
||||
void BAPhysicalControls::setOutput(unsigned index, int val) { |
||||
if (index >= m_outputs.size()) { return; } |
||||
m_outputs[index].set(val); |
||||
} |
||||
|
||||
void BAPhysicalControls::toggleOutput(unsigned index) { |
||||
if (index >= m_outputs.size()) { return; } |
||||
m_outputs[index].toggle(); |
||||
} |
||||
|
||||
|
||||
int BAPhysicalControls::getRotaryAdjustUnit(unsigned index) { |
||||
if (index >= m_encoders.size()) { return 0; } // index is greater than number of encoders
|
||||
|
||||
int encoderAdjust = m_encoders[index].getChange(); |
||||
if (encoderAdjust != 0) { |
||||
// clip the adjust to maximum abs value of 1.
|
||||
int encoderAdjust = (encoderAdjust > 0) ? 1 : -1; |
||||
} |
||||
|
||||
return encoderAdjust; |
||||
} |
||||
|
||||
bool BAPhysicalControls::checkPotValue(unsigned index, float &value) { |
||||
if (index >= m_pots.size()) { return false;} // index is greater than number of pots
|
||||
return m_pots[index].getValue(value); |
||||
} |
||||
|
||||
bool BAPhysicalControls::isSwitchToggled(unsigned index) { |
||||
if (index >= m_switches.size()) { return 0; } // index is greater than number of switches
|
||||
Bounce &sw = m_switches[index]; |
||||
|
||||
if (sw.update() && sw.fallingEdge()) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
///////////////////////////
|
||||
|
||||
void DigitalOutput::set(int val) { |
||||
m_val = val; |
||||
digitalWriteFast(m_pin, m_val); |
||||
} |
||||
|
||||
void DigitalOutput::toggle(void) { |
||||
m_val = !m_val; |
||||
digitalWriteFast(m_pin, m_val); |
||||
} |
||||
|
||||
|
||||
bool Potentiometer::getValue(float &value) { |
||||
|
||||
unsigned val = analogRead(m_pin); // read the raw value
|
||||
// Return false if the value is the same as the last sample, or 2 samples ago. The second check is to
|
||||
// prevent oscillating between two values.
|
||||
if ((val == m_lastValue) || (val == m_lastValue2)) { |
||||
return false; |
||||
} |
||||
|
||||
// Otherwise update the last value
|
||||
m_lastValue = val; |
||||
// constrain it within the calibration values, them map it to the desired range.
|
||||
val = constrain(val, m_minCalibration, m_maxCalibration); |
||||
value = static_cast<float>(val - m_minCalibration) / static_cast<float>(m_maxCalibration); |
||||
if (m_swapDirection) { |
||||
value = 1.0f - value; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
int Potentiometer::getRawValue() { |
||||
return analogRead(m_pin); |
||||
} |
||||
|
||||
void Potentiometer::adjustCalibrationThreshold(float thresholdFactor) |
||||
{ |
||||
float threshold = m_maxCalibration * thresholdFactor; |
||||
m_maxCalibration -= static_cast<unsigned>(threshold); |
||||
m_minCalibration += static_cast<unsigned>(threshold); |
||||
} |
||||
|
||||
Potentiometer::Calib Potentiometer::calibrate(uint8_t pin) { |
||||
Calib calib; |
||||
|
||||
Serial.print("Calibration pin "); Serial.println(pin); |
||||
Serial.println("Move the pot fully counter-clockwise to the minimum setting and press any key then ENTER"); |
||||
while (true) { |
||||
delay(100); |
||||
if (Serial.available() > 0) { |
||||
calib.min = analogRead(pin); |
||||
while (Serial.available()) { Serial.read(); } |
||||
break; |
||||
} |
||||
} |
||||
|
||||
Serial.println("Move the pot fully clockwise to the maximum setting and press any key then ENTER"); |
||||
while (true) { |
||||
delay(100); |
||||
if (Serial.available() > 0) { |
||||
calib.max = analogRead(pin); |
||||
while (Serial.available()) { Serial.read(); } |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (calib.min > calib.max) { |
||||
unsigned tmp = calib.max; |
||||
calib.max = calib.min; |
||||
calib.min = tmp; |
||||
calib.swap = true; |
||||
} |
||||
|
||||
Serial.print("The calibration for pin "); Serial.print(pin); |
||||
Serial.print(" is min:"); Serial.print(calib.min); |
||||
Serial.print(" max:"); Serial.print(calib.max); |
||||
Serial.print(" swap: "); Serial.println(calib.swap); |
||||
|
||||
return calib; |
||||
} |
||||
|
||||
|
||||
int RotaryEncoder::getChange() { |
||||
int32_t newPosition = read(); |
||||
int delta = newPosition - m_lastPosition; |
||||
m_lastPosition = newPosition; |
||||
if (m_swapDirection) { delta = -delta; } |
||||
return delta/m_divider; |
||||
} |
||||
|
||||
void RotaryEncoder::setDivider(int divider) { |
||||
m_divider = divider; |
||||
} |
||||
|
||||
} // BALibrary
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue