Magnetic Rotary Encoder v1.0

From RepRap
Revision as of 21:31, 2 May 2014 by DavidCary (talk | contribs) (mounting it on another popular (?) gearmotor)
Jump to: navigation, search

If your RepRap only uses stepper motors, like most of the top-rated RepRaps in the Comparison of Electronics, and you run them at low speed and low acceleration so they don't skip steps, you don't need this or any other encoder.

However, if you want to run at higher speeds or higher acceleration than is possible with a stepper motor, read on.

As of 2014, this is the most recent magnetic rotary encoder designed for RepRap. As of 2014, this is the best encoder of any kind designed for RepRap -- see RepRapServo 1 0 for an overview of various kinds of encoders.


I am a part of both the Generation 2 Electronics and Generation 3 Electronics Systems.

Overview

Cache-2582992504 0745333fee.jpg

Jump to the Table of Contents

This is an advanced, surface mount board. It requires steady hands and patience to solder.

Don't worry though, You Can Do It!

The Magnetic Rotary Encoder board is based around the Austria Microsystems AS5040 chip. This chip allows you to sense the rotational position of a magnet. Sounds boring, right? Wrong! When you combine this chip with a motor, a motor driver, and an Arduino it allows you to create a servo motor of unlimited size and rotation. You can measure the rotation of the motor and control it so that it goes to the position you desire. Or, in the case of our extruder, you can measure the speed of the motor and have it rotate at exactly the speed you desire, regardless of the load on the motor.

Get It!

Full Kit

Raw Components


Files

Cache-2584278597 4c2dc95198.jpg

You can download the electronics files from Sourceforge.

This file contains the following:

  • GERBER files for getting it manufactured
  • PDF files of the schematic, copper layers, and silkscreen
  • Eagle source files for modification
  • 3D rendered image as well as POVRay scene file
  • exerciser code to test your board.


Schematic

Magnetic Rotary Encoder 1.0 Schematic

Interface

The AS5040 provides many different ways of getting the position data from the chip. Each one has its advantages and disadvantages, so feel free to use the one best suited to your needs.

Pinout

Pin Name Function
1 PWM A PWM output signal, where the width of the pulse (1 usec to 1023 usec wide) is based upon the position of magnet (0-360 degrees)
2 ANALOG An analog output signal from 0-5v signifying the position of the magnet (0-360 degrees)
3 SELECT The AS5040 provides a digital output using SSI, this is the select (or latch) pin.
4 CLOCK The AS5040 provides a digital output using SSI, this is the clock pin.
5 DATA The AS5040 provides a digital output using SSI, this is the data (or MISO) pin.
6 INDEX When the magnet is at the 0 degrees position, this pin is HIGH, otherwise LOW. This pin will pulse once per revolution
7 B The AS5040 outputs quadrature signals. This pin is the Quadrature Phase B signal
8 A The AS5040 outputs quadrature signals. This pin is the Quadrature Phase A signal
9 GND This is the ground pin. Connect this to ground on your Arduino.
10 5V This is the 5V input pin. Connect this to 5v on your Arduino.

LEDS

LED Meaning
MAG+ This is the Magnetic Field Increasing LED. If the magnetic field strength is increasing, this LED will light up.
MAG- This is the Magnetic Field Decreasing LED. If the magnetic field strength is decreasing, this LED will light up.
QUAD_A This LED is directly wired to Quadrature Phase A, it gives you a direct view of the chip activity.
QUAD_B This LED is directly wired to Quadrature Phase B, it gives you a direct view of the chip activity.
INDEX This LED is directly wired to the Index pin, it will flash once per revolution.
PWM This LED is wired to the PWM pin, along with a capacitor. Its brightness will vary according to the position of the magnet.

If both MAG+ and MAG- are on, it means your magnet is Out of Range. If they sporadically light during magnet rotation, it means your magnet alignment is slightly out of range. Adjust it accordingly until they do not light during normal use. Use these LEDs to align your magnet properly.

Build It

Board Bugs

  • No bugs yet, please report any you find to the forums.

Printed Circuit Board

Cache-2585171074 2ce5898cea.jpg

