# SparkFun Forums

Where electronics enthusiasts find answers.

### Rotary Encoder to Voltage (0v-5v) - MCP4725

For the discussion of Arduino related topics.

### Rotary Encoder to Voltage (0v-5v) - MCP4725#201126

By greenbarron64
#201126
Hey There

I would like to Convert the Output from my Rotary Encoder into a proportion voltage output using the MCP4725.

Here's the Encoder I own: http://www.encoderonline.com/Data-Sheet ... ata-07.htm
Outout AB / 1,000ppr

I'm able to read the change in state on the serial with the code below.

I however need to be able to output a voltage range to correspond with the RPM the encoder is spinning at.

My Shaft's MAX RPM is 100, hence I'd like 100RPM to equate to 5v, RPM to 0v, 50RPM to 2.5v. Ect (IE clear range from 0v - 5v)

Can someone please write the code for me to accomplish this on the Arduino UNO
Code: Select all
``````/*     Arduino Rotary Encoder Tutorial
*
*  by Dejan Nedelkovski, www.HowToMechatronics.com
*
*/

#define outputA 6
#define outputB 7
int counter = 0;
int aState;
int aLastState;
void setup() {
pinMode (outputA,INPUT);
pinMode (outputB,INPUT);

Serial.begin (9600);
// Reads the initial state of the outputA
aLastState = digitalRead(outputA);
}
void loop() {
aState = digitalRead(outputA); // Reads the "current" state of the outputA
// If the previous and the current state of the outputA are different, that means a Pulse has occured
if (aState != aLastState){
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(outputB) != aState) {
counter ++;
} else {
counter --;
}
Serial.print("Position: ");
Serial.println(counter);
}
aLastState = aState; // Updates the previous state of the outputA with the current state
}
``````

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201149

By jremington
#201149
I suggest to study the Adafruit tutorial, in order to learn how to use the MCP4725: https://www.adafruit.com/product/935

You will also need to learn how to convert encoder state changes into RPM values.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201151

By lyndon
#201151
Sure, what's your budget? Alternately, research frequency-to-voltage converter circuits.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201152

By greenbarron64
#201152
lyndon wrote: Sat Nov 24, 2018 4:48 pm Sure, what's your budget? Alternately, research frequency-to-voltage converter circuits.
Hi Lyndon, thanks for your reply. My first attempt was using the LM331 but it was notoriously imprecise, the second issue was getting the parts to improve the circuit.

I chose to use the microcontroller route because of two things (1.) I have a couple of Arduinos laying around and (2.) The lead time for getting LM33 or Similar circuit components is quite long.

My budget is really a time issue, that's why I opted to using an Arduino alongside one of the MCP4725 I had lying around.

Can you please recommend an effective solution for me?

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201153

By greenbarron64
#201153
jremington wrote: Sat Nov 24, 2018 3:29 pm I suggest to study the Adafruit tutorial, in order to learn how to use the MCP4725: https://www.adafruit.com/product/935

You will also need to learn how to convert encoder state changes into RPM values.
Hi jremington,

I learned how to convert encoder state changes into RPM values using code from this source;

Arduino RPM code with Quadrature Encoder 600ppr
https://stackoverflow.com/questions/512 ... der-600ppr
Code: Select all
``````const int encoder_a = 3; // Pin 3
const int encoder_b = 5; // Pin 5
long encoder_pulse_counter = 0;
long direction = 1;

void encoderPinChangeA()
{
encoder_pulse_counter += 1;
direction = digitalRead(encoder_a) == digitalRead(encoder_b) ? -1 : 1;
}

void encoderPinChangeB()
{
encoder_pulse_counter += 1;
direction = digitalRead(encoder_a) != digitalRead(encoder_b) ? -1 : 1;
}

void setup()
{
Serial.begin(9600);
pinMode(encoder_a, INPUT_PULLUP);
pinMode(encoder_b, INPUT_PULLUP);
attachInterrupt(0, encoderPinChangeA, CHANGE);
attachInterrupt(1, encoderPinChangeB, CHANGE);
}

void loop()
{
long speed = encoder_pulse_counter/1000.00*60; // For encoder plate with 1000 Pulses per Revolution
Serial.print("RPM: ");
Serial.println(direction*speed);
encoder_pulse_counter = 0; // Clear variable just before counting again
delay(1000);
}``````
My final step is now having the RPM value scaled down proportional to my (0v-5v) voltage range and converted to a clean voltage (0v-5v) output using the MCP4725.

