Shop OBEX P1 Docs P2 Docs Learn Events
ADC0831 C code — Parallax Forums

ADC0831 C code

As mentioned in my other post, I also purchased an ADC0831 chip. I guess the first thing to address is, how do you hook this thing up to the FLiP chip. I looked in the Learn forum, and did not find any sources. I also noticed that the only code available is blocklyprop. I still cannot get my head around the idea of using blocklyprop.

Does anybody have a diagram for connecting the ADC0831 to a FLiP module? I guess I have to get the thing hooked up before I can proceed with developing some C code. Again, I am using SimpleIDE; I looked for a driver in the Libs folder, but not sure if the one that is in there is for accessing the ADC0831 chip.

Thanks

Ray

Comments

  • Ray,
    Try writing a short blockly program, then you can do a couple of things. Clicking "code" will show you the C code. You can check that to get the library name.
    You can also export the blockly to SimpleIDE.

    Tom
  • There is a connection diagram inside this file. Open with Propeller Tool (it uses the Parallax font). Since Spin doesn't have shiftout and shiftin I coded things manually -- it should be easy to port to C with built-in functions.
  • Having a tough time figuring out the adc0831 pin outs.

    I looked at the JonnyMac diagram, but I am not sure what to make of it.

    pin on the ADC0831:
    1 - CS, gets connected to pin 22 on the FLiP module.
    2 - ?
    3 - ?
    4 - GND, gets connected to the ground on the FLiP module.
    5 - VREF, ?? gets connected to the 5V on the FLiP module.
    6 - DO, gets connected to pin 21 on the FLiP module.
    7 - CLK, gets connected to pin 20 on the FLiP module.
    8 - ?

    I have a voltage divider breakout board which has an output pin for ground, and output pin for the new voltage. So, which pins on the ADC0831 get the input from the voltage divider breakout board? Can some point me in the right direction.

    I basically got spoiled using the Activity Board ADC setup, plug one wire into the GND and the other wire into the ADC socket, and mission accomplished.

    Ray
  • kwinnkwinn Posts: 8,697
    edited 2018-09-19 03:12
    Rsadeika wrote: »
    Having a tough time figuring out the adc0831 pin outs.

    I looked at the JonnyMac diagram, but I am not sure what to make of it.

    pin on the ADC0831:
    1 - CS, gets connected to pin 22 on the FLiP module.
    2 - ?
    3 - ?
    4 - GND, gets connected to the ground on the FLiP module.
    5 - VREF, ?? gets connected to the 5V on the FLiP module.
    6 - DO, gets connected to pin 21 on the FLiP module.
    7 - CLK, gets connected to pin 20 on the FLiP module.
    8 - ?

    I have a voltage divider breakout board which has an output pin for ground, and output pin for the new voltage. So, which pins on the ADC0831 get the input from the voltage divider breakout board? Can some point me in the right direction.

    I basically got spoiled using the Activity Board ADC setup, plug one wire into the GND and the other wire into the ADC socket, and mission accomplished.

    Ray

    2 - Connects to the voltage out from the breakout board you want to measure
    3 -Connects to the ground on the breakout board.
    4 - GND, gets connected to the ground on the FLiP module.
    5 - VREF, ?? gets connected to the 5V on the FLiP module.
    6 - DO, gets connected to pin 21 on the FLiP module.
    7 - CLK, gets connected to pin 20 on the FLiP module.
    8 - Either connects to the +5V USB supply from the Flip board or an external +5V supply.
  • kwinnkwinn Posts: 8,697
    Do keep in mind that the DO from the ADC0831 is 5V so you do need a current limiting resistor between the ADC and pin 21.
  • JonnyMacJonnyMac Posts: 9,103
    edited 2018-09-19 17:24
    I looked at the JonnyMac diagram, but I am not sure what to make of it.
    If you haven't downloaded the ADC0831 data sheet, that's the best place to start. Never count on a code library having all the answers.
  • Below is a C port of jm_0831.spin program. Again, this is a quick and dirty version, just to verify that something is happening.

    Now, the value that is being printed out, 184, in this case, is what? I have a voltage source of 8V. Should the value that is being shown really be 1.84, that would make sense seeing that it is being run through a voltage divider. Does anybody know if the 184 value is really a true voltage value that has to be manipulated, or is it something else.

    Ray
    /*
      adc0831_test.c
      September 20, 2018
      
      C port of jm_adc0831.spin code, Jon McPhalen.
      
    */
    #include "simpletools.h"
    
    /*
    1 - CS, gets connected to pin 22 on the FLiP module.
    2 - Connects to the voltage out from the breakout board
        you want to measure
    3 - Connects to the ground on the breakout board.
    4 - GND, gets connected to the ground on the FLiP module.
    5 - VREF, ?? gets connected to the 5V on the FLiP module.
    6 - DO, gets connected to pin 21 on the FLiP module.
    7 - CLK, gets connected to pin 20 on the FLiP module.
    8 - Either connects to the +5V USB supply from the 
        Flip board or an external +5V supply. 
    */
    
    #define US_005 (80000000 / 1000000 * 5)
    
    int cspin = 22;
    int clkpin = 21;
    int dataOutpin = 20;
    
    int cs,clk;
    int dataOut;
    
    void init(int cspin, int clkpin, int dataOutpin)
    {
      cs = cspin;
      high(cs);
      set_direction(cs,1);
      
      clk = clkpin;
      low(clk);
      set_direction(clk,1);
      
      dataOut = dataOutpin;
      set_direction(dataOut,0);
    }
    
    void cleanup()
    {
      set_direction(cs,0);
      set_direction(clk,0);
    }
    
    int readADC()
    {
      int level = 0;
    
      low(cs);
      pause_ticks(US_005);
      level = 0;
      
      for(int i = 0; i < 9; i++)
      {
        high(clk);
        pause_ticks(US_005);
        low(clk);
        pause_ticks(US_005);
        level = (level << 1) | get_state(dataOut);
      }
      high(cs);
      return(level & 0xFF);    
    }
    
    int scale(int raw, int minOut, int maxOut)
    {
      if((raw < 256) && (minOut < maxOut))
        return((raw * (maxOut - minOut)) / 255) + minOut;
      else
        return raw;
    }        
    
    int main()
    {
      // Add startup code here.
    
      init(22,21,20);  // 22 = dopin, 21 = clkpin, 20 = cspin
      print("Something: %d\n",readADC());
     
      while(1)
      {
        // Add main loop code here.
        
      }  
    }
    
  • You should be able to use the built-in shiftOut() and shiftIn() functions. Once the 1-to-1 port is working, I would suggest converting to built-in functions.
  • kwinnkwinn Posts: 8,697
    The "184" is a binary representation of the input voltage compared to the ADC reference voltage. If your Vref to the ADC0831 is +5V then the actual voltage input to the ADC would be 184x5/256=3.59V. How does that compare to the expected voltage from the voltage divider output with the 8V input.
  • I charged up the two li_ion batteries so I would be getting an 8V. The reading that I am getting now is 199.

    199*5/256=3.8867, not sure how this figures.

    What I did do, for a test, is ((199*.01)*4.0201). The 4.0201=(8/1.99). Not sure if I am making the numbers fit the solution, or I am completely wet on this one.


    Ray
  • I made some changes, and the result is shown below. I am getting 7976 code size, and I wondering what is driving up size of the code. Could it be the use of putFloatPrecision() command, aside from that, I am not sure what can be done to reduce the size.

    Ray
    /*
      adc0831_test.c
      September 20, 2018
      
      C port of jm_adc0831.spin code, Jon McPhalen.
      
    */
    #include "simpletools.h"
    
    /*
    1 - CS, gets connected to pin 22 on the FLiP module.
    2 - Connects to the voltage out from the breakout board
        you want to measure
    3 - Connects to the ground on the breakout board.
    4 - GND, gets connected to the ground on the FLiP module.
    5 - VREF, ?? gets connected to the 5V on the FLiP module.
    6 - DO, gets connected to pin 21 on the FLiP module.
    7 - CLK, gets connected to pin 20 on the FLiP module.
    8 - Either connects to the +5V USB supply from the 
        Flip board or an external +5V supply. 
    */
    
    #define US_005 (80000000 / 1000000 * 5)
    
    int cspin = 22;
    int clkpin = 21;
    int dataOutpin = 20;
    
    int cs,clk;
    int dataOut;
    
    void init(int cspin, int clkpin, int dataOutpin)
    {
      cs = cspin;
      high(cs);
      set_direction(cs,1);
      
      clk = clkpin;
      low(clk);
      set_direction(clk,1);
      
      dataOut = dataOutpin;
      set_direction(dataOut,0);
    }
    
    /*
    void cleanup()
    {
      set_direction(cs,0);
      set_direction(clk,0);
    }*/
    
    int readADC()
    {
      int level = 0;
    
      low(cs);
      pause_ticks(US_005);
      level = 0;
      
      for(int i = 0; i < 9; i++)
      {
        high(clk);
        pause_ticks(US_005);
        low(clk);
        pause_ticks(US_005);
        level = (level << 1) | get_state(dataOut);
      }
      high(cs);
      return(level & 0xFF);    
    }
    
    /*
    int scale(int raw, int minOut, int maxOut)
    {
      if((raw < 256) && (minOut < maxOut))
        return((raw * (maxOut - minOut)) / 255) + minOut;
      else
        return raw;
    } */       
    
    int main()
    {
      // Add startup code here.
    
      init(22,21,20);  // 22 = dopin, 21 = clkpin, 20 = cspin
      //print("Something: %d\n",readADC());
     
      while(1)
      {
        // Add main loop code here.
        float level1 = readADC();
        
        //print("Something: %d\n",readADC());
        putStr("Something: ");
        putFloatPrecision(((level1*.01)*4.01507),2,2);
        putStr("\n");
        //print("Smething: %.2f\n",((level1*.01)*4.01507));
       // print("Something: %.2f\n",(level1*.01));   
        pause(3000);
      }  
    }
    
  • kwinnkwinn Posts: 8,697
    edited 2018-09-21 00:11
    Sorry, my laptop seems to have gone mad.
  • kwinnkwinn Posts: 8,697
    Cancel
  • kwinnkwinn Posts: 8,697
    You can measure the input voltage and use the output number from the ADC to calculate a correction factor that gives the corrected voltage reading. This will correct for the voltage divider and Vref voltage. Best to avoid the need for floating point by doing all the calculations with integers. Not really all that hard to do either.

  • kwinnkwinn Posts: 8,697
    edited 2018-09-21 14:32
    Rsadeika wrote: »
    I charged up the two li_ion batteries so I would be getting an 8V. The reading that I am getting now is 199.

    199*5/256=3.8867, not sure how this figures.

    The problem with this formula is that it is not taking the voltage divider into account so that is the voltage out from the divider going in to the ADC. It also assumes that Vref is 5.00 volts, which is rarely the case when using a power supply as the reference. If you added in the voltage divider calculation (3.8867 * R1/(R1 + R2) and replaced the "5" in the initial calculation with the actual power supply voltage you would get a much more accurate result.

    What I did do, for a test, is ((199*.01)*4.0201). The 4.0201=(8/1.99). Not sure if I am making the numbers fit the solution, or I am completely wet on this one.


    Ray

    No, you are all dry on this one. Some variation of this method is what I have used to calibrate instruments for more years than I care to mention. Inputting a known accurate reference voltage is the best way to calibrate an ADC and any front end circuitry. Best to verify it using 3 to 5 voltages over the full range to verify linearity.

    Only suggestion I have is to do the calculations using integer math. That would result in 199 * 40201 = 7999999. Add 5000 to that for rounding and you get 8004999. Divide that by 1,000,000 and the result is 8.004999. Drop the last 4 digits to get 8.00 volts.

    An alternative would be to convert the 8004999 to ascii text, remove the last 4 digits, and insert the decimal point between the 8 and 0. Probably faster this way.


  • Thanks kwinn, I think I have a working C solution for the ADC8301.

    Ray
Sign In or Register to comment.