Switch to Platformio
This commit is contained in:
parent
1397098e64
commit
2d03423b63
22 changed files with 2136 additions and 233 deletions
17
.idea/misc.xml
Normal file
17
.idea/misc.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="PlatformIOSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<PlatformioProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</PlatformioProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
<component name="PlatformIOWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
1
.pio/libdeps/attiny88/Encoder/.piopm
Normal file
1
.pio/libdeps/attiny88/Encoder/.piopm
Normal file
|
@ -0,0 +1 @@
|
|||
{"type": "library", "name": "Encoder", "version": "1.4.2", "spec": {"owner": "paulstoffregen", "id": 129, "name": "Encoder", "requirements": null, "uri": null}}
|
10
.pio/libdeps/attiny88/Encoder/Encoder.cpp
Executable file
10
.pio/libdeps/attiny88/Encoder/Encoder.cpp
Executable file
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "Encoder.h"
|
||||
|
||||
// Yes, all the code is in the header file, to provide the user
|
||||
// configure options with #define (before they include it), and
|
||||
// to facilitate some crafty optimizations!
|
||||
|
||||
Encoder_internal_state_t * Encoder::interruptArgs[];
|
||||
|
||||
|
969
.pio/libdeps/attiny88/Encoder/Encoder.h
Executable file
969
.pio/libdeps/attiny88/Encoder/Encoder.h
Executable file
|
@ -0,0 +1,969 @@
|
|||
/* Encoder Library, for measuring quadrature encoded signals
|
||||
* http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
* Copyright (c) 2011,2013 PJRC.COM, LLC - Paul Stoffregen <paul@pjrc.com>
|
||||
*
|
||||
* Version 1.2 - fix -2 bug in C-only code
|
||||
* Version 1.1 - expand to support boards with up to 60 interrupts
|
||||
* Version 1.0 - initial release
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef Encoder_h_
|
||||
#define Encoder_h_
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#elif defined(WIRING)
|
||||
#include "Wiring.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#include "pins_arduino.h"
|
||||
#endif
|
||||
|
||||
#include "utility/direct_pin_read.h"
|
||||
|
||||
#if defined(ENCODER_USE_INTERRUPTS) || !defined(ENCODER_DO_NOT_USE_INTERRUPTS)
|
||||
#define ENCODER_USE_INTERRUPTS
|
||||
#define ENCODER_ARGLIST_SIZE CORE_NUM_INTERRUPT
|
||||
#include "utility/interrupt_pins.h"
|
||||
#ifdef ENCODER_OPTIMIZE_INTERRUPTS
|
||||
#include "utility/interrupt_config.h"
|
||||
#endif
|
||||
#else
|
||||
#define ENCODER_ARGLIST_SIZE 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// All the data needed by interrupts is consolidated into this ugly struct
|
||||
// to facilitate assembly language optimizing of the speed critical update.
|
||||
// The assembly code uses auto-incrementing addressing modes, so the struct
|
||||
// must remain in exactly this order.
|
||||
typedef struct {
|
||||
volatile IO_REG_TYPE * pin1_register;
|
||||
volatile IO_REG_TYPE * pin2_register;
|
||||
IO_REG_TYPE pin1_bitmask;
|
||||
IO_REG_TYPE pin2_bitmask;
|
||||
uint8_t state;
|
||||
int32_t position;
|
||||
} Encoder_internal_state_t;
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(uint8_t pin1, uint8_t pin2) {
|
||||
#ifdef INPUT_PULLUP
|
||||
pinMode(pin1, INPUT_PULLUP);
|
||||
pinMode(pin2, INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(pin1, INPUT);
|
||||
digitalWrite(pin1, HIGH);
|
||||
pinMode(pin2, INPUT);
|
||||
digitalWrite(pin2, HIGH);
|
||||
#endif
|
||||
encoder.pin1_register = PIN_TO_BASEREG(pin1);
|
||||
encoder.pin1_bitmask = PIN_TO_BITMASK(pin1);
|
||||
encoder.pin2_register = PIN_TO_BASEREG(pin2);
|
||||
encoder.pin2_bitmask = PIN_TO_BITMASK(pin2);
|
||||
encoder.position = 0;
|
||||
// allow time for a passive R-C filter to charge
|
||||
// through the pullup resistors, before reading
|
||||
// the initial state
|
||||
delayMicroseconds(2000);
|
||||
uint8_t s = 0;
|
||||
if (DIRECT_PIN_READ(encoder.pin1_register, encoder.pin1_bitmask)) s |= 1;
|
||||
if (DIRECT_PIN_READ(encoder.pin2_register, encoder.pin2_bitmask)) s |= 2;
|
||||
encoder.state = s;
|
||||
#ifdef ENCODER_USE_INTERRUPTS
|
||||
interrupts_in_use = attach_interrupt(pin1, &encoder);
|
||||
interrupts_in_use += attach_interrupt(pin2, &encoder);
|
||||
#endif
|
||||
//update_finishup(); // to force linker to include the code (does not work)
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENCODER_USE_INTERRUPTS
|
||||
inline int32_t read() {
|
||||
if (interrupts_in_use < 2) {
|
||||
noInterrupts();
|
||||
update(&encoder);
|
||||
} else {
|
||||
noInterrupts();
|
||||
}
|
||||
int32_t ret = encoder.position;
|
||||
interrupts();
|
||||
return ret;
|
||||
}
|
||||
inline int32_t readAndReset() {
|
||||
if (interrupts_in_use < 2) {
|
||||
noInterrupts();
|
||||
update(&encoder);
|
||||
} else {
|
||||
noInterrupts();
|
||||
}
|
||||
int32_t ret = encoder.position;
|
||||
encoder.position = 0;
|
||||
interrupts();
|
||||
return ret;
|
||||
}
|
||||
inline void write(int32_t p) {
|
||||
noInterrupts();
|
||||
encoder.position = p;
|
||||
interrupts();
|
||||
}
|
||||
#else
|
||||
inline int32_t read() {
|
||||
update(&encoder);
|
||||
return encoder.position;
|
||||
}
|
||||
inline int32_t readAndReset() {
|
||||
update(&encoder);
|
||||
int32_t ret = encoder.position;
|
||||
encoder.position = 0;
|
||||
return ret;
|
||||
}
|
||||
inline void write(int32_t p) {
|
||||
encoder.position = p;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
Encoder_internal_state_t encoder;
|
||||
#ifdef ENCODER_USE_INTERRUPTS
|
||||
uint8_t interrupts_in_use;
|
||||
#endif
|
||||
public:
|
||||
static Encoder_internal_state_t * interruptArgs[ENCODER_ARGLIST_SIZE];
|
||||
|
||||
// _______ _______
|
||||
// Pin1 ______| |_______| |______ Pin1
|
||||
// negative <--- _______ _______ __ --> positive
|
||||
// Pin2 __| |_______| |_______| Pin2
|
||||
|
||||
// new new old old
|
||||
// pin2 pin1 pin2 pin1 Result
|
||||
// ---- ---- ---- ---- ------
|
||||
// 0 0 0 0 no movement
|
||||
// 0 0 0 1 +1
|
||||
// 0 0 1 0 -1
|
||||
// 0 0 1 1 +2 (assume pin1 edges only)
|
||||
// 0 1 0 0 -1
|
||||
// 0 1 0 1 no movement
|
||||
// 0 1 1 0 -2 (assume pin1 edges only)
|
||||
// 0 1 1 1 +1
|
||||
// 1 0 0 0 +1
|
||||
// 1 0 0 1 -2 (assume pin1 edges only)
|
||||
// 1 0 1 0 no movement
|
||||
// 1 0 1 1 -1
|
||||
// 1 1 0 0 +2 (assume pin1 edges only)
|
||||
// 1 1 0 1 -1
|
||||
// 1 1 1 0 +1
|
||||
// 1 1 1 1 no movement
|
||||
/*
|
||||
// Simple, easy-to-read "documentation" version :-)
|
||||
//
|
||||
void update(void) {
|
||||
uint8_t s = state & 3;
|
||||
if (digitalRead(pin1)) s |= 4;
|
||||
if (digitalRead(pin2)) s |= 8;
|
||||
switch (s) {
|
||||
case 0: case 5: case 10: case 15:
|
||||
break;
|
||||
case 1: case 7: case 8: case 14:
|
||||
position++; break;
|
||||
case 2: case 4: case 11: case 13:
|
||||
position--; break;
|
||||
case 3: case 12:
|
||||
position += 2; break;
|
||||
default:
|
||||
position -= 2; break;
|
||||
}
|
||||
state = (s >> 2);
|
||||
}
|
||||
*/
|
||||
|
||||
public:
|
||||
// update() is not meant to be called from outside Encoder,
|
||||
// but it is public to allow static interrupt routines.
|
||||
// DO NOT call update() directly from sketches.
|
||||
static void update(Encoder_internal_state_t *arg) {
|
||||
#if defined(__AVR__)
|
||||
// The compiler believes this is just 1 line of code, so
|
||||
// it will inline this function into each interrupt
|
||||
// handler. That's a tiny bit faster, but grows the code.
|
||||
// Especially when used with ENCODER_OPTIMIZE_INTERRUPTS,
|
||||
// the inline nature allows the ISR prologue and epilogue
|
||||
// to only save/restore necessary registers, for very nice
|
||||
// speed increase.
|
||||
asm volatile (
|
||||
"ld r30, X+" "\n\t"
|
||||
"ld r31, X+" "\n\t"
|
||||
"ld r24, Z" "\n\t" // r24 = pin1 input
|
||||
"ld r30, X+" "\n\t"
|
||||
"ld r31, X+" "\n\t"
|
||||
"ld r25, Z" "\n\t" // r25 = pin2 input
|
||||
"ld r30, X+" "\n\t" // r30 = pin1 mask
|
||||
"ld r31, X+" "\n\t" // r31 = pin2 mask
|
||||
"ld r22, X" "\n\t" // r22 = state
|
||||
"andi r22, 3" "\n\t"
|
||||
"and r24, r30" "\n\t"
|
||||
"breq L%=1" "\n\t" // if (pin1)
|
||||
"ori r22, 4" "\n\t" // state |= 4
|
||||
"L%=1:" "and r25, r31" "\n\t"
|
||||
"breq L%=2" "\n\t" // if (pin2)
|
||||
"ori r22, 8" "\n\t" // state |= 8
|
||||
"L%=2:" "ldi r30, lo8(pm(L%=table))" "\n\t"
|
||||
"ldi r31, hi8(pm(L%=table))" "\n\t"
|
||||
"add r30, r22" "\n\t"
|
||||
"adc r31, __zero_reg__" "\n\t"
|
||||
"asr r22" "\n\t"
|
||||
"asr r22" "\n\t"
|
||||
"st X+, r22" "\n\t" // store new state
|
||||
"ld r22, X+" "\n\t"
|
||||
"ld r23, X+" "\n\t"
|
||||
"ld r24, X+" "\n\t"
|
||||
"ld r25, X+" "\n\t"
|
||||
"ijmp" "\n\t" // jumps to update_finishup()
|
||||
// TODO move this table to another static function,
|
||||
// so it doesn't get needlessly duplicated. Easier
|
||||
// said than done, due to linker issues and inlining
|
||||
"L%=table:" "\n\t"
|
||||
"rjmp L%=end" "\n\t" // 0
|
||||
"rjmp L%=plus1" "\n\t" // 1
|
||||
"rjmp L%=minus1" "\n\t" // 2
|
||||
"rjmp L%=plus2" "\n\t" // 3
|
||||
"rjmp L%=minus1" "\n\t" // 4
|
||||
"rjmp L%=end" "\n\t" // 5
|
||||
"rjmp L%=minus2" "\n\t" // 6
|
||||
"rjmp L%=plus1" "\n\t" // 7
|
||||
"rjmp L%=plus1" "\n\t" // 8
|
||||
"rjmp L%=minus2" "\n\t" // 9
|
||||
"rjmp L%=end" "\n\t" // 10
|
||||
"rjmp L%=minus1" "\n\t" // 11
|
||||
"rjmp L%=plus2" "\n\t" // 12
|
||||
"rjmp L%=minus1" "\n\t" // 13
|
||||
"rjmp L%=plus1" "\n\t" // 14
|
||||
"rjmp L%=end" "\n\t" // 15
|
||||
"L%=minus2:" "\n\t"
|
||||
"subi r22, 2" "\n\t"
|
||||
"sbci r23, 0" "\n\t"
|
||||
"sbci r24, 0" "\n\t"
|
||||
"sbci r25, 0" "\n\t"
|
||||
"rjmp L%=store" "\n\t"
|
||||
"L%=minus1:" "\n\t"
|
||||
"subi r22, 1" "\n\t"
|
||||
"sbci r23, 0" "\n\t"
|
||||
"sbci r24, 0" "\n\t"
|
||||
"sbci r25, 0" "\n\t"
|
||||
"rjmp L%=store" "\n\t"
|
||||
"L%=plus2:" "\n\t"
|
||||
"subi r22, 254" "\n\t"
|
||||
"rjmp L%=z" "\n\t"
|
||||
"L%=plus1:" "\n\t"
|
||||
"subi r22, 255" "\n\t"
|
||||
"L%=z:" "sbci r23, 255" "\n\t"
|
||||
"sbci r24, 255" "\n\t"
|
||||
"sbci r25, 255" "\n\t"
|
||||
"L%=store:" "\n\t"
|
||||
"st -X, r25" "\n\t"
|
||||
"st -X, r24" "\n\t"
|
||||
"st -X, r23" "\n\t"
|
||||
"st -X, r22" "\n\t"
|
||||
"L%=end:" "\n"
|
||||
: : "x" (arg) : "r22", "r23", "r24", "r25", "r30", "r31");
|
||||
#else
|
||||
uint8_t p1val = DIRECT_PIN_READ(arg->pin1_register, arg->pin1_bitmask);
|
||||
uint8_t p2val = DIRECT_PIN_READ(arg->pin2_register, arg->pin2_bitmask);
|
||||
uint8_t state = arg->state & 3;
|
||||
if (p1val) state |= 4;
|
||||
if (p2val) state |= 8;
|
||||
arg->state = (state >> 2);
|
||||
switch (state) {
|
||||
case 1: case 7: case 8: case 14:
|
||||
arg->position++;
|
||||
return;
|
||||
case 2: case 4: case 11: case 13:
|
||||
arg->position--;
|
||||
return;
|
||||
case 3: case 12:
|
||||
arg->position += 2;
|
||||
return;
|
||||
case 6: case 9:
|
||||
arg->position -= 2;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
/*
|
||||
#if defined(__AVR__)
|
||||
// TODO: this must be a no inline function
|
||||
// even noinline does not seem to solve difficult
|
||||
// problems with this. Oh well, it was only meant
|
||||
// to shrink code size - there's no performance
|
||||
// improvement in this, only code size reduction.
|
||||
__attribute__((noinline)) void update_finishup(void) {
|
||||
asm volatile (
|
||||
"ldi r30, lo8(pm(Ltable))" "\n\t"
|
||||
"ldi r31, hi8(pm(Ltable))" "\n\t"
|
||||
"Ltable:" "\n\t"
|
||||
"rjmp L%=end" "\n\t" // 0
|
||||
"rjmp L%=plus1" "\n\t" // 1
|
||||
"rjmp L%=minus1" "\n\t" // 2
|
||||
"rjmp L%=plus2" "\n\t" // 3
|
||||
"rjmp L%=minus1" "\n\t" // 4
|
||||
"rjmp L%=end" "\n\t" // 5
|
||||
"rjmp L%=minus2" "\n\t" // 6
|
||||
"rjmp L%=plus1" "\n\t" // 7
|
||||
"rjmp L%=plus1" "\n\t" // 8
|
||||
"rjmp L%=minus2" "\n\t" // 9
|
||||
"rjmp L%=end" "\n\t" // 10
|
||||
"rjmp L%=minus1" "\n\t" // 11
|
||||
"rjmp L%=plus2" "\n\t" // 12
|
||||
"rjmp L%=minus1" "\n\t" // 13
|
||||
"rjmp L%=plus1" "\n\t" // 14
|
||||
"rjmp L%=end" "\n\t" // 15
|
||||
"L%=minus2:" "\n\t"
|
||||
"subi r22, 2" "\n\t"
|
||||
"sbci r23, 0" "\n\t"
|
||||
"sbci r24, 0" "\n\t"
|
||||
"sbci r25, 0" "\n\t"
|
||||
"rjmp L%=store" "\n\t"
|
||||
"L%=minus1:" "\n\t"
|
||||
"subi r22, 1" "\n\t"
|
||||
"sbci r23, 0" "\n\t"
|
||||
"sbci r24, 0" "\n\t"
|
||||
"sbci r25, 0" "\n\t"
|
||||
"rjmp L%=store" "\n\t"
|
||||
"L%=plus2:" "\n\t"
|
||||
"subi r22, 254" "\n\t"
|
||||
"rjmp L%=z" "\n\t"
|
||||
"L%=plus1:" "\n\t"
|
||||
"subi r22, 255" "\n\t"
|
||||
"L%=z:" "sbci r23, 255" "\n\t"
|
||||
"sbci r24, 255" "\n\t"
|
||||
"sbci r25, 255" "\n\t"
|
||||
"L%=store:" "\n\t"
|
||||
"st -X, r25" "\n\t"
|
||||
"st -X, r24" "\n\t"
|
||||
"st -X, r23" "\n\t"
|
||||
"st -X, r22" "\n\t"
|
||||
"L%=end:" "\n"
|
||||
: : : "r22", "r23", "r24", "r25", "r30", "r31");
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
#ifdef ENCODER_USE_INTERRUPTS
|
||||
// this giant function is an unfortunate consequence of Arduino's
|
||||
// attachInterrupt function not supporting any way to pass a pointer
|
||||
// or other context to the attached function.
|
||||
static uint8_t attach_interrupt(uint8_t pin, Encoder_internal_state_t *state) {
|
||||
switch (pin) {
|
||||
#ifdef CORE_INT0_PIN
|
||||
case CORE_INT0_PIN:
|
||||
interruptArgs[0] = state;
|
||||
attachInterrupt(0, isr0, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT1_PIN
|
||||
case CORE_INT1_PIN:
|
||||
interruptArgs[1] = state;
|
||||
attachInterrupt(1, isr1, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT2_PIN
|
||||
case CORE_INT2_PIN:
|
||||
interruptArgs[2] = state;
|
||||
attachInterrupt(2, isr2, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT3_PIN
|
||||
case CORE_INT3_PIN:
|
||||
interruptArgs[3] = state;
|
||||
attachInterrupt(3, isr3, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT4_PIN
|
||||
case CORE_INT4_PIN:
|
||||
interruptArgs[4] = state;
|
||||
attachInterrupt(4, isr4, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT5_PIN
|
||||
case CORE_INT5_PIN:
|
||||
interruptArgs[5] = state;
|
||||
attachInterrupt(5, isr5, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT6_PIN
|
||||
case CORE_INT6_PIN:
|
||||
interruptArgs[6] = state;
|
||||
attachInterrupt(6, isr6, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT7_PIN
|
||||
case CORE_INT7_PIN:
|
||||
interruptArgs[7] = state;
|
||||
attachInterrupt(7, isr7, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT8_PIN
|
||||
case CORE_INT8_PIN:
|
||||
interruptArgs[8] = state;
|
||||
attachInterrupt(8, isr8, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT9_PIN
|
||||
case CORE_INT9_PIN:
|
||||
interruptArgs[9] = state;
|
||||
attachInterrupt(9, isr9, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT10_PIN
|
||||
case CORE_INT10_PIN:
|
||||
interruptArgs[10] = state;
|
||||
attachInterrupt(10, isr10, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT11_PIN
|
||||
case CORE_INT11_PIN:
|
||||
interruptArgs[11] = state;
|
||||
attachInterrupt(11, isr11, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT12_PIN
|
||||
case CORE_INT12_PIN:
|
||||
interruptArgs[12] = state;
|
||||
attachInterrupt(12, isr12, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT13_PIN
|
||||
case CORE_INT13_PIN:
|
||||
interruptArgs[13] = state;
|
||||
attachInterrupt(13, isr13, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT14_PIN
|
||||
case CORE_INT14_PIN:
|
||||
interruptArgs[14] = state;
|
||||
attachInterrupt(14, isr14, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT15_PIN
|
||||
case CORE_INT15_PIN:
|
||||
interruptArgs[15] = state;
|
||||
attachInterrupt(15, isr15, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT16_PIN
|
||||
case CORE_INT16_PIN:
|
||||
interruptArgs[16] = state;
|
||||
attachInterrupt(16, isr16, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT17_PIN
|
||||
case CORE_INT17_PIN:
|
||||
interruptArgs[17] = state;
|
||||
attachInterrupt(17, isr17, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT18_PIN
|
||||
case CORE_INT18_PIN:
|
||||
interruptArgs[18] = state;
|
||||
attachInterrupt(18, isr18, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT19_PIN
|
||||
case CORE_INT19_PIN:
|
||||
interruptArgs[19] = state;
|
||||
attachInterrupt(19, isr19, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT20_PIN
|
||||
case CORE_INT20_PIN:
|
||||
interruptArgs[20] = state;
|
||||
attachInterrupt(20, isr20, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT21_PIN
|
||||
case CORE_INT21_PIN:
|
||||
interruptArgs[21] = state;
|
||||
attachInterrupt(21, isr21, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT22_PIN
|
||||
case CORE_INT22_PIN:
|
||||
interruptArgs[22] = state;
|
||||
attachInterrupt(22, isr22, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT23_PIN
|
||||
case CORE_INT23_PIN:
|
||||
interruptArgs[23] = state;
|
||||
attachInterrupt(23, isr23, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT24_PIN
|
||||
case CORE_INT24_PIN:
|
||||
interruptArgs[24] = state;
|
||||
attachInterrupt(24, isr24, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT25_PIN
|
||||
case CORE_INT25_PIN:
|
||||
interruptArgs[25] = state;
|
||||
attachInterrupt(25, isr25, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT26_PIN
|
||||
case CORE_INT26_PIN:
|
||||
interruptArgs[26] = state;
|
||||
attachInterrupt(26, isr26, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT27_PIN
|
||||
case CORE_INT27_PIN:
|
||||
interruptArgs[27] = state;
|
||||
attachInterrupt(27, isr27, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT28_PIN
|
||||
case CORE_INT28_PIN:
|
||||
interruptArgs[28] = state;
|
||||
attachInterrupt(28, isr28, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT29_PIN
|
||||
case CORE_INT29_PIN:
|
||||
interruptArgs[29] = state;
|
||||
attachInterrupt(29, isr29, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CORE_INT30_PIN
|
||||
case CORE_INT30_PIN:
|
||||
interruptArgs[30] = state;
|
||||
attachInterrupt(30, isr30, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT31_PIN
|
||||
case CORE_INT31_PIN:
|
||||
interruptArgs[31] = state;
|
||||
attachInterrupt(31, isr31, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT32_PIN
|
||||
case CORE_INT32_PIN:
|
||||
interruptArgs[32] = state;
|
||||
attachInterrupt(32, isr32, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT33_PIN
|
||||
case CORE_INT33_PIN:
|
||||
interruptArgs[33] = state;
|
||||
attachInterrupt(33, isr33, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT34_PIN
|
||||
case CORE_INT34_PIN:
|
||||
interruptArgs[34] = state;
|
||||
attachInterrupt(34, isr34, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT35_PIN
|
||||
case CORE_INT35_PIN:
|
||||
interruptArgs[35] = state;
|
||||
attachInterrupt(35, isr35, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT36_PIN
|
||||
case CORE_INT36_PIN:
|
||||
interruptArgs[36] = state;
|
||||
attachInterrupt(36, isr36, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT37_PIN
|
||||
case CORE_INT37_PIN:
|
||||
interruptArgs[37] = state;
|
||||
attachInterrupt(37, isr37, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT38_PIN
|
||||
case CORE_INT38_PIN:
|
||||
interruptArgs[38] = state;
|
||||
attachInterrupt(38, isr38, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT39_PIN
|
||||
case CORE_INT39_PIN:
|
||||
interruptArgs[39] = state;
|
||||
attachInterrupt(39, isr39, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT40_PIN
|
||||
case CORE_INT40_PIN:
|
||||
interruptArgs[40] = state;
|
||||
attachInterrupt(40, isr40, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT41_PIN
|
||||
case CORE_INT41_PIN:
|
||||
interruptArgs[41] = state;
|
||||
attachInterrupt(41, isr41, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT42_PIN
|
||||
case CORE_INT42_PIN:
|
||||
interruptArgs[42] = state;
|
||||
attachInterrupt(42, isr42, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT43_PIN
|
||||
case CORE_INT43_PIN:
|
||||
interruptArgs[43] = state;
|
||||
attachInterrupt(43, isr43, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT44_PIN
|
||||
case CORE_INT44_PIN:
|
||||
interruptArgs[44] = state;
|
||||
attachInterrupt(44, isr44, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT45_PIN
|
||||
case CORE_INT45_PIN:
|
||||
interruptArgs[45] = state;
|
||||
attachInterrupt(45, isr45, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT46_PIN
|
||||
case CORE_INT46_PIN:
|
||||
interruptArgs[46] = state;
|
||||
attachInterrupt(46, isr46, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT47_PIN
|
||||
case CORE_INT47_PIN:
|
||||
interruptArgs[47] = state;
|
||||
attachInterrupt(47, isr47, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT48_PIN
|
||||
case CORE_INT48_PIN:
|
||||
interruptArgs[48] = state;
|
||||
attachInterrupt(48, isr48, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT49_PIN
|
||||
case CORE_INT49_PIN:
|
||||
interruptArgs[49] = state;
|
||||
attachInterrupt(49, isr49, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT50_PIN
|
||||
case CORE_INT50_PIN:
|
||||
interruptArgs[50] = state;
|
||||
attachInterrupt(50, isr50, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT51_PIN
|
||||
case CORE_INT51_PIN:
|
||||
interruptArgs[51] = state;
|
||||
attachInterrupt(51, isr51, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT52_PIN
|
||||
case CORE_INT52_PIN:
|
||||
interruptArgs[52] = state;
|
||||
attachInterrupt(52, isr52, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT53_PIN
|
||||
case CORE_INT53_PIN:
|
||||
interruptArgs[53] = state;
|
||||
attachInterrupt(53, isr53, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT54_PIN
|
||||
case CORE_INT54_PIN:
|
||||
interruptArgs[54] = state;
|
||||
attachInterrupt(54, isr54, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT55_PIN
|
||||
case CORE_INT55_PIN:
|
||||
interruptArgs[55] = state;
|
||||
attachInterrupt(55, isr55, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT56_PIN
|
||||
case CORE_INT56_PIN:
|
||||
interruptArgs[56] = state;
|
||||
attachInterrupt(56, isr56, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT57_PIN
|
||||
case CORE_INT57_PIN:
|
||||
interruptArgs[57] = state;
|
||||
attachInterrupt(57, isr57, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT58_PIN
|
||||
case CORE_INT58_PIN:
|
||||
interruptArgs[58] = state;
|
||||
attachInterrupt(58, isr58, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CORE_INT59_PIN
|
||||
case CORE_INT59_PIN:
|
||||
interruptArgs[59] = state;
|
||||
attachInterrupt(59, isr59, CHANGE);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif // ENCODER_USE_INTERRUPTS
|
||||
|
||||
|
||||
#if defined(ENCODER_USE_INTERRUPTS) && !defined(ENCODER_OPTIMIZE_INTERRUPTS)
|
||||
#ifdef CORE_INT0_PIN
|
||||
static void isr0(void) { update(interruptArgs[0]); }
|
||||
#endif
|
||||
#ifdef CORE_INT1_PIN
|
||||
static void isr1(void) { update(interruptArgs[1]); }
|
||||
#endif
|
||||
#ifdef CORE_INT2_PIN
|
||||
static void isr2(void) { update(interruptArgs[2]); }
|
||||
#endif
|
||||
#ifdef CORE_INT3_PIN
|
||||
static void isr3(void) { update(interruptArgs[3]); }
|
||||
#endif
|
||||
#ifdef CORE_INT4_PIN
|
||||
static void isr4(void) { update(interruptArgs[4]); }
|
||||
#endif
|
||||
#ifdef CORE_INT5_PIN
|
||||
static void isr5(void) { update(interruptArgs[5]); }
|
||||
#endif
|
||||
#ifdef CORE_INT6_PIN
|
||||
static void isr6(void) { update(interruptArgs[6]); }
|
||||
#endif
|
||||
#ifdef CORE_INT7_PIN
|
||||
static void isr7(void) { update(interruptArgs[7]); }
|
||||
#endif
|
||||
#ifdef CORE_INT8_PIN
|
||||
static void isr8(void) { update(interruptArgs[8]); }
|
||||
#endif
|
||||
#ifdef CORE_INT9_PIN
|
||||
static void isr9(void) { update(interruptArgs[9]); }
|
||||
#endif
|
||||
#ifdef CORE_INT10_PIN
|
||||
static void isr10(void) { update(interruptArgs[10]); }
|
||||
#endif
|
||||
#ifdef CORE_INT11_PIN
|
||||
static void isr11(void) { update(interruptArgs[11]); }
|
||||
#endif
|
||||
#ifdef CORE_INT12_PIN
|
||||
static void isr12(void) { update(interruptArgs[12]); }
|
||||
#endif
|
||||
#ifdef CORE_INT13_PIN
|
||||
static void isr13(void) { update(interruptArgs[13]); }
|
||||
#endif
|
||||
#ifdef CORE_INT14_PIN
|
||||
static void isr14(void) { update(interruptArgs[14]); }
|
||||
#endif
|
||||
#ifdef CORE_INT15_PIN
|
||||
static void isr15(void) { update(interruptArgs[15]); }
|
||||
#endif
|
||||
#ifdef CORE_INT16_PIN
|
||||
static void isr16(void) { update(interruptArgs[16]); }
|
||||
#endif
|
||||
#ifdef CORE_INT17_PIN
|
||||
static void isr17(void) { update(interruptArgs[17]); }
|
||||
#endif
|
||||
#ifdef CORE_INT18_PIN
|
||||
static void isr18(void) { update(interruptArgs[18]); }
|
||||
#endif
|
||||
#ifdef CORE_INT19_PIN
|
||||
static void isr19(void) { update(interruptArgs[19]); }
|
||||
#endif
|
||||
#ifdef CORE_INT20_PIN
|
||||
static void isr20(void) { update(interruptArgs[20]); }
|
||||
#endif
|
||||
#ifdef CORE_INT21_PIN
|
||||
static void isr21(void) { update(interruptArgs[21]); }
|
||||
#endif
|
||||
#ifdef CORE_INT22_PIN
|
||||
static void isr22(void) { update(interruptArgs[22]); }
|
||||
#endif
|
||||
#ifdef CORE_INT23_PIN
|
||||
static void isr23(void) { update(interruptArgs[23]); }
|
||||
#endif
|
||||
#ifdef CORE_INT24_PIN
|
||||
static void isr24(void) { update(interruptArgs[24]); }
|
||||
#endif
|
||||
#ifdef CORE_INT25_PIN
|
||||
static void isr25(void) { update(interruptArgs[25]); }
|
||||
#endif
|
||||
#ifdef CORE_INT26_PIN
|
||||
static void isr26(void) { update(interruptArgs[26]); }
|
||||
#endif
|
||||
#ifdef CORE_INT27_PIN
|
||||
static void isr27(void) { update(interruptArgs[27]); }
|
||||
#endif
|
||||
#ifdef CORE_INT28_PIN
|
||||
static void isr28(void) { update(interruptArgs[28]); }
|
||||
#endif
|
||||
#ifdef CORE_INT29_PIN
|
||||
static void isr29(void) { update(interruptArgs[29]); }
|
||||
#endif
|
||||
#ifdef CORE_INT30_PIN
|
||||
static void isr30(void) { update(interruptArgs[30]); }
|
||||
#endif
|
||||
#ifdef CORE_INT31_PIN
|
||||
static void isr31(void) { update(interruptArgs[31]); }
|
||||
#endif
|
||||
#ifdef CORE_INT32_PIN
|
||||
static void isr32(void) { update(interruptArgs[32]); }
|
||||
#endif
|
||||
#ifdef CORE_INT33_PIN
|
||||
static void isr33(void) { update(interruptArgs[33]); }
|
||||
#endif
|
||||
#ifdef CORE_INT34_PIN
|
||||
static void isr34(void) { update(interruptArgs[34]); }
|
||||
#endif
|
||||
#ifdef CORE_INT35_PIN
|
||||
static void isr35(void) { update(interruptArgs[35]); }
|
||||
#endif
|
||||
#ifdef CORE_INT36_PIN
|
||||
static void isr36(void) { update(interruptArgs[36]); }
|
||||
#endif
|
||||
#ifdef CORE_INT37_PIN
|
||||
static void isr37(void) { update(interruptArgs[37]); }
|
||||
#endif
|
||||
#ifdef CORE_INT38_PIN
|
||||
static void isr38(void) { update(interruptArgs[38]); }
|
||||
#endif
|
||||
#ifdef CORE_INT39_PIN
|
||||
static void isr39(void) { update(interruptArgs[39]); }
|
||||
#endif
|
||||
#ifdef CORE_INT40_PIN
|
||||
static void isr40(void) { update(interruptArgs[40]); }
|
||||
#endif
|
||||
#ifdef CORE_INT41_PIN
|
||||
static void isr41(void) { update(interruptArgs[41]); }
|
||||
#endif
|
||||
#ifdef CORE_INT42_PIN
|
||||
static void isr42(void) { update(interruptArgs[42]); }
|
||||
#endif
|
||||
#ifdef CORE_INT43_PIN
|
||||
static void isr43(void) { update(interruptArgs[43]); }
|
||||
#endif
|
||||
#ifdef CORE_INT44_PIN
|
||||
static void isr44(void) { update(interruptArgs[44]); }
|
||||
#endif
|
||||
#ifdef CORE_INT45_PIN
|
||||
static void isr45(void) { update(interruptArgs[45]); }
|
||||
#endif
|
||||
#ifdef CORE_INT46_PIN
|
||||
static void isr46(void) { update(interruptArgs[46]); }
|
||||
#endif
|
||||
#ifdef CORE_INT47_PIN
|
||||
static void isr47(void) { update(interruptArgs[47]); }
|
||||
#endif
|
||||
#ifdef CORE_INT48_PIN
|
||||
static void isr48(void) { update(interruptArgs[48]); }
|
||||
#endif
|
||||
#ifdef CORE_INT49_PIN
|
||||
static void isr49(void) { update(interruptArgs[49]); }
|
||||
#endif
|
||||
#ifdef CORE_INT50_PIN
|
||||
static void isr50(void) { update(interruptArgs[50]); }
|
||||
#endif
|
||||
#ifdef CORE_INT51_PIN
|
||||
static void isr51(void) { update(interruptArgs[51]); }
|
||||
#endif
|
||||
#ifdef CORE_INT52_PIN
|
||||
static void isr52(void) { update(interruptArgs[52]); }
|
||||
#endif
|
||||
#ifdef CORE_INT53_PIN
|
||||
static void isr53(void) { update(interruptArgs[53]); }
|
||||
#endif
|
||||
#ifdef CORE_INT54_PIN
|
||||
static void isr54(void) { update(interruptArgs[54]); }
|
||||
#endif
|
||||
#ifdef CORE_INT55_PIN
|
||||
static void isr55(void) { update(interruptArgs[55]); }
|
||||
#endif
|
||||
#ifdef CORE_INT56_PIN
|
||||
static void isr56(void) { update(interruptArgs[56]); }
|
||||
#endif
|
||||
#ifdef CORE_INT57_PIN
|
||||
static void isr57(void) { update(interruptArgs[57]); }
|
||||
#endif
|
||||
#ifdef CORE_INT58_PIN
|
||||
static void isr58(void) { update(interruptArgs[58]); }
|
||||
#endif
|
||||
#ifdef CORE_INT59_PIN
|
||||
static void isr59(void) { update(interruptArgs[59]); }
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(ENCODER_USE_INTERRUPTS) && defined(ENCODER_OPTIMIZE_INTERRUPTS)
|
||||
#if defined(__AVR__)
|
||||
#if defined(INT0_vect) && CORE_NUM_INTERRUPT > 0
|
||||
ISR(INT0_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(0)]); }
|
||||
#endif
|
||||
#if defined(INT1_vect) && CORE_NUM_INTERRUPT > 1
|
||||
ISR(INT1_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(1)]); }
|
||||
#endif
|
||||
#if defined(INT2_vect) && CORE_NUM_INTERRUPT > 2
|
||||
ISR(INT2_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(2)]); }
|
||||
#endif
|
||||
#if defined(INT3_vect) && CORE_NUM_INTERRUPT > 3
|
||||
ISR(INT3_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(3)]); }
|
||||
#endif
|
||||
#if defined(INT4_vect) && CORE_NUM_INTERRUPT > 4
|
||||
ISR(INT4_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(4)]); }
|
||||
#endif
|
||||
#if defined(INT5_vect) && CORE_NUM_INTERRUPT > 5
|
||||
ISR(INT5_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(5)]); }
|
||||
#endif
|
||||
#if defined(INT6_vect) && CORE_NUM_INTERRUPT > 6
|
||||
ISR(INT6_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(6)]); }
|
||||
#endif
|
||||
#if defined(INT7_vect) && CORE_NUM_INTERRUPT > 7
|
||||
ISR(INT7_vect) { Encoder::update(Encoder::interruptArgs[SCRAMBLE_INT_ORDER(7)]); }
|
||||
#endif
|
||||
#endif // AVR
|
||||
#if defined(attachInterrupt)
|
||||
// Don't intefere with other libraries or sketch use of attachInterrupt()
|
||||
// https://github.com/PaulStoffregen/Encoder/issues/8
|
||||
#undef attachInterrupt
|
||||
#endif
|
||||
#endif // ENCODER_OPTIMIZE_INTERRUPTS
|
||||
|
||||
|
||||
#endif
|
9
.pio/libdeps/attiny88/Encoder/README.md
Executable file
9
.pio/libdeps/attiny88/Encoder/README.md
Executable file
|
@ -0,0 +1,9 @@
|
|||
# Encoder Library
|
||||
|
||||
Encoder counts pulses from quadrature encoded signals, which are commonly available from rotary knobs, motor or shaft sensors and other position sensors.
|
||||
|
||||
http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
|
||||
http://www.youtube.com/watch?v=2puhIong-cs
|
||||
|
||||
![Encoder Knobs Demo](http://www.pjrc.com/teensy/td_libs_Encoder_1.jpg)
|
29
.pio/libdeps/attiny88/Encoder/examples/Basic/Basic.pde
Executable file
29
.pio/libdeps/attiny88/Encoder/examples/Basic/Basic.pde
Executable file
|
@ -0,0 +1,29 @@
|
|||
/* Encoder Library - Basic Example
|
||||
* http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
*
|
||||
* This example code is in the public domain.
|
||||
*/
|
||||
|
||||
#include <Encoder.h>
|
||||
|
||||
// Change these two numbers to the pins connected to your encoder.
|
||||
// Best Performance: both pins have interrupt capability
|
||||
// Good Performance: only the first pin has interrupt capability
|
||||
// Low Performance: neither pin has interrupt capability
|
||||
Encoder myEnc(5, 6);
|
||||
// avoid using pins with LEDs attached
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Basic Encoder Test:");
|
||||
}
|
||||
|
||||
long oldPosition = -999;
|
||||
|
||||
void loop() {
|
||||
long newPosition = myEnc.read();
|
||||
if (newPosition != oldPosition) {
|
||||
oldPosition = newPosition;
|
||||
Serial.println(newPosition);
|
||||
}
|
||||
}
|
46
.pio/libdeps/attiny88/Encoder/examples/NoInterrupts/NoInterrupts.pde
Executable file
46
.pio/libdeps/attiny88/Encoder/examples/NoInterrupts/NoInterrupts.pde
Executable file
|
@ -0,0 +1,46 @@
|
|||
/* Encoder Library - NoInterrupts Example
|
||||
* http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
*
|
||||
* This example code is in the public domain.
|
||||
*/
|
||||
|
||||
// If you define ENCODER_DO_NOT_USE_INTERRUPTS *before* including
|
||||
// Encoder, the library will never use interrupts. This is mainly
|
||||
// useful to reduce the size of the library when you are using it
|
||||
// with pins that do not support interrupts. Without interrupts,
|
||||
// your program must call the read() function rapidly, or risk
|
||||
// missing changes in position.
|
||||
#define ENCODER_DO_NOT_USE_INTERRUPTS
|
||||
#include <Encoder.h>
|
||||
|
||||
// Beware of Serial.print() speed. Without interrupts, if you
|
||||
// transmit too much data with Serial.print() it can slow your
|
||||
// reading from Encoder. Arduino 1.0 has improved transmit code.
|
||||
// Using the fastest baud rate also helps. Teensy has USB packet
|
||||
// buffering. But all boards can experience problems if you print
|
||||
// too much and fill up buffers.
|
||||
|
||||
// Change these two numbers to the pins connected to your encoder.
|
||||
// With ENCODER_DO_NOT_USE_INTERRUPTS, no interrupts are ever
|
||||
// used, even if the pin has interrupt capability
|
||||
Encoder myEnc(5, 6);
|
||||
// avoid using pins with LEDs attached
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("Basic NoInterrupts Test:");
|
||||
}
|
||||
|
||||
long position = -999;
|
||||
|
||||
void loop() {
|
||||
long newPos = myEnc.read();
|
||||
if (newPos != position) {
|
||||
position = newPos;
|
||||
Serial.println(position);
|
||||
}
|
||||
// With any substantial delay added, Encoder can only track
|
||||
// very slow motion. You may uncomment this line to see
|
||||
// how badly a delay affects your encoder.
|
||||
//delay(50);
|
||||
}
|
113
.pio/libdeps/attiny88/Encoder/examples/SpeedTest/SpeedTest.pde
Executable file
113
.pio/libdeps/attiny88/Encoder/examples/SpeedTest/SpeedTest.pde
Executable file
|
@ -0,0 +1,113 @@
|
|||
/* Encoder Library - SpeedTest - for measuring maximum Encoder speed
|
||||
* http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
*
|
||||
* This example code is in the public domain.
|
||||
*/
|
||||
|
||||
|
||||
// This SpeedTest example provides a simple way to verify how much
|
||||
// CPU time Encoder is consuming. Connect a DC voltmeter to the
|
||||
// output pin and measure the voltage while the encoder is stopped
|
||||
// or running at a very slow speed. Even though the pin is rapidly
|
||||
// pulsing, a DC voltmeter will show the average voltage. Due to
|
||||
// software timing, it will read a number much less than a steady
|
||||
// logic high, but this number will give you a baseline reading
|
||||
// for output with minimal interrupt overhead. Then increase the
|
||||
// encoder speed. The voltage will decrease as the processor spends
|
||||
// more time in Encoder's interrupt routines counting the pulses
|
||||
// and less time pulsing the output pin. When the voltage is
|
||||
// close to zero and will not decrease any farther, you have reached
|
||||
// the absolute speed limit. Or, if using a mechanical system where
|
||||
// you reach a speed limit imposed by your motors or other hardware,
|
||||
// the amount this voltage has decreased, compared to the baseline,
|
||||
// should give you a good approximation of the portion of available
|
||||
// CPU time Encoder is consuming at your maximum speed.
|
||||
|
||||
// Encoder requires low latency interrupt response. Available CPU
|
||||
// time does NOT necessarily prove or guarantee correct performance.
|
||||
// If another library, like NewSoftSerial, is disabling interrupts
|
||||
// for lengthy periods of time, Encoder can be prevented from
|
||||
// properly counting the intput signals while interrupt are disabled.
|
||||
|
||||
|
||||
// This optional setting causes Encoder to use more optimized code,
|
||||
// but the downside is a conflict if any other part of your sketch
|
||||
// or any other library you're using requires attachInterrupt().
|
||||
// It must be defined before Encoder.h is included.
|
||||
//#define ENCODER_OPTIMIZE_INTERRUPTS
|
||||
|
||||
#include <Encoder.h>
|
||||
#include "pins_arduino.h"
|
||||
|
||||
// Change these two numbers to the pins connected to your encoder
|
||||
// or shift register circuit which emulates a quadrature encoder
|
||||
// case 1: both pins are interrupts
|
||||
// case 2: only first pin used as interrupt
|
||||
Encoder myEnc(5, 6);
|
||||
|
||||
// Connect a DC voltmeter to this pin.
|
||||
const int outputPin = 12;
|
||||
|
||||
/* This simple circuit, using a Dual Flip-Flop chip, can emulate
|
||||
quadrature encoder signals. The clock can come from a fancy
|
||||
function generator or a cheap 555 timer chip. The clock
|
||||
frequency can be measured with another board running FreqCount
|
||||
http://www.pjrc.com/teensy/td_libs_FreqCount.html
|
||||
|
||||
+5V
|
||||
| Quadrature Encoder Signal Emulator
|
||||
Clock |
|
||||
Input o----*-------------------------- ---------------------------o Output1
|
||||
| |14 | |
|
||||
| _______|_______ | | _______________
|
||||
| | CD4013 | | | | CD4013 |
|
||||
| 5 | | 1 | | 9 | | 13
|
||||
---------| D Q |-----|----*----| D Q |------o Output2
|
||||
| | | | | | |
|
||||
| | 3 | | | 11 | |
|
||||
| ----|> Clk | ---------|> Clk |
|
||||
| | | | |
|
||||
| 6 | | 8 | |
|
||||
| ----| S | ----| S |
|
||||
| | | | | | |
|
||||
| | 4 | _ | 2 | 10 | _ | 12
|
||||
| *----| R Q |--- *----| R Q |----
|
||||
| | | | | | | |
|
||||
| | |_______________| | |_______________| |
|
||||
| | | | |
|
||||
| | | 7 | |
|
||||
| | | | |
|
||||
--------------------------------------------------------------
|
||||
| | |
|
||||
| | |
|
||||
----- ----- -----
|
||||
--- --- ---
|
||||
- - -
|
||||
*/
|
||||
|
||||
|
||||
void setup() {
|
||||
pinMode(outputPin, OUTPUT);
|
||||
}
|
||||
|
||||
#if defined(__AVR__) || defined(TEENSYDUINO)
|
||||
#define REGTYPE unsigned char
|
||||
#else
|
||||
#define REGTYPE unsigned long
|
||||
#endif
|
||||
|
||||
void loop() {
|
||||
volatile int count = 0;
|
||||
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
|
||||
REGTYPE mask = digitalPinToBitMask(outputPin);
|
||||
|
||||
while (1) {
|
||||
myEnc.read(); // Read the encoder while interrupts are enabled.
|
||||
noInterrupts();
|
||||
*reg |= mask; // Pulse the pin high, while interrupts are disabled.
|
||||
count = count + 1;
|
||||
*reg &= ~mask;
|
||||
interrupts();
|
||||
}
|
||||
}
|
||||
|
46
.pio/libdeps/attiny88/Encoder/examples/TwoKnobs/TwoKnobs.pde
Executable file
46
.pio/libdeps/attiny88/Encoder/examples/TwoKnobs/TwoKnobs.pde
Executable file
|
@ -0,0 +1,46 @@
|
|||
/* Encoder Library - TwoKnobs Example
|
||||
* http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
*
|
||||
* This example code is in the public domain.
|
||||
*/
|
||||
|
||||
#include <Encoder.h>
|
||||
|
||||
// Change these pin numbers to the pins connected to your encoder.
|
||||
// Best Performance: both pins have interrupt capability
|
||||
// Good Performance: only the first pin has interrupt capability
|
||||
// Low Performance: neither pin has interrupt capability
|
||||
Encoder knobLeft(5, 6);
|
||||
Encoder knobRight(7, 8);
|
||||
// avoid using pins with LEDs attached
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println("TwoKnobs Encoder Test:");
|
||||
}
|
||||
|
||||
long positionLeft = -999;
|
||||
long positionRight = -999;
|
||||
|
||||
void loop() {
|
||||
long newLeft, newRight;
|
||||
newLeft = knobLeft.read();
|
||||
newRight = knobRight.read();
|
||||
if (newLeft != positionLeft || newRight != positionRight) {
|
||||
Serial.print("Left = ");
|
||||
Serial.print(newLeft);
|
||||
Serial.print(", Right = ");
|
||||
Serial.print(newRight);
|
||||
Serial.println();
|
||||
positionLeft = newLeft;
|
||||
positionRight = newRight;
|
||||
}
|
||||
// if a character is sent from the serial monitor,
|
||||
// reset both back to zero.
|
||||
if (Serial.available()) {
|
||||
Serial.read();
|
||||
Serial.println("Reset both knobs to zero");
|
||||
knobLeft.write(0);
|
||||
knobRight.write(0);
|
||||
}
|
||||
}
|
4
.pio/libdeps/attiny88/Encoder/keywords.txt
Executable file
4
.pio/libdeps/attiny88/Encoder/keywords.txt
Executable file
|
@ -0,0 +1,4 @@
|
|||
ENCODER_USE_INTERRUPTS LITERAL1
|
||||
ENCODER_OPTIMIZE_INTERRUPTS LITERAL1
|
||||
ENCODER_DO_NOT_USE_INTERRUPTS LITERAL1
|
||||
Encoder KEYWORD1
|
10
.pio/libdeps/attiny88/Encoder/library.properties
Executable file
10
.pio/libdeps/attiny88/Encoder/library.properties
Executable file
|
@ -0,0 +1,10 @@
|
|||
name=Encoder
|
||||
version=1.4.2
|
||||
author=Paul Stoffregen
|
||||
maintainer=Paul Stoffregen
|
||||
sentence=Counts quadrature pulses from rotary & linear position encoders.
|
||||
paragraph=Encoder counts pulses from quadrature encoded signals, which are commonly available from rotary knobs, motor or shaft sensors and other position sensors.
|
||||
category=Signal Input/Output
|
||||
url=http://www.pjrc.com/teensy/td_libs_Encoder.html
|
||||
architectures=*
|
||||
|
104
.pio/libdeps/attiny88/Encoder/utility/direct_pin_read.h
Executable file
104
.pio/libdeps/attiny88/Encoder/utility/direct_pin_read.h
Executable file
|
@ -0,0 +1,104 @@
|
|||
#ifndef direct_pin_read_h_
|
||||
#define direct_pin_read_h_
|
||||
|
||||
#if defined(__AVR__)
|
||||
|
||||
#define IO_REG_TYPE uint8_t
|
||||
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))
|
||||
|
||||
#define IO_REG_TYPE uint8_t
|
||||
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(__SAM3X8E__) // || defined(ESP8266)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(__PIC32MX__)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0)
|
||||
|
||||
/* ESP8266 v2.0.0 Arduino workaround for bug https://github.com/esp8266/Arduino/issues/1110 */
|
||||
#elif defined(ESP8266)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)(0x60000000+(0x318)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
/* ESP32 Arduino (https://github.com/espressif/arduino-esp32) */
|
||||
#elif defined(ESP32)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(__SAMD21G18A__)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*((base)+8)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(__SAMD51__)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) portInputRegister(digitalPinToPort(pin))
|
||||
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
|
||||
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
|
||||
|
||||
#elif defined(RBL_NRF51822)
|
||||
|
||||
#define IO_REG_TYPE uint32_t
|
||||
#define PIN_TO_BASEREG(pin) (0)
|
||||
#define PIN_TO_BITMASK(pin) (pin)
|
||||
#define DIRECT_PIN_READ(base, pin) nrf_gpio_pin_read(pin)
|
||||
|
||||
#elif defined(__arc__) /* Arduino101/Genuino101 specifics */
|
||||
|
||||
#include "scss_registers.h"
|
||||
#include "portable.h"
|
||||
#include "avr/pgmspace.h"
|
||||
#define GPIO_ID(pin) (g_APinDescription[pin].ulGPIOId)
|
||||
#define GPIO_TYPE(pin) (g_APinDescription[pin].ulGPIOType)
|
||||
#define GPIO_BASE(pin) (g_APinDescription[pin].ulGPIOBase)
|
||||
#define EXT_PORT_OFFSET_SS 0x0A
|
||||
#define EXT_PORT_OFFSET_SOC 0x50
|
||||
#define PIN_TO_BASEREG(pin) ((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase)
|
||||
#define PIN_TO_BITMASK(pin) pin
|
||||
#define IO_REG_TYPE uint32_t
|
||||
static inline __attribute__((always_inline))
|
||||
IO_REG_TYPE directRead(volatile IO_REG_TYPE *base, IO_REG_TYPE pin)
|
||||
{
|
||||
IO_REG_TYPE ret;
|
||||
if (SS_GPIO == GPIO_TYPE(pin)) {
|
||||
ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS));
|
||||
} else {
|
||||
ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC);
|
||||
}
|
||||
return ((ret >> GPIO_ID(pin)) & 0x01);
|
||||
}
|
||||
#define DIRECT_PIN_READ(base, pin) directRead(base, pin)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
87
.pio/libdeps/attiny88/Encoder/utility/interrupt_config.h
Executable file
87
.pio/libdeps/attiny88/Encoder/utility/interrupt_config.h
Executable file
|
@ -0,0 +1,87 @@
|
|||
#if defined(__AVR__)
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#define attachInterrupt(num, func, mode) enableInterrupt(num)
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define SCRAMBLE_INT_ORDER(num) ((num < 4) ? num + 2 : ((num < 6) ? num - 4 : num))
|
||||
#define DESCRAMBLE_INT_ORDER(num) ((num < 2) ? num + 4 : ((num < 6) ? num - 2 : num))
|
||||
#else
|
||||
#define SCRAMBLE_INT_ORDER(num) (num)
|
||||
#define DESCRAMBLE_INT_ORDER(num) (num)
|
||||
#endif
|
||||
|
||||
static void enableInterrupt(uint8_t num)
|
||||
{
|
||||
switch (DESCRAMBLE_INT_ORDER(num)) {
|
||||
#if defined(EICRA) && defined(EIMSK)
|
||||
case 0:
|
||||
EICRA = (EICRA & 0xFC) | 0x01;
|
||||
EIMSK |= 0x01;
|
||||
return;
|
||||
case 1:
|
||||
EICRA = (EICRA & 0xF3) | 0x04;
|
||||
EIMSK |= 0x02;
|
||||
return;
|
||||
case 2:
|
||||
EICRA = (EICRA & 0xCF) | 0x10;
|
||||
EIMSK |= 0x04;
|
||||
return;
|
||||
case 3:
|
||||
EICRA = (EICRA & 0x3F) | 0x40;
|
||||
EIMSK |= 0x08;
|
||||
return;
|
||||
#elif defined(MCUCR) && defined(GICR)
|
||||
case 0:
|
||||
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
|
||||
GICR |= (1 << INT0);
|
||||
return;
|
||||
case 1:
|
||||
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
|
||||
GICR |= (1 << INT1);
|
||||
return;
|
||||
#elif defined(MCUCR) && defined(GIMSK)
|
||||
case 0:
|
||||
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
|
||||
GIMSK |= (1 << INT0);
|
||||
return;
|
||||
case 1:
|
||||
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
|
||||
GIMSK |= (1 << INT1);
|
||||
return;
|
||||
#endif
|
||||
#if defined(EICRB) && defined(EIMSK)
|
||||
case 4:
|
||||
EICRB = (EICRB & 0xFC) | 0x01;
|
||||
EIMSK |= 0x10;
|
||||
return;
|
||||
case 5:
|
||||
EICRB = (EICRB & 0xF3) | 0x04;
|
||||
EIMSK |= 0x20;
|
||||
return;
|
||||
case 6:
|
||||
EICRB = (EICRB & 0xCF) | 0x10;
|
||||
EIMSK |= 0x40;
|
||||
return;
|
||||
case 7:
|
||||
EICRB = (EICRB & 0x3F) | 0x40;
|
||||
EIMSK |= 0x80;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__PIC32MX__)
|
||||
|
||||
#ifdef ENCODER_OPTIMIZE_INTERRUPTS
|
||||
#undef ENCODER_OPTIMIZE_INTERRUPTS
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef ENCODER_OPTIMIZE_INTERRUPTS
|
||||
#undef ENCODER_OPTIMIZE_INTERRUPTS
|
||||
#endif
|
||||
|
||||
#endif
|
340
.pio/libdeps/attiny88/Encoder/utility/interrupt_pins.h
Executable file
340
.pio/libdeps/attiny88/Encoder/utility/interrupt_pins.h
Executable file
|
@ -0,0 +1,340 @@
|
|||
// interrupt pins for known boards
|
||||
|
||||
// Teensy (and maybe others) define these automatically
|
||||
#if !defined(CORE_NUM_INTERRUPT)
|
||||
|
||||
// Wiring boards
|
||||
#if defined(WIRING)
|
||||
#define CORE_NUM_INTERRUPT NUM_EXTERNAL_INTERRUPTS
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 0
|
||||
#define CORE_INT0_PIN EI0
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 1
|
||||
#define CORE_INT1_PIN EI1
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 2
|
||||
#define CORE_INT2_PIN EI2
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 3
|
||||
#define CORE_INT3_PIN EI3
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 4
|
||||
#define CORE_INT4_PIN EI4
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 5
|
||||
#define CORE_INT5_PIN EI5
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 6
|
||||
#define CORE_INT6_PIN EI6
|
||||
#endif
|
||||
#if NUM_EXTERNAL_INTERRUPTS > 7
|
||||
#define CORE_INT7_PIN EI7
|
||||
#endif
|
||||
|
||||
// Arduino Uno, Duemilanove, Diecimila, LilyPad, Mini, Fio, etc...
|
||||
#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) ||defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__)
|
||||
#define CORE_NUM_INTERRUPT 2
|
||||
#define CORE_INT0_PIN 2
|
||||
#define CORE_INT1_PIN 3
|
||||
|
||||
// Arduino Mega
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define CORE_NUM_INTERRUPT 6
|
||||
#define CORE_INT0_PIN 2
|
||||
#define CORE_INT1_PIN 3
|
||||
#define CORE_INT2_PIN 21
|
||||
#define CORE_INT3_PIN 20
|
||||
#define CORE_INT4_PIN 19
|
||||
#define CORE_INT5_PIN 18
|
||||
|
||||
// Arduino Nano Every, Uno R2 Wifi
|
||||
#elif defined(__AVR_ATmega4809__)
|
||||
#define CORE_NUM_INTERRUPT 22
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT6_PIN 6
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT9_PIN 9
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT20_PIN 20
|
||||
#define CORE_INT21_PIN 21
|
||||
|
||||
// Arduino Leonardo (untested)
|
||||
#elif defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY)
|
||||
#define CORE_NUM_INTERRUPT 5
|
||||
#define CORE_INT0_PIN 3
|
||||
#define CORE_INT1_PIN 2
|
||||
#define CORE_INT2_PIN 0
|
||||
#define CORE_INT3_PIN 1
|
||||
#define CORE_INT4_PIN 7
|
||||
|
||||
// Sanguino (untested) and ATmega1284P
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__)
|
||||
#define CORE_NUM_INTERRUPT 3
|
||||
#define CORE_INT0_PIN 10
|
||||
#define CORE_INT1_PIN 11
|
||||
#define CORE_INT2_PIN 2
|
||||
|
||||
// ATmega32u2 and ATmega32u16 based boards with HoodLoader2
|
||||
#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__)
|
||||
#define CORE_NUM_INTERRUPT 8
|
||||
#define CORE_INT0_PIN 8
|
||||
#define CORE_INT1_PIN 17
|
||||
#define CORE_INT2_PIN 13
|
||||
#define CORE_INT3_PIN 14
|
||||
#define CORE_INT4_PIN 15
|
||||
#define CORE_INT5_PIN 16
|
||||
#define CORE_INT6_PIN 19
|
||||
#define CORE_INT7_PIN 20
|
||||
|
||||
// Chipkit Uno32 - attachInterrupt may not support CHANGE option
|
||||
#elif defined(__PIC32MX__) && defined(_BOARD_UNO_)
|
||||
#define CORE_NUM_INTERRUPT 5
|
||||
#define CORE_INT0_PIN 38
|
||||
#define CORE_INT1_PIN 2
|
||||
#define CORE_INT2_PIN 7
|
||||
#define CORE_INT3_PIN 8
|
||||
#define CORE_INT4_PIN 35
|
||||
|
||||
// Chipkit Uno32 - attachInterrupt may not support CHANGE option
|
||||
#elif defined(__PIC32MX__) && defined(_BOARD_MEGA_)
|
||||
#define CORE_NUM_INTERRUPT 5
|
||||
#define CORE_INT0_PIN 3
|
||||
#define CORE_INT1_PIN 2
|
||||
#define CORE_INT2_PIN 7
|
||||
#define CORE_INT3_PIN 21
|
||||
#define CORE_INT4_PIN 20
|
||||
|
||||
// http://hlt.media.mit.edu/?p=1229
|
||||
#elif defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
#define CORE_NUM_INTERRUPT 1
|
||||
#define CORE_INT0_PIN 2
|
||||
|
||||
// ATtiny441 ATtiny841
|
||||
#elif defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)
|
||||
#define CORE_NUM_INTERRUPT 1
|
||||
#define CORE_INT0_PIN 9
|
||||
|
||||
//https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/extras/ATtiny_x313.md
|
||||
#elif defined(__AVR_ATtinyX313__)
|
||||
#define CORE_NUM_INTERRUPT 2
|
||||
#define CORE_INT0_PIN 4
|
||||
#define CORE_INT1_PIN 5
|
||||
|
||||
// Attiny167 same core as abobe
|
||||
#elif defined(__AVR_ATtiny167__)
|
||||
#define CORE_NUM_INTERRUPT 2
|
||||
#define CORE_INT0_PIN 14
|
||||
#define CORE_INT1_PIN 3
|
||||
|
||||
|
||||
// Arduino Due
|
||||
#elif defined(__SAM3X8E__)
|
||||
#define CORE_NUM_INTERRUPT 54
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT6_PIN 6
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT9_PIN 9
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT20_PIN 20
|
||||
#define CORE_INT21_PIN 21
|
||||
#define CORE_INT22_PIN 22
|
||||
#define CORE_INT23_PIN 23
|
||||
#define CORE_INT24_PIN 24
|
||||
#define CORE_INT25_PIN 25
|
||||
#define CORE_INT26_PIN 26
|
||||
#define CORE_INT27_PIN 27
|
||||
#define CORE_INT28_PIN 28
|
||||
#define CORE_INT29_PIN 29
|
||||
#define CORE_INT30_PIN 30
|
||||
#define CORE_INT31_PIN 31
|
||||
#define CORE_INT32_PIN 32
|
||||
#define CORE_INT33_PIN 33
|
||||
#define CORE_INT34_PIN 34
|
||||
#define CORE_INT35_PIN 35
|
||||
#define CORE_INT36_PIN 36
|
||||
#define CORE_INT37_PIN 37
|
||||
#define CORE_INT38_PIN 38
|
||||
#define CORE_INT39_PIN 39
|
||||
#define CORE_INT40_PIN 40
|
||||
#define CORE_INT41_PIN 41
|
||||
#define CORE_INT42_PIN 42
|
||||
#define CORE_INT43_PIN 43
|
||||
#define CORE_INT44_PIN 44
|
||||
#define CORE_INT45_PIN 45
|
||||
#define CORE_INT46_PIN 46
|
||||
#define CORE_INT47_PIN 47
|
||||
#define CORE_INT48_PIN 48
|
||||
#define CORE_INT49_PIN 49
|
||||
#define CORE_INT50_PIN 50
|
||||
#define CORE_INT51_PIN 51
|
||||
#define CORE_INT52_PIN 52
|
||||
#define CORE_INT53_PIN 53
|
||||
|
||||
// ESP8266 (https://github.com/esp8266/Arduino/)
|
||||
#elif defined(ESP8266)
|
||||
#define CORE_NUM_INTERRUPT EXTERNAL_NUM_INTERRUPTS
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
// GPIO6-GPIO11 are typically used to interface with the flash memory IC on
|
||||
// most esp8266 modules, so we should avoid adding interrupts to these pins.
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
|
||||
// ESP32 (https://github.com/espressif/arduino-esp32)
|
||||
#elif defined(ESP32)
|
||||
|
||||
#define CORE_NUM_INTERRUPT 40
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
// GPIO6-GPIO11 are typically used to interface with the flash memory IC on
|
||||
// esp32, so we should avoid adding interrupts to these pins.
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT21_PIN 21
|
||||
#define CORE_INT22_PIN 22
|
||||
#define CORE_INT23_PIN 23
|
||||
#define CORE_INT25_PIN 25
|
||||
#define CORE_INT26_PIN 26
|
||||
#define CORE_INT27_PIN 27
|
||||
#define CORE_INT32_PIN 32
|
||||
#define CORE_INT33_PIN 33
|
||||
#define CORE_INT34_PIN 34
|
||||
#define CORE_INT35_PIN 35
|
||||
#define CORE_INT36_PIN 36
|
||||
#define CORE_INT39_PIN 39
|
||||
|
||||
|
||||
// Arduino Zero - TODO: interrupts do not seem to work
|
||||
// please help, contribute a fix!
|
||||
#elif defined(__SAMD21G18A__)
|
||||
#define CORE_NUM_INTERRUPT 31
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT6_PIN 6
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT9_PIN 9
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT20_PIN 20
|
||||
#define CORE_INT21_PIN 21
|
||||
#define CORE_INT22_PIN 22
|
||||
#define CORE_INT23_PIN 23
|
||||
#define CORE_INT24_PIN 24
|
||||
#define CORE_INT25_PIN 25
|
||||
#define CORE_INT26_PIN 26
|
||||
#define CORE_INT27_PIN 27
|
||||
#define CORE_INT28_PIN 28
|
||||
#define CORE_INT29_PIN 29
|
||||
#define CORE_INT30_PIN 30
|
||||
|
||||
#elif defined(__SAMD51__)
|
||||
#define CORE_NUM_INTERRUPT 26
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT6_PIN 6
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT9_PIN 9
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT20_PIN 20
|
||||
#define CORE_INT21_PIN 21
|
||||
#define CORE_INT22_PIN 22
|
||||
#define CORE_INT23_PIN 23
|
||||
#define CORE_INT24_PIN 24
|
||||
#define CORE_INT25_PIN 25
|
||||
|
||||
// Arduino 101
|
||||
#elif defined(__arc__)
|
||||
#define CORE_NUM_INTERRUPT 14
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(CORE_NUM_INTERRUPT)
|
||||
#error "Interrupts are unknown for this board, please add to this code"
|
||||
#endif
|
||||
#if CORE_NUM_INTERRUPT <= 0
|
||||
#error "Encoder requires interrupt pins, but this board does not have any :("
|
||||
#error "You could try defining ENCODER_DO_NOT_USE_INTERRUPTS as a kludge."
|
||||
#endif
|
||||
|
1
.pio/libdeps/attiny88/integrity.dat
Normal file
1
.pio/libdeps/attiny88/integrity.dat
Normal file
|
@ -0,0 +1 @@
|
|||
paulstoffregen/Encoder@^1.4.2
|
233
TrigorMortse.ino
233
TrigorMortse.ino
|
@ -1,233 +0,0 @@
|
|||
#include <Encoder.h>
|
||||
#include <Arduino.h>
|
||||
#include "src/MortseUi.h"
|
||||
|
||||
const byte MorseTable[] = {0b00100000,0,0b00010010,0,0,0,0,0b00011110,0b10110110,0b00101101,0,0b10101010,0b00110011,0b00100001,0b00010101,0b10110010,0b10111111,0b10101111,0b10100111,0b10100011,0b10100001,0b10100000,0b10110000,0b10111000,0b10111100,0b10111111,0b00111000,0b00101010,0,0b10110001,0,0b00001100,0b00011010,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0,0b00001101,0b00011110,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0};
|
||||
|
||||
const int Channel1 = 9; //Output Channel 1
|
||||
const int Channel2 = 10; //Output Channel 2
|
||||
const int Channel3 = 11; //Output Channel 3
|
||||
const int Enc1P1 = 2; //Encoder 1 Pin 1 to Interrupt
|
||||
const int Enc2P1 = 3; //Encoder 2 Pin 1 to Interrupt
|
||||
const int Enc1P2 = 14; //Encoder 1 Pin 2 to non-Interrupting pin because we only have 2
|
||||
const int Enc2P2 = 15; //Encoder 2 Pin 2 to non-Interrupting pin because we only have 2
|
||||
const int Enc1Btn = 16; //Encoder 1 Button
|
||||
const int Enc2Btn = 17; //Encoder 2 Button
|
||||
const int ClockIn = 4; //Clock In
|
||||
const int ClockDetect = 7; //Detect clock jack
|
||||
const int DebounceTime = 10; //Debounce time in ms
|
||||
|
||||
const int DisplaySpi = 0; //todo: find spi port ## from library
|
||||
|
||||
Encoder LeftEnc( Enc1P1, Enc1P2);
|
||||
Encoder RightEnc( Enc2P1, Enc2P2);
|
||||
|
||||
//MortseUi Ui(DisplaySpi);
|
||||
|
||||
String TestText = "Momento Mortse";
|
||||
|
||||
int E1 = 0;
|
||||
int E2 = 0;
|
||||
int Channel1Index = 0;
|
||||
int MorseIndex = 0;
|
||||
bool E1Btn = false;
|
||||
bool E2Btn = false;
|
||||
bool ClockState = false;
|
||||
bool Beat = false;
|
||||
unsigned int Channel1Trig = 0, Channel2Trig = 0, Channel3Trig = 0;
|
||||
bool E1Prev, E2Prev, CDPrev, E1Click, E2Click, CDIn = false, Channel1State = false, Channel2State = false, Channel3State = false;
|
||||
unsigned int E1Bounce, E2Bounce, CDBounce = 0, BeatBounce = 0;
|
||||
unsigned long ClockPrev = 0, ClockInPrev = 0, LastBeat = 0;
|
||||
byte Input = 0;
|
||||
int PpQN = 1;
|
||||
float Clock = 15;
|
||||
float ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
unsigned long ClockTime = 0;
|
||||
unsigned long LastStepTime = 0;
|
||||
long EncLeft, EncRight = 0;
|
||||
|
||||
void setup() {
|
||||
|
||||
//Open Serial for output prior to installing a screen
|
||||
Serial.begin( 115200 );
|
||||
Serial.println("Momento Mortse");
|
||||
randomSeed(analogRead(A7));
|
||||
|
||||
pinMode(Enc1Btn, INPUT_PULLUP);
|
||||
pinMode(Enc2Btn, INPUT_PULLUP);
|
||||
pinMode(ClockIn, INPUT);
|
||||
pinMode(ClockDetect, INPUT_PULLUP);
|
||||
pinMode(Channel1, OUTPUT);
|
||||
pinMode(Channel2, OUTPUT);
|
||||
pinMode(Channel3, OUTPUT);
|
||||
|
||||
E1Btn = digitalRead(Enc1Btn);
|
||||
E1Prev = E1Btn;
|
||||
E2Btn = digitalRead(Enc2Btn);
|
||||
E2Prev = E2Btn;
|
||||
ClockState = digitalRead(ClockIn);
|
||||
CDPrev = digitalRead(ClockDetect);
|
||||
digitalWrite(Channel1, LOW);
|
||||
digitalWrite(Channel2, LOW);
|
||||
digitalWrite(Channel2, LOW);
|
||||
|
||||
// Timer0 is already used for millis() - we'll just interrupt somewhere
|
||||
// in the middle and call the "Compare A" function below
|
||||
OCR0A = 0xAF;
|
||||
TIMSK0 |= _BV(OCIE0A);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
long newLEnc = LeftEnc.read();
|
||||
long newREnc = RightEnc.read();
|
||||
|
||||
if (digitalRead(Enc1Btn) != E1Btn){
|
||||
if (E1Bounce == 0 & E1Click == false){
|
||||
Serial.println("E1Btn State Change");
|
||||
E1Btn = !E1Btn;
|
||||
E1Bounce = DebounceTime;
|
||||
E1Click = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (digitalRead(Enc2Btn) != E2Btn){
|
||||
if (E2Bounce == 0 & E2Click == false){
|
||||
Serial.println("E2Btn State Change");
|
||||
E2Btn = !E2Btn;
|
||||
E2Bounce = DebounceTime;
|
||||
E2Click = true;
|
||||
}
|
||||
}
|
||||
|
||||
//false click handler
|
||||
E1Click = false;
|
||||
E2Click = false;
|
||||
|
||||
bool newCD = digitalRead(ClockDetect);
|
||||
|
||||
if (newCD != CDPrev){
|
||||
if (CDBounce == 0){
|
||||
Serial.println("Clock Jack Status Change");
|
||||
CDPrev = CDIn = newCD;
|
||||
CDBounce = DebounceTime << 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ( digitalRead(ClockIn) != ClockState){
|
||||
ClockState = !ClockState;
|
||||
if (ClockState){
|
||||
unsigned long tmpClock = micros();
|
||||
float clkInTick = tmpClock - ClockPrev;
|
||||
ClockPrev = tmpClock;
|
||||
|
||||
if (abs(ClockInPrev - clkInTick) > 500){
|
||||
Clock =((1.0/(clkInTick/1000000.0)) * 60.0)/(float)PpQN;
|
||||
String outputBPM = "New BPM: ";
|
||||
outputBPM.concat(Clock);
|
||||
Serial.println(outputBPM);
|
||||
outputBPM = "Clock Tick: ";
|
||||
outputBPM.concat(clkInTick);
|
||||
Serial.println(outputBPM);
|
||||
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
}
|
||||
else{
|
||||
Beat = true;
|
||||
LastBeat = tmpClock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((LastBeat + ClockTick) < micros()){
|
||||
Beat = true;
|
||||
LastBeat = micros();
|
||||
}
|
||||
|
||||
if (newLEnc != EncLeft || newREnc != EncRight){
|
||||
String output = "Left Enc Pos: ";
|
||||
output.concat(newLEnc);
|
||||
output.concat( ", Right Enc Pos: ");
|
||||
output.concat(newREnc);
|
||||
Serial.print(output);
|
||||
|
||||
if (newLEnc != EncLeft){
|
||||
Clock = Clock + (((float)EncLeft - (float)newLEnc)/40.0);
|
||||
} else{
|
||||
Clock = Clock + ((EncRight - newREnc) * 2.5);
|
||||
}
|
||||
|
||||
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
EncLeft = newLEnc;
|
||||
EncRight = newREnc;
|
||||
output = " Clock: ";
|
||||
output.concat(Clock);
|
||||
output.concat( " Clocktick: ");
|
||||
output.concat( ClockTick);
|
||||
|
||||
Serial.println(output);
|
||||
|
||||
}
|
||||
|
||||
if (Beat){
|
||||
Beat = false;
|
||||
if (BeatBounce == 0){
|
||||
BeatBounce = DebounceTime;
|
||||
|
||||
//Insert Beat Output here!
|
||||
char outputChar = TestText[Channel1Index];
|
||||
Serial.println(outputChar);
|
||||
if (outputChar == '\0' ){
|
||||
Channel1Index = 0;
|
||||
outputChar = TestText[Channel1Index];
|
||||
}
|
||||
byte morseLength = MorseTable[((int)outputChar - 32)];
|
||||
byte morsePattern = morseLength;
|
||||
bool trigger = (morsePattern >> MorseIndex) & 1;
|
||||
|
||||
if (MorseIndex == 0){
|
||||
Channel1Index++;
|
||||
outputChar = TestText[Channel1Index];
|
||||
MorseIndex = (((MorseTable[((int)outputChar - 32)]) >> 5)) & 7;
|
||||
}
|
||||
|
||||
MorseIndex--;
|
||||
|
||||
if (trigger){
|
||||
digitalWrite(Channel1, HIGH);
|
||||
Channel1Trig = DebounceTime;
|
||||
Channel1State = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Channel1State) && (Channel1Trig == 0)){
|
||||
digitalWrite(Channel1, LOW);
|
||||
Channel1State = false;
|
||||
}
|
||||
if (Channel2State && !Channel2Trig){
|
||||
digitalWrite(Channel2, LOW);
|
||||
Channel2State = false;
|
||||
}
|
||||
if (Channel3State && !Channel3Trig){
|
||||
digitalWrite(Channel3, LOW);
|
||||
Channel3State = false;
|
||||
}
|
||||
|
||||
//Ui.tick();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Interrupt is called once a millisecond,
|
||||
SIGNAL(TIMER0_COMPA_vect)
|
||||
{
|
||||
E1Bounce = (E1Bounce - 1) & 0b10000000;
|
||||
E2Bounce = (E2Bounce - 1) & 0b10000000;
|
||||
CDBounce = (CDBounce - 1) & 0b10000000;
|
||||
BeatBounce = (BeatBounce - 1) & 0b01111111;
|
||||
Channel1Trig = (Channel1Trig - 1) & 0b01111111;
|
||||
Channel2Trig = (Channel2Trig - 1) & 0b10000000;
|
||||
Channel3Trig = (Channel3Trig - 1) & 0b10000000;
|
||||
}
|
39
include/README
Normal file
39
include/README
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
lib/README
Normal file
46
lib/README
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
15
platformio.ini
Normal file
15
platformio.ini
Normal file
|
@ -0,0 +1,15 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:attiny88]
|
||||
platform = atmelavr
|
||||
board = attiny88
|
||||
framework = arduino
|
||||
lib_deps = paulstoffregen/Encoder@^1.4.2
|
233
src/main.cpp
Normal file
233
src/main.cpp
Normal file
|
@ -0,0 +1,233 @@
|
|||
#include <Encoder.h>
|
||||
#include <Arduino.h>
|
||||
#include "MortseUi.h"
|
||||
|
||||
const byte MorseTable[] = {0b00100000,0,0b00010010,0,0,0,0,0b00011110,0b10110110,0b00101101,0,0b10101010,0b00110011,0b00100001,0b00010101,0b10110010,0b10111111,0b10101111,0b10100111,0b10100011,0b10100001,0b10100000,0b10110000,0b10111000,0b10111100,0b10111111,0b00111000,0b00101010,0,0b10110001,0,0b00001100,0b00011010,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0,0b00001101,0b00011110,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0};
|
||||
|
||||
const int Channel1 = 9; //Output Channel 1
|
||||
const int Channel2 = 10; //Output Channel 2
|
||||
const int Channel3 = 11; //Output Channel 3
|
||||
const int Enc1P1 = 2; //Encoder 1 Pin 1 to Interrupt
|
||||
const int Enc2P1 = 3; //Encoder 2 Pin 1 to Interrupt
|
||||
const int Enc1P2 = 14; //Encoder 1 Pin 2 to non-Interrupting pin because we only have 2
|
||||
const int Enc2P2 = 15; //Encoder 2 Pin 2 to non-Interrupting pin because we only have 2
|
||||
const int Enc1Btn = 16; //Encoder 1 Button
|
||||
const int Enc2Btn = 17; //Encoder 2 Button
|
||||
const int ClockIn = 4; //Clock In
|
||||
const int ClockDetect = 7; //Detect clock jack
|
||||
const int DebounceTime = 10; //Debounce time in ms
|
||||
|
||||
const int DisplaySpi = 0; //todo: find spi port ## from library
|
||||
|
||||
Encoder LeftEnc( Enc1P1, Enc1P2);
|
||||
Encoder RightEnc( Enc2P1, Enc2P2);
|
||||
|
||||
//MortseUi Ui(DisplaySpi);
|
||||
|
||||
String TestText = "Momento Mortse";
|
||||
|
||||
int E1 = 0;
|
||||
int E2 = 0;
|
||||
int Channel1Index = 0;
|
||||
int MorseIndex = 0;
|
||||
bool E1Btn = false;
|
||||
bool E2Btn = false;
|
||||
bool ClockState = false;
|
||||
bool Beat = false;
|
||||
unsigned int Channel1Trig = 0, Channel2Trig = 0, Channel3Trig = 0;
|
||||
bool E1Prev, E2Prev, CDPrev, E1Click, E2Click, CDIn = false, Channel1State = false, Channel2State = false, Channel3State = false;
|
||||
unsigned int E1Bounce, E2Bounce, CDBounce = 0, BeatBounce = 0;
|
||||
unsigned long ClockPrev = 0, ClockInPrev = 0, LastBeat = 0;
|
||||
byte Input = 0;
|
||||
int PpQN = 1;
|
||||
float Clock = 15;
|
||||
float ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
unsigned long ClockTime = 0;
|
||||
unsigned long LastStepTime = 0;
|
||||
long EncLeft, EncRight = 0;
|
||||
|
||||
void setup() {
|
||||
|
||||
//Open Serial for output prior to installing a screen
|
||||
Serial.begin( 115200 );
|
||||
Serial.println("Momento Mortse");
|
||||
randomSeed(analogRead(A7));
|
||||
|
||||
pinMode(Enc1Btn, INPUT_PULLUP);
|
||||
pinMode(Enc2Btn, INPUT_PULLUP);
|
||||
pinMode(ClockIn, INPUT);
|
||||
pinMode(ClockDetect, INPUT_PULLUP);
|
||||
pinMode(Channel1, OUTPUT);
|
||||
pinMode(Channel2, OUTPUT);
|
||||
pinMode(Channel3, OUTPUT);
|
||||
|
||||
E1Btn = digitalRead(Enc1Btn);
|
||||
E1Prev = E1Btn;
|
||||
E2Btn = digitalRead(Enc2Btn);
|
||||
E2Prev = E2Btn;
|
||||
ClockState = digitalRead(ClockIn);
|
||||
CDPrev = digitalRead(ClockDetect);
|
||||
digitalWrite(Channel1, LOW);
|
||||
digitalWrite(Channel2, LOW);
|
||||
digitalWrite(Channel2, LOW);
|
||||
|
||||
// Timer0 is already used for millis() - we'll just interrupt somewhere
|
||||
// in the middle and call the "Compare A" function below
|
||||
OCR0A = 0xAF;
|
||||
TIMSK0 |= _BV(OCIE0A);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
long newLEnc = LeftEnc.read();
|
||||
long newREnc = RightEnc.read();
|
||||
|
||||
if (digitalRead(Enc1Btn) != E1Btn){
|
||||
if (E1Bounce == 0 & E1Click == false){
|
||||
Serial.println("E1Btn State Change");
|
||||
E1Btn = !E1Btn;
|
||||
E1Bounce = DebounceTime;
|
||||
E1Click = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (digitalRead(Enc2Btn) != E2Btn){
|
||||
if (E2Bounce == 0 & E2Click == false){
|
||||
Serial.println("E2Btn State Change");
|
||||
E2Btn = !E2Btn;
|
||||
E2Bounce = DebounceTime;
|
||||
E2Click = true;
|
||||
}
|
||||
}
|
||||
|
||||
//false click handler
|
||||
E1Click = false;
|
||||
E2Click = false;
|
||||
|
||||
bool newCD = digitalRead(ClockDetect);
|
||||
|
||||
if (newCD != CDPrev){
|
||||
if (CDBounce == 0){
|
||||
Serial.println("Clock Jack Status Change");
|
||||
CDPrev = CDIn = newCD;
|
||||
CDBounce = DebounceTime << 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ( digitalRead(ClockIn) != ClockState){
|
||||
ClockState = !ClockState;
|
||||
if (ClockState){
|
||||
unsigned long tmpClock = micros();
|
||||
float clkInTick = tmpClock - ClockPrev;
|
||||
ClockPrev = tmpClock;
|
||||
|
||||
if (abs(ClockInPrev - clkInTick) > 500){
|
||||
Clock =((1.0/(clkInTick/1000000.0)) * 60.0)/(float)PpQN;
|
||||
String outputBPM = "New BPM: ";
|
||||
outputBPM.concat(Clock);
|
||||
Serial.println(outputBPM);
|
||||
outputBPM = "Clock Tick: ";
|
||||
outputBPM.concat(clkInTick);
|
||||
Serial.println(outputBPM);
|
||||
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
}
|
||||
else{
|
||||
Beat = true;
|
||||
LastBeat = tmpClock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((LastBeat + ClockTick) < micros()){
|
||||
Beat = true;
|
||||
LastBeat = micros();
|
||||
}
|
||||
|
||||
if (newLEnc != EncLeft || newREnc != EncRight){
|
||||
String output = "Left Enc Pos: ";
|
||||
output.concat(newLEnc);
|
||||
output.concat( ", Right Enc Pos: ");
|
||||
output.concat(newREnc);
|
||||
Serial.print(output);
|
||||
|
||||
if (newLEnc != EncLeft){
|
||||
Clock = Clock + (((float)EncLeft - (float)newLEnc)/40.0);
|
||||
} else{
|
||||
Clock = Clock + ((EncRight - newREnc) * 2.5);
|
||||
}
|
||||
|
||||
ClockTick = (1/((Clock * PpQN)/60)) * 1000;
|
||||
EncLeft = newLEnc;
|
||||
EncRight = newREnc;
|
||||
output = " Clock: ";
|
||||
output.concat(Clock);
|
||||
output.concat( " Clocktick: ");
|
||||
output.concat( ClockTick);
|
||||
|
||||
Serial.println(output);
|
||||
|
||||
}
|
||||
|
||||
if (Beat){
|
||||
Beat = false;
|
||||
if (BeatBounce == 0){
|
||||
BeatBounce = DebounceTime;
|
||||
|
||||
//Insert Beat Output here!
|
||||
char outputChar = TestText[Channel1Index];
|
||||
Serial.println(outputChar);
|
||||
if (outputChar == '\0' ){
|
||||
Channel1Index = 0;
|
||||
outputChar = TestText[Channel1Index];
|
||||
}
|
||||
byte morseLength = MorseTable[((int)outputChar - 32)];
|
||||
byte morsePattern = morseLength;
|
||||
bool trigger = (morsePattern >> MorseIndex) & 1;
|
||||
|
||||
if (MorseIndex == 0){
|
||||
Channel1Index++;
|
||||
outputChar = TestText[Channel1Index];
|
||||
MorseIndex = (((MorseTable[((int)outputChar - 32)]) >> 5)) & 7;
|
||||
}
|
||||
|
||||
MorseIndex--;
|
||||
|
||||
if (trigger){
|
||||
digitalWrite(Channel1, HIGH);
|
||||
Channel1Trig = DebounceTime;
|
||||
Channel1State = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Channel1State) && (Channel1Trig == 0)){
|
||||
digitalWrite(Channel1, LOW);
|
||||
Channel1State = false;
|
||||
}
|
||||
if (Channel2State && !Channel2Trig){
|
||||
digitalWrite(Channel2, LOW);
|
||||
Channel2State = false;
|
||||
}
|
||||
if (Channel3State && !Channel3Trig){
|
||||
digitalWrite(Channel3, LOW);
|
||||
Channel3State = false;
|
||||
}
|
||||
|
||||
//Ui.tick();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Interrupt is called once a millisecond,
|
||||
SIGNAL(TIMER0_COMPA_vect)
|
||||
{
|
||||
E1Bounce = (E1Bounce - 1) & 0b10000000;
|
||||
E2Bounce = (E2Bounce - 1) & 0b10000000;
|
||||
CDBounce = (CDBounce - 1) & 0b10000000;
|
||||
BeatBounce = (BeatBounce - 1) & 0b01111111;
|
||||
Channel1Trig = (Channel1Trig - 1) & 0b01111111;
|
||||
Channel2Trig = (Channel2Trig - 1) & 0b10000000;
|
||||
Channel3Trig = (Channel3Trig - 1) & 0b10000000;
|
||||
}
|
11
test/README
Normal file
11
test/README
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
Reference in a new issue