The JeeLib library includes two C++ classes called “PortI2C” and “DeviceI2C”, on which a lot of other code in JeeLib is based – derived classes for various plugs as well as several examples.
This stuff is well inside C++ territory, so if you’re not familiar with “OO design” it’s easy to get lost…
Let’s first look at what we’re trying to model:
In short: one port (any of the 4 on a JeeNode) is driven as an I2C bus using software bit-banging, and one or more I2C-type JeePlugs are attached to it. Each plug may or may not be of the same type.
What we want is a set of software modules which we can use in our sketch. Say we have three plugs, responding to I2C addresses 0x20, 0x21, and 0x22. Then the code might be something like:
const byte portNumber = 3; PortI2C myPort (portNumber); DeviceI2C plugOne (myPort, 0x20); DeviceI2C plugTwo (myPort, 0x21); DeviceI2C plugThree (myPort, 0x22);
This would set up three C++ objects, where each knows how to reach and control its own plug.
But that’s not all. Suppose plug #3 is a Memory Plug, i.e. an EEPROM memory of 128..512 kB. JeeLib contains extra support code to easily read and write data to such a plug, in the form of a C++ class called “MemoryPlug”. It’s an I2C device, but it always has a fixed bus address of 0x50, which for convenience is already built into the JeeLib code. To use this, all we have to do is replace that last plugThree definition above by this line:
MemoryPlug plugMem (myPort);
Once this works, we get a lot of functionality for free. Here’s how to send an I2C packet to plug #1:
plugOne.send(); plugOne.write(0x01); plugOne.write(0x02); plugOne.write(0x03); plugOne.stop();
Or you can save a 3-byte string to the Memory Plug, on page 12, at offset 21:
plugMem.save(12, "abc", 21, 3);
There’s a lot going on behind the scenes, but the result leads to a fairly clean coding style with all the details nicely tucked away. The question remains how this “tucking away” with C++ classes and objects is done.
Stay tuned, this will be described next week…