You can either buy this PCB from the RepRap Research Foundation, or you can make your own. The image above shows the professionally manufactured PCB ready for soldering.


Components

Cache-2582155611 24130a278d.jpg

<iframe src="http://parts.reprap.org/embed/module/Magnetic+Rotary+Encoder+v1.0" width="600" height="500" frameborder="0">Visit http://parts.reprap.org/embed/module/Magnetic+Rotary+Encoder+v1.0</iframe>

Soldering Instructions

This is a mostly surface mount component board, so the techniques will be a bit different than usual. In addition to your standard soldering toolkit, you will also need the following:

  • a soldering iron with a good, small tip
  • some tweezers, or small needle nose pliers
  • some thin solder (0.025" diameter or smaller)
  • a flux pen, flux paste, or other flux dispensing device
  • some solder wick
  • a magnifying glass

Before you start, you may want to watch this video on Surface Mount Soldering and/or read the SparkFun tutorial.

Cache-2582984310 89b2a0139b.jpg
]

10nF capacitor

The 10nF and 100nF capacitors themselves are not marked, so we have marked the 10nF capacitor with blue marker. If you mix them up, don't worry its okay.

The orientation on this capacitor does not matter.

The basic process goes like this:

  1. apply a small bit of solder to one of the raw pads to prep it
  2. pick up component with tweezers, and apply a small amount of flux to the ends
  3. position the component in place and heat one side with the iron (causing it to bond to the pad on that side)
  4. solder the other side to the other pad. if its sticking up a bit, solder it until the entire chip heats up and settles in.
  5. you may need to add more solder to either side to get a nice solid joint


Cache-2582156545 b7531058a4.jpg

100nF capacitor

Follow the directions above to solder the non-marked capacitor in.

The orientation on this capacitor does not matter.


Cache-2582985434 f453025c1b.jpg

560 Ohm Resistors

These resistors will all be marked '561'. The orientation does not matter, but it helps to solder them so the text is all facing the same way. Do as I say, not as I do ;)

Solder them with the same technique you used for the capacitors.


Cache-2582985864 8ed93abd80.jpg

4.7K Ohm Resistors

These resistors will be marked '472'. Solder them in just as with the 560 ohm resistors.


Cache-2582158623 4f55bea8b9.jpg

LEDS

The LEDs are polarized, meaning you need to solder them in the correct orientation! They will have green dots towards one side of the package. These dots need to match the dots on the silkscreen. Be careful, since the orientation changes for the various LEDs. Always check and double check the orientation before you solder.

Other than that, you can solder them using the same technique you used above. Be careful not to heat them up too much, as you may damage them.


Cache-2582160445 bf287ffbcc.jpg

AS5040

This is the hardest part of the board. Take a quick break before you do it. Wipe the sweat from your brow, take a deep breath, and calm yourself.

1. 2. 3. 4. 5. Exhale.

Awesome, lets start. First off, the chip needs to be soldered in properly. There is a circle mark on the chip that corresponds to the mark on the silkscreen. Make sure they match up before you solder.

The basic soldering process goes like this:

  1. use flux on the legs of the chip and/or the board
  2. position the chip over the pads
  3. solder one corner of the chip to the corresponding pad
  4. solder the opposite corner of the chip to the corresponding pad
  5. solder the rest of the pins, ignoring solder bridges
  6. use the solder wick to remove any solder bridges
  7. profit!

If you're still confused, please watch this video. It will change your life. Maybe.

If all goes well, you'll have a nicely soldered chip. The rest is simple.


Cache-2582161779 e3eed7af59.jpg

1uF Electrolytic Capacitors

These guys are the little tin-can looking things. They have polarity, so be sure to double check which way you are soldering them to the board. One side will have square corners, and the other will have beveled edges. Make sure you match these up with the silkscreen.

Once you understand how to place them, you'll want to prepare the surface for mounting just like you did with the other capacitors, resistors, and LEDs by applying a bit of solder to the empty pads. Then you simply solder the capacitor down one pad at a time. Yay!


Cache-2582163059 57a1d3f064.jpg

IDC Header

