Rotory Encoder + MCP4812 - Page 1
Forum section: electronics / general

author: Instro_Spark
author_rank: Contributor
timestamp: March 08, 2014, 02:04:16 pm
content: Hey guys was hoping that someone would be able to help us merge two separate codes. One for the rotory encoder and the other the DAC (Microchip MCP4821) using SPI.What im trying to achieve is to take the signal from the encoder and send it to the DAC which will eventually go into a non inverting amp to obtaing a 0 -10v signal. Using a ATmega328 be nice im very green when it comes to coding.Rotory Encoder Sketch (http://www.hobbytronics.co.uk/arduino-tutorial6-rotary-encoder)Code:// Rotary Encoder Exampleint brightness = 0; // how bright the LED is, start at half brightnessint fadeAmount = 5; // how many points to fade the LED byunsigned long currentTime;unsigned long loopTime;const int pin_A = 7;const int pin_B = 6;unsigned char encoder_A;unsigned char encoder_B;unsigned char encoder_A_prev=0;void setup() {// declare pin 9 to be an output:pinMode(9, OUTPUT);pinMode(pin_A, INPUT);pinMode(pin_B, INPUT);currentTime = millis();loopTime = currentTime;}void loop() {// get the current elapsed timecurrentTime = millis();if(currentTime >= (loopTime + 2.5)){// 5ms since last check of encoder = 200Hzencoder_A = digitalRead(pin_A); // Read encoder pinsencoder_B = digitalRead(pin_B);if((!encoder_A) && (encoder_A_prev)){// A has gone from high to lowif(encoder_B) {// B is high so clockwise// increase the brightness, dont go over 255if(brightness + fadeAmount <= 255) brightness += fadeAmount;}else {// B is low so counter-clockwise// decrease the brightness, dont go below 0if(brightness - fadeAmount >= 0) brightness -= fadeAmount;}}encoder_A_prev = encoder_A; // Store value of A for next time// set the brightness of pin 9:analogWrite(9, brightness);loopTime = currentTime; // Updates loopTime}// Other processing can be done here}MCP DAC Sketch (http://hacking.majenko.co.uk/MCPDAC)Code:// MCPDAC relies on SPI.#include <SPI.h>#include <MCPDAC.h>void setup(){// CS on pin 10, no LDAC pin (tie it to ground).MCPDAC.begin(10);// Set the gain to "HIGH" mode - 0 to 4096mV.MCPDAC.setGain(CHANNEL_A,GAIN_HIGH);// Do not shut down channel A, but shut down channel B.MCPDAC.shutdown(CHANNEL_A,false);MCPDAC.shutdown(CHANNEL_B,true);}void loop(){static unsigned int volts;// Set the voltage of channel A.MCPDAC.setVoltage(CHANNEL_A,volts&0x0fff);// Increase the voltage in steps of 100mV.volts+=100;}

author: dannyf
author_rank: Super Contributor
timestamp: March 08, 2014, 02:11:15 pm
content: 1) write a set of libraries for encoder / mcp4812 - you need both .h and .c/.cpp files.2) in your project, include them (use the multi-tab function of the incredibly challenged Arduino ide).3) you should think about if the encoder routines should run from an isr or not.

author: awallin
author_rank: Frequent Contributor
timestamp: March 08, 2014, 02:48:07 pm
content: Here's what I'm using for an encoder with Arduino Due:https://github.com/aewallin/Arduino-DDS/blob/master/ddscontrol/encoderlib.hsorry it's not that well documented - try reading the code and experimenting with minimal examples.I'd suggest you get your two devices (encoder and DAC) working separately first - after that get them to interact.AW

author: Instro_Spark
author_rank: Contributor
timestamp: March 08, 2014, 03:18:06 pm
content: Cheers for that mate yeah I've actually got the two different sketches working perfectly i was able to use the encoder to output a pwm 0-5v signal which i filtered. i was also able to get the DAC to communicate and output a ramp waveform which i verified with a scope. Im just trying to send the signal from the encoder to the DAC which i have no idea how to do

