working on it ...

Filters

Explore Public Snippets

Sort by

Found 105 snippets matching: rotary

    public by tomsim  2211  0  5  0

    Rotary Encoder State table

    Read Rotary Encoder using state table instead of interrupt
    /* Common 2 pins rotary encoder (ignore push button pin)
      Default pin output = (0,0)
      Read each pin and combine them into one value
      then use it to index the state table to advance to next state
      State sequence 00->01->11->10->00 return -1
          Next state  0   1   3   2   0
                     00->10->11->01->00 return +1
                      0   2   3   1   0
    */
    const int ENC_A = 2;
    const int ENC_B = 3;
    
    // State table
    static uint8_t stb[][4] =
    {
    //       0 1 2 3
            {8,2,1,8}, //0 start here v=0
            {0,8,1,3}, //1 0*2(-3-1-0 -1
            {0,8,2,4}, //2 0*1(-3-2-0
            {8,5,1,3}, //3 0-2*3(-1-0 -1
            {8,2,6,4}, //4 0-1*3(-2-0
            {7,5,8,3}, //5 0-2-3*1(-0 -1
            {9,8,6,4}, //6 0-1-3*2(-0
    };
    static int encRead( int pa, int pb)
    {
    	int8_t cx = 0; 			// initial state 0
    	int errCnt = 0;
    	while (errCnt < 1550)
    	{
    		uint8_t v = digitalRead(pa) | digitalRead(pb)<<1;
    
    		if (v < 4)
    		{
    			uint8_t nx = stb[cx][v];
    
    			if (nx > 6)
    			{
    		    if (nx == 8)
    		      errCnt++;
    				else
    					return (8 - (int)nx);
    			}
    			else
    			{
    				cx = nx;
    			}
    		}
    		else
    		{
    			cx = 0;
    			errCnt++;
    		}
    	}
    
    	return 0;
    }
    
    void setup()
    {
    	Serial.begin(9600);
    
    	pinMode( ENC_A, INPUT_PULLUP);
    	pinMode( ENC_B, INPUT_PULLUP);
    
    }
    
    const int MAX_VAL = 64*6 -1;
    
    int lastPos = 0;
    
    void loop() {
    
    	unsigned long 	sampleTime = millis();
    	int rv = encRead(ENC_A,ENC_B);
    	sampleTime = millis() - sampleTime;
    
    	if (rv == 0)
    	{
    		delay(50);
    	}
    	else
    	{
    		lastPos += rv;
    		if (sampleTime < 20)
    			sampleTime = 20;
    		// simulate acceleration
    		lastPos += rv*int(9000.0/(sampleTime*sampleTime));
    
    		if (lastPos < 0) lastPos = 0;
    		if (lastPos > MAX_VAL) lastPos = MAX_VAL;
    
    		Serial.print(lastPos); Serial.print(" "); Serial.println(sampleTime);
    
    	}
    
    }
    
    
    
    
    
                                        

    external by calaveraInfo  369  3  3  0

    Use rotary encoder with Arduino Micro to increase/decrease a value and show that value on SSD1306 display. Based on https://learn.adafruit.com/pro-trinket-rotary-encoder/example-rotary-encoder-volume-control

    Use rotary encoder with Arduino Micro to increase/decrease a value and show that value on SSD1306 display. Based on https://learn.adafruit.com/pro-trinket-rotary-encoder/example-rotary-encoder-volume-control: rotary-encoder.ino
    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    #define OLED_DC         6
    #define OLED_CS         7
    #define OLED_RESET      8
    #define PIN_ENCODER_A   4 //Micro pin 4 - encoder A
    #define PIN_ENCODER_B   6
    #define PIN_ENCODER_BX  12 //Micro pin 12 - encoder B
    #define ARDUINO_PINx    PIND
    
    Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
    
    static uint8_t enc_prev_pos = 0;
    static uint8_t enc_flags = 0;
    int displayedNumber = 0;
    const int ledPin =  13; 
    
    void setup()
    {
      // set pins as input with internal pull-up resistors enabled
      pinMode(PIN_ENCODER_A, INPUT);
      pinMode(PIN_ENCODER_BX, INPUT);
      digitalWrite(PIN_ENCODER_A, HIGH);
      digitalWrite(PIN_ENCODER_BX, HIGH);
    
      display.begin(SSD1306_SWITCHCAPVCC);
    
      display.display(); // show splashscreen
    
      //delay(2000);
      //display.clearDisplay();
       
      // get an initial reading on the encoder pins
      if (digitalRead(PIN_ENCODER_A) == LOW)
      {
        enc_prev_pos |= (1 << 0);
      }
      if (digitalRead(PIN_ENCODER_BX) == LOW)
      {
        enc_prev_pos |= (1 << 1);
      }
    }
     
    void loop()
    {
      int8_t enc_action = 0; // 1 or -1 if moved, sign is direction
       
      // note: for better performance, the code will now use
      // direct port access techniques
      // http://www.arduino.cc/en/Reference/PortManipulation
      uint8_t enc_cur_pos = 0;
    
      // read in the encoder state first
      if (bit_is_clear(ARDUINO_PINx, PIN_ENCODER_A))
      {
        enc_cur_pos |= (1 << 0);
      }
      if (bit_is_clear(ARDUINO_PINx, PIN_ENCODER_B))
      {
        enc_cur_pos |= (1 << 1);
      }
       
      // if any rotation at all
      if (enc_cur_pos != enc_prev_pos)
      {
        if (enc_prev_pos == 0x00)
        {
          // this is the first edge
          if (enc_cur_pos == 0x01)
          {
            enc_flags |= (1 << 0);
          }
          else if (enc_cur_pos == 0x02)
          {
            enc_flags |= (1 << 1);
          }
        }
       
        if (enc_cur_pos == 0x03)
        {
          // this is when the encoder is in the middle of a "step"
          enc_flags |= (1 << 4);
        }
        else if (enc_cur_pos == 0x00)
        {
          // this is the final edge
          if (enc_prev_pos == 0x02)
          {
            enc_flags |= (1 << 2);
          }
          else if (enc_prev_pos == 0x01)
          {
            enc_flags |= (1 << 3);
          }
       
          // check the first and last edge
          // or maybe one edge is missing, if missing then require the middle state
          // this will reject bounces and false movements
          if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4)))
          {
            enc_action = 1;
          }
          else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4)))
          {
            enc_action = 1;
          }
          else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4)))
          {
            enc_action = -1;
          }
          else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4)))
          {
            enc_action = -1;
          }
         
          enc_flags = 0; // reset for next time
        }
      }
       
      enc_prev_pos = enc_cur_pos;
       
      if (enc_action > 0)
      {
        draw(++displayedNumber);
        digitalWrite(ledPin, HIGH);
      }
      else if (enc_action < 0)
      {
        digitalWrite(ledPin, LOW);
        draw(--displayedNumber);
      }
      else {
        // do nothing
      }
    }
    
    void draw(int number) {
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println(number);
      display.display();
    }
    
    
    

    external by Kent Inverarity  91  0  1  0

    Read incremental rotary encoder (optical) using Arduino Uno

    Read incremental rotary encoder (optical) using Arduino Uno: rotary_encoder.ino
    /* 
    Read optical incremental rotary encoder output.
    
    Serial output gives encoder position (absolute since start of program), and speed in /second separated by a tab.
    
    Seems reasonably repeatable.
    */
    
    // Pin definitions.
    #define enc_a  2
    #define enc_b  3
    #define led 13
    
    volatile int prev = 0;
    volatile int current = 0;
    volatile int enc_pos = 0;
    volatile int enc_pos_prev = 0;
    volatile int enc_pos_change = 0;
    volatile unsigned long micros_current = 0;
    volatile unsigned long micros_prev = 0;
    volatile boolean state_a = 0;
    volatile boolean state_b = 0;
    
    void setup() 
    {
    	pinMode(enc_a, INPUT);
    	pinMode(enc_b, INPUT); 
    
    	state_a = (boolean) digitalRead(enc_a);
    	state_b = (boolean) digitalRead(enc_b);
    
    	attachInterrupt(0, interrupt_enc_a, CHANGE);
    	attachInterrupt(1, interrupt_enc_b, CHANGE); 
      
    	Serial.begin(115200);
    }
    
    
    void loop()
    {  
    	Serial.print(enc_pos);
    	Serial.print("\t");
    
    	// Need to handle overflow in micros_prev (i.e. micros() < micros_prev)
    	micros_current = micros();
    	enc_pos_change = enc_pos - enc_pos_prev;
    	enc_pos_change = abs(enc_pos_change);
    	Serial.print(enc_pos_change / ((micros_current - micros_prev) / 1e6));
    
    	Serial.print("\n");
    	enc_pos_prev = enc_pos;
    	micros_prev = micros_current;
    	delay(100);
    }
    
    void interrupt_enc_a()
    {
    	
    	if (!state_a) {
    		state_b ? enc_pos++: enc_pos--;			
    	}
    	state_a = !state_a;
    }
    
    void interrupt_enc_b()  
    {
    	state_b = !state_b;
    }
    
    
    

    external by Kristian Mide  638  16  3  0

    fastled demoreel100 with rotary encoder

    fastled demoreel100 with rotary encoder: lampe.ino
    #include "FastLED.h"
    
    FASTLED_USING_NAMESPACE
    
    #define DATA_PIN    10
    //#define CLK_PIN   4
    #define LED_TYPE    WS2812B
    #define COLOR_ORDER GRB
    #define NUM_LEDS    6
    CRGB leds[NUM_LEDS];
    
    volatile byte BRIGHTNESS = 0;
    #define FRAMES_PER_SECOND  120
    
    static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
    static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
    static int pinC = 4;
    volatile long pinCignoreCycles = 0;         // the last time the output pin was sampled
    volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
    volatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
    volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
    volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
    volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
    volatile bool encoderMode = true; // 0 brightness // 1 pattern
    // List of patterns to cycle through.  Each is defined as a separate function below.
    typedef void (*SimplePatternList[])();
    SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, white, red,redglitter, green,greenglitter, blue };
    
    uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
    uint8_t gHue = 0; // rotating "base color" used by many of the patterns
    
    
    void setup() {
    	  delay(3000); // 3 second delay for recovery
    
      // tell FastLED about the LED strip configuration
      FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
      //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
    
      // set master brightness control
      FastLED.setBrightness(BRIGHTNESS);
    
      pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
      pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
      attachInterrupt(0,PinA,RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
      attachInterrupt(1,PinB,RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
      pinMode(pinC, INPUT_PULLUP);
      Serial.begin(115200); // start the serial monitor link
    }
    
    void PinA(){
      cli(); //stop interrupts happening before we read pin values
      reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
      if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    	encoderPos ++; //decrement the encoder's position count
    	bFlag = 0; //reset flags for the next turn
    	aFlag = 0; //reset flags for the next turn
      }
      else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
      sei(); //restart interrupts
    }
    
    void PinB(){
      cli(); //stop interrupts happening before we read pin values
      reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
      if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
    	encoderPos --; //increment the encoder's position count
    	bFlag = 0; //reset flags for the next turn
    	aFlag = 0; //reset flags for the next turn
      }
      else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
      sei(); //restart interrupts
    }
    byte b; // used to detect if brighness have overflowed
    void loop(){
    
    	if(oldEncPos != encoderPos) {
    		if (encoderMode) {
    			if (oldEncPos > encoderPos) {
    				b = BRIGHTNESS;
    				BRIGHTNESS -= 15;
    				if(BRIGHTNESS > b) {
    					BRIGHTNESS = 0;
    				}
    			} else {
    				b = BRIGHTNESS;
    				BRIGHTNESS += 15;
    				if(BRIGHTNESS < b) {
    					BRIGHTNESS = 255;
    				}
    			}
    			FastLED.setBrightness(BRIGHTNESS);
    		}
    		if (!encoderMode) {
    			if (oldEncPos > encoderPos) {
    				prevPattern();
    			} else {
    				nextPattern();
    			}
    		}
    
    		Serial.print("C:");
    		Serial.print(BRIGHTNESS);
    		Serial.print(",");
    		Serial.print(gCurrentPatternNumber);
    		Serial.println(".");
    		oldEncPos = encoderPos;
    	}
    
    	if (pinCignoreCycles > 0) {
    		pinCignoreCycles--;
    	}
    
    	if(pinCignoreCycles == 0) {
    		if(digitalRead(pinC) == LOW) {
    			pinCignoreCycles = 25;
    			Serial.println("Btn");
    			encoderMode = !encoderMode;
    
    		}
    	}
    
    	// Call the current pattern function once, updating the 'leds' array
    	gPatterns[gCurrentPatternNumber]();
    
    	// send the 'leds' array out to the actual LED strip
    	FastLED.show();
    	// insert a delay to keep the framerate modest
    	FastLED.delay(1000/FRAMES_PER_SECOND);
    
    	// do some periodic updates
    	EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
    	EVERY_N_SECONDS(30) {
    		if(BRIGHTNESS > 0) {
    			BRIGHTNESS--;
    			Serial.print("A:");
    			Serial.print(BRIGHTNESS);
    			Serial.print(",");
    			Serial.print(gCurrentPatternNumber);
    			Serial.println(".");
    			if (BRIGHTNESS == 0) {
    				encoderMode = true; //fall back to brightness mode
    			}
    			FastLED.setBrightness(BRIGHTNESS);
    		}
    	}
    }
    
    
    #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
    
    void nextPattern()
    {
      // add one to the current pattern number, and wrap around at the end
      gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
    }
    void prevPattern()
    {
    	gCurrentPatternNumber = (gCurrentPatternNumber - 1);
    	if (gCurrentPatternNumber > ARRAY_SIZE(gPatterns)) {
    		gCurrentPatternNumber = ARRAY_SIZE(gPatterns)-1;
    	}
    }
    
    void rainbow()
    {
      // FastLED's built-in rainbow generator
      fill_rainbow( leds, NUM_LEDS, gHue, 7);
    }
    
    void rainbowWithGlitter()
    {
      // built-in FastLED rainbow, plus some random sparkly glitter
      rainbow();
      addGlitter(80);
    }
    
    void addGlitter( fract8 chanceOfGlitter)
    {
      if( random8() < chanceOfGlitter) {
        leds[ random16(NUM_LEDS) ] += CRGB::White;
      }
    }
    
    void confetti()
    {
      // random colored speckles that blink in and fade smoothly
      fadeToBlackBy( leds, NUM_LEDS, 10);
      int pos = random16(NUM_LEDS);
      leds[pos] += CHSV( gHue + random8(64), 200, 255);
    }
    
    void sinelon()
    {
      // a colored dot sweeping back and forth, with fading trails
      fadeToBlackBy( leds, NUM_LEDS, 20);
      int pos = beatsin16(13,0,NUM_LEDS);
      leds[pos] += CHSV( gHue, 255, 192);
    }
    
    void bpm()
    {
      // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
      uint8_t BeatsPerMinute = 62;
      CRGBPalette16 palette = PartyColors_p;
      uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
      for( int i = 0; i < NUM_LEDS; i++) { //9948
        leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
      }
    }
    
    void juggle() {
      // eight colored dots, weaving in and out of sync with each other
      fadeToBlackBy( leds, NUM_LEDS, 20);
      byte dothue = 0;
      for( int i = 0; i < 8; i++) {
        leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
        dothue += 32;
      }
    }
    void white() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0xFFFFFF;
    	}
    }
    void red() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0x00FF00;
    	}
    }
    void redglitter() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0x00FF00;
    	}
    	addGlitter(80);
    }
    void green() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0xFF0000;
    	}
    }
    void greenglitter() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0xFF0000;
    		addGlitter(80);
    	}
    }
    void blue() {
    	for(int i=0; i < NUM_LEDS; i++) {
    		leds[i] = 0x0000FF;
    	}
    }
    
    

    external by newdigate  424  18  3  0

    Arduino - Rotary encoder using Neopixel ring indicator

    Arduino - Rotary encoder using Neopixel ring indicator: rotary_encoder_and_neopixel_ring.ino
    #include <Adafruit_NeoPixel.h>
    
     /* Read Quadrature Encoder
      * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
      *
      * Sketch by max wolf / www.meso.net
      * v. 0.1 - very basic functions - mw 20061220
      *
      */  
    
    #define PIN            9
    #define NUMPIXELS      16  
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
    
    
     int val; 
     int encoder0PinA = 2;
     int encoder0PinB = 3;
     int encoder0Pos = 0;
     int encoder0PinALast = LOW;
     int n = LOW;
    
     void setup() { 
       pinMode (encoder0PinA,INPUT);
       pinMode (encoder0PinB,INPUT);
       pinMode (5, OUTPUT);
       pinMode (6, OUTPUT);
       digitalWrite (5, HIGH);
       digitalWrite (6, LOW );
       Serial.begin (9600);   
       pixels.begin(); // This initializes the NeoPixel library.
     } 
    
     void loop() { 
       n = digitalRead(encoder0PinA);
       if ((encoder0PinALast == LOW) && (n == HIGH)) {
         if (digitalRead(encoder0PinB) == LOW) {
           encoder0Pos--;
         } else {
           encoder0Pos++;
         }
         Serial.print (encoder0Pos);
         Serial.print ("\n");
    
         for (byte i=0; i<16; i++) {
            if (encoder0Pos == 0) {
              pixels.setPixelColor(i, pixels.Color(0, 0, 0));
            } else if (encoder0Pos > 0) {
              uint32_t pixelColor = (encoder0Pos > i)? Wheel((15-i)*16) : 0;
              pixels.setPixelColor(i,pixelColor);
            } else {
               uint32_t pixelColor = (encoder0Pos < -i)? Wheel((i+1)*16) : 0;
               pixels.setPixelColor(15-i, pixelColor);
            }
            
            
           
         }
         pixels.show();
       } 
       encoder0PinALast = n;
     } 
    
     // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    uint32_t Wheel(byte WheelPos) {
      WheelPos = 255 - WheelPos;
      if(WheelPos < 85) {
        return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
      }
      if(WheelPos < 170) {
        WheelPos -= 85;
        return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
      }
      WheelPos -= 170;
      return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
    
    

    external by io2work  11  0  1  0

    Code for a Tessel automated rotary welder

    Code for a Tessel automated rotary welder: tessel-welder.js
    var tessel = require('tessel');
    var led = require('tessel-led');
    var _ = require('underscore');
    
    // Setup the Relay module on Port A
    var relaylib = require('relay-mono');
    var relay = relaylib.use(tessel.port['A']);
    
    // Setup all switches & sensors to the GPIO
    var gpio = tessel.port['GPIO'];
    var swTurnTable = gpio.pin['G1'];
    var btnWeld = gpio.pin['G2'];
    var btnHome = gpio.pin['G3'];
    var btnJog = gpio.pin['G6'];
    
    // Add/Set 'Active' state for each GPIO object
    swTurnTable.pressed = false;
    btnWeld.pressed = false;
    btnHome.pressed = false;
    btnJog.pressed = false;
    
    // Set pulldown switches/sensors (Tessel 'pull' functionality wasn't working when I did this project so I hardwired some physical pulldown resistors inline with my wiring)
    //swTurnTable.pull('pulldown');
    //btnWeld.pull('pulldown');
    //btnHome.pull('pulldown');
    //btnJog.pull('pulldown');
    
    // Set all switches & sensors to input
    swTurnTable.input();
    btnWeld.input();
    btnHome.input();
    btnJog.input();
    
    // underscore debounce function time
    var timeDebounce = 100;
    
    // Wait for the relay module to connect
    relay.on('ready', function() {
    
        console.log('Ready to weld...');
    
        // Check for btnWeld... then start welding
        btnWeld.on('rise', _.debounce(function(time, type) {
            if ( btnWeld.read() ) {
                console.log('btnWeld was pressed!', type, time);
                btnWeld.pressed = true;
                weld();
            }
        }, debounceTime));
    
        // Check for btnHome... then home the turn table w/o welding
        btnHome.on('rise', _.debounce(function(time, type) {
            if ( btnHome.read() ) {
                console.log('btnHome was pressed!', type, time);
                btnHome.pressed = true;
                weld();
            }
        }, timeDebounce));
    
        // Check for btnJog... then jog the turn table w/o welding
        btnJog.on('change', _.debounce(function(time, type) {
            if ( btnJog.read() ) {
                console.log('btnJog was pressed!', type, time);
                btnJog.pressed = true;
                jog();
            }
            if ( !btnJog.read() && btnJog.pressed ) {
                console.log('btnJog was released!', type, time);
                btnJog.pressed = false;
                jog();
            }
        }, timeDebounce));
    
    });
    
    // When a relay 'latch' state is changed, it emits the 'latch' event
    relay.on('latch', function(channel, value) {
        if ( channel == 1 ) {
            console.log('latch on turn table relay (channel ' + channel + ') switched to', value);
        }
        if ( channel == 2 ) {
            console.log('latch on welder relay (channel ' + channel + ') switched to', value);
        }
    });
    
    
    // Function to weld or home the turn table
    function weld() {
    
        swTurnTable.on('rise', _.debounce(function(time, type) {
    
            if ( swTurnTable.read() && !swTurnTable.pressed ) {
    
                swTurnTable.pressed = true;
    
                console.log('on ' + type + ': ' + swTurnTable.read());
    
                swTurnTable.once('low', _.debounce(function(time, type) {
    
                    led.green.hide();
                    led.blue.hide();
    
                    console.log('once ' + type + ': ' + swTurnTable.read());
    
                    if ( btnWeld.pressed || btnHome.pressed ) {
                        relay.turnOff(1, function(err) {
                            if (err) console.log('Err turning off turn table relay 1', err);
                            btnHome.pressed = false;
                        });
                    }
                    if ( btnWeld.pressed ) {
                        relay.turnOff(2, function(err) {
                            if (err) console.log('Err turning off welder relay 2', err);
                            btnWeld.pressed = false;
                        });
                    }
    
                    swTurnTable.removeAllListeners();
                    swTurnTable.pressed = false;
    
                }, timeDebounce));
    
            }
    
        }, timeDebounce));
    
        if ( btnWeld.pressed || btnHome.pressed ) {
            relay.turnOn(1, function(err) {
                if ( err ) {
                    console.log('Err turning on turn table relay 1', err);
                }
                else {
                    if ( btnWeld.pressed ) {
                        led.green.show();
                    }
                    if ( btnHome.pressed ) {
                        led.blue.show();
                    }
                }
            });
        }
    
        if ( btnWeld.pressed ) {
            relay.turnOn(2, function(err) {
                if ( err ) {
                    console.log('Err turning on welder relay 2', err);
                }
            });
        }
    
    }
    
    
    // Function to jog the weld turn table while btnJog is pressed
    function jog() {
        if ( btnJog.pressed ) {
            relay.turnOn(1, function(err) {
                if (err) console.log("Err turning on relay 1", err);
                led.blue.show();
            });
        }
        else {
            relay.turnOff(1, function(err) {
                if (err) console.log("Err turning off relay 1", err);
                led.blue.hide();
            });
        }
    }
    
    

    external by EarToEarOak  959  0  3  0

    Control the frequency in SDR# with a rotary encoder. From the tutorial http://eartoearoak.com/tutorials-and-examples/sdrsharp-physical-controls

    Control the frequency in SDR# with a rotary encoder. From the tutorial http://eartoearoak.com/tutorials-and-examples/sdrsharp-physical-controls: SDRSharp Frequency Control.ino
    /*
      Basic example demonstrating the how to control SDR# frequency
      with SDRSharp Net Remote, an Arduino and rotary encoder.
      
      Copyright 2015 Al Brown
     
      Requires:
          http://eartoearoak.com/software/sdrsharp-net-remote
          http://www.pjrc.com/teensy/td_libs_Encoder.html
     
      Connections:
          Encoder    Arduino
          A          D3
          B          D2
          C          GND
     
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation, or (at your option)
      any later version.
    
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
    
      You should have received a copy of the GNU General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include <Encoder.h>
    
    // Initialise the encoder on digital pins 2 & 3
    Encoder encoder(2, 3);
    long oldPos  = -999;
    
    // Initial frequency
    long frequency = 100000000;
    
    
    void setup() {
      Serial.begin(115200);
    }
    
    void loop() {
      // Get the encoder position
      long newPos = encoder.read();
      if (newPos != oldPos) {
        oldPos = newPos;
    	
        // Send the command to change the frequency via the serial port
        Serial.print("{\"Command\": \"Set\", \"Method\": \"Frequency\", \"Value\": ");
        Serial.print(frequency + (newPos * 1000));
        Serial.println("}");
      }
    }
    
    

    external by Maxim Kachurovskiy  420  3  3  0

    Pi4j rotary encoder reading

    Pi4j rotary encoder reading: PI4JRotaryEncoderReading.java
    // Pin pinA - CLK pin,
    // Pin pinB - DT pin
    // rotate(int i) - callback receiving -1 or 1
    
    inputA = gpio.provisionDigitalInputPin(pinA, "PinA", PinPullResistance.PULL_UP);
    inputB = gpio.provisionDigitalInputPin(pinB, "PinB", PinPullResistance.PULL_UP);
    inputA.addListener(new GpioPinListenerDigital() {
      int lastA;
    
      @Override
      public synchronized void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent arg0) {
        int a = inputA.getState().getValue();
        int b = inputB.getState().getValue();
        if (lastA != a) {
          rotate(b == a ? -1 : 1);
          lastA = a;	
        }
      }
    });
    
    

    external by bembu  287  3  3  0

    A simple intervalometer for Arduino. Requires a rotary encoder, a SSD1306 OLED display and a bunch of analog electronics. With display idle sleep.

    A simple intervalometer for Arduino. Requires a rotary encoder, a SSD1306 OLED display and a bunch of analog electronics. With display idle sleep.: intervalometer.cpp
    #include <Arduino.h>
    
    #include <SPI.h>  // problems with PlatformIO
    #include <U8g2lib.h>
    #include <Wire.h>
    
    #include <ClickEncoder.h>
    #include <TimerOne.h>
    
    #include <TaskScheduler.h>
    
    #define SW1 4               // Rotary switch
    #define CAMERA_FOCUS   14   // -> optoisolator circuit
    #define CAMERA_SHUTTER 13   // -> optoisolator circuit
    
    #define DISPLAY_AUTOSLEEP_MS 15000  // sleep display on idle (after ms)
    #define DISPLAY_BLIT_FREQ 100       // redraw display every N ms
    
    // Forward declarations
    void takePhoto();
    void blitDisplay();
    void tick();
    void blitActive();
    void displaySleep();
    void displayWake();
    
    // logic variables
    int timelapseInterval = 0;
    bool timelapseRunning = false;
    bool focus = false;
    int shootCount = 0;
    bool blit = true;
    uint8_t activityToggle = 0;
    bool isSleeping = false;
    
    // Library initializations
    ClickEncoder *encoder;
    U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(SCL, SDA, U8X8_PIN_NONE);
    
    Task takePhotoTask(0, TASK_FOREVER, &takePhoto);
    Task blitDisplayTask(DISPLAY_BLIT_FREQ, TASK_FOREVER, &blitDisplay);
    Task blitActiveTask(250, TASK_FOREVER, &blitActive);
    Task sleepTimerTask(DISPLAY_AUTOSLEEP_MS, TASK_ONCE, &displaySleep);
    
    Scheduler scheduler;
    
    void timerIsr() {
      encoder->service();
    }
    
    void setup(void) {
      pinMode(SW1, INPUT_PULLUP);
      pinMode(CAMERA_FOCUS, OUTPUT);
      pinMode(CAMERA_SHUTTER, OUTPUT);
    
      // Encoder in pins 2, 3 (hw int). Switch in 4.
      encoder = new ClickEncoder(3, 2, SW1, 4);
    
      // Begin SSD1306 128x64 OLED in fast mode
      u8x8.begin();
      u8x8.setFont(u8x8_font_pxplusibmcgathin_r);
      u8x8.setContrast(0);
    
      // Timer1 is needed for encoder interrupts
      Timer1.initialize(1000);
      Timer1.attachInterrupt(timerIsr);
    
      // Initialize the scheduler.
      // takePhotoTask is enabled / disabled by pressing the button (in tick())
      // blitDisplayTask is ran every 100ms if variable blit = true
      scheduler.init();
      scheduler.addTask(takePhotoTask);
      scheduler.addTask(blitDisplayTask);
      scheduler.addTask(blitActiveTask);
      scheduler.addTask(sleepTimerTask);
    
      blitDisplayTask.enable();
      blitActiveTask.enable();
      sleepTimerTask.enableDelayed(); //
    }
    
    void loop(void) {
      tick();               // tick inputs
      scheduler.execute();  // tick scheduler
    }
    
    void takePhoto() {
      /* Takes a single photo */
      if (focus) {
        digitalWrite(CAMERA_FOCUS, HIGH);
        delay(10);
        digitalWrite(CAMERA_FOCUS, LOW);
      }
      digitalWrite(CAMERA_SHUTTER, HIGH);
      delay(10);
      digitalWrite(CAMERA_SHUTTER, LOW);
      shootCount++;
      blit = true;
    }
    
    void blitActive() {
      if (timelapseRunning) {
        switch(activityToggle) {
          case 0:
            u8x8.drawString(15, 7, "/");
            break;
          case 1:
            u8x8.drawString(15, 7, "|");
            break;
          case 2:
            u8x8.drawString(15, 7, "\\");
            break;
          case 3:
            u8x8.drawString(15, 7, "-");
            break;
        }
        activityToggle++;
        if (activityToggle > 3) activityToggle = 0;
      }
    }
    
    void blitDisplay() {
      /* This function is called once every 100 ms by blitDisplayTask */
      /* OLED: 16 cols, 8 rows*/
      if (blit) {   // draw only if necessary
        // interval
        char buf[10];
        sprintf(buf, "%02d:%02d", timelapseInterval/60 ,timelapseInterval%60);
        u8x8.drawString(5, 3, buf);
    
        //photos taken
        sprintf(buf, "#%03d", shootCount);
        u8x8.drawString(0, 7, buf);
    
        //ON / OFF ?
        u8x8.drawString(13, 7, timelapseRunning ? "ON " : "OFF");
      }
      blit = false;
    }
    
    void tick(void) {
      // Check encoder's button
      if ((encoder->getButton() == ClickEncoder::Clicked)) {
        if (!isSleeping) {
          timelapseRunning = !timelapseRunning;
          if (timelapseRunning) {
            takePhotoTask.setInterval(timelapseInterval * 1000);
            takePhotoTask.enable();
          }
          else {
            takePhotoTask.disable();
            shootCount = 0;
          }
          blit = true;
          sleepTimerTask.restartDelayed();
        }
        else {
          displayWake();
        }
      }
    
      // Check rotary encoder's delta -> update interval in seconds
      int8_t encoder_value = encoder->getValue();
      if (encoder_value != 0) {
        if (!isSleeping) {
          if (!timelapseRunning) {
            timelapseInterval += encoder_value;
            if (timelapseInterval < 0)
              timelapseInterval = 0;
          }
          sleepTimerTask.restartDelayed();
          blit = true;
        }
        else {
          displayWake();
        }
      }
    
    }
    
    void displaySleep() {
      u8x8.setPowerSave(true);
      isSleeping = true;
    }
    
    void displayWake() {
      u8x8.setPowerSave(false);
      isSleeping = false;
      sleepTimerTask.restartDelayed();
    }
    
    
    

    external by Heracles Papatheodorou  492  0  3  0

    Reading one Rotary Encoder from a Raspberry Pi with Processing 3

    Reading one Rotary Encoder from a Raspberry Pi with Processing 3: rotary_encoder.pde
    /*
    Reading one Rotary Encoder from a Raspberry Pi
    
    Translated from C to Processing by Heracles Papatheodorou
    via http://theatticlight.net/posts/Reading-a-Rotary-Encoder-from-a-Raspberry-Pi/
    
    
    		GND 	MIDDLE encoder leg
    GPIO22	GPIO23	LEFT and RIGHT legs
    3.3V			LEFT and RIGHT, splits to two 10k resistors for pull-up
    
    Processing doesn't support pull-ups, hardware pull-up required:
    	https://learn.adafruit.com/processing-on-the-raspberry-pi-and-pitft/hardware-io
    	https://learn.sparkfun.com/tutorials/pull-up-resistors/what-is-a-pull-up-resistor
    
    Processing reference:
    	https://github.com/processing/processing/wiki/Raspberry-Pi
    	https://processing.org/reference/libraries/io/index.html
    
    Reading rotary encoders on the RaspPi:
    	http://theatticlight.net/posts/Reading-a-Rotary-Encoder-from-a-Raspberry-Pi/
    	https://projects.drogon.net/raspberry-pi/wiringpi/functions/
    */
    
    import processing.io.*; // import the hardware IO library
    
    int pin_a = 22;
    int pin_b = 23;
    long value = 0;
    int lastEncoded = 0;
    
    void setup() {
    	noCursor();
    
    	GPIO.pinMode(pin_a, GPIO.INPUT);
    	GPIO.pinMode(pin_b, GPIO.INPUT);
    
    	//pullUpDnControl(pin_a, PUD_UP); //Processing doesn't support pull-ups so far
    	//pullUpDnControl(pin_b, PUD_UP);
    
    	GPIO.attachInterrupt(pin_a, this, "updateEncoder", GPIO.CHANGE);
    	GPIO.attachInterrupt(pin_b, this, "updateEncoder", GPIO.CHANGE);
    }
    
    void draw() {
    	
    }
    
    void updateEncoder(int pin) {
    	int MSB = GPIO.digitalRead(pin_a);
    	int LSB = GPIO.digitalRead(pin_b);
    
    	int encoded = (MSB << 1) | LSB;
    	int sum = (lastEncoded << 2) | encoded;
    
    	if (sum == unbinary("1101") || sum == unbinary("0100") || sum == unbinary("0010") || sum == unbinary("1011")) {
    		value++;
    	}
    	if (sum == unbinary("1110") || sum == unbinary("0111") || sum == unbinary("0001") || sum == unbinary("1000")) { 
    		value--;
    	}
    
    	lastEncoded = encoded;
    
    	println(value); //DEBUG
    }
    
    
    • Public Snippets
    • Channels Snippets