From 7c739a8d0c6c8379d0f1e7e75c0659376e21a64d Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Tue, 13 Aug 2013 16:55:28 +0200 Subject: [PATCH] something's working already --- Encoder.zip | Bin 0 -> 13936 bytes wtf/Encoder.cpp | 10 + wtf/Encoder.h | 941 ++++++++++++++++++++++++++++++++++++++++++++++++ wtf/wtf.ino | 154 ++++++++ 4 files changed, 1105 insertions(+) create mode 100644 Encoder.zip create mode 100644 wtf/Encoder.cpp create mode 100644 wtf/Encoder.h create mode 100644 wtf/wtf.ino diff --git a/Encoder.zip b/Encoder.zip new file mode 100644 index 0000000000000000000000000000000000000000..61dfff8adc3100fd78a5a5034f8c61b70d537ed8 GIT binary patch literal 13936 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 literal 0 HcmV?d00001 diff --git a/wtf/Encoder.cpp b/wtf/Encoder.cpp new file mode 100644 index 0000000..6911b4f --- /dev/null +++ b/wtf/Encoder.cpp @@ -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[]; + + diff --git a/wtf/Encoder.h b/wtf/Encoder.h new file mode 100644 index 0000000..b51d3bf --- /dev/null +++ b/wtf/Encoder.h @@ -0,0 +1,941 @@ +/* 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 + * + * 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 void write(int32_t p) { + noInterrupts(); + encoder.position = p; + interrupts(); + } +#else + inline int32_t read() { + update(&encoder); + return encoder.position; + } + 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); + } +*/ + +private: + 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 + } +/* +#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 +#endif // ENCODER_OPTIMIZE_INTERRUPTS + + +#endif diff --git a/wtf/wtf.ino b/wtf/wtf.ino new file mode 100644 index 0000000..e1dfd0a --- /dev/null +++ b/wtf/wtf.ino @@ -0,0 +1,154 @@ +#include +#include + + +Encoder rotEnc(A0, A1); +long encVal = 0; +int activeTimer=0; +int timerLens[3]; +int grindCheck = 0; + +bool buttonLeftPressed=false; +void buttonLeft() { + buttonLeftPressed=true; +} + +bool buttonRightPressed=false; +void buttonRight() { + buttonRightPressed=true; +} + +bool buttonMidPressed=false; +void buttonMid() { + buttonMidPressed=true; +} + +bool turnedLeft=false; +void turnLeft() { + turnedLeft=true; +} + +bool turnedRight=false; +void turnRight() { + turnedRight=true; +} + +bool rotPressed=false; +void pressRot() { + rotPressed=true; +} + +void lcdPut(char* text) { + char str[35]; + //printf("%c[2K", 27); + //printf("\r%s", text ); + //fflush(stdout); + sprintf(str, "%c[2K\n\r%s", 27, text); + Serial.println(str); +} + + +void grind(int time) { + lcdPut("grinding..."); + delay(time); + lcdPut("Fin..."); + delay(80); +} + + +void boilerplate() { + + if(rotEnc.read() < encVal) { + encVal = rotEnc.read(); + turnLeft(); + return; + } else if(rotEnc.read() > encVal) { + encVal = rotEnc.read(); + turnRight(); + return; + } + + if( digitalRead(A2) == LOW && grindCheck > 25 ) { + grind( timerLens[activeTimer] ); + grindCheck = 0; + delay(25); + } + if( digitalRead(A2) == LOW && grindCheck >= 0 && grindCheck <= 25 ) { + grindCheck++; + } + if( digitalRead(A2) == HIGH && grindCheck > 0 ) { + grindCheck = 0; + } + + + if( digitalRead(A3) == LOW ) { + buttonLeft(); + delay(25); + } + + if( digitalRead(A4) == LOW ) { + buttonMid(); + delay(25); + } + + if( digitalRead(A5) == LOW ) { + buttonRight(); + delay(25); + } + + +} + + +void loop() { + boilerplate(); + + char str[16]; + sprintf(str, "T%1d: %10d", activeTimer, timerLens[activeTimer]); + lcdPut(str); + + if(buttonLeftPressed) { + buttonLeftPressed=false; + activeTimer=0; + } + if(buttonRightPressed) { + buttonRightPressed=false; + activeTimer=2; + } + if(buttonMidPressed) { + buttonMidPressed=false; + activeTimer=1; + } + if(turnedLeft) { + turnedLeft=false; + timerLens[activeTimer] -= 5; + } + if(turnedRight) { + turnedRight=false; + timerLens[activeTimer] += 5; + } + if(rotPressed) { + rotPressed=false; + grind(timerLens[activeTimer]); + } +} + + + +void setup() +{ + Serial.begin(9600); + + timerLens[0] = 1000; + timerLens[1] = 250; + timerLens[2] = 2500; + + pinMode(A3, INPUT); + digitalWrite(A3,HIGH); + pinMode(A4, INPUT); + digitalWrite(A4,HIGH); + pinMode(A5, INPUT); + digitalWrite(A5,HIGH); + + +}