author: dannyf
author_rank: Super Contributor
timestamp: March 08, 2014, 04:37:49 pm
content: QuoteThat's the risk of flattening the learning curve: you get to program a mcu without learning anything about it -> in the end, you really learn nothing about it.Pretty much your code.Code:// MCPDAC relies on SPI.#include <SPI.h>#include <MCPDAC.h>//initialize mcp4822, channel avoid mcp4822a_setup(void){// CS on pin 10, no LDAC pin (tie it to ground).MCPDAC.begin(10);// Set the gain to "HIGH" mode - 0 to 4096mV.MCPDAC.setGain(CHANNEL_A,GAIN_HIGH);// Do not shut down channel A, but shut down channel B.MCPDAC.shutdown(CHANNEL_A,false);MCPDAC.shutdown(CHANNEL_B,true);}//output on mcp4822, channel avoid mcp4822a_output(unsigned short volts){static unsigned int volts;// Set the voltage of channel A.MCPDAC.setVoltage(CHANNEL_A,volts&0x0fff);// Increase the voltage in steps of 100mV.volts+=100;}// Rotary Encoder Example//int brightness = 0; // how bright the LED is, start at half brightnessint fadeAmount = 5; // how many points to fade the LED byunsigned long currentTime;unsigned long loopTime;const int pin_A = 7;const int pin_B = 6;unsigned char encoder_A;unsigned char encoder_B;unsigned char encoder_A_prev=0;//set up the encodervoid encoder_setup() {// declare pin 9 to be an output:pinMode(9, OUTPUT);pinMode(pin_A, INPUT);pinMode(pin_B, INPUT);currentTime = millis();loopTime = currentTime;}unsigned char encoder_read(void) {static unsigned char brightness=0; //encoder count// get the current elapsed timecurrentTime = millis();if(currentTime >= (loopTime + 2.5)){// 5ms since last check of encoder = 200Hzencoder_A = digitalRead(pin_A); // Read encoder pinsencoder_B = digitalRead(pin_B);if((!encoder_A) && (encoder_A_prev)){// A has gone from high to lowif(encoder_B) {// B is high so clockwise// increase the brightness, dont go over 255if(brightness + fadeAmount <= 255) brightness += fadeAmount;}else {// B is low so counter-clockwise// decrease the brightness, dont go below 0if(brightness - fadeAmount >= 0) brightness -= fadeAmount;}}encoder_A_prev = encoder_A; // Store value of A for next time// set the brightness of pin 9://analogWrite(9, brightness);loopTime = currentTime; // Updates loopTime}// Other processing can be done herereturn brightness;}void setup(void) {encoder_setup(); //set up the encodermcp4822a_setup(); //set up mcp4822, ch a}void loop(void) {mcp4822a_output(encoder_read()); //output encoder output on mcp4822, ch a}Code not verified so use it at your own risk.The code is poorly written and poorly structured and I would not suggest you use it.

author: Pack34
author_rank: Frequent Contributor
timestamp: March 09, 2014, 04:10:09 pm
content: What's your CPR and expected rpm for that encoder? If you're attempting to directly monitor the encoder output then you're going to be missing counts when your mcu is processing other code, especially during time consuming portions such as prints and general com work. I'd suggest looking at a buffer if accuracy is important.http://www.superdroidrobots.com/shop/item.aspx/dual-ls7366r-quadrature-encoder-buffer-breakout-board/1523/

author: dannyf
author_rank: Super Contributor
timestamp: March 09, 2014, 06:34:38 pm
content: QuoteOr interrupts. But the arduino crowd is for some reason quite fearful of interrupts.

author: Pack34
author_rank: Frequent Contributor
timestamp: March 09, 2014, 06:39:05 pm
content: Quote from: dannyf on March 09, 2014, 06:34:38 pmInterrupts work, when they aren't disabled. Doing any type of COM work will throw a wrench in it. Especially if you're doing anything slower than a 115200 baud rate.

author: dannyf
author_rank: Super Contributor
timestamp: March 09, 2014, 07:32:26 pm
content: QuoteBecause Arduino's serial transmission isn't worth the paper it is coded on.