OK I misunderstood what the attachInterrupt and detachInterrupt calls were for. As the code is written, they are needed - they are switching the rising interrupt off and the falling interrupt on, and vice versa. This is a most unusual way of doing things, but should be OK. The more usual approach would be to use a single interrupt service routine to handle the CHANGE interrupt, and read the pin state to see whether it was rising or falling.
dc42:
The more usual approach would be to use a single interrupt service routine to handle the CHANGE interrupt, and read the pin state to see whether it was rising or falling.
In search of encoder code I found this one first, and because I got it working i went along using it in my project.
If this code isn't the most efficient or best way then it's no problem to rewrite my code.
Can you give or show me an example of a smart code so I can figure it out how it works and i can use it in my project?
I also searching the net my self and have no problem to find some, but I can't tell if it's smart or not.
...
Just found an encoder library, didn't know it exits.
http://www.pjrc.com/teensy/td_libs_Encoder.html
look simple to me.
Had a go with the library from Encoder Library, for Measuring Quadarature Encoded Position or Rotation Signals, had some success, some luck but now have some problems ![]()
First I loaded the example code given on the site which worked fine, tweaked it so it worked with three encoders.
Then I rewrote my original code now with the library.
Problem now is that the encoder value can't be multiplied.
When compiling a get the fault message:
--Cannot convert 'Encoder' to 'float' in assignment--
I probably have to convert 'Encoder' to something else but don't know what.
//*************************************************************************************
// *************--------------Sjuul's Digital Read out system------------***************
// *************************************************************************************
// ------- INCLUDING LIBRARIES & DECLARING -------------
#include <Encoder.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Encoder Xpulses(16, 18);
Encoder Ypulses(17, 19);
Encoder Zpulses(3, 2);
const int ZeroXbutton = 53;
const int ZeroYbutton = 52;
const int ZeroZbutton = 51;
float Xmm;
float Ymm;
float Zmm;
float Last_Xmm;
float Last_Ymm;
float Last_Zmm;
float Scale;
void setup(){
{
lcd.begin(20,4);
Scale = 5;
}
// ------- FLASHING BACKLIGHT -------------
{
for(int i = 0; i< 3; i++)
{
lcd.backlight();
delay(100);
lcd.noBacklight();
delay(100);
}
lcd.backlight();
//-------- WELCOMING MESSAGE ------------------
lcd.setCursor(0,0);
lcd.print("********************");
lcd.setCursor(0,1);
lcd.print("* *");
lcd.setCursor(0,2);
lcd.print("* *");
lcd.setCursor(0,3);
lcd.print("********************");
delay(500);
lcd.setCursor(4,1);
lcd.print("Sjuul's DRO");
lcd.setCursor(2,2);
lcd.print("Mini Mill ZX7016");
delay(2000);
//-------- TEMPLATE ------------------
lcd.clear();
lcd.setCursor(0,0);
lcd.print("X: mm ");
delay(100);
lcd.setCursor(0,1);
lcd.print("Y: mm ");
delay(100);
lcd.setCursor(0,2);
lcd.print("Z: mm ");
delay(100);
lcd.setCursor(0,3);
lcd.print("n: RPM");
}
}
//-------- MAIN PROGRAMM ------------------
void loop(){
//-------- Axes MASURING, CALCULATING AND PRINTING ------------------
Xmm = Xpulses * Scale;
Ymm = Ypulses * Scale;
Zmm = Zpulses * Scale;
if (Xmm != Last_Xmm){
WriteX();
Last_Xmm = Xmm;
}
if (Ymm != Last_Ymm){
WriteY();
Last_Ymm = Ymm;
}
if (Zmm != Last_Zmm){
WriteZ();
Last_Zmm = Zmm;
}
if (digitalRead(ZeroXbutton) == HIGH){
Xpulses = 0;
}
if (digitalRead(ZeroYbutton) == HIGH){
Ypulses = 0;
}
if (digitalRead(ZeroZbutton) == HIGH){
Zpulses = 0;
}
}
//-------- WRITING FUNCTIONS --------------
void WriteX(){
lcd.setCursor(3,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(Xmm);
}
void WriteY(){
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(3,1);
lcd.print(Ymm);
}
void WriteZ(){
lcd.setCursor(3,2);
lcd.print(" ");
lcd.setCursor(3,2);
lcd.print(Zmm);
}
Instead of:
Encoder Xpulses(16, 18);
use:
Encoder Xencoder(16, 18);
long Xpulses = 0;
Then instead of:
Xmm = Xpulses * Scale;
use:
Xpulses = Xencoder.read();
Xmm = Xpulses * Scale;
[Warning: I haven't tested that!]
Thanks!!!
It works, can you explain me why?
What does --long Xpulses = 0;-- do?
Only the zero routines don't zero yet, I'll look at that tomorrow.
Hopefully I get the chips tomorrow and a new display without I2C.
// *************************************************************************************
// *************--------------Sjuul's Digital Read out system------------***************
// *************************************************************************************
// ------- INCLUDING LIBRARIES & DECLARING -------------
#include <Encoder.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Encoder Xencoder(16, 18);
long Xpulses = 0;
Encoder Yencoder(17, 19);
long Ypulses = 0;
Encoder Zencoder(3, 2);
long Zpulses = 0;
const int ZeroXbutton = 53;
const int ZeroYbutton = 52;
const int ZeroZbutton = 51;
float Xmm;
float Ymm;
float Zmm;
float Last_Xmm;
float Last_Ymm;
float Last_Zmm;
float Scale;
void setup(){
{
lcd.begin(20,4);
Scale = 5;
}
// ------- FLASHING BACKLIGHT -------------
{
for(int i = 0; i< 3; i++)
{
lcd.backlight();
delay(100);
lcd.noBacklight();
delay(100);
}
lcd.backlight();
//-------- WELCOMING MESSAGE ------------------
lcd.setCursor(0,0);
lcd.print("********************");
lcd.setCursor(0,1);
lcd.print("* *");
lcd.setCursor(0,2);
lcd.print("* *");
lcd.setCursor(0,3);
lcd.print("********************");
delay(500);
lcd.setCursor(4,1);
lcd.print("Sjuul's DRO");
lcd.setCursor(2,2);
lcd.print("Mini Mill ZX7016");
delay(2000);
//-------- TEMPLATE ------------------
lcd.clear();
lcd.setCursor(0,0);
lcd.print("X: mm ");
delay(100);
lcd.setCursor(0,1);
lcd.print("Y: mm ");
delay(100);
lcd.setCursor(0,2);
lcd.print("Z: mm ");
delay(100);
lcd.setCursor(0,3);
lcd.print("n: RPM");
}
}
//-------- MAIN PROGRAMM ------------------
void loop(){
//-------- Axes MASURING, CALCULATING AND PRINTING ------------------
Xpulses = Xencoder.read();
Xmm = Xpulses * Scale;
Ypulses = Yencoder.read();
Ymm = Ypulses * Scale;
Zpulses = Zencoder.read();
Zmm = Zpulses * Scale;
if (Xmm != Last_Xmm){
WriteX();
Last_Xmm = Xmm;
}
if (Ymm != Last_Ymm){
WriteY();
Last_Ymm = Ymm;
}
if (Zmm != Last_Zmm){
WriteZ();
Last_Zmm = Zmm;
}
if (digitalRead(ZeroXbutton) == HIGH){
Xpulses = 0;
}
if (digitalRead(ZeroYbutton) == HIGH){
Ypulses = 0;
}
if (digitalRead(ZeroZbutton) == HIGH){
Zpulses = 0;
}
}
//-------- WRITING FUNCTIONS --------------
void WriteX(){
lcd.setCursor(3,0);
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(Xmm);
}
void WriteY(){
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(3,1);
lcd.print(Ymm);
}
void WriteZ(){
lcd.setCursor(3,2);
lcd.print(" ");
lcd.setCursor(3,2);
lcd.print(Zmm);
}
Sjuuls:
Thanks!!!
It works, can you explain me why?
What does --long Xpulses = 0;-- do?Only the zero routines don't zero yet, I'll look at that tomorrow.
"Encoder" is a class that looks after a rotary encoder. "long Xpulses = 0;" declares xPulses to be a variable of type Long. "Xpulses = Xencoder.read();" asks the encoder what its current setting is.
To get the zero working:
-
Remove the "long xPulses = 0;" line that I told you to add. You don't need the Xpuluses variable at all.
-
Change:
Xpulses = Xencoder.read();
Xmm = Xpulses * Scale;
to:
Xmm = Xencoder.read() * Scale;
- Change:
if (digitalRead(ZeroXbutton) == HIGH){
Xpulses = 0;
}
to:
if (digitalRead(ZeroXbutton) == HIGH){
Xencoder.write(0);
}
Please use code tags (the # button in the menu) instead of quote tags when posting code.
Zeroing Works ![]()
The chips came in today, put a scale on the arduino, ran the code but no counting :~
The arduino senses something because it rapidly counts between 1 and 0 an -1...
Tomorrow ill bring the scoop from work so I can look at the output from the SN 75176 BP
also fixed the code quote in my previous posts
Got a sample of the wave, looks good but its not as (I thought) it shoot be.
I know now why it's not working but don't know why the wave looks like this.

Suggestions:
-
You appear to have the scope set to AC coupling, since the voltages go negative. Set it to DC coupled inputs instead.
-
Check the connections very carefully, in particular the ground and Vcc connections to the 75176.
-
Make sure you have a common ground between the Arduino, the measuring device, and the scope probes.
-
If you can't find the problem, post a trace with the scope connected to the A+ and A- outputs.
Look like what ?
Tell what you expected to see instead of letting others guess about it.
This is how a encoder wave shoot be like, and where the library is written for:
Quadrature Encoder Signal
You will always see imperfections in a scope view.
Do you see the bumps up in the channel that is not pulled down on your scope screendump ?
That is not abnormal, it's just the channels interfering.
You should also look up any timing tolerances, in the datasheet of the ruler, as well as in that of those 75176.
Sjuuls:
This is how a encoder wave shoot be like, and where the library is written for:
Quadrature Encoder Signal
And that is how the signal is depicted on the label of the device, as can be seen in the photo attached to reply #2. The bumps are not the problem; the problem is that the pulses do not overlap.
Did you by any chance connect A from your ruler to input A of the 75176 and B to input B of the same 75176 ?
That might result in something like the picture you're seeing.
If you did, you should connect A to A and A* to B of the same 75176.
Could be that you have to connect A* to A and A to B.
And you still need 2 75176's to handle one complete signal.
I did used two chips, one for the A pulse (PCA and *PCA) and one for the B pulse (PCB and *PCB)
The arduino has a 9Volt battery, ruler has a 5V power supply all GND are connected.
I check the complete wiring tonight and going to switch with different rulers an measuring heads.
Can you confirm that you are powering the 75176s from Arduino +5V?
uh, I used the 5V powersupply from the ruler, is this wrong? ![]()
Yes, you should use the 5V Arduino pin to power the 75176s. Otherwise, you might damage the 75176 or the Arduino when just the Arduino or just the ruler is powered up. And make sure the Arduino ground, 75176 ground and ruler ground are all connected.
Got it!!!
Checked all the connections and found out that my breadboard had a surprise
after all it was a ground problem, pulses looking good arduino counts up and down.
next is reprograming the LCD, I now use the I2C bus but I need those pins because those are interupts.
Next problem is that when its finished, and in use I don't have an arduino mega anymore ![]()
That's not a surprise, it's a feature ![]()