Go Down

Topic: Rotary encoder output to lcd 1602a (Read 15691 times) previous topic - next topic

williamjcoates

Hi MarkT,
Thanks For pointing that out. Do you have a link to some sample code that I could work with. Being very new to arduino I am not sure what would be better code. For now I just want to have the encoder output from 0 - 100 for one rotation to the serial monitor. But because the encoder is 1024 P/R there is no way to code the output to read 0-100? If not that would it be possible to measure in degrees of rotation?
Bill

MarkT

[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

Wawa

Not too much experience with encoders, but isn't OP's one outputting 3-bit Grey code.

I think 360 steps from a 1024 encoder would be as impossible as 100 steps.
Leo..

williamjcoates

Thanks MarkT,
I will have a look. I have been reading threads and going back over some as the coding becomes clearer. I did do this
Code: [Select]
void loop() {
  // Send the value of counter
   Serial.println (counter / 20.24);
   
}

And it goes up to 100.00 on a CW rotation but when i go CCW it starts at 3230.00. weird. The thing to remember is that I am using the rotary encoder as a means to measure the distance between two points on the dial. I then would take this value and put it on a graph. I am starting to get somewhere with this.
Bill

TomGeorge

Hi
Do you have to have exactly 100 steps per turn, do you have the encoder knob marked off in 1/100 divisions.

If not.
In other words a blank knob, you can have 1024/100= 10.24pulses per 1/100 of turn.
Who's to know that its not exact.
I gather you have the position readout on the display.

If you turn the knob 1 turn, how are you to know that its only 99 steps, a little turn more and it 100. the knob position has nothing to be referenced against. You only want the numbers to be displayed.
That is if you do not mark/calibrate the knob.

Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

williamjcoates

Hi,
Thats right. It would be nice if the numbers on the display matched the numbers on the actual dial that I would be measuring the movement on  but not critical. I think with more research I could get it worked out though. Its about taking the output of the encoder and filtering it into what I want in the display...I think anyway. Still very new to this stuff. Now i just started working on my lcd 1602 by soldering the pin header strip onto it. Going to try the hello world example. I would then like to output the encoder information to the lcd screen. Not sure on how to do this and if anyone can steer me in the right direction i would sure appreciate it.
Bill

Wawa

I think the first step is to make the encoder work.
1024 clicks per turn clockwise and 1024 clicks per turn anti-clockwise.
If that works reliably, then think of scaling it down to 100 click per turn.
Leo..

williamjcoates

Hi Leo,
I did this
Code: [Select]
// Send the value of counter
  Serial.println (counter / 20.24);
It Gives me 100 on a full rotation CW and goes back down to 0 when I go CCW. If I start CCW however I get 6238.00 as the starting number and counts down from there. I'll figure it out sooner or later. Up until this point I have been using the serial monitor to view the output of the encoder. I now have a DF ROBOT LCD Keypad Shield Which I now have mounted on a arduino UNO board. I have done some tutorials with this setup and the lcd sheid works fine. Just had to change
Code: [Select]
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); to
Code: [Select]
LiquidCrystal lcd(8, 9, 5, 4, 6, 7);

I would now like to read the output of the rotary encoder on my lcd shield. Could someone show me how to go about this? Here is the sketch I am using now
Code: [Select]
/* Rotary encoder with attachInterrupt
Counts pulses from an incremental encoder and put the result in variable counter.
Taking also into account the direction and counts down when the rotor rotates in
the other direction.
This code is used attachInterrupt 0 and 1 which are pins 2 and 3 moust Arduino.
For more information about attachInterrupt see:
http://arduino.cc/en/Reference/AttachInterrupt
 
created 2014
by Ben-Tommy Eriksen
https://github.com/BenTommyE/BenRotaryEncoder
 
*/

// Encoder connect to digitalpin 2 and 3 on the Arduino.

volatile unsigned int counter = 0;  //This variable will increase or decrease depending on the rotation of encoder

void setup() {
  Serial.begin (9600);
  //Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(0, ai0, RISING);
 
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(1, ai1, RISING);
}

void loop() {
  // Send the value of counter
  Serial.println (counter / 20.24);
 
}

void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(3)==LOW) {
    counter++;
  }else{
    counter--;
  }
}

void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(2)==LOW) {
    counter--;
  }else{
    counter++;
  }
}

