Skip to menu

Robotics with Object Pascal

Controls

My note for pascalio/test/mcp23017_plain/project2.lpr file

 

{ Testing Unit i2c_dev with MCP23017 GPIO extender

  Copyright (C) 2013 Simon Ameis, <simon.ameis@web.de>

  This source is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.

  This code 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.

  A copy of the GNU General Public License is available on the World Wide Web
  at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  MA 02111-1307, USA.
}


{
  This demo program shows how to use unit i2c_dev to access a simple device
  like the MCP23017.
  It assumes:
  - MCP23017 is connected to I2C Port 1
  - The device address is set to $20 by connecting all thre address pins to GND
  - All A ports will be configured as input (connect to GND or +3V3)
  - All B ports will be configured as output (connect them to a LED)

  How to connect:
                      +---------+
         (blink) LED<-| 1     28|->3V3 (read)
                     /| 2     27|->GND (read)
                    / | 3     26|\
                   /  | 4  M  25| \
          (blink) <   | 5  C  24|  \ whatever you want
                   \  | 6  P  23|  / (will be read)
                    \ | 7  2  22| /
                     \| 8  3  21|/
                 3V3<-| 9  0  20|
                 GND<-|10  1  19|
                      |11  7  18|
                 SCL<-|12     17|->GND
                 SDA<-|13     16|->GND
                      |14     15|->GND
                      +---------+

}

 

program project2;


uses
  i2c_dev, BaseUnix; 
//
i2c_dev.pas unit is part of pascalio
const
 
// I2C bus to which the device is connected. /dev/i2c-# can be changed by hardware setting.
  BUS_NAME = '/dev/i2c-1';
 
// mcp23017 device's default adress (as set by address pins)
  ADDR = $20;

var
  fileh: cint;   
// device handle
  rval: LongInt;  // variable used for reading from PortA $12
  i: Integer;     // dummy counter
begin
 
// open device file
  fileh := FpOpen(BUS_NAME, O_RDWR); 
// same as FpOpen('/dev/i2c-1', O_RDWR); O_RDWR = read/write
  if fileh < 0 then  // if handle is not properly connected = FAILED
  begin
    writeln('Opening file ', BUS_NAME ,' failed: ',fileh); 
// screen display failed message
    halt(1);  // Quit.
  end
  else
    WriteLn('Opening file ', BUS_NAME,' succeeded: ', fileh);
// screen display success message

  // set device address
  if (FpIOCtl(fileh, I2C_SLAVE, Pointer(ADDR)) < 0) then
// Assign address on handle failed
  begin                                                  // pointing $20 address of '/dev/i2c-1'
    writeln('Opening slave ', ADDR, ' failed.'); // screen display failed message
    halt(1);  // Quit.
  end else
    writeln('Opening slave ', ADDR, ' succeeded');
// screen display success message

  // set Input/Output modes
  rval := i2c_smbus_write_byte_data(fileh, $00, $FF);// GPIOA = INPUT, set portA's 8 pins input 
  rval := i2c_smbus_write_byte_data(fileh, $01, $00);// GPIOB = Output
, set portB's 8 pins output

  // gets input values from GPIOA, address $12 is used for accessing portA
  rval := i2c_smbus_read_byte_data(fileh, $12); // read High/Low status from port A
  writeln('Input Values A: ', rval); // screen display of port A (8 pins)

  // blink GPIOB
  for i := 0 to 5 do
  begin  
// address $13 is used for accessing portB
    i2c_smbus_write_byte_data(fileh, $13, $FF); // on = set all pins high on portB
    FpSleep(1); 
// Sleep 1 second. Its unit is seconds.  Use Sleep command for millisecond.
    i2c_smbus_write_byte_data(fileh, $13, $00); // off = set all pins low on portB
    fpsleep(1);  // Sleep 1 second. Its unit is seconds.  Use Sleep command for millisecond.
  end;

 
// close file handle!
  fpclose(fileh);
end.

 

// ================================================================= //
// =====  My Better Display of Binary Value ==================================== //

