subash
Posts: 3
Joined: Thu Aug 14, 2014 6:52 am

ADS1115 interface with raspberry pi in Matlab

Thu Aug 14, 2014 6:59 am

Hi,
I am beginner to raspberry pi, I am trying to interface ADS1115 to raspberry pi using Matlab. The code is very simple as follows,

clear all;
mypi = raspi
mypi.AvailableI2CBuses
i2cadc = i2cdev(mypi,'i2c-1','0x48')
act_val=0;
for i= 1:1:1000
writeRegister(i2cadc,1,hex2dec('C3E3'),'uint16'); %single shot
while (value ~= 50147)
[value]=readRegister(i2cadc,1,'uint16');
end
[value1]=readRegister(i2cadc,0,'int16');
act_val1(i)=value1;
act_val(i)=(value1*4.096)/32767.0;
end
figure;plot(act_val1);
figure;plot(act_val);

In this code i am trying to acquire the data from A0 channel of ADS1115 at 860sps in a single shot mode, hence for every iteration the config register will configured and conversion register will be read. the connections between the raspberry pi and ADS1115 are intact and correct. With the following code, I am getting only noise rather than the input sinusoidal signal of 50 Hz. Kindly let me know what is the issue with this code.

murat_belge
Posts: 27
Joined: Fri Feb 14, 2014 6:18 pm

Re: ADS1115 interface with raspberry pi in Matlab

Fri Sep 05, 2014 4:59 pm

Here is a MATLAB class for ADS1115 ADC:

Code: Select all