This is where you will plug in the IDC cable to your board. Solder it so the center tab faces the center of the board. Just like it shows on the silkscreen!

This one is thru-hole and thus insanely easy compared to what you just did.


Cache-2582163727 7d957e2fcd.jpg

Insert IDC Connector

First, you must make an IDC cable. Next, insert it into the header. It is keyed, so it can only be inserted in one orientation. Yay!


Congratulations, you just soldered a fairly difficult board. Go have a frosty beverage of your choice to celebrate.

Mount It

GM3 Gear Motor

Cache-2612715269 b984603240.jpg

The Magnetic Rotary Encoder Board provides precise mounting holes to mount it to a GM3 Gearmotor. You'll need spacers that are 7/16" long to space the board far enough away.

Attach the Magnet

The first step is to mount the magnet on the GM3 gearmotor's non-output shaft. This is the shaft with one flat side, NOT the shaft with two flat sides. Get some super glue and put a dab on the shaft of the motor. Quickly place the magnet onto the shaft, being careful that the magnet is closely aligned with the motor shaft. It should be slightly inside the curve of the shaft. Press firmly for 10 seconds to allow the glue to bond. If you messed up, pry the magnet off and try again. It may take 2 applications of the superglue to get a good bond. Finally, clean off any gunk from the side and top of the magnet.


Cache-2631512184 1f6131b123.jpg

Mount the MRE Board

Using the M3 bolts, attach the MRE to the GM3 Motor using the spacers provided. The magnet should just barely enter the large drill hole beneath the chip. You can then mount the GM3 motor wherever you need it to be mounted. If you need more spacing, you can easily add a washer or two between the spacer and the motor.

More information on hacking the GM3 Gearmotor is here.


Mounting on a Makerbot Kysan DC Gearmotor

"Encoder Mount"

Other Uses

You can use the MRE board to measure rotation for many things, and we've provided 6 different mounting holes for you to use. The magnet can be positioned directly above or below the AS5040 chip, and we've provided a 6.1mm diameter hole that will help with aligning the magnet as well. Please refer to the AS5040 datasheet for more information on mounting tolerances.

Use It

Quadrature Output

Cache-2595067189 d0b3f895f9.jpg

Quadrature Encoding is very useful. It allows you to determine both position and rotation direction in a simple manner. Not only that, but it is incremental, which means that you can use quadrature encoding to record positions that are as large as you can store in your variable!!!

Not only that, but it only uses 2 pins. Rad.

Here is an Arduino program to read the position via quadrature encoding. Connect the pins as follows:

MRE Pin Arduino Pin
5V 5V
GND GND
QUAD_A 2
QUAD_B 3

Then, upload this code, and open your Serial Monitor at speed 19200.

#define ENCODER_A_PIN 2
#define ENCODER_B_PIN 3

long position;

void setup()
{
   Serial.begin(19200);
   Serial.println("Started");
   
   pinMode(ENCODER_A_PIN, INPUT);
   pinMode(ENCODER_B_PIN, INPUT);
   
   attachInterrupt(0, read_quadrature, CHANGE);
}

void loop()
{
   Serial.print("Position: ");
   Serial.println(position, DEC);
   delay(1000);
}

void read_quadrature()
{  
  // found a low-to-high on channel A
  if (digitalRead(ENCODER_A_PIN) == HIGH)
  {   
    // check channel B to see which way
    if (digitalRead(ENCODER_B_PIN) == LOW)
        position++;
    else
        position--;
  }
  // found a high-to-low on channel A
  else                                        
  {
    // check channel B to see which way
    if (digitalRead(ENCODER_B_PIN) == LOW)
        position--;
    else
        position++;
  }
}


Digital SSI Output

Cache-2595901706 0463f72276.jpg

The AS5040 provides a digital output which is also very useful. It uses 3 pins, but provides some other useful features such as a checksum, and error flags to help you diagnose any potential errors. Additionally, it is possible to do some advanced things with the digital output, such as daisy chaining AS5040 chips to allow you to read multiple AS5040 chips with the same 3 pins, or allowing you to read them in parallel using 2 + N pins where N is the number of AS5040 chips to use.

