i2c ADC 4 channel (ADS1115)
2023.12.20 00:40
====================================================
// library
{ ## ADS1115_Unit ## }
{ ## ## }
{ ## Library for ADS1115 ## }
{ ## Based on: ## }
{ ## - Adafruit_ADS1015 library from K. Townsend (Adafruit Industries) ## }
{ ## - pascalio library: https://github.com/SAmeis/pascalio ## }
{ ## ## }
{ ## Copyright (C) 2018-2019 : Dr. J��rgen Abel ## }
{ ## Email : juergen@mve.info ## }
{ ## Internet : https://www.juergen-abel.info ## }
{ ## ## }
{ ## This program is free software: you can redistribute it and/or modify ## }
{ ## it under the terms of the GNU Lesser General Public License as published by ## }
{ ## the Free Software Foundation, either version 3 of the License, or ## }
{ ## (at your option) any later version with the following modification: ## }
{ ## ## }
{ ## As a special exception, the copyright holders of this library give you ## }
{ ## permission to link this library with independent modules to produce an ## }
{ ## executable, regardless of the license terms of these independent modules, and ## }
{ ## to copy and distribute the resulting executable under terms of your choice, ## }
{ ## provided that you also meet, for each linked independent module, the terms ## }
{ ## and conditions of the license of that module. An independent module is a ## }
{ ## module which is not derived from or based on this library. If you modify ## }
{ ## this library, you may extend this exception to your version of the library, ## }
{ ## but you are not obligated to do so. If you do not wish to do so, delete this ## }
{ ## exception statement from your version. ## }
{ ## ## }
{ ## This program is distributed in the hope that it will be useful, ## }
{ ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## }
{ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## }
{ ## GNU General Public License for more details. ## }
{ ## ## }
{ ## You should have received a copy of the GNU Lesser General Public License ## }
{ ## COPYING.LGPL.txt along with this program. ## }
{ ## If not, see <https://www.gnu.org/licenses/>. ## }
unit ADS1115_Unit;
{$mode objfpc}{$H+}
interface
uses
CThreads, BaseUnix, Classes;
const
// I2C general data
ADS1115_ADDRESS = $48; // I2C adress
ADS1115_CONVERSION_DELAY = 8; // Conversation delay in msec
ADS1115_DEVICE_PATH = '/dev/i2c-1'; // Path to device
ADS1115_I2C_SLAVE = $0703; // I2C slave id
ADS1115_I2C_SMBUS = $0720; // I2C SMBUS id
ADS1115_I2C_BUFFER_MAX_SIZE = 32; // I2C maximal buffer size
// Pointer register
ADS1115_REGISTER_POINTER_MASK = $03;
ADS1115_REGISTER_POINTER_CONVERT = $00;
ADS1115_REGISTER_POINTER_CONFIG = $01;
ADS1115_REGISTER_POINTER_LOW_THRESHOLD = $02;
ADS1115_REGISTER_POINTER_HIGH_THRESHOLD = $03;
// Config register
ADS1115_REGISTER_CONFIG_OS_MASK = $8000;
ADS1115_REGISTER_CONFIG_OS_NOEFFECT = $0000; // When writing : No effect
ADS1115_REGISTER_CONFIG_OS_SINGLE = $8000; // When writing : Set to start a single-conversion
ADS1115_REGISTER_CONFIG_OS_BUSY = $0000; // When reading : Bit = 0 when conversion is in progress
ADS1115_REGISTER_CONFIG_OS_NOTBUSY = $8000; // When reading : Bit = 1 when device is not performing a conversion
ADS1115_REGISTER_CONFIG_MUX_MASK = $7000;
ADS1115_REGISTER_CONFIG_MUX_DIFF_0_1 = $0000; // Differential P = AIN0, N = AIN1 (default)
ADS1115_REGISTER_CONFIG_MUX_DIFF_0_3 = $1000; // Differential P = AIN0, N = AIN3
ADS1115_REGISTER_CONFIG_MUX_DIFF_1_3 = $2000; // Differential P = AIN1, N = AIN3
ADS1115_REGISTER_CONFIG_MUX_DIFF_2_3 = $3000; // Differential P = AIN2, N = AIN3
ADS1115_REGISTER_CONFIG_MUX_SINGLE_0 = $4000; // Single-ended AIN0
ADS1115_REGISTER_CONFIG_MUX_SINGLE_1 = $5000; // Single-ended AIN1
ADS1115_REGISTER_CONFIG_MUX_SINGLE_2 = $6000; // Single-ended AIN2
ADS1115_REGISTER_CONFIG_MUX_SINGLE_3 = $7000; // Single-ended AIN3
ADS1115_REGISTER_CONFIG_PGA_MASK = $0E00;
ADS1115_REGISTER_CONFIG_PGA_6_144V = $0000; // +/-6.144V range = Gain 2/3
ADS1115_REGISTER_CONFIG_PGA_4_096V = $0200; // +/-4.096V range = Gain 1 (new constructor default)
ADS1115_REGISTER_CONFIG_PGA_2_048V = $0400; // +/-2.048V range = Gain 2 (default)
ADS1115_REGISTER_CONFIG_PGA_1_024V = $0600; // +/-1.024V range = Gain 4
ADS1115_REGISTER_CONFIG_PGA_0_512V = $0800; // +/-0.512V range = Gain 8
ADS1115_REGISTER_CONFIG_PGA_0_256V = $0A00; // +/-0.256V range = Gain 16
ADS1115_REGISTER_CONFIG_MODE_MASK = $0100;
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS = $0000; // Continuous conversion mode
ADS1115_REGISTER_CONFIG_MODE_SINGLE = $0100; // Power-down single-shot mode (default)
ADS1115_REGISTER_CONFIG_DR_MASK = $00E0;
ADS1115_REGISTER_CONFIG_DR_8SPS = $0000; // 8 samples per second
ADS1115_REGISTER_CONFIG_DR_16SPS = $0020; // 16 samples per second
ADS1115_REGISTER_CONFIG_DR_32SPS = $0040; // 32 samples per second
ADS1115_REGISTER_CONFIG_DR_64SPS = $0060; // 64 samples per second
ADS1115_REGISTER_CONFIG_DR_128SPS = $0080; // 128 samples per second (default)
ADS1115_REGISTER_CONFIG_DR_250SPS = $00A0; // 250 samples per second
ADS1115_REGISTER_CONFIG_DR_475SPS = $00C0; // 475 samples per second
ADS1115_REGISTER_CONFIG_DR_860SPS = $00E0; // 860 samples per second
ADS1115_REGISTER_CONFIG_CMODE_MASK = $0010;
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL = $0000; // Traditional comparator with hysteresis (default)
ADS1115_REGISTER_CONFIG_CMODE_WINDOW = $0010; // Window comparator
ADS1115_REGISTER_CONFIG_CPOL_MASK = $0008;
ADS1115_REGISTER_CONFIG_CPOL_ACTVLOW = $0000; // ALERT/RDY pin is low when active (default)
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH = $0008; // ALERT/RDY pin is high when active
ADS1115_REGISTER_CONFIG_CLAT_MASK = $0004; // Determines if ALERT/RDY pin latches once asserted
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH = $0000; // Non-latching comparator (default)
ADS1115_REGISTER_CONFIG_CLAT_LATCH = $0004; // Latching comparator
ADS1115_REGISTER_CONFIG_CQUE_MASK = $0003;
ADS1115_REGISTER_CONFIG_CQUE_1CONV = $0000; // Assert ALERT/RDY after one conversions
ADS1115_REGISTER_CONFIG_CQUE_2CONV = $0001; // Assert ALERT/RDY after two conversions
ADS1115_REGISTER_CONFIG_CQUE_4CONV = $0002; // Assert ALERT/RDY after four conversions
ADS1115_REGISTER_CONFIG_CQUE_NONE = $0003; // Disable the comparator and put ALERT/RDY in high state (default)
type
// Number types
Int_8 = Shortint;
P_Int_8 = ^Int_8;
U_Int_8 = Byte;
P_U_Int_8 = ^U_Int_8;
Char = Int_8;
P_Char = ^Char;
U_Char = U_Int_8;
P_U_Char = ^U_Char;
Int_16 = Smallint;
P_Int_16 = ^Int_16;
U_Int_16 = Word;
P_U_Int_16 = ^U_Int_16;
Int_32 = Longint;
P_Int_32 = ^Int_32;
U_Int_32 = Longword;
P_U_Int_32 = ^U_Int_32;
Int_64 = Int64;
P_Int_64 = ^Int_64;
U_Int_64 = QWord;
P_U_Int_64 = ^U_Int_64;
Bool = Bytebool;
P_Bool = ^Bool;
T_I2C_Buffer_A = packed array [0..ADS1115_I2C_BUFFER_MAX_SIZE + 1] of U_Int_8;
{$PACKENUM 1}
T_I2C_Read_Write_Mode = (
I2C_READ_WRITE_MODE_WRITE = 0,
I2C_READ_WRITE_MODE_READ = 1
);
{$PACKENUM 4}
T_I2C_Transaction = (
I2C_TRANSACTION_QUICK = 0,
I2C_TRANSACTION_BYTE = 1,
I2C_TRANSACTION_BYTE_DATA = 2,
I2C_TRANSACTION_WORD_DATA = 3,
I2C_TRANSACTION_PROC_CALL = 4,
I2C_TRANSACTION_BLOCK_DATA = 5,
I2C_TRANSACTION_I2C_BLOCK_BROKEN = 6,
I2C_TRANSACTION_BLOCK_PROC_CALL = 7,
I2C_TRANSACTION_I2C_BLOCK_DATA = 8
);
{$PACKENUM DEFAULT}
T_I2C_IOCTL_Data = record
Read_Write_Mode : T_I2C_READ_WRITE_MODE;
Command : U_Int_8;
Transaction : T_I2C_TRANSACTION;
P_Buffer : ^T_I2C_Buffer_A;
end;
{ ## T_ADS1115 ## }
T_ADS1115 = class (TObject)
protected
M_I2C_Address : U_Int_8;
M_Gain : U_Int_16;
M_I2C_Handle : CInt;
public
constructor create (F_I2C_Adress : U_Int_8 = ADS1115_ADDRESS; F_Gain : U_Int_16 = ADS1115_REGISTER_CONFIG_PGA_4_096V);
destructor destroy; override;
function I2C_Read_Buffer (F_Command : U_Int_8; F_Length : U_Int_8; F_P_Buffer : P_U_Int_8) : Integer;
function I2C_Write_Buffer (F_Command : U_Int_8; F_Length : U_Int_8; F_P_Buffer : P_U_Int_8) : Integer;
procedure Start_ALERT_RDY;
procedure Stop_ALERT_RDY;
procedure Start_ADC_Differential_0_1_Continuous_Conversion;
function Get_Last_Conversion_Result : Integer;
procedure SetModeForPinA0;
procedure SetModeForPinA1;
procedure SetModeForPinA2;
procedure SetModeForPinA3;
published
end; // T_ADS1115
implementation
uses SysUtils, Dialogs, Math;
{ ## T_ADS1115 ## }
constructor T_ADS1115.Create (F_I2C_Adress : U_Int_8 = ADS1115_ADDRESS; F_Gain : U_Int_16 = ADS1115_REGISTER_CONFIG_PGA_4_096V);
{ Initialization of the object }
begin // T_ADS1115.Create
inherited create ();
{ Initialize data }
M_I2C_Address := F_I2C_Adress;
M_Gain := F_Gain;
M_I2C_Handle := FpOpen ('/dev/i2c-1', O_RDWR);
sleep (100);
if M_I2C_Handle < 0 then begin
{ Error }
ShowMessage ('Can not open I��C bus, Error:' + IntToStr (M_I2C_Handle));
Halt;
end;
// Connect as I2C slave
FpioCTL (M_I2C_Handle, ADS1115_I2C_SLAVE, Pointer (ADS1115_ADDRESS));
sleep (100);
end; // T_ADS1115.Create
destructor T_ADS1115.Destroy (); // Free data
begin // T_ADS1115.Destroy
FpClose (M_I2C_Handle);
inherited destroy;
end; //{ T_ADS1115.Destroy
function T_ADS1115.I2C_Read_Buffer (F_Command : U_Int_8; F_Length : U_Int_8; F_P_Buffer : P_U_Int_8) : Integer; Inline;
var // Return last conversion result
I2C_Buffer_A : T_I2C_Buffer_A;
Transaction : T_I2C_Transaction;
IOCTL_Data : T_I2C_IOCTL_Data;
begin // T_ADS1115.I2C_Read_Buffer
F_Length := Min (F_Length, ADS1115_I2C_BUFFER_MAX_SIZE);
I2C_Buffer_A[0] := F_Length;
if F_Length = ADS1115_I2C_BUFFER_MAX_SIZE then
Transaction := I2C_TRANSACTION_I2C_BLOCK_BROKEN
else
Transaction := I2C_TRANSACTION_I2C_BLOCK_DATA;
IOCTL_Data.Read_Write_Mode := I2C_READ_WRITE_MODE_READ;
IOCTL_Data.Command := F_Command;
IOCTL_Data.Transaction := Transaction;
IOCTL_Data.P_Buffer := @I2C_Buffer_A;
if FpIOCtl (M_I2C_Handle, ADS1115_I2C_SMBUS, @IOCTL_Data) <> 0 then
Result := -1
else
begin
Move (I2C_Buffer_A [1], F_P_Buffer^, I2C_Buffer_A [0]);
Result := I2C_Buffer_A [0];
end;
end; // T_ADS1115.I2C_Read_Buffer
function T_ADS1115.I2C_Write_Buffer (F_Command : U_Int_8; F_Length : U_Int_8; F_P_Buffer : P_U_Int_8) : Integer; Inline;
// Return last conversion result
var
I2C_Buffer_A : T_I2C_Buffer_A;
IOCTL_Data : T_I2C_IOCTL_Data;
begin // T_ADS1115.I2C_Write_Buffer
F_Length := Min (F_Length, ADS1115_I2C_BUFFER_MAX_SIZE);
Move (F_P_Buffer^, I2C_Buffer_A [1], F_Length);
I2C_Buffer_A[0] := F_Length;
IOCTL_Data.Read_Write_Mode := I2C_READ_WRITE_MODE_WRITE;
IOCTL_Data.Command := F_Command;
IOCTL_Data.Transaction := I2C_TRANSACTION_I2C_BLOCK_BROKEN;
IOCTL_Data.P_Buffer := @I2C_Buffer_A;
Result := FpIOCtl (M_I2C_Handle, ADS1115_I2C_SMBUS, @IOCTL_Data);
end; // T_ADS1115.I2C_Write_Buffer
procedure T_ADS1115.Start_ALERT_RDY; // Start ALERT/RDY interupt signal
var
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ALERT_RDY
// Turn on ALERT/RDY : Set MSB of Hi_thresh to 1
Buffer[0] := $8000 shr 8;
Buffer[1] := $8000 and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_HIGH_THRESHOLD, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set MSB of Hi_thresh to 1)');
Halt;
end;
// Turn on ALERT/RDY : Set MSB of Lo_thresh to 0
Buffer[0] := $0000 shr 8;
Buffer[1] := $0000 and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_LOW_THRESHOLD, 2, @Buffer [0]);
if Result_Value < 0 then begin { then }
ShowMessage ('Error writing to I��C (Set MSB of Lo_thresh to 0)');
Halt;
end;
sleep (100);
end; // T_ADS1115.Start_ALERT_RDY
procedure T_ADS1115.Stop_ALERT_RDY; // Stop ALERT/RDY interupt signal
var
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Stop_ALERT_RDY
// Turn off ALERT/RDY : Set MSB of Hi_thresh to 0
Buffer[0] := $0000 shr 8;
Buffer[1] := $0000 and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_HIGH_THRESHOLD, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set MSB of Hi_thresh to 0)');
Halt;
end;
{ Turn off ALERT/RDY : Set MSB of Lo_thresh to 1 }
Buffer[0] := $FFFF shr 8;
Buffer[1] := $FFFF and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_LOW_THRESHOLD, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set MSB of Lo_thresh to 1)');
Halt;
end;
end; // T_ADS1115.Stop_ALERT_RDY
procedure T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion;
var // Start continuous conversion mode
Config : U_Int_16;
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
// Start ADC with continouos operation }
Config :=
ADS1115_REGISTER_CONFIG_OS_SINGLE or
ADS1115_REGISTER_CONFIG_MUX_DIFF_0_1 or
M_Gain or
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS or
ADS1115_REGISTER_CONFIG_DR_475SPS or
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL or
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH or
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH or
ADS1115_REGISTER_CONFIG_CQUE_2CONV;
Buffer[0] := Config shr 8;
Buffer[1] := Config and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
Sleep (100);
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set config)');
Halt;
end;
Start_ALERT_RDY (); // Turn on ALERT/RDY
end; // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
procedure T_ADS1115.SetModeForPinA0; // Added by Henry
var // Start continuous conversion mode
Config : U_Int_16;
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
// Start ADC with continouos operation }
Config :=
ADS1115_REGISTER_CONFIG_OS_SINGLE or
ADS1115_REGISTER_CONFIG_MUX_SINGLE_0 or
M_Gain or
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS or
ADS1115_REGISTER_CONFIG_DR_475SPS or
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL or
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH or
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH or
ADS1115_REGISTER_CONFIG_CQUE_2CONV;
Buffer[0] := Config shr 8;
Buffer[1] := Config and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
Sleep (20);
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set config)');
Halt;
end;
Start_ALERT_RDY (); // Turn on ALERT/RDY
end;
procedure T_ADS1115.SetModeForPinA1; // Added by Henry
var // Start continuous conversion mode
Config : U_Int_16;
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
// Start ADC with continouos operation }
Config :=
ADS1115_REGISTER_CONFIG_OS_SINGLE or
ADS1115_REGISTER_CONFIG_MUX_SINGLE_1 or
M_Gain or
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS or
ADS1115_REGISTER_CONFIG_DR_475SPS or
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL or
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH or
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH or
ADS1115_REGISTER_CONFIG_CQUE_2CONV;
Buffer[0] := Config shr 8;
Buffer[1] := Config and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
Sleep (20);
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set config)');
Halt;
end;
Start_ALERT_RDY (); // Turn on ALERT/RDY
end;
procedure T_ADS1115.SetModeForPinA2; // Added by Henry
var // Start continuous conversion mode
Config : U_Int_16;
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
// Start ADC with continouos operation }
Config :=
ADS1115_REGISTER_CONFIG_OS_SINGLE or
ADS1115_REGISTER_CONFIG_MUX_SINGLE_2 or
M_Gain or
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS or
ADS1115_REGISTER_CONFIG_DR_475SPS or
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL or
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH or
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH or
ADS1115_REGISTER_CONFIG_CQUE_2CONV;
Buffer[0] := Config shr 8;
Buffer[1] := Config and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
Sleep (20);
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set config)');
Halt;
end;
Start_ALERT_RDY (); // Turn on ALERT/RDY
end;
procedure T_ADS1115.SetModeForPinA3; // Added by Henry
var // Start continuous conversion mode
Config : U_Int_16;
Buffer : packed array [0 .. 9] of U_Int_8;
Result_Value : Integer;
begin // T_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion
// Start ADC with continouos operation }
Config :=
ADS1115_REGISTER_CONFIG_OS_SINGLE or
ADS1115_REGISTER_CONFIG_MUX_SINGLE_3 or
M_Gain or
ADS1115_REGISTER_CONFIG_MODE_CONTINUOUS or
ADS1115_REGISTER_CONFIG_DR_475SPS or
ADS1115_REGISTER_CONFIG_CMODE_TRADITIONAL or
ADS1115_REGISTER_CONFIG_CPOL_ACTVHIGH or
ADS1115_REGISTER_CONFIG_CLAT_NONLATCH or
ADS1115_REGISTER_CONFIG_CQUE_2CONV;
Buffer[0] := Config shr 8;
Buffer[1] := Config and $FF;
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
Sleep (20);
Result_Value := I2C_Write_Buffer (ADS1115_REGISTER_POINTER_CONFIG, 2, @Buffer [0]);
if Result_Value < 0 then begin
ShowMessage ('Error writing to I��C (Set config)');
Halt;
end;
Start_ALERT_RDY (); // Turn on ALERT/RDY
end;
function T_ADS1115.Get_Last_Conversion_Result : Integer;
var // Return last conversion result
Result_Value : Integer;
Buffer : packed array [0 .. 9] of U_Int_8;
begin // T_ADS1115.Get_Last_Conversion_Result
Result_Value := I2C_Read_Buffer (ADS1115_REGISTER_POINTER_CONVERT, 2, @Buffer);
if Result_Value <> 2 then begin
Result_Value := I2C_Read_Buffer (ADS1115_REGISTER_POINTER_CONVERT, 2, @Buffer);
if Result_Value <> 2 then begin
Buffer[0] := 0;
Buffer[1] := 0;
end;
end;
Result := Int_16 ((Buffer [0] shl 8) or (Buffer [1]));
end; // T_ADS1115.Get_Last_Conversion_Result
end.
====================================================
// main code
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls,
StdCtrls, ADS1115_Unit;
type
TfrmMain = class(TForm)
lbl1: TLabel;
lbl2: TLabel;
lbl3: TLabel;
lbl4: TLabel;
pb1: TProgressBar;
pb2: TProgressBar;
pb3: TProgressBar;
pb4: TProgressBar;
Timer1: TTimer;
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
public
my_ADS1115 : T_ADS1115;
end;
var
frmMain: TfrmMain;
implementation
{$R *.lfm}
{ TfrmMain }
procedure TfrmMain.FormShow(Sender: TObject);
begin
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
Timer1.Interval := 100;
Timer1.Enabled := true;
my_ADS1115 := T_ADS1115.Create (ADS1115_ADDRESS, ADS1115_REGISTER_CONFIG_PGA_0_256V);
my_ADS1115.Start_ADC_Differential_0_1_Continuous_Conversion();
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
var
i : integer;
v : real;
Begin { TMain_F.Chart_TTimer }
my_ADS1115.SetModeForPinA0;
v := my_ADS1115.Get_Last_Conversion_Result / 256;
lbl1.caption := inttostr(round(v));
pb1.position := round(v);
sleep(10);
my_ADS1115.SetModeForPinA1;
v := my_ADS1115.Get_Last_Conversion_Result / 256;
lbl2.caption := inttostr(round(v));
pb2.position := round(v);
sleep(10);
my_ADS1115.SetModeForPinA2;
v := my_ADS1115.Get_Last_Conversion_Result / 256;
lbl3.caption := inttostr(round(v));
pb3.position := round(v);
sleep(10);
my_ADS1115.SetModeForPinA3;
v := my_ADS1115.Get_Last_Conversion_Result / 256;
lbl4.caption := inttostr(round(v));
pb4.position := round(v);
Application.ProcessMessages;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
my_ADS1115.Stop_ALERT_RDY ();
my_ADS1115.free;
end;
end.
// Testing .mp4 video is in attached file