Author Topic: Rotory Encoder + MCP4812  (Read 4544 times)

0 Members and 1 Guest are viewing this topic.

Offline Instro_SparkTopic starter

  • Contributor
  • Posts: 13
  • Country: au
  • Love the Smell Of Solder In The Morning
Rotory Encoder + MCP4812
« on: March 08, 2014, 02:04:16 pm »
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.


Code: [Select]
// Rotary Encoder Example


int brightness = 0;    // how bright the LED is, start at half brightness
int fadeAmount = 5;    // how many points to fade the LED by
unsigned 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 time
  currentTime = millis();
  if(currentTime >= (loopTime + 2.5)){
    // 5ms since last check of encoder = 200Hz 
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low
      if(encoder_B) {
        // B is high so clockwise
        // increase the brightness, dont go over 255
        if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
      }   
      else {
        // B is low so counter-clockwise     
        // decrease the brightness, dont go below 0
        if(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
                           
}


Code: [Select]
// 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;
}
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Rotory Encoder + MCP4812
« Reply #1 on: March 08, 2014, 02:11:15 pm »
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.
================================
https://dannyelectronics.wordpress.com/
 

Offline awallin

  • Frequent Contributor
  • **
  • Posts: 694
Re: Rotory Encoder + MCP4812
« Reply #2 on: March 08, 2014, 02:48:07 pm »
Here's what I'm using for an encoder with Arduino Due:
https://github.com/aewallin/Arduino-DDS/blob/master/ddscontrol/encoderlib.h

sorry 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
 

Offline Instro_SparkTopic starter

  • Contributor
  • Posts: 13
  • Country: au
  • Love the Smell Of Solder In The Morning
Re: Rotory Encoder + MCP4812
« Reply #3 on: March 08, 2014, 03:18:06 pm »
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
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Rotory Encoder + MCP4812
« Reply #4 on: March 08, 2014, 04:37:49 pm »
Quote
which i have no idea how to do

That'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: [Select]
// MCPDAC relies on SPI.
#include <SPI.h>
#include <MCPDAC.h>

//initialize mcp4822, channel a
void 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 a
void 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 brightness
int fadeAmount = 5;    // how many points to fade the LED by
unsigned 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 encoder
void 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 time
  currentTime = millis();
  if(currentTime >= (loopTime + 2.5)){
    // 5ms since last check of encoder = 200Hz 
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low
      if(encoder_B) {
        // B is high so clockwise
        // increase the brightness, dont go over 255
        if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
      }   
      else {
        // B is low so counter-clockwise     
        // decrease the brightness, dont go below 0
        if(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
     
  return brightness;                     
}

void setup(void) {
  encoder_setup(); //set up the encoder
  mcp4822a_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.
================================
https://dannyelectronics.wordpress.com/
 

Offline Pack34

  • Frequent Contributor
  • **
  • Posts: 753
Re: Rotory Encoder + MCP4812
« Reply #5 on: March 09, 2014, 04:10:09 pm »
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/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Rotory Encoder + MCP4812
« Reply #6 on: March 09, 2014, 06:34:38 pm »
Quote
I'd suggest looking at a buffer if accuracy is important.

Or interrupts. But the arduino crowd is for some reason quite fearful of interrupts.
================================
https://dannyelectronics.wordpress.com/
 

Offline Pack34

  • Frequent Contributor
  • **
  • Posts: 753
Re: Rotory Encoder + MCP4812
« Reply #7 on: March 09, 2014, 06:39:05 pm »
Quote
I'd suggest looking at a buffer if accuracy is important.

Or interrupts. But the arduino crowd is for some reason quite fearful of interrupts.

Interrupts 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.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Rotory Encoder + MCP4812
« Reply #8 on: March 09, 2014, 07:32:26 pm »
Quote
Doing any type of COM work will throw a wrench in it.

Because Arduino's serial transmission isn't worth the paper it is coded on.


================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf