@ Brett - well, even before I read the Arduino article, just by reading the documentation for the chip, I put together the 0’s and 1’s and assumed there should be an missing 0 I front to get the 8 bits - thereby getting the wrong address just because I misinterpreted the information from about I2C in the article under help on this site. I was sure there had to be 8 bits as we always talk about 8bits/1byte in context of computers. That’s why the article I linked to was so helpful, because it explained the stuff about people thinking wrong about it - even chip makers when they write documentation. And it also tells you how you could spot the errors in addresses.
But the 7-bit versus 8-bit information is explicitly called out in here
https://www.ghielectronics.com/docs/12/i2c at least twice. Propose a change, lets see how we can make it better?? I agree, lets try to make it crystal clear
There are 3 lines of information about a topic that 100% of users fail to understand.
I really don’t understand this good enough (yet) to come up with a good recipe. But it’s clear that something needs to be rewritten. I know from other areas that it’s hard to write basic documentation about stuff you know well, because you take for granted much of the basic knowledge you have - witch is essential to get this up and running.
I don’t understand this…
Spawning off a simple background thread and trying different addresses should eventually find the chip(s)… but it’s a no-go. Anyone care to enlighten me?
Code used:
void ProgramStarted()
{
Debug.Print("Program Started");
GT.Timer timer1 = new GT.Timer(500);
timer1.Tick += timer1_Tick;
timer1.Start();
Thread t1 = new Thread(new ThreadStart(ThreadStartT1));
t1.Start();
}
void timer1_Tick(GT.Timer timer)
{
// pulse debug led to show signs of life
this.PulseDebugLED();
}
ushort ta = 0x00;
private void ThreadStartT1()
{
I2CDevice.Configuration config = null;
I2CDevice device = null;
while (true)
{
if (ta > 0xFF) ta = 0x00;
config = null;
device = null;
char_Display.Clear();
char_Display.PrintString("addy: 0x" + ta.ToString("X2"));
char_Display.SetCursor(1, 0);
try
{
config = new I2CDevice.Configuration(ta, 100);
if (config == null) char_Display.PrintString("config == null");
Thread.Sleep(5);
device = new I2CDevice(config);
if (device == null) char_Display.PrintString("device == null");
Thread.Sleep(5);
var result = device.GetRegisters(config, 500, 0x00, 2);
char_Display.PrintString("result.len: " + result.Length);
char_Display.SetCursor(1, 0);
char_Display.PrintString("0: " + result[0].ToString());
char_Display.SetCursor(1, 8);
char_Display.PrintString("1: " + result[1].ToString());
if (result[0] != 0 && result[1] != 0)
{
char_Display.SetCursor(0, 14);
char_Display.PrintString("OK");
break;
}
}
catch
{
char_Display.PrintString("cfg=" + (config == null ? "null " : "obj "));
char_Display.PrintString("dev=" + (device == null ? "null" : "obj" ));
}
ta++;
Thread.Sleep(100);
}
while (true)
{
char_Display.Clear();
var result = device.GetRegisters(config, 500, 0x00, 2);
char_Display.PrintString("result.len: " + result.Length);
char_Display.SetCursor(1, 0);
char_Display.PrintString("0: " + result[0].ToString());
char_Display.SetCursor(1, 8);
char_Display.PrintString("1: " + result[1].ToString());
Thread.Sleep(1000);
}
}
It newer gets out of the first loop… it can sit forever, but it does throw an InvalidOperationException every time it tries to create a new Device…
If Config is null wouldnt you want to go to the next address without hitting device = new I2CDevice(config); ?
@ Justin - well, yes. But config is always an object, so that is not an issue here, but in production code, then you are right. It’s always the code that creates a new device that fails…
Call Dispose on previous device, before creating a new one.
On a second thought, create I2CDevice instance once and just switch the Config property every time you are trying a new address. This is the way you supposed to work with I2C bus and multiple devices anyways.
@ Architect - disposing it before recreating did the trick ;D
Testing 3 different sensors:
I do not see the GetRegisters method:
var result = device.GetRegisters(config, 500, 0x00, 2);
I have not upgraded to sdk package R3 yet. Is this method in the new sdk?
@ Bill_Wyo - ExtentionMethod
@ danibjor - Glad you got it working. Switching the Config is still a more proper way of doing it.
@ Architect - thanks for all the help! I just needed to get this think working - just a single sign of life is enough to get the faith back in this stuff
I guess I should rewrite it (the right way) to a proper driver now as I got the basics in place.
You are welcome!
Cleaned up the code and made a gadgeteer driver out of all this mess. It’s to be found here: https://www.ghielectronics.com/community/codeshare/entry/827
Good job!