I have an Arduino Mega 2560, an Omron Optical encoder with an Index (360 steps), a 60 led NeoPixel ring (no Clk wire) and another Arduino Uno. Here is my question, I have some code written that works with the Arduino Mega and optical encoder outputting decently to the serial monitor for diagnostic purposes. When I add the additional code to run the Neopixel ring I get a terrible response on the ring. I have tried the NeoPixel and FastLED libraries with the same terrible success. It even states in their documentation that they don't work well with interrupts. I started thinking about sending the 3 digit output to a Direct Pin output from the Mega to be read by another Mega/Uno to run the Neopixel Ring and a 4x20 LCD screen. Does anyone else have any ideas on this. Below is my code for the Mega and the Encoder.

    // Wiring connections for my encoder:
    // Brown : VCC = 5V
    // Blue + Shield : 0V = GND
    // Black : ENCODER0PINA, Pin 18
    // White : ENCODER0PINB, Pin 17
    // Orange : ENCODER0PINI, Pin 19

    #define ENCODER0PINA         18      // this pin needs to support interrupts
    #define ENCODER0PINB         17      // no interrupt required
    #define ENCODER0PINI         19      // this pin needs to support interrupts

    // variables modified by interrupt handler must be declared as volatile
    volatile long encoder0Position = 0;
    volatile long interruptsReceived = 0;
    volatile byte INTFLAG1 = 0;

    // track last position so we know whether it's worth printing new output
    long previousPosition = 0;

    void setup()
      // inputs
      pinMode(ENCODER0PINA, INPUT);
      digitalWrite(ENCODER0PINA, HIGH);  // turn on pullup resistor
      pinMode(ENCODER0PINB, INPUT);
      digitalWrite(ENCODER0PINB, HIGH);  // turn on pullup resistor
      pinMode(ENCODER0PINI, INPUT);
      digitalWrite(ENCODER0PINI, HIGH);  // turn on pullup resistor

      // interrupts
      attachInterrupt(5, onInterrupt, RISING);  // encoder track A on interrupt 3 - pin 18
      attachInterrupt(4, onReset, RISING);  // encoder Index track on interrupt 4 - pin 19

      // enable diagnostic output
      Serial.begin (115200);

    void loop()
      // only display position info if has changed
      if (encoder0Position != previousPosition )
        Serial.println(encoder0Position, DEC);

        previousPosition = encoder0Position;

// interrupt function needs to do as little as possible

void onInterrupt()
  // read both directional inputs
  int a = digitalRead(ENCODER0PINA);
  int b = digitalRead(ENCODER0PINB);

  if (a == b)
    // b is leading a (counter-clockwise)
    if (encoder0Position < 0)
      encoder0Position = ((encoder0Position + 360) % 360);
    // a is leading b (clockwise)
    if (encoder0Position >= 360)
      encoder0Position = ((encoder0Position - 360) % 360);

void onReset()
  // read Index input
  int i = digitalRead(ENCODER0PINI);
  if (i == 1)
  encoder0Position = INTFLAG1;
  • i would use the ESP32, which can drive the WS2812b in hardware using the IR remote control functionality, and had a whole 2nd core if that's somehow not good enough. Also, try to avoid analogRead() in the ISR, that takes quite some time, and with 360 clicks, you're going to be quite busy with any kind of rapid twisting.
    – dandavis
    Jan 8 '19 at 21:59
  • Will the ESP32 be good for taking the 3 digit integer reading from the encoder to other devices as well? My complete goal would be to use the ESP32 for the 60 NeoPixel Ring, monitoring signal strength (0 to 5 V, pin input) and output some results to a 4x20 LCD screen. Lastly rectifying the 3 digit reading from the encoder with the ultimate compass from AdaFruit.?
    – Bkukuk62
    Jan 8 '19 at 22:23
  • yes, it would be great for that, being hundreds of times faster and dozens of times more memory, with many hardware-accelerated interfaces to reduce core resource usage. might also grab a few level-shifters; sometimes the ESP32 doesn't like 5v devices, though many, such as neopixels, work fine as-is...
    – dandavis
    Jan 9 '19 at 3:29

This site is temporarily in read only mode and not accepting new answers.

Browse other questions tagged .