Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

I2C - difficulties on Netduino 2

i2c

Best Answer Jack Chidley, 04 May 2013 - 08:00 AM

I swapped to using 1k pull ups following the advice here: http://forums.netdui...s5611-sensor/">http://forums.netdui...-ms5611-sensor/, in parallel with the 10k on-board ones.  Incidentally I'm also using 1k pull ups (not in parallel) with another i2c device, the DS-2482, as 4.7k is not enough with my setup.

 

There is a fuller explanation here http://dsscircuits.c...esistors.html">http://dsscircuits.c...-resistors.html.  I think that my setup of leads, bread-board, etc has a lot higher capacitance than normal.  However it doesn't explain why the Arduino is more tolerant of this than the Netduino.  Perhaps the Neduino has a higher inherent capacitance on the I2C lines?

 

I am new to this hardware game.  I found that a logic analyser (the Saleae.com one is fantastic) essential.  I now think that an oscilloscope is necessary too - suggestions anyone?

Go to the full post


  • Please log in to reply
11 replies to this topic

#1 Jack Chidley

Jack Chidley

    Advanced Member

  • Members
  • PipPipPip
  • 99 posts

Posted 02 May 2013 - 06:42 PM

This code works on my Netduino Plus and at least once on the Netduino 2.  But it doesn't work reliably and, when I use a Saleae, there is no outputs on the SCA/SCL pins.  Nothing wrong with the compass module - it works fine on both an Arduino Uno and Leonardo.

using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace N2_HMC6352{    public class Program    {        public static void Main()        {            // write your code here            Compass myCompass = new Compass();            OutputPort Digital5 = new OutputPort(Pins.GPIO_PIN_D5, false);            while (true)            {                float heading = myCompass.ReadHeading();                Debug.Print(heading.ToString("F1") + "  ");                Thread.Sleep(1000);                Digital5.Write(!Digital5.Read());            }        }        public class Compass : IDisposable        {            // Set Constants for Address and Clock Frequency            const ushort HMC6352_ADDRESS = 0x42 >> 1;            const int CLOCK_FREQ = 100;            const int DELAY = 50;            //Write Buffer            byte[] A = new byte[] { 0x41 }; // A command            //Read Buffer            byte[] inBuffer = new byte[2];            //Init I2C Device Config            I2CDevice.Configuration config = new I2CDevice.Configuration(HMC6352_ADDRESS, CLOCK_FREQ);            //Init I2C Device & Read/Write Transactions            I2CDevice cmp;            I2CDevice.I2CWriteTransaction writeTrans;            I2CDevice.I2CReadTransaction readTrans;            public Compass()            {                // cmp = new I2CDevice(config);                cmp = new I2CDevice(new I2CDevice.Configuration(0x21, 100));                                writeTrans = I2CDevice.CreateWriteTransaction(A);                readTrans = I2CDevice.CreateReadTransaction(inBuffer);            }            public void Dispose()            {                cmp.Dispose();                config = null;                writeTrans = null;                readTrans = null;            }            public float ReadHeading()            {                //Execute Both Transactions and Return Heading as float with 0.1 deg resolution                I2CDevice.I2CTransaction[] transactions = new I2CDevice.I2CTransaction[] { writeTrans, readTrans };                cmp.Execute(transactions, DELAY);                int heading = inBuffer[0] * 256 + inBuffer[1];                float realHeading = (float)(heading / 10.0f);                return realHeading;            }        }    }}

Any ideas?  Before you ask, yes I am using the new SCL/SCA pins.

 

Netduino2 running latest firmware.



#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 03 May 2013 - 12:16 AM

Hi! The datasheet says the device used address 0x42 for writing and 0x43 for reading but you seem to use 0x21 for both. I don't think it matters but why do you create two i2c configs? What do you mean when you say it doesn't work reliably - doesn't work at all or works every other reading or so?

#3 NooM

NooM

    Advanced Member

  • Members
  • PipPipPip
  • 490 posts
  • LocationAustria

Posted 03 May 2013 - 02:51 AM

the address is 0x21, you dont have to care abour read and write address, the i2c driver does it on its own

 

i also wouldnt wonder if you get strange results, that doesent look correctly - you read 2 bytes -

thats a bit few for 3 angles

 

i honestly havent looked at the datasheet, but i have a hmc5883l

 

i do it something like that:

read 6 bytes for the correct register..

 

byte[] buffer = new byte[6];

 

distance.X = ToInt16(buffer[0], buffer[1]) * 0.92f;

distance.Y = ToInt16(buffer[4], buffer[5]) * 0.92f;

rotation = (

 

Single)Math.Atan2(distance.Y, distance.X)

* 180f / (

 

Single)Math.PI + 180f;



#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 03 May 2013 - 06:41 AM

Ok, so the slave addresses 0x42 and 0x43 include the r/w bit. I don't get why some state the slave address with the r/w bit and some without.



#5 Jack Chidley

Jack Chidley

    Advanced Member

  • Members
  • PipPipPip
  • 99 posts

Posted 03 May 2013 - 05:00 PM

The issue is either hardware, the I2C drivers or my misuse of the same.  My application level code may or may not be great.  But, whatever happens I should see something on the trace.  I should see the Netduino sending stuff to the slave.  The device has 10k pull ups on board for both SCL/SDA.

 

When I look at the Saleae Logic trace, there is nothing happening - no clock, no data, etc.  Both lines are correctly pulled-up and this is a working electrical setup with the Arduinos, same commands etc.

 

The slave address is 0x42 (bit shifted by 1 is 0x21) - and the "A" is a command to send back data.

 

This is just a compass, so it's the heading in degress, hence 2 bytes.

 

Config's in there twice because I hard coded it the second time (and left in the first).  Didn't help.

 

Removed the I2C slave, connected SCL, SDA to 4k7 pull up resistors.  Still nothing on the trace.



#6 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 03 May 2013 - 05:48 PM

You are right, no point in discussing other stuff, you should see something. What if you disconnect the compass but keep the pullups, see something then and what voltage do you measure on each of the lines? And surely, when you wrote "SCL/SCA pins" you meant "scl/sda" and in that order from left to right when looking at the board with the usb receptacle pointing to the left?

#7 Jack Chidley

Jack Chidley

    Advanced Member

  • Members
  • PipPipPip
  • 99 posts

Posted 03 May 2013 - 06:59 PM

I'm now using different code below. Shorter program with the on board LED and D5 used to see what's happening.

 

It's doing something during the execute - when I change Delay to 6000 it add 6 sec to the inner loop.  I take it that the delay is in milli secs: the documentation on MSDN isn't clear.

using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace N2_I2C{    public class Program    {        public static void Main()        {            // write your code here            OutputPort LED = new OutputPort(Pins.ONBOARD_LED, false);            OutputPort D5 = new OutputPort(Pins.GPIO_PIN_D5, false);            I2CDevice i2cTest = new I2CDevice(new I2CDevice.Configuration(0x21, 100));            I2CDevice.I2CWriteTransaction writeTrans;            I2CDevice.I2CReadTransaction readTrans;            //Write Buffer            byte[] A = new byte[] { 0x41 }; // A command            //Read Buffer            byte[] inBuffer = new byte[2];            writeTrans = I2CDevice.CreateWriteTransaction(A);            readTrans = I2CDevice.CreateReadTransaction(inBuffer);            while (true)            {                //Execute Both Transactions and Return Heading as float with 0.1 deg resolution                I2CDevice.I2CTransaction[] transactions = new I2CDevice.I2CTransaction[] { writeTrans, readTrans };                i2cTest.Execute(transactions, 6);                LED.Write(!LED.Read());                D5.Write(!D5.Read());                Thread.Sleep(100);             }        }    }}

 

I'm using a Netduino 2 and plugging the stuff into the, labelled, SDA and SCL lines.  They're helpfully labelled on both the Netduino and the HMC6352 module.



#8 Jack Chidley

Jack Chidley

    Advanced Member

  • Members
  • PipPipPip
  • 99 posts

Posted 03 May 2013 - 07:06 PM

Very, very odd. Nothing working until I accidentally rebooted the Netduino with the SCL/SDA lines unplugged and then plugged them back in before the program had started (thank god I used the LED so I could tell). Don't know what's going on... but might be closer to a reproducible error. Delay isn't milli secs. 6 appears to be 60 micro secs.

 

unplugging and replugging the SCL/SDA lines changes things: sometimes nothing on the trace, sometimes just a continuous clock, very rarely the correct trace.



#9 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 03 May 2013 - 07:28 PM

Maybe delay is given in clock cycles, at 100kHz a cycle is 10us and thus 6 cycles is 60us. Makes sense since some devices need delays which are sometimes specified in cycles. Naturally, that does not explain the odd behavior. I normally use 4k7 pullups, what happens if you try that or even just 2k?

#10 Jack Chidley

Jack Chidley

    Advanced Member

  • Members
  • PipPipPip
  • 99 posts

Posted 04 May 2013 - 08:00 AM   Best Answer

I swapped to using 1k pull ups following the advice here: http://forums.netdui...s5611-sensor/">http://forums.netdui...-ms5611-sensor/, in parallel with the 10k on-board ones.  Incidentally I'm also using 1k pull ups (not in parallel) with another i2c device, the DS-2482, as 4.7k is not enough with my setup.

 

There is a fuller explanation here http://dsscircuits.c...esistors.html">http://dsscircuits.c...-resistors.html.  I think that my setup of leads, bread-board, etc has a lot higher capacitance than normal.  However it doesn't explain why the Arduino is more tolerant of this than the Netduino.  Perhaps the Neduino has a higher inherent capacitance on the I2C lines?

 

I am new to this hardware game.  I found that a logic analyser (the Saleae.com one is fantastic) essential.  I now think that an oscilloscope is necessary too - suggestions anyone?



#11 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 04 May 2013 - 06:37 PM

Good you solved it!

Here's my standard answer: Go get a Rigol ds1052e and you won't regret it.

http://www.eevblog.c...-rigol-ds1052e/
http://www.rigolna.c...s1000e/ds1052e/
http://www.batronix....ol-DS1052E.html

It's a great scope with great value for money plus it can be hacked into doing 100Mhz:
http://www.eevblog.c...he-dummy-guide/

#12 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 04 May 2013 - 07:50 PM

I second hanzibals suggestion on the inexpensive Rigol scope.  mine came in just a day before I experienced my own i2c problem, and it made short work of it.  (and also of the next problem, which arose from a software i2c impl not doing the final ack correctly).  I would also point out that, since the 100mhz hack for the rigol leaked out a couple years ago, Rigol has adjusted their pricing such that the 100mhz version is less than $100 more than the 50mhz.  Maybe something to think about relative to time to hack and any warranty concerns....  Also, I think the Atten scope is the same hardware rebadged (or maybe rigol is a rebadged atten, or....)







0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.