classdef ads1115 < handle & matlab.mixin.CustomDisplay
    %ADS1115 Analog-to-Digital converter.
    %
    % adc = ads1115(rpi, bus) creates a ADS1115 ADC object attached to the
    % specified I2C bus. The first parameter, rpi, is a raspi object. The
    % I2C address of the ADS1115 ADC defaults to '0x48'.
    %
    % adc = ads1115(rpi, bus, address) creates a ADS1115 ADC object
    % attached to the specified I2C bus and I2C address. Use this form if
    % you used the ADDR pin to change the I2C address of the ADS1115 from
    % the default '0x48' to something else.
    %
    % readVoltage(adc, AINp) reads the single-ended voltage measurement
    % from AINp input port. 
    %
    % readVoltage(adc, AINp, AINn) reads the differential voltage
    % measurement between AINp and AINn input ports.
    %
    % The OperatingMode property of the ADS1115 ADC object determines power
    % consumption, speed and accuracy. The default OperatingMode is
    % 'single-shot' meaning that the ADS1115 performs a single analog to
    % digital conversion upon request and goes to power save mode. In
    % continuous mode, the device performs continuous conversions.
    %
    % The SamplesPerSecond property sets the conversion rate. 
    %
    % The VoltageScale property of the ADS1115 ADC object determines the
    % setting of the Programmable Gain Amplifier (PGA) value applied before
    % analog to digital conversion. See table below to correlate the
    % input voltage scale with the PGA value:
    %
    % VoltageScale | PGA Value 
    % -------------------------
    %    6.144  |    2/3
    %    4.096  |    1
    %    2.048  |    2  
    %    1.024  |    4   
    %    0.512  |    8   
    %    0.256  |    16   
    %
    % <a href="http://www.ti.com/lit/gpn/ads1115">Device Datasheet</a>
    %
    % NOTE: Do not apply voltages excedding VDD+0.3V to any input pin.
    
    % Copyright 2014 The MathWorks, Inc.
    
    properties (SetAccess = private, GetAccess = public)
        Address = bin2dec('1001000') % Default address 0x48
    end
    
    properties (Access = public)
        OperatingMode
        VoltageScale    
        SamplesPerSecond
    end
    
    properties (Access = private)
        i2cObj
        PGAbits
        AINp
        AINn
        NumInputs = 4
        ConfigReg
    end
    
    properties (Constant, Hidden)
        AvailableSamplesPerSecond = [8, 16, 32, 64, 128, 250, 475, 860]
        AvailableVoltageScale = [6.144, 4.096, 2.048, 1.024, 0.512, 0.256]
        AvailableOperatingMode = {'single-shot', 'continuous'}
    end
    
    properties (Constant, Access = private)
        % Register addresses
        CONVERSION_REG = 0
        CONFIG_REG     = 1
        LOTHRESH_REG   = 2
        HITHRESH_REG   = 3
        
        % Config register bit shifts
        CONFIG_OS_SHIFT        = 15
        CONFIG_MUX_SHIFT       = 12
        CONFIG_PGA_SHIFT       = 9
        CONFIG_MODE_SHIFT      = 8
        CONFIG_DR_SHIFT        = 5
        CONFIG_COMP_MODE_SHIFT = 4
        CONFIG_COMP_POL_SHIFT  = 3
        CONFIG_COMP_LAT_SHIFT  = 2
        CONFIG_COMP_QUE_SHIFT  = 0
        
        % Full scale for ADS1115 is 4.096 volts
        FS_VOLTAGE = 4.096
        
        % 16-bit ADC result needs to be scaled by this value
        ADC_SCALAR = 2^15 - 1
    end
    
    methods
        function obj = ads1115(raspiObj, bus, address)
            % Set I2C address if not using default
            if nargin > 2
                obj.Address = address;
            end
            
            % Set defaults
            obj.SamplesPerSecond = 128;
            obj.OperatingMode = 'single-shot';
            obj.VoltageScale = 2.048;
            
            % Initialize config register value
            obj.ConfigReg = 0;
            
            % Create an i2cdev object to talk to ADS1115
            obj.i2cObj = i2cdev(raspiObj, bus, obj.Address);
        end
        
        function voltage = readVoltage(obj, AINp, AINn)
            % voltage = readVoltage(obj, AINp) reads the single-ended input
            % voltage value at channe AINp.
            %
            % voltage = readVoltage(obj, AINp, AINn) reads the input
            % voltage value that is the difference between AINp and AINn.
            validateattributes(AINp, {'numeric'}, ...
                {'scalar', '>=', 0, '<=', obj.NumInputs-1}, '', 'AINp');
            if nargin > 2
                validateattributes(AINn, {'numeric'}, ...
                    {'scalar', '>=', 0, '<=', obj.NumInputs-1}, '', 'AINn');
            else
                AINn = -1;
            end
 
            % Configure ADC and read requested conversion value
            configReg = getConfigReg(obj, AINp, AINn);
            if isequal(obj.OperatingMode, 'single-shot') || ...
                    (configReg ~= obj.ConfigReg)
                obj.ConfigReg = configReg;
                configureDevice(obj);
            end
            
            % Each I2C transaction with raspi object takes about 5ms. If
            % conversion time is greater than this we must wait
            if isequal(obj.OperatingMode, 'single-shot') && ...
                    (1/obj.SamplesPerSecond > 0.005)
                pause(1/obj.SamplesPerSecond);
            end
            
            % Read raw ADC conversion value and convert to voltage
            data = readRegister(obj.i2cObj, obj.CONVERSION_REG, 'int16'); 
            voltage = double(swapbytes(data)) * (obj.VoltageScale) / obj.ADC_SCALAR;
        end
    end
    
    methods
        function set.Address(obj, value)
            if isnumeric(value)
                validateattributes(value, {'numeric'}, ...
                    {'scalar', 'nonnegative'}, '', 'Address');
            else
                validateattributes(value, {'char'}, ...
                    {'nonempty'}, '', 'Address');
                value = obj.hex2dec(value);
            end
            if (value < obj.hex2dec('0x48')) || (value > obj.hex2dec('0x51'))
                error('raspi:ads1115:InvalidI2CAddress', ...
                    'Invalid I2C address. I2C address must be one of the following: 0x48, 0x49, 0x50, 0x51');
            end
            obj.Address = value;
        end
        
        function set.SamplesPerSecond(obj, value)
            validateattributes(value, {'numeric'}, ...
                {'scalar', 'nonnan', 'finite'}, '', 'SamplesPerSecond');
            if ~ismember(value, obj.AvailableSamplesPerSecond)
                error('raspi:ads1115:InvalidSamplesPerSecond', ...
                    'SamplesPerSecond must be one of the following: %d', ...
                    obj.AvailableSamplesPerSecond);
            end
            obj.SamplesPerSecond = value;
        end
        
        function set.VoltageScale(obj, value)
            validateattributes(value, {'numeric'}, ...
                {'scalar', 'nonnan', 'finite'}, '', 'VoltageScale');
            if ~ismember(value, obj.AvailableVoltageScale)
                error('raspi:ads1115:InvalidVoltageScale', ...
                    'VoltageScale must be one of the following: %d', ...
                    obj.AvailableVoltageScale);
            end
            obj.VoltageScale = value;
            switch obj.VoltageScale
                case 6.144, 
                    obj.PGAbits = 0; %#ok<*MCSUP>
                case 4.096, 
                    obj.PGAbits = 1; 
                case 2.048, 
                    obj.PGAbits = 2;
                case 1.024, 
                    obj.PGAbits = 3;
                case 0.512, 
                    obj.PGAbits = 4;
                case 0.256
                    obj.PGAbits = 5;
            end
        end
        
        function set.OperatingMode(obj, value)
            value = validatestring(value, obj.AvailableOperatingMode);
            obj.OperatingMode = value;
        end
    end
    
    methods (Access = protected)
        function displayScalarObject(obj)
            header = getHeader(obj);
            disp(header);
            
            % Display main options
            fprintf('                Address: %-15s\n', ['0x' dec2hex(obj.Address)]);
            fprintf('          OperatingMode: %-15s (''single-shot'' or ''continuous'')\n', ...
                obj.OperatingMode);
            fprintf('       SamplesPerSecond: %-15d (8, 16, 32, 64, 128, 250, 475, or 860)\n', ...
                obj.SamplesPerSecond);
            fprintf('           VoltageScale: %-15.3f (6.144, 4.096, 2.048, 1.024, 0.512, or 0.256)\n', ...
                obj.VoltageScale);
            fprintf('\n');
            
            % Allow for the possibility of a footer.
            footer = getFooter(obj);
            if ~isempty(footer)
                disp(footer);
            end
        end
        
        function configReg = getConfigReg(obj, AINp, AINn)
            % Disable comparator
            configReg = bitshift(bin2dec('11'), obj.CONFIG_COMP_QUE_SHIFT);
            
            % Set samples per second bits DR[2:0]
            switch obj.SamplesPerSecond
                case 8
                    DRbits = 0;
                case 16
                    DRbits = 1;
                case 32
                    DRbits = 2;
                case 64
                    DRbits = 3;
                case 128
                    DRbits = 4;
                case 250
                    DRbits = 5;
                case 475 
                    DRbits = 6;
                case 860
                    DRbits = 7;
            end
            configReg = bitor(configReg, bitshift(DRbits, obj.CONFIG_DR_SHIFT));
            
            % Set operating mode bits MODE[8]
            if isequal(obj.OperatingMode, 'single-shot')
                MODEbits = 1;
                configReg = bitor(configReg, bitshift(MODEbits, obj.CONFIG_MODE_SHIFT));
                configReg = bitor(configReg, bitshift(1, obj.CONFIG_OS_SHIFT));
            end
            
            % Set PGA bits PGA[2:0]
            configReg = bitor(configReg, bitshift(obj.PGAbits, obj.CONFIG_PGA_SHIFT));
            
            % Set MUX bits MUX[2:0]
            if AINn == -1
                switch AINp
                    case 0,
                        MUXbits = bin2dec('100');
                    case 1,
                        MUXbits = bin2dec('101');
                    case 2,
                        MUXbits = bin2dec('110');
                    case 3,
                        MUXbits = bin2dec('111');
                end
            else
                if (AINp == 0) && (AINn == 1)
                    MUXbits = 0;
                elseif (AINp == 0) && (AINn == 3)
                    MUXbits = 1;
                elseif (AINp == 1) && (AINn == 3)
                    MUXbits = 2;
                elseif (AINp == 2) && (AINn == 3)
                    MUXbits = 3;
                else
                    error('raspi:ads1115:InvalidAIN', ...
                        ['Invalid (AINp, AINn) pair for differential voltage measurement. ', ...
                        'Supported (AINp, AINn) values are: (0, 1), (0, 3), (1, 3), (2, 3).']);
                end
            end
            configReg = bitor(configReg, bitshift(MUXbits, obj.CONFIG_MUX_SHIFT));   
        end
    end
    
    methods (Access = private)
        function configureDevice(obj)
            obj.i2cObj.writeRegister(obj.CONFIG_REG, ...
                swapbytes(uint16(obj.ConfigReg)), 'uint16');
        end
        
        function reg = readConfigReg(obj)
            reg = swapbytes(readRegister(obj.i2cObj, obj.CONFIG_REG, 'uint16'));
        end
    end
    
    methods (Static)
        function decvalue = hex2dec(hexvalue)
            decvalue = hex2dec(regexprep(hexvalue, '0x', ''));
        end
        
        function hexvalue = dec2hex(decvalue)
            hexvalue = sprintf('0x%02s', dec2hex(decvalue));
        end
    end
end
To use the ads1115 class, copy the code provided above and save it to a file called "ads1115.m". I tested the implementation using ADAFRUIT break-out board for ADS1115. Here is how you use it:

Assuming ADS1115 is connected to R-Pi, check to see if R-Pi sees the device on the I2C bus. On the MATLAB command line:

Code: Select all

>> rpi = raspi;
>> scanI2CBus(rpi, 'i2c-1')
ans = 

    '0x48'
The commands above should return the default I2C address of '0x48' if you connected ADDR pin of ADS1115 to ground. Note that I scanned 'i2c-1' bus since I am using a Model B+ board. This should also work fine for Model B Rev. 2 board. For Model B Rev 1 boards, use 'i2c-0' bus. Next, create an ads1115 object:

Code: Select all

>> adc = ads1115(rpi, 'i2c-1')

adc = 

  ads1115 with properties:

                Address: 0x48           
          OperatingMode: single-shot     ('single-shot' or 'continuous')
       SamplesPerSecond: 128             (8, 16, 32, 64, 128, 250, 475, or 860)
           VoltageScale: 2.048           (6.144, 4.096, 2.048, 1.024, 0.512, or 0.256)
Let's set SamplesPerSecond to 250, VoltageScale to 4.096 and read a single-ended voltage measurement from AIN0:

