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 0×20, 0×21, and 0×22. 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 0×50, 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…