Wawa

Not a coder, so I might give you the wrong info.
What is the datatype of "counter".
Did you try "unsigned". e.g.  unsigned int counter = 0;

Printing to LCD is almost the same as printing to serial monitor.
Serial.println (counter / 20.24); becomes lcd.print (counter / 20.24);
https://www.arduino.cc/en/Reference/LiquidCrystal
Leo..


cattledog

#24
Aug 20, 2015, 04:20 am Last Edit: Aug 20, 2015, 04:47 am by cattledog
Quote
I think the first step is to make the encoder work.
I agree with Wawa. You are clearly not reading the encoder properly. Based on the specific encoder reading  algorithm you should get 1024, 2048, or 4096 counts per revolution of an encoder with 1024 pulses per revolution. You can read 1,2, or 4 of the quadrature steps.

The code you are using reads two of the four and should produce 2048 counts per revolution. This certainly seems like enough resolution for your application, and should reliably indicate direction.

However, the code you are using is peculiar in that it reads rising edges on two interrupts and it is reading the first two pulses of the train of four instead of every other transition. To look at 2048 counts (instead of 4096,using the example #3 suggested by MarkT) a better algorithm is to trigger on one channel of the encoder CHANGE, and read the value of both channels in the ISR with digital read or faster alternatives. If both channels are high or low, it is going in one direction, if they are opposite, its going in the other.

It is basically the approach of the second example in the Arduino Playground Encoder tutorial, but be aware that the example in the tutorial uses Serial.print() in the ISR which is likely to fail.

Getting your information on the lcd is very simple so fix the encoder reading first. Your counts are not correct, the divisor should be 20.48, and  something is wrong with the direction. 
Quote
If I start CCW however I get 6238.00 as the starting number and counts down from there.
Quote
What is the datatype of "counter".
Did you try "unsigned". e.g.  unsigned int counter = 0;
Code: [Select]
volatile unsigned int counter=0; "Volatile" is correct for a value changed within an ISR. Depending upon how may revolutions you make in a direction it could be a volatile int since you only have 2048 counts per revolution. I do believe that you should be using a volatile int (or long) because if you start at 0 and go ccw you want it to start reading -1.

williamjcoates

Hi,
I checked the code I have and it had the "Volatile" statement. So its time to scrap this code and try example 3. I think I tried this one before and received compile errors. Is this the code that Jurs supplied. I noticed later that I had to create a "Tab" named encoder.h. I tried doing this and it still wouldn't compile. I did up a new file and put the encoder code in it and named it encoder.h. the file ended up being called encoder.h.ino. i removed the last extension so it was named encoder.h and put it in the same directory as the sample code file.....So what did i do wrong?

williamjcoates

I figured out how to get jurs code to work. Only question would be if this was example 3 that I should be looking at?
Bill

cattledog

Quote
I figured out how to get jurs code to work
I do not see where jurs has contributed to this thread, so I do not know what code you are talking about.

Example 3 in the Arduino Playground Encoder Tutorial does not use an additional header file encoder.h.


williamjcoates

Hi cattledog, I went to a link that MarkT gave me.
Wow, 100 pulse/revolution rotary encoders are expensive!
http://www.digikey.com/product-search/en?pv395=4&FV=fff4001e%2Cfff80033&k=rotary+encoder&mnonly=0&newproducts=0&ColumnSort=0&page=1&stock=1&quantity=0&ptm=0&fid=0&pageSize=25

I don't see a datasheet for Yumo-E6B2-CWZ3E.
Counting encoder pulses and displaying them is pretty straightforward.
See the code here for counting them, change as needed for your display.
http://forum.arduino.cc/index.php?topic=318170.0



there was some examples there. I used the 3 one which Jurs had uploaded
Bill

cattledog

That reference was from Crossroads, not MarkT.

MarkT in reply #16 pointed you at http://playground.arduino.cc/Main/RotaryEncoders#Example3

I am sure that many variations of code reading an encoder will work for you. There are also libraries which require you to do nothing other than enter some pin numbers.

I would recommend that you find something you understand. Take a look at the quadrature square wave pattern produced by these encoders, and analyse how the code detects and processes the changes. I believe that understanding the fundamentals will help you in the end, and these encoders will seem simple and not mysterious.
 


Go Up