Encoder sends data when cable is touched

Hi.
Pretty new to electronics

Im trying to make an 20 pulse encoder work

It does but sometimes sends a string of repeated numbers, and if i touch the CLK cable it sends infinite numbers. It doesnt happend with the DT cable

Any idea? Resistor?

Yes you need either pull up resistors or pull down ones depending how you have wired it up to your Arduino.

You have what is known as a floating input, that is one connected to nothing. An input pin has to be wired to a path that leads to the supply voltage of the processor or to ground.

Thnak you

Pull up, doesnt seems to solve it.

Question

5v and ground on Arduino One are only connected to the encoder 5v and ground.

Any of the data pins of the encoder (SW, DT, CLK) has to go to ground or 5v ?

Pull up, doesnt seems to solve it.

Well it should so could you post the schematic of what you are trying to make along with a clear photograph of your wiring.

Here is the code and a pic of connections
I tried with a different encoder with same results

I tried 3.5 volts

Thnaks.

int A = 2;      
int B = 4;       
int C = 3;
int ANTERIOR = 0;    

volatile int POSICION = 0; 
       
void setup() {
  pinMode(A, INPUT_PULLUP);    
  pinMode(B, INPUT_PULLUP);   
  pinMode(C, INPUT_PULLUP);
  
  Serial.begin(9600);  

  attachInterrupt(digitalPinToInterrupt(A), encoder, LOW);
              
}


void loop() {
  if (POSICION != ANTERIOR) { 
    Serial.println(POSICION);
    ANTERIOR = POSICION ; 
  }

 if (digitalRead(C) == LOW) {
 Serial.println  ("bang");
 delay (300);
 
 }
}


void encoder()  {
  static unsigned long ultimaInterrupcion = 0;  
           
  unsigned long tiempoInterrupcion = millis();  

  if (tiempoInterrupcion - ultimaInterrupcion > 3) {  
             
    if (digitalRead(B) == HIGH)     
    {
      POSICION-- ;       
    }
    else {         
      POSICION++ ;       
    }

  
    ultimaInterrupcion = tiempoInterrupcion;  
 
  
  
  
  
  
  }          
}

if i touch the CLK cable it sends infinite numbers

It happens because you set:-

attachInterrupt(digitalPinToInterrupt(A), encoder, LOW);

where did you get that code? The interrupts should be edge triggered not level triggered.

There also doesn't seem to have any debounce code.

Read this:-

I found this code that eliminates interference

#define CLK_PIN  2
#define DATA_PIN 7


////////////////////////////////////////////////////
void setup() {
   pinMode(CLK_PIN,INPUT);
   pinMode(DATA_PIN,INPUT);


   Serial.begin(9600);
 
}

////////////////////////////////////////////////////
void loop() {


static uint16_t state=0,counter=0;

    

    state=(state<<1) | digitalRead(CLK_PIN) | 0xe000;

    if (state==0xf000){
       state=0x0000;
       if(digitalRead(DATA_PIN))
         counter++;
       else
         counter--;
       Serial.println(counter);
    }





}

But if a add to Void loop the switch part.

if (!digitalRead(PinSWITCH_PIN)) {      
             
   Serial.println (1000);
 
 delay(200);

 
 }

It sends the string of data (of the switch button only) when i touch it, or the encoder board, or cable.

Data from CLK and DT works just fine.

Strange. With other sketches I got that behavior from CLK and DT. So the problem seems to be in the code, not the wiring.

Is there anything on the rotary part I can try on the switch

If i do this

#define CLK_PIN  2
#define DATA_PIN 7
#define PinSW_PIN 4

////////////////////////////////////////////////////
void setup() {
   pinMode(CLK_PIN,INPUT);
   pinMode(DATA_PIN,INPUT);
   pinMode(PinSW_PIN,INPUT_PULLUP);

   Serial.begin(9600);
 
}

////////////////////////////////////////////////////
void loop() {


static uint16_t state=0,counter=0;
static uint16_t SWITCH=digitalRead(PinSW_PIN);

 
if (!digitalRead(PinSW_PIN))   
             
   Serial.println (1000);
 
 delay(200);



   

    state=(state<<1) | digitalRead(CLK_PIN) | 0xe000;

    if (state==0xf000){
       state=0x0000;
       if(digitalRead(DATA_PIN))
         counter++;
       else
         counter--;
       Serial.println(counter);
    }





}

then the Button has no interference. Good. But now the rotary does nothing.