// ================================================================= //

// add strutils on uses clauses for inttobin(rval, 8);

// uses i2c_dev, BaseUnix, strutils;

// Connect one of the pin of PortA with one of the pin of PortB : to see value changes

// After each fpSleep(1), add following code

//  rval := i2c_smbus_read_byte_data(fileh, $12);

//  writeln('Input Values A: ', inttobin(rval, 8));

//  This will produce status of 8 of PortA pins in binary format.

 

status_updates.png

 

program MyTest01;

uses
   i2c_dev, BaseUnix, strutils; // i2c_dev unit is part of pascalio.
                                // struitls is needed for inttobin(ival, 8) display
                                  
const
   // I2C bus to which the device is connected. /dev/i2c-# can be changed by hardware setting.
   BUS_NAME = '/dev/i2c-1';
   // mcp23017 device's default adress (as set by address pins)
   ADDR = $20;                        
 
var
   handle_mcp23017 : cint; // device handle
   readingVal : LongInt;  // variable used for reading from PortA $12 or PortB $13
   i: integer;     // dummy counter
 
begin  
   // First, assign the handle to the device
   handle_mcp23017 := FpOpen(BUS_NAME, O_RDWR); // FpOpen('/dev/i2c-1', O_RDWR); readable & writeable
   
   if handle_mcp23017 < 0 then  // if handle is not properly connected = FAILED
      begin
         writeln('Opening file ', BUS_NAME ,' failed: ', handle_mcp23017);  // screen display failed message
         halt(1);  // Quit.
      end;
      
   WriteLn('Opening file ', BUS_NAME,' succeeded: ', handle_mcp23017); // screen display success message
   
   // set device address : pointing $20 address of '/dev/i2c-1'
   if (FpIOCtl(handle_mcp23017, I2C_SLAVE, Pointer(ADDR)) < 0) then // if Assign address on handle failed
      begin                                              
         writeln('Opening slave ', ADDR, ' failed.'); // screen display failed message
         halt(1);  // Quit.
      end;

   writeln('Opening slave ', ADDR, ' succeeded'); // screen display success message
   
   // set Input/Output modes
   readingVal := i2c_smbus_write_byte_data(handle_mcp23017, $00, $FF);// GPIOA = INPUT, set portA's 8 pins input
      // GPIOA = $00, Last $FF = %11111111 = all pins are for input,
   readingVal := i2c_smbus_write_byte_data(handle_mcp23017, $01, $00);// GPIOB = Output, set portB's 8 pins
      // GPIOB = $01, Last $00 = %00000000 = all pins are for output
      
   // Now you can read from PortA since its all 8 pins are set for INPUT   
   readingVal := i2c_smbus_read_byte_data(handle_mcp23017, $12); // read High/Low status from port A which is $12
   writeln('Input Values A: ', inttobin(readingVal, 8));  // Display result in binary format on screen
   
   // blink GPIOB

   for i := 0 to 5 do
      begin   // address $13 is used for accessing portB
         i2c_smbus_write_byte_data(handle_mcp23017, $13, $FF); // on = set all pins high on portB
         readingVal := i2c_smbus_read_byte_data(handle_mcp23017, $12); // read High/Low status from port A which is $12
         writeln('Input Values A: ', inttobin(readingVal, 8));  // Display result in binary format on screen
         FpSleep(1);  // Sleep 1 second. Its unit is seconds.  Use Sleep command for millisecond.
         
         i2c_smbus_write_byte_data(handle_mcp23017, $13, $00); // off = set all pins low on portB
         readingVal := i2c_smbus_read_byte_data(handle_mcp23017, $12); // read High/Low status from port A which is $12
         writeln('Input Values A: ', inttobin(readingVal, 8));  // Display result in binary format on screen
         FpSleep(1);  // Sleep 1 second. Its unit is seconds.  Use Sleep command for millisecond.
      end;

   // close file handle!
   fpclose(handle_mcp23017);

end.


mpc23017_1.jpg

 

my_setting.jpg

 

 

Multimedia video is in attached.