Multiple I2C devices using RPi ZERO

The place to share and discuss your Ultibo projects.
ph1lj
Posts: 9
Joined: Wed Jun 15, 2016 1:59 pm

Multiple I2C devices using RPi ZERO

Postby ph1lj » Tue Jul 19, 2016 1:33 pm

Hi All

Thought this might be of use to some, thanks to Ultibo for all there help.

Note the rather unconventional method of using 2 diodes on the Vcc line of the Max - guess you should really use a logic level shifter - but this simple method puts the Max within the logic levels supplied by the RPi and worked for me.

Hope someone finds it useful

https://www.dropbox.com/s/1l7g71tqojeoc ... 7.pdf?dl=0

Ph1lj
Gavinmc42
Posts: 1460
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Multiple I2C devices using RPi ZERO

Postby Gavinmc42 » Wed Jul 20, 2016 12:51 am

SDA on slave chip is/should be an open drain transistor.
So you can have a 5V chips connected to a 3.3V micro.
You just need to make sure the SCL clock level gets high enough, Max517 is 4.5-5.5V device, but VIH is 2.4V.
Whoops wrong SCL is 0.7 x Vdd = 3.5V when VDD=5V, the ADx logic inputs is 2.4V.

Ok, you could have problems with this chip, your one diode drop and run at a lower clock speed, 10k, 50k will help.
Or better yet use a real 3.3V part.
I use MCP4725 single and MCP4728 quad dacs.
Highest number of i2c parts I have used has maybe been twelve on 5m+ of cable.
Gavinmc42
Posts: 1460
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Multiple I2C devices using RPi ZERO

Postby Gavinmc42 » Thu Jul 21, 2016 4:21 am

Some code to check the i2c bus, find devices and dump the 1st 8 bytes of each device found.
Sort of a combined version of the Linux i2cdetect and i2cdump.

Very useful, if like me you are doing IoT sensor stuff.
Won't work perfectly with every i2c chip as some act weird, but it can be hacked for them too.
This only reads one byte from each address, some chips like temperature sensors, you read two bytes(a word) to get the lsb and msb.
So play with Numbytes, SizeOf(Bytes) etc.

Now to try to see if I can read the Pi touchscreen data.

Code: Select all

program i2cdetect;

{$mode objfpc}{$H+}

{ Raspberry Pi Application                                                     }
{  Add your program code below, add additional units to the "uses" section if  }
{  required and create new units by selecting File, New Unit from the menu.    }
{                                                                              }
{  To compile your program select Run, Compile (or Run, Build) from the menu.  }

uses
  RaspberryPi,
  GlobalConfig,
  GlobalConst,
  GlobalTypes,
  Platform,
  Threads,
  Console,
  GraphicsConsole,
  Framebuffer,
  Devices,
  I2C,
  SysUtils,
  DateUtils,
  Classes,
  Ultibo
  { Add additional units here };

var

 WindowHandle:TWindowHandle;
 WindowHandle2:TWindowHandle;
 I2CDevice:PI2CDevice;
 Address:Word;
 Numbytes:LongWord;
 Register:LongWord;
 Data:Word;
 Hexadd:String;
 Hexdata:String;

begin
  { Add your program code here }
 FRAMEBUFFER_CONSOLE_DEFAULT_DESKTOPCOLOR:=COLOR_BLUE;
 WindowHandle:=ConsoleWindowCreate(ConsoleDeviceGetDefault,CONSOLE_POSITION_LEFT,True);
 WindowHandle2:=ConsoleWindowCreate(ConsoleDeviceGetDefault,CONSOLE_POSITION_RIGHT,True);

 I2CDevice:=PI2CDevice(DeviceFindByDescription('BCM2835 BSC1 Master I2C'));

 while True do
  begin
       if I2CDeviceStart(I2CDevice,100000) <> ERROR_SUCCESS then
       begin
            //Error Occurred
           ConsoleWindowWriteLn(WindowHandle,'i2c error!!');
       end
  else
      for Address:=$01 to $7f do
          begin
              Numbytes:=1;
              Register:=0;
              if I2CDeviceWriteRead(I2CDevice,Address,@Register, Numbytes, @Data,SizeOf(Byte),Numbytes) = ERROR_SUCCESS then
                 begin
                     Hexadd:=IntToHex(Address, 2);
                     Hexdata:=IntToHex(Data, 2);
                     ConsoleWindowWrite(WindowHandle, ' 0x' + Hexadd + ' 0x' + Hexdata );
                     ConsoleWindowWrite(WindowHandle2, 'i2c address=0x' + Hexadd + ' data=');

                     for Register:=$00 to $07 do
                         begin

                             if I2CDeviceWriteRead(I2CDevice,Address,@Register,Numbytes,@Data,SizeOf(Byte),Numbytes) = ERROR_SUCCESS then
                                 begin
                                      Hexdata:=IntToHex(Data, 2);
                                      ConsoleWindowWrite(WindowHandle2,  ' 0x' + Hexdata );
                                 end;
                         end;
                     ConsoleWindowWriteLn(WindowHandle2, '');
                     ConsoleWindowWriteLn(WindowHandle2, '');
                     if Address MOD 8 = 0 then
                        begin
                             ConsoleWindowWriteLn(WindowHandle, '');
                        end;
                 end
              else
                 begin
                     Hexadd:=IntToHex(Address, 2);
                     ConsoleWindowWrite(WindowHandle, ' 0x' + Hexadd + '_____' );
                     if Address MOD 8 = 0 then
                        begin
                             ConsoleWindowWriteLn(WindowHandle, '');
                        end;

                 end;
          end;
    ConsoleWindowWriteLn(WindowHandle, ' ');
    ConsoleWindowWriteLn(WindowHandle, ' ');
   Sleep(3000);
 end;

 {We're not doing a loop this time so we better halt this thread before it exits}
 ThreadHalt(0);

end.
                 
Gavinmc42
Posts: 1460
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Multiple I2C devices using RPi ZERO

Postby Gavinmc42 » Fri Jul 29, 2016 5:46 am

Ran i2c code for over a week, reading and logging every 5 seconds.
Not a single i2c error was logged.

Compared to Linux using i2cget or python-smbus, Ultibo is orders of magnitude better when using i2c.

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 2 guests