Code: Select all

>> adc.SamplesPerSecond = 250;
>> adc.VoltageScale = 4.096;
readVoltage(adc, 0)

ans =

    3.3114
In this case I connected the AIN0 pin to 3.3V voltage rail. Next, set the operating mode to continuous and measure differential voltage between AIN0 and AIN3:

Code: Select all

>> adc.OperatingMode = 'continuous';
>>  readVoltage(adc, 0, 3)
ans =

     0
In this case AIN3 is connected to AIN0. For further help, type "help ads1115" on the MATLAB command line. I provide a link to device data sheet in the help for ads1115.

I appreciate if you report any bugs you find. This implementation can also be used for ADS1113 and ADS1114 with minor modifications. I'll extend the class to support all three devices in the same family when I find some time.

murat_belge
Posts: 27
Joined: Fri Feb 14, 2014 6:18 pm

Re: ADS1115 interface with raspberry pi in Matlab

Fri Sep 05, 2014 7:15 pm

It is rather late but the issue with the original code is this line:

Code: Select all

writeRegister(i2cadc,1,hex2dec('C3E3'),'uint16'); 
Datasheet for the device says that you need to send the high byte first followed by the low byte for the 16-bit register value. The code above does the opposite. The code should have been:

Code: Select all

writeRegister(i2cadc,1, swapbytes(uint16(hex2dec('C3E3'))),'uint16'); 
Likewise, you need to do a similar transformation when reading the raw ADC conversion value from the conversion register. Look at my ads1115 class for details.

murat_belge
Posts: 27
Joined: Fri Feb 14, 2014 6:18 pm

Re: ADS1115 interface with raspberry pi in Matlab

Mon Sep 08, 2014 4:54 pm

While we are at it, here is another MATLAB class for an MCP4725 DAC:

Code: Select all

classdef mcp4725 < handle & matlab.mixin.CustomDisplay
    %MCP4725 12-bit DAC.
    %
    % dac = mcp4725(rpi, bus, address) creates a MCP4725 DAC object
    % attached to the specified I2C bus with the specified I2C address. The
    % first parameter, rpi, is a raspi object. If not specified, the I2C
    % address of the MCP4725 defaults to '0x62'.
    %
    % dac = mcp4725(rpi, bus, address, voltageReference) creates a MCP4725
    % DAC object with specified voltage reference. The voltageReference
    % defaults to 3.3V. Set the voltageReference value to the voltage
    % applied to the VDD pin of the MCP4725.
    %
    % writeVoltage(dac, voltage) sets the output voltage of the DAC.
    %
    % enterPowerDownMode(dac, resistor) puts DAC in power down mode. In
    % power down mode, all internal circuits (except for I2C) are disabled
    % and no output voltage is available. The output is tied to VSS
    % (usually ground) pin via a resistor. The resistor value can be 1000
    % Ohm, 100000 Ohm or 500000 Ohm. To exit the power down mode, use
    % writeVoltage method.
    %
    % writeEEPROM(dac, voltage) saves the specified voltage to the internal
    % EEPROM memory of the DAC. When DAC powers up after a reset, it
    % automatically outputs the voltage value written to EEPROM. Note that
    % writing to EEPROM also changes the current output voltage.
    %
    % writeEEPROM(dac, voltage, resistor) saves the specified voltage and
    % resistor value for power downd mode to the internal EEPROM memory of
    % the DAC. When DAC powers up after reset, it automatically enters
    % power down mode.
    %
    % <a href="https://www.sparkfun.com/datasheets/BreakoutBoards/MCP4725.pdf">Device Datasheet</a>
    %
    
    % Copyright 2014 The MathWorks, Inc.
    
    properties (SetAccess = private, GetAccess = public)
        Address = bin2dec('1100010') % Default address 0x62
    end
    
    properties (Access = public)
        VoltageReference = 3.3       % Reference voltage supplied to the VDD pin
    end
    
    properties (Access = private)
        i2cObj
        ConfigReg
    end
    
    properties (Constant, Hidden)
        AvailablePowerDownResistor = [1000, 100000, 500000]
    end
    
    properties (Constant, Access = private)      
        % Bitfield shifts
        CONFIG_FAST_MODE_PD_SHIFT = 4
        CONFIG_EEPROM_C_SHIFT  = 5
        CONFIG_EEPROM_PD_SHIFT = 1
        CONFIG_EEPROM_D_SHIFT  = 4
        
        % 12-bit DAC voltage scale
        DAC_SCALAR = 2^12 - 1
    end
    
    methods
        function obj = mcp4725(raspiObj, bus, address, voltageReference)
            % Set I2C address if not using default
            if nargin > 2
                obj.Address = address;
            end
            if nargin > 3
                obj.VoltageReference = voltageReference;
            end
            
            % Initialize config register value
            obj.ConfigReg = zeros(1, 3, 'uint8');
            
            % Create an i2cdev object to talk to ADS1115
            obj.i2cObj = i2cdev(raspiObj, bus, obj.Address);
        end
        
        function writeVoltage(obj, voltage)
            % voltage = readVoltage(obj, AINp) reads the single-ended input
            % voltage value at channe AINp.
            %
            % voltage = readVoltage(obj, AINp, AINn) reads the input
            % voltage value that is the difference between AINp and AINn.
            validateattributes(voltage, {'numeric'}, ...
                {'scalar', '>=', 0, '<=', obj.VoltageReference}, '', 'voltage');

            % Fast mode
            % Set PD bits for normal mode
            % PD = b00, C2:C1 = 0:0
            % Initialize config register value
            inputCode = getDACInputCode(obj, voltage);
            obj.ConfigReg(1) = bitshift(bitand(inputCode, hex2dec('F00')), -8);
            obj.ConfigReg(2) = bitand(inputCode, hex2dec('FF'));
            write(obj.i2cObj, obj.ConfigReg(1:2)); % Fast-mode requires two bytes
        end
        
        function writeEEPROM(obj, voltage, resistor)
            validateattributes(voltage, {'numeric'}, ...
                {'scalar', '>=', 0, '<=', obj.VoltageReference}, '', 'voltage');
            if nargin > 2
                validateattributes(resistor, {'numeric'}, ...
                    {'scalar', 'nonnan', 'finite'}, '', 'resistor');
                if ~ismember(resistor, obj.AvailablePowerDownResistor)
                    error('raspi:mcp4725:InvalidPowerDownResistor', ...
                    'Resistor must be one of the following: 1000, 100000, 500000');
                end
            else
                resistor = 0;
            end
            
            % Set config register
            % PD = bxx, C2,C1,C0 = 0,1,1
            obj.ConfigReg(1) = bitshift(bin2dec('011'), obj.CONFIG_EEPROM_C_SHIFT);
            obj.ConfigReg(1) = bitor(obj.ConfigReg(1), ...
                bitshift(obj.getPDBits(resistor), obj.CONFIG_EEPROM_PD_SHIFT));
                
            % Add DAC input code
            inputCode = getDACInputCode(obj, voltage);
            obj.ConfigReg(2) = bitshift(inputCode, -4);
            obj.ConfigReg(3) = bitshift(bitand(inputCode, hex2dec('F')), 4);
            write(obj.i2cObj, obj.ConfigReg);
        end
        
        function enterPowerDownMode(obj, resistor)
            validateattributes(resistor, {'numeric'}, ...
                {'scalar', 'nonnan', 'finite'}, '', 'resistor');
            if ~ismember(resistor, obj.AvailablePowerDownResistor)
                error('raspi:mcp4725:InvalidPowerDownResistor', ...
                    'Resistor must be one of the following: 1000, 100000, 500000');
            end
            
            % Set config register
            obj.ConfigReg(1) = bitor(obj.ConfigReg(1), ...
                bitshift(obj.getPDBits(resistor), obj.CONFIG_FAST_MODE_PD_SHIFT));
            write(obj.i2cObj, obj.ConfigReg(1:2)); % Fast-mode requires two bytes
        end
    end
    
    methods
        function set.Address(obj, value)
            if isnumeric(value)
                validateattributes(value, {'numeric'}, ...
                    {'scalar', 'nonnegative'}, '', 'Address');
            else
                validateattributes(value, {'char'}, ...
                    {'nonempty'}, '', 'Address');
                value = obj.hex2dec(value);
            end
            obj.Address = value;
        end
    end
    
    methods (Access = protected)
        function displayScalarObject(obj)
            header = getHeader(obj);
            disp(header);
            
            % Display main options
            fprintf('               Address: %-15s\n', ['0x' dec2hex(obj.Address)]);
            fprintf('      VoltageReference: %-15.2f\n', obj.VoltageReference);
            fprintf('\n');
            
            % Allow for the possibility of a footer.
            footer = getFooter(obj);
            if ~isempty(footer)
                disp(footer);
            end
        end
        
        function ret = getDACInputCode(obj, voltage) 
            % Compute input code
            voltage = uint16((voltage / obj.VoltageReference) * obj.DAC_SCALAR);
            ret = bitand(voltage, hex2dec('FFF'));
        end
    end
    
    methods (Static)
        function decvalue = hex2dec(hexvalue)
            decvalue = hex2dec(regexprep(hexvalue, '0x', ''));
        end
        
        function hexvalue = dec2hex(decvalue)
            hexvalue = sprintf('0x%02s', dec2hex(decvalue));
        end
        
        function ret = getPDBits(resistor)
            % Set PD bits 
            switch resistor
                case 0
                    ret = 0; % Normal mode
                case 1000
                    ret = 1; % Power down mode with 1 kOhm reistor to GND
                case 100000
                    ret = 2; % Power down mode with 100 kOhm reistor to GND
                case 500000
                    ret = 3; % Power down mode with 500 kOhm reistor to GND
            end
        end
    end