It has some very useful potential.

Here is an Arduino program to read the position via the digital interface. Connect the pins as follows:

MRE Pin Arduino Pin
5V 5V
GND GND
SELECT 4
CLOCK 5
DATA 6

Then, upload this code, and open your Serial Monitor at speed 19200.

#define SELECT_PIN 4
#define CLOCK_PIN 5
#define DATA_PIN 6

void setup()
{
  //setup our pins
  pinMode(DATA_PIN, INPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(SELECT_PIN, OUTPUT);

  //give some default values
  digitalWrite(CLOCK_PIN, HIGH);
  digitalWrite(SELECT_PIN, HIGH);

  Serial.begin(19200);
}

//variables to keep track of position
int reading = 0;
float angle = 0;

void loop()
{
   reading = readPosition();
   
   if (reading >= 0)
   {
      angle = ((float)reading / 1024.0) * 360.0;

      Serial.print("Reading: ");
      Serial.print(reading, DEC);
      Serial.print(" Angle: ");
      Serial.println((int)angle, DEC);
   }
   else
   {
      Serial.print("Error: ");
      Serial.println(reading);
   }
   
   delay(1000);
}

//read the current angular position
int readPosition()
{
  unsigned int position = 0;

  //shift in our data  
  digitalWrite(SELECT_PIN, LOW);
  delayMicroseconds(1);
  byte d1 = shiftIn(DATA_PIN, CLOCK_PIN);
  byte d2 = shiftIn(DATA_PIN, CLOCK_PIN);
  digitalWrite(SELECT_PIN, HIGH);

  //get our position variable
  position = d1;
  position = position << 8;
{| border="1"
|-
  position ||= d2;
|}

  position = position >> 6;

  //check the offset compensation flag: 1 == started up
  if (!(d2 & B00100000))
    position = -1;

  //check the cordic overflow flag: 1 = error
  if (d2 & B00010000)
    position = -2;

  //check the linearity alarm: 1 = error
  if (d2 & B00001000)
    position = -3;

  //check the magnet range: 11 = error
  if ((d2 & B00000110) == B00000110)
    position = -4;

  return position;
}

//read in a byte of data from the digital input of the board.
byte shiftIn(byte data_pin, byte clock_pin)
{
  byte data = 0;

  for (int i=7; i>=0; i--)
  {
    digitalWrite(clock_pin, LOW);
    delayMicroseconds(1);
    digitalWrite(clock_pin, HIGH);
    delayMicroseconds(1);

    byte bit = digitalRead(data_pin);
{| border="1"
|-
    data ||= (bit << i);
|}

  }

  Serial.print("byte: ");
  Serial.println(data, BIN);

  return data;
}


Analog Output

Cache-2595067403 1caa0f74c1.jpg

By using a filter circuit, the AS5040 is capable of outputting an analog position value. Its not nearly as accurate as the Quadrature or Digital outputs, but it is useful in its own right.

Here is an Arduino program to read the position via analog. Connect the pins as follows:

MRE Pin Arduino Pin
5V 5V
GND GND
ANALOG Analog 0

Then, upload this code, and open your Serial Monitor at speed 19200.

#define ANALOG_PIN 0

int reading = 0;
float angle = 0;

void setup()
{
   Serial.begin(19200);
   Serial.println("Started");
}

void loop()
{
   reading = analogRead(ANALOG_PIN);
   angle = ((float)reading / 1024.0) * 360.0;
   
   Serial.print("Reading: ");
   Serial.print(reading, DEC);
   Serial.print(" Angle: ");
   Serial.println((int)angle, DEC);
   
   delay(1000);
}

PWM Output

Coming soon. Anyone have a good idea on how to use this output?

Index Output

Coming soon. This one is pretty easy.


Index

other encoders

  • Is the MagServo significantly different from this Magnetic Rotary Encoder 1.0?
  • the open-source OpenServo OpenEncoder seems surprisingly similar to this RepRap magnetic rotary encoder.
  • KMZ10 (A/B/C) is analog encoder (only analog output) - it is very cheap - 1$ and simple to interface with (just one differential amp)