On adafruit.com there aren't any projects similar to mine using the MCP4725. Can you help?

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201154

By jremington
#201154
Sure, just output a voltage V = RPM*5.0/100.0

As you can see, V=5 if RPM=100, V=2.5 if RPM=50, etc.

The Adafruit tutorial I linked shows you how to output a voltage.

Keep in mind that 5V output from the MCP4725 corresponds numerically to 4095 at 12 bit resolution, so the formula that you will actually be using is V=4095.*RPM/100.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201155

By greenbarron64
#201155
jremington wrote: Sat Nov 24, 2018 7:15 pm Sure, just output a voltage V = RPM*5.0/100.0

As you can see, V=5 if RPM=100, V=2.5 if RPM=50, etc.

The Adafruit tutorial I linked shows you how to output a voltage.

Keep in mind that 5V output from the MCP4725 corresponds numerically to 4095 at 12 bit resolution, so the formula that you will actually be using is V=4095.*RPM/100.
Hi jremington, thanks a lot for your reply. I'm new to coding with the Arduino. Can you please help me modify the existing sketch provided by adafruit to work with my application. I understand the mathematical calculation but don't know how to code it.
Code: Select all
``````/**************************************************************************/
/*!
@file     trianglewave.pde
@author   Adafruit Industries
@license  BSD (see license.txt)

This example will generate a triangle wave with the MCP4725 DAC.

This is an example sketch for the Adafruit MCP4725 breakout board
----> http://www.adafruit.com/products/935

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
*/
/**************************************************************************/
#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

void setup(void) {
Serial.begin(9600);
Serial.println("Hello!");

// For Adafruit MCP4725A1 the address is 0x62 (default) or 0x63 (ADDR pin tied to VCC)
// For MCP4725A0 the address is 0x60 or 0x61
// For MCP4725A2 the address is 0x64 or 0x65
dac.begin(0x62);

Serial.println("Generating a triangle wave");
}

void loop(void) {
uint32_t counter;
// Run through the full 12-bit scale for a triangle wave
for (counter = 0; counter < 4095; counter++)
{
dac.setVoltage(counter, false);
}
for (counter = 4095; counter > 0; counter--)
{
dac.setVoltage(counter, false);
}
}``````

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201159

By jremington
#201159
If you want to succeed in this hobby, you need to learn the material.

Arduino is a learning tool, and the designers have bent over backwards to make it easy to use. Start with simpler projects, like the examples that come with Arduino (and tutorials on the web), and work your way up.

If you don't intend to pursue the hobby, and just want to get something done, post on the Gigs & Collaborations section of the Arduino forum and be prepared to pay for the help.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201163

By greenbarron64
#201163
Hi jremington,

This is 1 of 3 different types of encoders I'm working on. Reverse engineering code or circuits helps the learning process but typically one needs to start from a working solution backwards. Projects too different from what I'm trying to accomplish in terms of length and complexity of code will take a long time than I have to learn. Right about now I'm not even sure what I'm trying to accomplish is possible because its not yet done.

Difficulty is relative when it comes to learning anything and although I'm good with discrete electronics I'm new to programming and know I'll eventually learn a lot at the end of the project as a whole. Just like you have sample circuits on a datasheet, solutions are helpful to the learning process.

As noted earlier I've been working on this for a while so my asking for help comes not from an unwillingness to learn but a desire to.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201177

By lyndon
#201177
What jremington is getting at is exactly your problem: you're unskilled at programming and this is primarily a programming task. So you should start by learning to program something simpler and work up.

What you are asking for is certainly possible and not particularly difficult. A basic algorithm would be:
Code: Select all
``````S = 0
Interrupted = false
Setup:
{
Configure interrupt for rising edge
}

Loop:
{
if (Interrupted)
{
Interrupted = false;
Now = millis()
Period = Now - S
S = Now
Calculate RPM from Period
Update DAC
}
}

ISR:
{
Interrupted = true
}
``````
That will work. However, getting it to work *well* is where experience and time comes in.

### Re: Rotary Encoder to Voltage (0v-5v) - MCP4725#201179

By greenbarron64
#201179
Hi lyndon,

Thanks for your reply.