Shop OBEX P1 Docs P2 Docs Learn Events
DS2450 ADC 1-wire revisited — Parallax Forums

DS2450 ADC 1-wire revisited

I was in contact with Maxim Integrated through one of the company's application engineers based in Europe. The problem the software engineers were tasked to work on is the erroneous discussion of the setup of the DS2450 ADC for 5.1 volt and 16-bit conversion. Maxim Integrated in the US setup a DS2450 and successfully operated it in 5.1 and 16-bit mode using a C test program. Maxim USA told me through the applications engineer to have a software engineer look at the code and find out what bits need to be set in the table in their document "DS2450 1-Wire Quad A/D Converter" MEMORY MAP PAGE 1, CONTROL/STATUS DATA Figure 5b. They said that there is an instruction: ctrl = NO_OUTPUT | Bits_8; that needs to be changed to ctrl = NO_OUTPUT | Bits_16;

My software personnel cannot figure out how to relate the "C" instructions into the proper bits for the Figure 5b table.

I would appreciate it greatly if a sharp software engineer would look at the code provided by Maxim Integrated and provide the correct setup for the table. I am using the BS2p one-wire controller in my system and really need the full 5.1 and 16-bit capability offered by the DS2450 ADC. The device comes up in 2.55 volts and 8-bits.

//

// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//
//
//
// atodtst.c - Application for the DS2450 - 1-Wire Quad A/D Converter.
//
// This application uses the files from the 'Public Domain' MicroLAN
// libraries ('general' and 'userial').
//
// Version: 2.00
//

#include <stdio.h>
#include <stdlib.h>
#include "ownet.h"
#include "atod20.h"
#include "findtype.h"

// defines
#define MAXDEVICES 20

// global serial numbers
uchar FamilySN[MAXDEVICES][8];

