Pages: [1]   Go Down
Author Topic: interfacing encoder to arduino  (Read 1175 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys, I just bought this encoder

http://usdigital.com/assets/datasheets/E7P_datasheet.pdf?k=634861190727125957

and I'm trying to use it in my robot by using this code:

Code:
// Define pin locations and delay time between each query
#define EncoderPinA  3
#define EncoderPinB  5
#define DELAY_TIME 500
 
// Define some physical constants
#define WHEEL_CIRCUMFERENCE 0.9 // In meters
#define WHEEL_TICKS 244         // The number of 'ticks' for a full wheel cycle
 
// Create a variable in memory that the interrupt code can access
// Also create the change value globally
volatile unsigned int EncoderPos = 0;
double dVal = 0;
 
// Initialize
void setup()
{
  // Set input pin state for the line sensors
  pinMode(EncoderPinA, INPUT);
  pinMode(EncoderPinB, INPUT);
 
  // Register a hardware interupt function for pin 3 (which is indexed by value 1)
  // This function sets the EncoderEvent() function to be called whenever a line detector detects a change
  attachInterrupt(1, EncoderEvent, CHANGE);
 
  // Start serial communication
  Serial.begin (9600);
}
 
// Program loop
void loop()
{
  // Find the before and after value between the delay times
  unsigned int OldPos = EncoderPos;
  delay(DELAY_TIME);
  unsigned int NewPos = EncoderPos;
 
  // If an integer overflow occures, throw out the new value
  if(abs(NewPos - OldPos) < 30000)
    dVal = ((double)(NewPos - OldPos) / (double)DELAY_TIME) * 1000.0;
 
  // Convert between angular velocity to velocity
  double angVel = dVal / (double)WHEEL_TICKS;
  double velocity = (angVel * WHEEL_CIRCUMFERENCE);
 
  // Print data
  Serial.print("Velocity: ");
  PrintDouble(velocity, 5);
}
 
// Encoder event for the interrupt call
void EncoderEvent()
{
  // Read for data and bit changes
  // This is gray-code logic
  if (digitalRead(EncoderPinA) == HIGH)
  {
    if (digitalRead(EncoderPinB) == LOW)
      EncoderPos++;
    else
      EncoderPos--;
  }
  else
  {
    if (digitalRead(EncoderPinB) == LOW)
      EncoderPos--;
    else
      EncoderPos++;
  }
}
 
// Print a double value onto the serial stream
// This is from the Arduino.cc forum
void PrintDouble( double val, byte precision)
{
  Serial.print (int(val));  //prints the int part
  if( precision > 0) {
    Serial.print("."); // print the decimal point
    unsigned long frac;
    unsigned long mult = 1;
    byte padding = precision -1;
    while(precision--)
mult *=10;
 
    if(val >= 0)
frac = (val - int(val)) * mult;
    else
frac = (int(val)- val ) * mult;
    unsigned long frac1 = frac;
    while( frac1 /= 10 )
padding--;
    while(  padding--)
Serial.print("0");
    Serial.println(frac,DEC) ;
  }
}

However, when I turned on the motor and run the wheel, the serial monitor can only detect velocity = 0.000. I don't know what went wrong. Appreciate your help. Thanks
Logged

Offline Offline
Edison Member
*
Karma: 56
Posts: 2145
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not knowing about this device, I would first see if I was getting an output form the encoder.
Would you confirm with a scope that the signal going to the Arduino is indeed there?
Also, show us your schematic for this project.
Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1023
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not knowing what type of outputs your encoder has. Are they TTL (5V) or are they differential? Differential outputs may not have enough voltage swing. If that is the situation then you would need a differential reciever to convert to a 5V TTL level signal for the Arduino.

I have used that code with an encoder so I know it works.
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 331
Posts: 16499
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not knowing what type of outputs your encoder has. Are they TTL (5V) or are they differential? Differential outputs may not have enough voltage swing. If that is the situation then you would need a differential reciever to convert to a 5V TTL level signal for the Arduino.

I have used that code with an encoder so I know it works.

The spec sheet shows the differential outputs working at the same output voltages as the single ended outputs, both TTL levels. So he only needs to wire up to the A+ and B+ output signal lines to the arduino if he indeed has the differential output model and it will then operate just like the single ended output model.

Lefty
Logged

0
Offline Offline
Shannon Member
****
Karma: 160
Posts: 10416
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The min output HIGH is 2.4V, not enough, although typical figure is 3.4V (just enough), for the single-ended or
differential output version.

The ATmega needs a minimum of 3V to guarantee reading HIGH.  In general TTL levels are not compatible with CMOS
without a level shifting circuit or intermediate 74HCT buffer chip (a 74HCT14 schmitt-trigger inverter is often used
to map TTL to CMOS levels at 5V).  The 74HCT family of CMOS logic has TTL-compatible input thresholds.

Having said all that we I'm talking worst-case here - it is likely to work as is, but its worth checking with a meter that
the HIGH output voltage level is more like 3.5V than 2.4V
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The min output HIGH is 2.4V, not enough, although typical figure is 3.4V (just enough), for the single-ended or
differential output version.

The ATmega needs a minimum of 3V to guarantee reading HIGH.  In general TTL levels are not compatible with CMOS
without a level shifting circuit or intermediate 74HCT buffer chip (a 74HCT14 schmitt-trigger inverter is often used
to map TTL to CMOS levels at 5V).  The 74HCT family of CMOS logic has TTL-compatible input thresholds.

Having said all that we I'm talking worst-case here - it is likely to work as is, but its worth checking with a meter that
the HIGH output voltage level is more like 3.5V than 2.4V

Do you mean that I need to increase the output voltage from the encoder to make it work?
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The worst-case high level output (2.4V) is given at 20mA load, whereas the Arduino presents only a tiny load. So I very much doubt that insufficient high level output voltage is the problem. Nevertheless, I suggest you change the pin mode of the two encoder input pins to INPUT_PULLUP to be safe.

My guess is that one of the four wires between the encoder and the Arduino is not properly connected.

Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Edison Member
*
Karma: 28
Posts: 2036
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've seen it recommended,  that the variable accessed in the interrupt routine should be declared  "volatile",   although whether it matters in this case,  I don't know.
Logged

0
Offline Offline
Shannon Member
****
Karma: 160
Posts: 10416
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've seen it recommended,  that the variable accessed in the interrupt routine should be declared  "volatile",   although whether it matters in this case,  I don't know.

If a variable is used both in an interrupt routine and in the rest of the sketch you make it volatile - otherwise
the compiler might do the wrong thing.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have checked the output voltage of the encoder using a scope and it is shown that the output voltage is always at 3.7 V, regardless the position of the wheel. What could be the cause of this problem?
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are saying that when the code wheel rotates relative the mounting base of the encoder, the outputs don't change? If so, check that the ground connection between the encoder and the Arduino is good.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Are saying that when the code wheel rotates relative the mounting base of the encoder, the outputs don't change? If so, check that the ground connection between the encoder and the Arduino is good.

Checked the ground and the outputs work just fine from the scope, however the serial output still says 0 velocity
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solved, thanks
Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1023
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solved, thanks

How? WHat was the problem?
Logged

Pages: [1]   Go Up
Jump to: