Netduino home hardware projects downloads community

Jump to content


Photo

Trying to communicate with a 24LC256


  • Please log in to reply
19 replies to this topic

#1 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 18 May 2011 - 07:00 PM

Hi :)

I have connected a 24LC256 to the Netduino and try to communicate with it. I used the schematic found at http://grokthink.com/wordpress/?p=395 and the code below, but it gives errors on "this._IcDevice.Execute(WriteTransaction, 100);" in Ic24LC256.Write().

#### Exception System.ArgumentException - 0xfd000000 (1) ####
#### Message:
#### Microsoft.SPOT.Hardware.I2CDevice::Execute [IP: 0000] ####
#### NetduinoApplication1.Ic24LC256::Write [IP: 0039] ####
#### NetduinoApplication1.Program::Main [IP: 001a] ####
A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll
An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll

namespace NetduinoApplication1
{
    public class Program
    {
        public static void Main()
        {
            // write your code here

            Ic24LC256 Storage = new Ic24LC256(false, false, false);
            Storage.Write(0, (new byte[] { 0, 46, 125, 0, 0, 224, 183 }));
        }

    }

    /// <summary>
    /// 24LC256 EEPROM IC
    /// </summary>
    public class Ic24LC256
    {
        /// <summary>
        /// Contains the IC's address
        /// </summary>
        private ushort _Address;

        /// <summary>
        /// Reference to the IC on the I2C bus
        /// </summary>
        private I2CDevice _IcDevice;

        /// <summary>
        /// Defines a 24LC256 EEPROM IC
        /// </summary>
        /// <param name="Address">The IC's address</param>
        public Ic24LC256(byte Address)
        {
            this._Address = Address;
            this._Init();
        }

        /// <summary>
        /// Defines a 24LC256 IC
        /// </summary>
        /// <param name="A0">Address pin 0 state (False = Low/Gnd, True = High/Vcc)</param>
        /// <param name="A1">Address pin 1 state (False = Low/Gnd, True = High/Vcc)</param>
        /// <param name="A2">Address pin 2 state (False = Low/Gnd, True = High/Vcc)</param>
        public Ic24LC256(bool A0, bool A1, bool A2)
        {
            this._Address = (byte)(0x50 + (A0 ? 1 : 0) + (A1 ? 2 : 0) + (A2 ? 4 : 0));
            this._Init();
        }

        public void Read(UInt16 Address, byte[] ReadBuffer)
        {
            // Splits the address in two bytes
            byte[] AddressBytes = {
                                      (byte)(Address >> 8),   // most significant address byte
                                      (byte)(Address & 0xff)  // least significant address byte
                                  };

            // Queues the transaction (first write the address, then read the response)
            I2CDevice.I2CTransaction[] ReadTransaction = { 
                                                             I2CDevice.CreateWriteTransaction(AddressBytes),
                                                             I2CDevice.CreateReadTransaction(ReadBuffer) 
                                                         };
            
            // Executes the transaction
            this._IcDevice.Execute(ReadTransaction, 100);
        }

        public void Write(UInt16 Address, byte[] WriteBuffer)
        {
            // Splits the address in two bytes
            byte[] AddressBytes = {
                                      (byte)(Address >> 8),   // most significant address byte
                                      (byte)(Address & 0xff)  // least significant address byte
                                  };

            // Queues the transaction (first write the address, then write the data)
            I2CDevice.I2CTransaction[] WriteTransaction = {
                                                              I2CDevice.CreateWriteTransaction(AddressBytes),
                                                              I2CDevice.CreateWriteTransaction(WriteBuffer)
                                                          };
            
            // Executes the transaction
            this._IcDevice.Execute(WriteTransaction, 100);
        }

        /// <summary>
        /// Initiates the I2C-bus
        /// </summary>
        private void _Init()
        {
            I2CDevice.Configuration IcConfig = new I2CDevice.Configuration(this._Address, 115200);
            this._IcDevice = new I2CDevice(IcConfig);
        }
    }
}

Now I have a simple question: help! :D
What am I doing wrong?
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#2 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1072 posts
  • LocationNorth Yorkshire, UK

Posted 18 May 2011 - 07:16 PM

Now I have a simple question: help! :D
What am I doing wrong?

Are you confusing the addresses? There are two addresses at play here, one if the address of the device (which looks to be 0x50) and the other is the address you wish to write to.

Looking at the blog you mention, I would be looking to create and I2C object which is talking to the device at address 0x50. I'm not sure where A0-A2 come into the picture when you try to set up the address in the constructor.


Hope this helps.
Mark

To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#3 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 18 May 2011 - 07:18 PM

According to the specs, A0 to A2 can modify the chips I2C address from 0x50 to 0x57. When I do a Debug.Print( this._Address ); it gives 80 back, which is in fact 0x50. I just made it configurable so it's possible in the end to use all possible addresses.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#4 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 18 May 2011 - 07:19 PM

What am I doing wrong?

IMHO the clock rate parameter in the I2CDevice.Configuration (115200) is out of range - 24LC256 supports clock frequency up to 400 kHz (so the value should be <= 400). And, you'd need beta firmware with I2C repeated start condition support for random read/write operations that take an address parameter.

#5 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 18 May 2011 - 07:24 PM

IMHO the clock rate parameter in the I2CDevice.Configuration (115200) is out of range - 24LC256 supports clock frequency up to 400 kHz (so the value should be <= 400). And, you'd need beta firmware with I2C repeated start condition support for random read/write operations that take an address parameter.


:o clockrateKHz, I read 'ClockrateHz'... big difference!

Silly me :)
Just had the above routine with adjusted speed runned without problems. Now going to experiment some more. Thanks !

-edit- hmm I read only zeroes... think something is still wrong :) But for now I'm OK. Lets figure this out :D

Edited by Stefan, 18 May 2011 - 07:26 PM.

"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#6 EvanLaske

EvanLaske

    New Member

  • Members
  • Pip
  • 6 posts

Posted 18 May 2011 - 09:43 PM

I know your problem was fixed, but you might want to look into this code on the forums:

I2C EEPROM "Library"

It uses the I2CBus class from Fusionware to implement an EEPROM API, which the 24LC256 is part of. I am working on improving a couple things on it, but it works well. I haven't tested random read/write operations with it, but then again, I am running the current release firmware (not beta).

Just thought it might save you some time.

Edit: I decided to test the random read/write, and it worked even with the stock firmware. Although, I am using an off-brand chip currently (CAT24C256), I originally was using the Microchip chip.

Edited by EvanLaske, 18 May 2011 - 09:50 PM.


#7 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 21 May 2011 - 11:33 PM

Actually, my code wasn't far from working, but my schematic was :D I'll post a brief overview of the requirements tomorrow. Now it's bedtime. Glad I have this working though!
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#8 sky

sky

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationMoscow, Russia

Posted 14 November 2011 - 03:33 PM

Hello all!
I'm reading all the zeroes too -)
Was the problem resolved? I have the 24LC256

I also tried to use EEPROM library attached above, but from the box I receive the exception:

int byteCount = this.Device.Execute(xacts, TimeOut);
  if(byteCount < ReadBuffer.Length)
    throw new System.IO.IOException();


#9 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 14 November 2011 - 03:46 PM

Hi sky and welcome to the forums! I got it working with that library. Strange that yours doesn't. Did you wire it correctly? Did you use the correct pullup resistors?
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#10 sky

sky

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationMoscow, Russia

Posted 15 November 2011 - 06:31 AM

It seems that all the parts wired properly. And I used 10k resistors as pullup. I also tried the final schematic with the Bus Pirate and it worked. Both Bus Pirate and Netduino connect to 24LC256 via I2C. I can write to and read from this IC gracefully via BP. But when I try to run the C# test, it fails %)

Can you provide your working piece of code here?

#11 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 15 November 2011 - 06:39 AM

Is the EEProm powered at +3.3V or +5V?
Biggest fault of Netduino? It runs by electricity.

#12 sky

sky

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationMoscow, Russia

Posted 15 November 2011 - 06:47 AM

Hello, Mario, According to the datasheet, it can be powered both 3.3 and 5V. Now I have it connected to +5V, but also unsuccessfully tried with 3.3V. Moreover, both 3.3 and 5V works with 24LC256 being connected to Bus Pirate.

#13 sky

sky

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationMoscow, Russia

Posted 15 November 2011 - 07:07 AM

It seems to me that I'm stupid. I missed the word "Analog" in Netduino I2C pin description. Connected to analog pins 4-5, the library doesn't throw an exceptions and "Netduino!" string was written and read good. I'll try to work with it. Thank you, guys! -)

#14 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 15 November 2011 - 07:38 AM

It seems to me that I'm stupid. I missed the word "Analog" in Netduino I2C pin description.
Connected to analog pins 4-5, the library doesn't throw an exceptions and "Netduino!" string was written and read good.
I'll try to work with it. Thank you, guys! -)

Great to read it's solved :D
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#15 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 15 November 2011 - 08:15 AM

Sky, I'm happy that you solved the problem... ...however, it's not the same thing powering the chip at +5V or +3.3V. Your Netduino works at +3.3V, and the EEProm specs say that the high-level min threshold is 0.7*Vcc (that is 3.5V when powered at +5V). It seems to me that you'll have the EEProm working at the borderline, thus the reliability won't be so good. I'd keep the EEprom supplied at +3.3V, which is always more common as voltage for the logic circuits. Cheers
Biggest fault of Netduino? It runs by electricity.

#16 sky

sky

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationMoscow, Russia

Posted 15 November 2011 - 01:35 PM

Sky, I'm happy that you solved the problem...
...however, it's not the same thing powering the chip at +5V or +3.3V.
Your Netduino works at +3.3V, and the EEProm specs say that the high-level min threshold is 0.7*Vcc (that is 3.5V when powered at +5V). It seems to me that you'll have the EEProm working at the borderline, thus the reliability won't be so good.
I'd keep the EEprom supplied at +3.3V, which is always more common as voltage for the logic circuits.
Cheers


Mario, you're right. It's better not to mix different voltages within one scheme to avoid borderline problems. Or, do it carefully =) The thing I discovered in this library - the _24LC01::Write function waits for a 100ms to give 24LC256 some time to finish. Respecting to the datasheet, the bus is not busy, when the data and clock remain high. I think it's possible to poll the lines to determine the end of the transaction and exit earlier then 100ms elapses.

#17 kiwi65

kiwi65

    Member

  • Members
  • PipPip
  • 23 posts

Posted 14 June 2015 - 01:10 AM

Hi Guys, this is a really really old thread I know.... but after several days struggling to get my 24LC256 eeprom working I'm stuck. 

 

Here's the setup .....

 

Hardware: It's wired with (A0, A1 and A2) to Gnd giving an I2C bus address of 0x50. WP and Vcc are wired to Gnd enabling write operations. SCL and SDA connected to my Mini, and I've used two 4k7 pullups. Both the Mini and the 24LC256 are powered with 5v.

 

Software: Have tried lots of variants on the same theme, but have now implemented/copied Stefan code above with a variation to return the byte count returned by i2c.Execute(..), and to accept CLockRate and bus timeouts as constructor parameters.

        private static void Test24LC256()
        {
            OutputPort sda = new OutputPort(Pins.GPIO_PIN_9, Hardware.Helpers.High);
            Thread.Sleep(200);
            sda.Write(Hardware.Helpers.Low);
            sda.Dispose();

            const byte ff = 0xff;
            const int Address = 0x00;
            const int ClockSpeed = 100;
            const int TimeoutMilliseconds = 500;
            byte[] buffer = new[] {ff,ff,ff,ff,ff,ff,ff,ff,ff,ff};

            Ic24LC256 storage = new Ic24LC256(false, false, false, ClockSpeed, TimeoutMilliseconds);
            Debug.Print("Write> " + storage.Write(Address, (new byte[] {0, 46, 125, 0, 0, 224, 183})));
            Debug.Print("Read> " + storage.Read(Address, buffer));
        }

The output is:

Write> 9

Read> 2

 

and buffer contains a full set of 0xff's

 

The Write count of 9 looked good.. until I tried removing the power from the eeprom... and the code returned the same result..!!

The Read count never looked good. The number returned here is the length of the byte buffer used in CreateWriteTransaction used to set the read address. If I make that buffer [n] long, then the Read count shows [n]. In all cases the read buffer is untouched - it contains the same contents it was initialised with, in the code above 0xff's

 

Suggestions anyone?  Stefan... you wouldn't happen to still have your hardware diagram?

 

Update: Just discovered that I can remove the 24LC256 from my breadboard and the software works identically to when the chip is inserted. Look to me the the Mini isn't talking I2C at all. Very odd.



#18 HSven1611

HSven1611

    Member

  • Members
  • PipPip
  • 14 posts

Posted 15 June 2015 - 11:27 AM

Did you use Pull Up Resistors on your IC Bus?



#19 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 15 June 2015 - 09:29 PM

Hi kiwi65,

Are you using the built-in I2C feature of NETMF...or software I2C?

Chris

#20 kiwi65

kiwi65

    Member

  • Members
  • PipPip
  • 23 posts

Posted 16 June 2015 - 05:29 AM

Hi Chris, Using the standard NetMF code:

    public class Ic24LC256
    {
        private readonly int _clockKhz;
        private readonly int _timeoutMilliseconds;

        /// <summary>
        ///     Contains the IC's address
        /// </summary>
        private readonly ushort _Address;

        /// <summary>
        ///     Reference to the IC on the I2C bus
        /// </summary>
        private I2CDevice _IcDevice;

        /// <summary>
        ///     Defines a 24LC256 EEPROM IC
        /// </summary>
        /// <param name="Address">The IC's address</param>
        public Ic24LC256(byte Address)
        {
            _Address = Address;
            _Init();
        }

        /// <summary>
        ///     Defines a 24LC256 IC
        /// </summary>
        /// <param name="A0">Address pin 0 state (False = Low/Gnd, True = High/Vcc)</param>
        /// <param name="A1">Address pin 1 state (False = Low/Gnd, True = High/Vcc)</param>
        /// <param name="A2">Address pin 2 state (False = Low/Gnd, True = High/Vcc)</param>
        public Ic24LC256(bool A0, bool A1, bool A2, int clockKhz, int timeoutMilliseconds)
        {
            _Address = (byte) (0x50 + (A0 ? 1 : 0) + (A1 ? 2 : 0) + (A2 ? 4 : 0));
            _clockKhz = clockKhz;
            _timeoutMilliseconds = timeoutMilliseconds;
            _Init();
        }

        public int Read(UInt16 Address, byte[] ReadBuffer)
        {
            // Splits the address in two bytes
            byte[] AddressBytes =
            {
                (byte) (Address >> 8), // most significant address byte
                (byte) (Address & 0xff) // least significant address byte
            };

            // Queues the transaction (first write the address, then read the response)
            I2CDevice.I2CTransaction[] ReadTransaction =
            {
                I2CDevice.CreateWriteTransaction(AddressBytes),
                I2CDevice.CreateReadTransaction(ReadBuffer)
            };

            // Executes the transaction
            return (_IcDevice.Execute(ReadTransaction, _timeoutMilliseconds));
        }

        public int Write(UInt16 Address, byte[] WriteBuffer)
        {
            // Splits the address in two bytes
            byte[] AddressBytes =
            {
                (byte) (Address >> 8), // most significant address byte
                (byte) (Address & 0xff) // least significant address byte
            };

            // Queues the transaction (first write the address, then write the data)
            I2CDevice.I2CTransaction[] WriteTransaction =
            {
                I2CDevice.CreateWriteTransaction(AddressBytes),
                I2CDevice.CreateWriteTransaction(WriteBuffer)
            };

            // Executes the transaction
            return (_IcDevice.Execute(WriteTransaction, _timeoutMilliseconds));
        }

        /// <summary>
        ///     Initiates the I2C-bus
        /// </summary>
        private void _Init()
        {
            var IcConfig = new I2CDevice.Configuration(_Address, _clockKhz);
            _IcDevice = new I2CDevice(IcConfig);
        }
    }

I've played with I2C InternalAddress (repeated start bit) support, but to no avail. It was about then I discovered that removing the eeprom from my breadboard made no difference to the program output.... leading me to think I2C just isn't working at all.

 

Appreciate your help .. this problem is driving me nuts. Well... more nuts than my colleagues already take me for :)






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.