Shop OBEX P1 Docs P2 Docs Learn Events
Having fun with analog — Parallax Forums

Having fun with analog

I had a project that needed to read the voltage value from a device.

The P2 has this function but it not straight forward as using a voltmeter.

Each pin on the P2 has different calibration values so you need to determine what the low and high reading are. So, 0 volts and 3.3 volts have different value based on what pin you decide to use.

At first, I tried using a 5K pot to see how the values changed. Trying to set an exact voltage level on the pin is tedious at best.

I then remembered I had an AD5220 chip laying around somewhere if only I could remember where.

After finding it I wired it up and built a program to adjust the voltage programmatically from low to high and then some voltage I wanted to measure. I thought this was so neat that I had a board made so I could just plug this in and find the values of whatever pin I needed.

The AD5220 has 128 positions available and the only way to set it is start at the bottom or top and could each position. The newer variable resistor unit now use I2C or SPI to set what position you want but they are not bread board friendly.

By programming the AD5220 to a value I need to apply a voltage to a pin I can load a test program and test that voltage without having to touch a pot. Look ma no hands!

#include <stdio.h>
#include <propeller.h>
#include "smartpins.h"

void Check(void);
void Set(int, int);
int Status(void);


#define CK 22
#define CS 20
#define UD 21
#define POWER 36


int Low;
int High;
int Middle;
int Factor;
volatile int wait;


int main(int argc, char** argv)
{
    int i;
    int j;

    _pinh(CS);
    _pinl(CK);
    _pinl(UD);
    _pinl(CS);

    _pinstart(POWER, P_ADC | P_ADC_1X, 13, 0);

    printf("Starting\n");

    Check();

    printf("Low: %d, Middle: %d, High: %d\n", Low, Middle, High);

    Set(128, 0);

    Factor = (High - Low) * 10 / 33;

    printf("Per Volt Factor: %d\n", Factor);

    j = (High - Low) / 128;
    j = (Factor * 205) / j / 100; // ten amps = 2.5 + .4 / 2

    //j = 49;
    printf("Setting to 2V --> %d\n", j);

    Set(j, 1);

    _waitms(500);

    i = _rdpin(POWER) - Low;

    printf("Adjusted Reading: %d, %dV X 100\n", i, i * 100 / Factor);

    i = Status();

    printf("Read Time: %d useconds X 10\n", i);

    _pinh(CS);

    while (1)
    {
        _waitms(5000);
    }
}

void Check()
{
    int i;

    Set(128, 0);

    _waitms(500);
    Low = _rdpin(POWER);

    Set(128, 1);

    _waitms(500);
    High = _rdpin(POWER);

    Set(64, 0);

    _waitms(500);
    Middle = _rdpin(POWER);

}

void Set(int x, int ud)
{
    if (ud == 0)
        _pinl(UD);
    else
        _pinh(UD);

    _waitx(250);

    for (int i=0;i<x;i++)
    {
        _pinh(CK);
        _waitx(250);
        _pinl(CK);
        _waitx(250);
    }
}

int Status()
{
    int i;
    int useconds = 0;
    int v;
    int t;

    while (_pinr(POWER) == 0);

    for (i=0;i<10;i++)
    {
        t = _getus();
        while (_pinr(POWER) == 0);
        v = _rdpin(POWER);
        useconds += _getus() - t;
    }

    return useconds;
}

By running this program, it will give me the low, high and conversion factor for any given pin.

Mike

Sign In or Register to comment.