Close

I²C troubles & MCU ideas

A project log for Modular Vertical Farming

Growing food where it's needed, ready to be sold.

alphaninjaalpha_ninja 04/19/2015 at 21:380 Comments

I²C is great.

When it works.

I've been doing a lot of work on the controller-module communication—and, while doing so, I've learned a lot.

  1. The Raspberry Pi I²C implementation would be a lot better if it had support for clock stretching.
    (I probably won't be using πs as part of this project.)
  2. The Arduino Wire library, which I'm probably going to use, has a really weird bug. I'm not sure if it's specific to that library, but it's annoying as all hell

So, want to know more about that bug?

Here it is.

Yep.

So, using the line of code you'll find anywhere when you search for "arduino change i2c frequency", this mess comes out. I'm assuming the stuff at the far left is a result of the exponential curves being shorter than I could detect using 1kHz steps. I'm using an Arduino UNO as master and Arduino NG as slave. I'm using this code:

TWBR = ((16000000L / I2C_HZ) - 16) / 2;

If you're wondering, I've been experimenting around mostly to see what frequencies I can safely use for this project - the signal will have to go several meters, after all.


On a slightly unrelated note: I've been thinking about I²C addresses. Here's my thoughts.

I've decided it makes most sense to add a few pins to the module-frame connections to tell modules where they are (and use that to calculate their address). This means 6 extra pins are needed per module. Theoretically, less could be used with voltage-dividing by resistors and using the analog inputs on the AVRs.

The addresses should then be assigned based on the top-left position of the module.

The address for a given spot is:

(row + 1) << 3 + col

Thus, each controller should have, at most, 8x8 space for modules (that's 2,40m × 2,40m or [7' 10.5" × 7' 10.5"]). I think this should be enough.

Examples of addresses (with (x | y) positions):

top left (0 | 0) - 0001000
bottom left (0 | 7) - 1000000
top right (7 | 0) - 1000000
bottom right (7 | 7) - 1000111

The reason for the row codes starting at one is that some I²C addresses beginning with 000 or 111 are reserved.

This method leaves addresses beginning with 101, 110, 0001, and 1110 completely free (that's 48 additional slaves, while leaving the possibility for future use of 10-bit addresses open)

Of course, it is possible to use I²C switches, but I doubt that will be necessary for my prototypes.


Another thing: I'll probably use AtMEGA168s for the modules. They seem to be the cheapest AtMEGAs on mouser (in a SMD package), and the AtTINYs I was considering (AtTINY441 - the simplest ones with EEPROM and TWI / I²C) are cheaper by only a few cents and not quite as strong.

For the controllers, a normal arduino is probably all that's necessary. I'll probably use an ethernet connection in the future.

Discussions