//
// Main Test for the DS2450 - 1-Wire Quad A/D Converter
//
int main(int argc, char **argv)
{
char msg[45];
int NumDevices = 0;
int i = 0;
int start_address = 0x8;
int end_address = 0x11;
float prslt[4];
uchar ctrl[16];
int try_overdrive=0;
int portnum=0;

//
// Introduction header
printf("\n/
\n");
printf(" Channels A to D Application - V2.00\n"
" The following is a test to excersize a\n"
" DS2450 - 1-Wire Quad A/D Converter \n\n");

printf(" Press any CTRL-C to stop this program.\n\n");
printf(" Output [Serial Number(s) ... Channel 'A' Value ... Channel 'B' Value ... \n"
" ... Channel 'C' Value ... Channel 'D' Value] \n\n");

// check for required port name
if (argc != 2)
{
printf("1-Wire Net name required on command line!\n"
" (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
"(Linux DS2480),\"{1,5}\" (Win32 TMEX)\n");
exit(1);
}

// attempt to acquire the 1-Wire Net
if ((portnum = owAcquireEx(argv[1])) < 0)
{
OWERROR_DUMP(stdout);
exit(1);
}

// success
printf("Port opened: %s\n",argv[1]);

// Find the device(s)
NumDevices = FindDevices(portnum, &FamilySN[0], 0x20, MAXDEVICES);
if (NumDevices>0)
{
printf("\n");
printf("Device(s) Found: \n");

for (i = 0; i < NumDevices; i++)
{

PrintSerialNum(FamilySN);
printf("\n");

if (SetupAtoDControl(portnum, FamilySN, &ctrl[0], &msg[0]))
{
printf("A/D settings found\n %s\n", msg);
}
else
printf("\n\n\n ERROR, device set up unsuccessful!\n");


if (WriteAtoD(portnum, try_overdrive, FamilySN, &ctrl[0], start_address, end_address))
{
printf("\nA/D settings written");

}
else
printf("\n\n\n ERROR, device not found!\n");
}
}

// (stops on CTRL-C)
do
{
// read the current channels
for (i = 0; i < NumDevices; i++)
{
printf("\n\n");
PrintSerialNum(FamilySN);

if (!DoAtoDConversion(portnum, try_overdrive, FamilySN))
{
printf("\nError doing conversion, verify device present: %d\n",
(int)owVerify(portnum,FALSE));
}
if (ReadAtoDResults(portnum, try_overdrive, FamilySN, &prslt[0], &ctrl[0]))
{
int c = 0;
for (c = 0; c < 4; c++)
{
printf(" %1.3f ", prslt[c]);
}
}
else
{
printf("\nError reading channel, verify device present: %d\n",
(int)owVerify(portnum,FALSE));
}

}
}
while (!key_abort());

// release the 1-Wire Net
owRelease(portnum);
printf("Closing port %s.\n", argv[1]);
exit(0);

return 0;
}

Sincerely,

Discovery

Comments

  • Apparently, the whole code file did not append to the earlier file. I will try to append it again below.

    Sincerely,

    Discovery

    //
    // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the "Software"),
    // to deal in the Software without restriction, including without limitation
    // the rights to use, copy, modify, merge, publish, distribute, sublicense,
    // and/or sell copies of the Software, and to permit persons to whom the
    // Software is furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
    // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    // OTHER DEALINGS IN THE SOFTWARE.
    //
    // Except as contained in this notice, the name of Dallas Semiconductor
    // shall not be used except as stated in the Dallas Semiconductor
    // Branding Policy.
    //
    //
    // atod20.c - Module(s) to do conversion, setup, read, and write
    // on the DS2450 - 1-Wire Quad A/D Converter.
    //
    //
    // Version: 2.00
    //
    //
    //

    #include <stdio.h>
    #include "ownet.h"
    #include "atod20.h"

    //
    // Setup A to D control data. This is hardcoded to 5.12Volt scale at
    // 8 bits, but it could be read from a file.
    //
    // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
    // indicate the symbolic port number.
    // 'SerialNum' - Serial Number of device
    // 'ctrl' - pointer to conrtol data to set (fixed info for now)
    // 'msg' - poniter to string to return message
    //
    int SetupAtoDControl(int portnum, uchar *SerialNum, uchar *ctrl, char *msg)
    {
    uchar i;

    // set the device serial number to the DS2450 device
    owSerialNum(portnum,SerialNum,FALSE);

    // setup CONTROL register
    for (i = 0; i < 8; i += 2)
    {
    ctrl = NO_OUTPUT | BITS_8;
    ctrl[i + 1] = RANGE_512 | ALARM_HIGH_DISABLE | ALARM_LOW_DISABLE;
    }

    // setup ALARM register
    for (i = 8; i < 16; i++)
    ctrl = 0;

    // set return value
    sprintf(msg, "All channels set to 5.12V range at 8 bits");

    return TRUE;
    }

    //

    // Write A to D with provided buffer.
    //
    // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
    // indicate the symbolic port number.
    // 'try_overdrive' - True(1) if want to try to use overdrive
    // 'SerialNum' - Serial Number of device
    // 'ctrl' - pointer to conrtol data to write
    // 'start_address' - start address to write
    // 'end_address' - end of address to write
    //
    // Returns: TRUE, success, results read ok
    // FALSE, failure to read
    //
    int WriteAtoD(int portnum, int try_overdrive, uchar *SerialNum,
    uchar *ctrl, int start_address, int end_address)
    {
    uchar send_block[50];
    uchar i;
    short send_cnt=0;
    int address, flag;
    ushort lastcrc16;

    // build the first part of the packet to write
    // reset CRC
    setcrc16(portnum,0);
    send_cnt = 0;
    // write memory command
    send_block[send_cnt++] = 0x55;
    lastcrc16 = docrc16(portnum,0x55);
    // address
    send_block[send_cnt] = (uchar) (start_address & 0xFF);
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);
    send_block[send_cnt] = (uchar)((start_address >> 8) & 0xFF);
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);

    // set the device serial number to the DS2450 device
    owSerialNum(portnum,SerialNum,FALSE);

    // select the device
    if (Select(portnum,try_overdrive))
    {
    // loop to write each byte
    for (address = start_address; address <= end_address; address++)
    {
    // build the packet to write
    // init CRC on all but first pass
    if (address != start_address)
    setcrc16(portnum,(ushort)address);
    // data to write
    send_block[send_cnt] = ctrl[address - start_address];
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);
    // read CRC16
    send_block[send_cnt++] = 0xFF;
    send_block[send_cnt++] = 0xFF;
    // echo of byte
    send_block[send_cnt++] = 0xFF;

    // send the block
    flag = owBlock(portnum,FALSE, send_block, send_cnt);

    // check results of block
    if (flag == TRUE)
    {
    // perform crc16 on last 2 bytes
    for (i = (send_cnt - 3); i <= (send_cnt - 2); i++)
    lastcrc16 = docrc16(portnum,send_block);

    // verify crc16 is correct
    if ((lastcrc16 != 0xB001) ||
    (send_block[send_cnt-1] != ctrl[address - start_address]))
    return FALSE;
    }
    else
    return FALSE;

    // reset the packet
    setcrc16(portnum,0);
    send_cnt = 0;
    }
    }
    // no device
    else
    return FALSE;

    return TRUE;
    }

    //

    // Attempt to do an A to D conversion
    //
    // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
    // indicate the symbolic port number.
    // 'try_overdrive' - True(1) if want to try to use overdrive
    // 'SerialNum' - Serial Number of device
    //
    //
    // Returns: TRUE, success, conversion ok
    // FALSE, failure to do conversion
    //
    int DoAtoDConversion(int portnum, int try_overdrive, uchar *SerialNum)
    {
    uchar send_block[50];
    int i;
    short send_cnt=0;
    ushort lastcrc16;

    // set the device serial number to the DS2450 device
    owSerialNum(portnum,SerialNum,FALSE);

    // access the device
    if (Select(portnum,try_overdrive))
    {
    setcrc16(portnum,0);
    // create a block to send
    send_block[send_cnt] = 0x3C;
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);

    // input select mask (all channels)
    send_block[send_cnt] = 0x0F;
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);

    // read-out control
    send_block[send_cnt] = 0x00;
    lastcrc16 = docrc16(portnum,send_block[send_cnt++]);

    // read CRC16
    send_block[send_cnt++] = 0xFF;
    send_block[send_cnt++] = 0xFF;

    // now send the block
    if (owBlock(portnum,FALSE, send_block, (send_cnt)))
    {
    // check the CRC
    for (i = send_cnt - 2; i < (send_cnt); i++)
    lastcrc16 = docrc16(portnum,send_block);

    // verify CRC16 is correct
    if (lastcrc16 != 0xB001)
    {
    OWERROR(OWERROR_CRC_FAILED);
    return FALSE;
    }

    // if success then apply the strong pullup
    if(!owWriteBytePower(portnum,((send_cnt-1) & 0x1F)))
    return FALSE;
    // delay the max time, 6ms
    msDelay(6);
    // set the pullup back to normal
    if(MODE_NORMAL != owLevel(portnum,MODE_NORMAL))
    {
    OWERROR(OWERROR_LEVEL_FAILED);
    return FALSE;
    }

    // check conversion over
    if (owReadByte(portnum) == 0xFF)
    return TRUE;
    }
    }

    return FALSE;
    }

    //

    // Read A to D results
    //
    // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
    // indicate the symbolic port number.
    // 'try_overdrive' - True(1) if want to try to use overdrive
    // 'SerialNum' - Serial Number of device
    // 'prslt' - pointer to array of 4 floats to return voltage results
    // 'ctrl' - pointer to conrtol data for reference when calculating
    // results.
    //
    // Returns: TRUE, success, results read ok
    // FALSE, failure to read
    //
    int ReadAtoDResults(int portnum, int try_overdrive, uchar *SerialNum,
    float *prslt, uchar *ctrl)
    {
    uchar i, send_cnt=0;
    ulong templong;
    uchar rt=FALSE;
    uchar send_block[30];
    ushort lastcrc16;

    setcrc16(portnum,0);

    // set the device serial number to the DS2450 device
    owSerialNum(portnum,SerialNum,FALSE);

    // access the device
    if (Select(portnum,try_overdrive))
    {
    // create a block to send that reads the DS2450
    send_block[send_cnt++] = 0xAA;
    lastcrc16 = docrc16(portnum,0xAA);

    // address block
    send_block[send_cnt++] = 0x00;
    send_block[send_cnt++] = 0x00;
    lastcrc16 = docrc16(portnum,0x00);
    lastcrc16 = docrc16(portnum,0x00);

    // read the bytes
    for (i = 0; i < 10; i++)
    send_block[send_cnt++] = 0xFF;

    // send the block
    if (owBlock(portnum,FALSE, send_block, send_cnt))
    {
    // perform CRC16
    for (i = send_cnt - 10; i < send_cnt; i++)
    lastcrc16 = docrc16(portnum,send_block);

    // verify CRC16 is correct
    if (lastcrc16 == 0xB001)
    {
    // success
    rt = TRUE;
    }

    }

    // verify read ok
    if (rt == TRUE)
    {
    // convert the value read to floats
    for (i = 3; i < 11; i += 2) // (1.01)
    {
    templong = ((send_block[i + 1] << 8) | send_block) & 0x0000FFFF;
    prslt[(i - 3) / 2] = (float)((float)(templong / 65535.0) *
    ((ctrl[(i - 3) + 1] & 0x01) ? 5.12 : 2.56)); // (1.01)
    }
    }
    }

    return rt;
    }

    //

    // Select the current device and attempt overdrive if possible.
    //
    // 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
    // indicate the symbolic port number.
    //
    // 'try_overdrive' - True(1) if want to try to use overdrive
    //
    // Returns: TRUE(1) current device selected
    // FALSE(0) device not present
    //
    int Select(int portnum, int try_overdrive)
    {
    static uchar current_speed = MODE_NORMAL;

    // attempt to do overdrive
    if (try_overdrive)
    {
    // verify device is in overdrive
    if (current_speed == MODE_OVERDRIVE)
    {
    if (owAccess(portnum))
    return TRUE;
    }

    if (owOverdriveAccess(portnum))
    current_speed = MODE_OVERDRIVE;
    else
    current_speed = MODE_NORMAL;
    }

    return (owAccess(portnum));
    }
  • Your question was put in the Basic Stamp forum and the code you provided is in C. None of the Basic Stamps support C and only a few models of the Basic Stamp support 1-Wire devices, specifically the BS2p, BS2pe, and BS2px models.

    Are you interested in using the DS2450 with one of these Basic Stamp models or are you interested in using the DS2450 with a Propeller which supports both C and 1-Wire devices? If the latter, this post needs to be moved to the Propeller 1 forum.
  • For each channel, the first byte should be $00, and the second byte should be $8D (or $81 if you don't want to enable alarms). The explanation of the bits in the control bytes is on page 4 & 5 of the datasheet.
  • kwinnkwinn Posts: 8,697
    Mike Green wrote: »
    Your question was put in the Basic Stamp forum and the code you provided is in C. None of the Basic Stamps support C and only a few models of the Basic Stamp support 1-Wire devices, specifically the BS2p, BS2pe, and BS2px models.

    Are you interested in using the DS2450 with one of these Basic Stamp models or are you interested in using the DS2450 with a Propeller which supports both C and 1-Wire devices? If the latter, this post needs to be moved to the Propeller 1 forum.

    The C code was provided by Maxim Integrated so I suspect he is trying to figure out what commands/data he needs to send from a Basic Stamp to the DS2450 to set up and read from it based on the C code.
  • Thank you Kwinn,

    My systems run pBasic code on BS2p controllers over the DS one-wire to many devices including several DS2450s. In all cases I am hamstrung with only 2.55 volts input range working with sensors that output 5 volts max range.

    The brilliant people at Maxim Integrated setup the DS2450 using the C code I posted and they told me that any good software engineer would be able to look at the code and figure out the correct bits to put into the control table of the Data Sheet for the DS2450.

    I am not a good enough software engineer to do that trick.

    Is anyone?

    Discovery
  • Did the people at Maxim provide the .h files? I am interested in atod20.h in particular.
  • Hi Tom,

    Yes they did. I responded that I was not able to figure out how to generate the setup in the DS2450 Controls and Status table from the atod20.h file to make the ADC into a 5.1 volt input and 16-bit conversion device. I got a response back from Maxim through their stool pigeon in Europe showing a screen shot of the DS2450 memory bits and another screen shot of the traces of a digital signal analyzer. They also included, as a download, the software for running their Digital Signal Analyzer but the software download messed up my computer and thus could not be used. It is becoming clear that Maxim cannot solve the problem.

    Discovery
Sign In or Register to comment.