Shop OBEX P1 Docs P2 Docs Learn Events
SimpleIDE C sample code for ADC MCP3204? — Parallax Forums

SimpleIDE C sample code for ADC MCP3204?

dougmdougm Posts: 11
edited 2014-12-22 06:51 in General Discussion
Not wanting to reinvent the wheel if possible, does anyone have some sample C code to drive this chip ?

I'm converting my project from SPIN to SimpleIDE.

Thanks,

DougM

Comments

  • pmrobertpmrobert Posts: 673
    edited 2014-10-03 12:24
    http://forums.parallax.com/showthread.php/141893-SPI-amp-MCP3208-in-C has code that should work for you, possibly with some minor changes. Check the datasheets - I think both the 04 and 08 use the same number of returned bits but I'm definitely not sure.
  • dougmdougm Posts: 11
    edited 2014-10-03 13:04
    Thanks Robert, that thread looks to contain everything I'll need.

    DougM
  • dougmdougm Posts: 11
    edited 2014-10-07 10:24
    Ok, this is totally AmosSam's stuff but I modified it to run in the current iteration of SIDE and also because my DI and DO pins aren't tied together.

    Posting for reference, but suggestions and modifications are welcome,

    DougM


    /*
    * mcp3208.c
    *
    * Created on: Oct 07, 2014
    * Author: DougM
    * Based on work by: AmosSam
    */
    #include "simpletools.h" // Include simple tools
    // #include <propeller.h>


    #define ADC_cs 24
    #define ADC_clk 27
    #define ADC_do 26
    #define ADC_di 25

    // function protos
    void pinPulseHL(int pin, int d, int d1);
    void pinPulseLH(int pin, int d, int d1);
    int readADC(int channel, int din, int dout, int clk, int cs);
    int readADCAverage(int channel, int din, int dout, int clk, int cs, int samples);

    // party time
    int main()
    {
    int ADCVal;
    ADCVal = 0;

    while(1)
    {

    // readADC(channel, di, do, clk, cs);
    // ADCVal = readADC(1, ADC_di, ADC_do, ADC_clk, ADC_cs);
    // readADCAverage(int channel, int din, dout, int clk, int cs, int samples)
    ADCVal = readADCAverage(1, ADC_di, ADC_do, ADC_clk, ADC_cs, 10);

    printf("ADCVal = %d\r", ADCVal);
    pause(500);
    }
    }

    /**
    * @brief sets pin, int pin, state to high, delays specified time, int d,
    * and then puts pin low, and delays specified time, int d1
    */
    void pinPulseHL(int pin, int d, int d1)
    {
    high(pin);
    if (d > 10)
    usleep(d);
    low(pin);
    if (d1 > 10)
    usleep(d1);
    }

    /**
    * @brief sets pin, int pin, state to low, delays specified time, int d,
    * and then puts pin high, and delays specified time, int d1
    */
    void pinPulseLH(int pin, int d, int d1)
    {
    high(pin);
    if (d > 10)
    usleep(d);
    low(pin);
    if (d1 > 10)
    usleep(d1);
    }

    /**
    * @brief Reads value from mcp3208/mcp3204 ADC
    * @details This function reads data from mcp3208/mcp3204 ADC
    * over SPI.
    *
    * @param channel What channel to read? 0 - 7
    * @param din Pin number on which DIN is connected
    * @param dout Pin number on which DOUT is connected
    * @param clk Pin number on which CLK is connected
    * @param cs Pin number on which CS is connected
    * @returns Value read from mcp3208/mcp3204 ADC
    */
    int readADC(int channel, int din, int dout, int clk, int cs)
    {
    int i;
    int AdcResult;
    int setup;

    // In case pin was already been low, we put it high
    // so we can initiate communication after setting up pins
    high(cs);
    low(din);
    low(clk);
    low(cs); // Active chip select by setting pin low

    // Sending configuration to device
    setup = channel | 0b11000;
    for(i=0; i < 5;i++) {
    pinPulseHL(clk, 10, 0);
    if ((setup & 0b10000) == 0b10000)
    high(din);
    else
    low(din); // is MSB != 0
    setup <<= 1; // shift left
    usleep(10);
    }

    pinPulseHL(clk, 10, 10); //Empty clock, for sampling

    pinPulseHL(clk, 10, 10); //Device returns low, NULL bit, we ignore it...

    // read ADC result 12 bit
    AdcResult=0;
    for(i=0;i<12;i++) {
    // We are sending pulse, clock signal, to ADC, because on falling edge it will return data...
    pinPulseHL(clk, 10, 0);
    // Shifting bit to left, to make room for current one...
    AdcResult<<=1;
    AdcResult=AdcResult | (input(dout) & 0x01);
    usleep(10);
    }
    high(cs);
    return(AdcResult);
    }


    /**
    * @brief Reads specified number of values from mcp3208/mcp3204 ADC
    * @details This function reads specified number of times
    * data from mcp3208/mcp3204 ADC over SPI,
    *
    * @param channel What channel to read? 0 - 7
    * @param din Pin number on which DIN is connected
    * @param dout Pin number on which DOUT is connected
    * @param clk Pin number on which CLK is connected
    * @param cs Pin number on which CS is connected
    * @param samples Number of samples that will be gathered, and then taken average before it's returned
    * @returns Value read from mcp3208/mcp3204 ADC
    */
    int readADCAverage(int channel, int din, int dout, int clk, int cs, int samples)
    {
    int i, k = 0;

    for (i=0;i<samples;i++)
    k = k + readADC(channel, din, dout, clk, cs);
    return k/samples;
    }
  • DavidZemonDavidZemon Posts: 2,973
    edited 2014-12-22 06:51
    Sorry I missed this two months ago. I have a ready-made object for you in PropWare. Of course I'd encourage you to give the whole thing a try, but if you prefer to just grab the bare minimum, you'll need the following files from this folder in your SimpleIDE project:
    https://github.com/DavidZemon/PropWare/tree/release-2.0-nightly/PropWare

    PropWare.h
    PropWare_asm.h
    mcp3000.h
    spi.h
    spi.cpp
    spi_as.S

    You can see a sample usage of a MCP3004/8 here:
    https://github.com/DavidZemon/PropWare/blob/release-2.0-nightly/Examples/PropWare_MCP3000/MCP3000_Demo.cpp

    And all you'd need to change to use your MCP3204 would be line 39, which would read
    const PropWare::MCP3000::PartNumber PART_NUMBER = PropWare::MCP3000::MCP320x;
    
    for you.
Sign In or Register to comment.