... with the data in the device, "(4)NIMH" - 4 being the number of bytes following (SMBus spec) ... results in "(4)N(FF)(FF)"... or to be precise, "FF"'s all the way up 'til the buffer length, without cutting off.

I noticed that the timing diagrams for i2c block read and SMBus block read don't exactly line up right... but yet, I can't find ANYWHERE online where anyone's ever even *tried* to do an SMBus block read with an Arduino.

Why, you might ask, would I need this functionality? Well... I'm using Wire (and Arduino's i2c controller) mostly for the occasional PC laptop battery hack. There's lots of amazing information in these packs that can be hacked using the Arduino i2c interface. And the block read is only used for a couple useless quirks; otherwise i2c overlays on SMBus pretty nicely; sending "commands" instead of "addresses" and doing reads the same way as an EEPROM. Take a look at this hacked-up sketch I wrote that interfaces with this old NiMH battery I'm trying to repair... (">>" indicates things I enter into the Serial Monitor window)

Is the i2c protocol hard-coded into the ATmega chip itself? There are just slight differences in handling sequential "ack"'s in order to extract a full sequence of bytes from an SMBus device, but I think the controller is sending a "refresh code" and knocking out the sequence. Problem is, there's no way to even retrieve those missing bytes without following protocol, since "bytes of a block" can't be directly addressed... one command of 11 characters is 0x20, the next command of 8 characters is 0x21. They just have to be read in bursts like this...

If I could get SMBus working properly, I could probably polish up this sketch and turn it into a much more useful "battery tool"

In this old forum entry: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1214872633 someone was having trouble with an SMBus device using the "Wire" library so they switched to an i2cmaster library and that worked. Perhaps that library will help with your problem.

Perfect! Works like a dream! Full control over ACK and NACK is exactly what I needed, and with the exception of a few "oops, didn't realize it didn't do that" - like turning on pull-ups and using i2c_start_wait() - it was a flawless conversion. Code blew up pretty big in size, though, to the tune of about 6.4kb, but meh, I'm not really going for efficiency

This is such a sweet sight to see, coming from 2 wires poking into the connector of a laptop battery (and a 12v/2a switching power supply providing the manual "but assisted" charging):

Here's the full code, now that it's working pretty well... this is based on a bq2040 "Gas Gauge IC with SMBus Interface". By tweaking the command parameters (sorry, I didn't #define them), it's pretty easy to adapt it to other batteries... all batteries that I know of use this SMBus interface

I'm trying to get battery monitor bq2060 working with arduino fio. I noticed there is huge similarity between my project and what you have done here (Relief!) Initially i started out with wire library but could not get my ic working. I have tried i2c sensors before so my coding wasnt a problem. While searching for alternative library, i found this page and i must thank you for making your code public.

I have few doubts and would appreciate your help. I downloaded i2c master library from here( http://homepage.hispeed.ch/peterfleury/avr-software.html) is this the one you're referring to? When i copy paste this folder in 'library' folder of arduino and import the library in arduino IDE , it isnt working.. Do you have any idea why this must be happening?

I have installed the library in Arduino.app/Contents/Resources/Java/Libraries/i2cmaster (I am on a Mac).I have renamed twimaster.c as twimaster.cpp and test_i2cmaster.c as test_i2cmaster.cpp.I have modified the F_CPU with value 16000000UL and the SCL_CLOCK with value 50000L in twimaster.cpp.I have created a keywords file (see it at the bottom of this message) and put it within the library's folder.

However there is something wrong because the code doesn't run. Even my basic Serial.print() instructions are not executed.What am I doing wrong

The start byte address for the AD7745/AD7746 is 0x90 for a write and 0x91 for a read.

You're right but I have tried 0x48 as well as 0x90 because 0x48 = 0x90 >> 1 and I wasn't sure 0x90 included the read/write bit or not. Finally 0x90 seems indeed the right address because 0x48 hangs the program and 0x90 doesn't.

However the problem was indeed that I2C_WRITE and I2C_READ were not defined. I thought they were constants defined by the library hence I didn't define them myself.