Please help.

That board you have is called a KY - 040 board. It is a rotary encoder and a push switch. If you flip it over you should see three surface mount resistors R1, R2 and R3. These are built in pull up resistors, so it should not matter if you set those pins to INPUT or INPUT_PULLUP the results should be the same.

If they are not the same then there is something wrong, probably with the continuity of the wiring.

However, the new code you found might be looking at these signals the wrong way up and not considering the three pullups on the board. Little snippets of code are only useful in the context of having the full code, so please post ALL your code.

While the photograph was useful it did not show clearly where the wires went on the top right, it was all tangled up and covered by a very large reflection.

In your code use the variable names clk, dt and sw these are meaningful names. You can do without meaningful names but why make things more complex than they need to be.

The code you are using should involve interrupts from both the clk and the dt signals on both edges, so that means these should be wired to pins 2 & 3, it doesn't matter which.

Thank you for your time. I appreciate the effort to guide someone who knows close to nothing.

Im a musician and im trying to build a controller, thats why i dont make a clean ground up learning curve, this probably will be my only arduino proyect.

Quick question before i try something else.

You mentioned the wiring. I have a male-male wire from the borad to a female-female wire that connects to the encoder.

That could be it? Should i try soldering the male end directly to the encoder?

That could be it?

It could, a bit unlikely though. But rather than solder everything up I would try and test the continuity or the voltage with a DVM. If you have not got one you can get them at thrift stores for less than $10, and it is well worth having.

Im a musician and im trying to build a controller,

Interesting, I am not a musician but love to play about with sounds. I am about to embark on a MIDI controller project but for the Raspberry Pi.

I have an audio book out http://www.apress.com/9781484217207 but that does not include a MIDI controller using rotary encoders.

How many rotary encoders do you plan to use? My initial design will use two, after all you only have two hands. Using a lot of rotary encoders is difficult due to lack of interrupt enable pins but it can be done.

By good luck I have exactly that sort or encoder board, so give it a few days and I might be able to arrange to sort out some Arduino code for this.

¨ I am not a musician but love to play about with sounds.¨

Well, where do you draw the line? We may be closer than we think. I just may use the word musician in a more generous way.

Im trying to do something like this. Pretty sure its not going to look like that beauty thou.

I´ll do it with Adafruit Neotrellis.

Its a permanent connection. I was thinking of soldering anyway. See any drawback?

I will use 2 encoders

Soldered it.

No luck

Hi,
I have just ran your code posted in post #5.
First the KY-040 encoder is very very very prone to contact bounce(cheap).
I have one here and it is just about uncontrollable.

Solution to try;

  • Change Serial.begin(9600) to Serial.begin(115200), and change the IDE monitor speed.
  • ADD a 0.1uF capacitor between CLK and GND.
  • ADD a 0.1uF capacitor between DT and GND.

The caps will minimise the bounce, the higher monitor baud just makes it display better.
I always run at 115200. If you had a 286PC then 9600, but not these days.

Here is your code;

int A = 2;
int B = 4;
int C = 3;
int ANTERIOR = 0;
volatile int POSICION = 0;

void setup()
{
  pinMode(A, INPUT_PULLUP);
  pinMode(B, INPUT_PULLUP);
  pinMode(C, INPUT_PULLUP);

  Serial.begin(115200);
  Serial.println("===ENCODER CODE===");
  attachInterrupt(digitalPinToInterrupt(A), encoder, LOW);

}

void loop()
{
  if (POSICION != ANTERIOR)
  {
    Serial.println(POSICION);
    ANTERIOR = POSICION ;
  }
  if (digitalRead(C) == LOW)
  {
    Serial.println  ("bang");
    delay (300);
  }
}

void encoder()
{
  static unsigned long ultimaInterrupcion = 0;
  unsigned long tiempoInterrupcion = millis();
  if (tiempoInterrupcion - ultimaInterrupcion > 3)
  {
    if (digitalRead(B) == HIGH)
    {
      POSICION-- ;
    }
    else
    {
      POSICION++ ;
    }
    ultimaInterrupcion = tiempoInterrupcion;
  }
}

Tom... :slight_smile:

I tested this code with the KY-040 boardand it works. Wire CLK to pin 2 DT to pin 3. It does not handle the switch, simply connect this to any pin and do a digital read what you want to see it.

/* 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(2, 3);
//   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);
  }
}

You can download the Encoder library from the menu Sketch → Include Library → Manage Libraries