end
I used the MCP4725 to test the ADS1115 ADC. Here is how to use this class to control an MCP4725 ADC attached to Raspberry Pi 'i2c-1' bus:
dac = mcp4725(rpi, 'i2c-1', '0x62', 3.3)
I attached my MCP4725 to the 'i2c-1' bus of my model B+ board. The I2C address was printed on the break-out board (from ADAFRUIT) as '0x62'. Since I connected the VDD pin of the DAC to 3.3V rail, I entered the voltageReference as 3.3V. If you are using a Raspberry Pi Model 1, change the I2C bus to 'i2c-0'.

Next, set the output voltage of the MCP4725 to 1.9 volts:

Code: Select all

>> writeVoltage(dac, 1.9)
This device has a power down mode which allows it to go to sleep. In sleep mode, the device uses very little power. To put the device into sleep mode, you also have to specify a resistor value which can be 1000, 100000, or 500000 Ohm. The resistor value is used to tie the VOUT pin to VSS. Let's put MCP4725 to power down mode with a 1 KOhm resistor:

Code: Select all

>> enterPowerDownMode(dac, 1000)
If you measure the output voltage between VOUT and VSS pins after executing this command, you should see zero volts. To take the device out of power down mode, use writeVoltage method.

Finally, the MCP4725 has a built-in EEPROM memory that can be used to save output voltage value and power down mode setting. The saved values are used when device comes out of reset. To save a set the DAC output voltage value use the following:

Code: Select all

>> writeEEPROM(dac, 1.5)

The command above sets the saved output voltage value to 1.5 volts. If you disconnect the VDD pin (a reset condition) and re-connect it back, you will see that the output will be 1.5 volts.

You can also set the MCP4725 to assume power down mode after a reset:

Code: Select all

>> writeEEPROM(dac, 1.5, 1000)
Again, let me know if you see any bugs in the code.

subash
Posts: 3
Joined: Thu Aug 14, 2014 6:52 am

Re: ADS1115 interface with raspberry pi in Matlab

Tue Sep 09, 2014 5:56 am

Hi Murat Belge,
Thank you very much for the ADS1115 Class. I have checked the ADS1115 class. The code considers only 'single shot mode'. If the operating mode is continuous, i don't know where the appropriate bit is set in the "obj.AvailableOperatingMode".

As you have mentioned, If the DC signal is sampled using ADS1115 it gives exact values. I have tested the ADS1115 with sine and pulse waveforms, but the output is a discontinuous signal. Is this something to do with the delay ? or the SPS is not setting properly in the code.
I have attached the output signal of ADC for 20 Hz (unipolar) sine signal.

Using ADS1115 Class
adc.SamplesPerSecond = 860;
adc.VoltageScale = 4.096;
adc.OperatingMode = 'single-shot';
val=0;
for i=1:1:250
val(i)=readVoltage(adc, 0);
end
figure;plot(val);
Attachments
ADS1115.jpg
ADS1115.jpg (30.4 KiB) Viewed 13256 times

murat_belge
Posts: 27
Joined: Fri Feb 14, 2014 6:18 pm

Re: ADS1115 interface with raspberry pi in Matlab

Tue Sep 09, 2014 2:42 pm

To set the ADS1115 class has a property named OperatingMode which can be set to 'single-shot' or 'continuous'. Example:

Code: Select all

adc = ads1115(rpi, 'i2c-1');
adc.OperatingMode = 'continuous';
AvailableOperatingMode is a hidden property that helps me to validate the input. You should not use it.

In 'continuous' mode, ADC does an automatic conversion and stores the result in the conversion register according to the SamplesPerSecond parameter you set. At 860 samples per second, you need to be able to read one sample per 12ms. From my experiments, this is not possible over TCP/IP. The best case scenario I got was about 15ms per ADC read. The discontinuties in the signal is a result of the fact that you are dropping conversion results. This ADC really is not designed for that kind of a scenario where you would get accurate results for sampling a sine wave. It is more suited for applications where you measure the voltage across an analog temperature sensor once in a while.

The right way to continuously sample a time-varying signal would be to configure the ADC with an interrupt (i.e. use the ALERT) and read and buffer the ADC conversion result at every interrupt. You would then read a chunk of the buffer containing a segment of the continuously sampled signal. You can do this in C but not using the MATLAB API's. In any case, 860 samples per second is far too low for sampling a continuous signal like a sine wave.

murat_belge
Posts: 27
Joined: Fri Feb 14, 2014 6:18 pm

Re: ADS1115 interface with raspberry pi in Matlab

Tue Sep 09, 2014 2:58 pm

By the way Subash what exactly is your use case? I know that you are trying to sample an external signal but what is the big picture? What are you going to do with the data? Knowing the use case would help me suggest an alternative workflow.

subash
Posts: 3
Joined: Thu Aug 14, 2014 6:52 am

Re: ADS1115 interface with raspberry pi in Matlab

Wed Sep 10, 2014 3:20 am

Hi Murat Belge,

Thank you very much. It was a very clear explanation of the issue that i have faced.
My purpose is to sample a power line frequency signal with a sampling frequency of minimum 5-10kHz.
I was just checking with ADS1115, how good the sampling will be done and transferred with I2C interface.
As you have pointed out, ADS1115 is not at all suitable for my purpose.

Holistically what i am trying to do is,
1. Acquisition of data from a 5-10kHz ADC using the Raspberry Pi (to take FFT in Matlab with good frequency resolution)
2. Acquisition of image from the Pi camera interfaced with the Raspberry Pi ( to do image processing)
4. Acquisition of data from MLX90620 (16x4 IR thermal array) interfaced with the Raspberry Pi

For the first point, i come to know the issue. I need to look for high sampling frequency ADC with good buffer size.
Second point is straight forward, camera interface is very good using the Matlab API
I started developing code for getting data from MLX90620 and facing some issues in reading the EEPROM register.
I will post MLX90620 issues in a separate thread.
Kindly let me know your suggestion regarding my workflow

krimmel
Posts: 1
Joined: Wed Nov 11, 2015 1:52 pm

Re: ADS1115 interface with raspberry pi in Matlab

Wed Nov 11, 2015 1:59 pm

Hi guys,
Can you help me to create a block for Simulink from this class.
I believe it is possible, right? But I always get an error message.

"
-> Invalid setting in 'untitled / MATLAB System' for parameter 'System' -> Error evaluationg parameter 'system' in 'untitled / MATLAB System' -> Not enough input argument.
"

What am I doing wrong?
Thank you for your efforts

mubarak111
Posts: 5
Joined: Tue May 30, 2017 4:49 pm

Re: ADS1115 interface with raspberry pi in Matlab

Thu Jul 13, 2017 10:37 am

Dear respected sir, Hope you are in good health with success and happiness.

I'm trying to make a heart bit/pulse monitoring system using Raspberry pi. I'm using Heart Rate Pulse Sensor Pulsesensor Sensor which gives analog value as output. But you know raspberry pi is not able to read analog value.

Therefore I'm trying to convert analog value to digital as input for Rasperry pi.
I'm using MATLAB to code Raspberry pi.

Please could you help me about how to convert Analog data to digital data sothat it can be feed into Raspery pi?

Please sir, Help me. I'm waiting for response........

Return to “Beginners”