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

Send Bytes over I2C.


  • Please log in to reply
8 replies to this topic

#1 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 19 September 2012 - 06:58 AM

Hi community,

i trying to send and revive bytes over I2C from a PCF8574(A).
But i found only some "Revivers", not send-samples, and i need help to learn and understand the I2C-Bus with the NetduinoPlus.
What i try:
Send Address and Bytes (To turn a led on / off)
Revive Bytes and "Sender Address" from a button (over the PCF8574-IC)

I would be grateful, when you help me with some informations or a sample.
I just readed some I2C-Theories and how it works, but i dont have the "know-how" to make it on the netduino :(

mfg

gfcwfzkm

EDIT:// i found a sample code, but it show me a error (line 11)-> Implements IDisposable
Public Class I2CBus
        Implements IDisposable
        Private Shared _instance As I2CBus = Nothing
        Private Shared ReadOnly LockObject As New Object()

        Public Shared Function GetInstance() As I2CBus
            SyncLock LockObject
                If _instance Is Nothing Then
                    _instance = New I2CBus()
                End If
                Return _instance
            End SyncLock
        End Function


        Private _slaveDevice As I2CDevice

        Private Sub New()
            Me._slaveDevice = New I2CDevice(New I2CDevice.Configuration(0, 0))
        End Sub

        Public Sub Dispose()
            Me._slaveDevice.Dispose()
        End Sub

        ''' <summary>
        ''' Generic write operation to I2C slave device.
        ''' </summary>
        ''' <param name="config">I2C slave device configuration.</param>
        ''' <param name="writeBuffer">The array of bytes that will be sent to the device.</param>
        ''' <param name="transactionTimeout">The amount of time the system will wait before resuming execution of the transaction.</param>
        Public Function Write(ByVal config As I2CDevice.Configuration, ByVal writeBuffer As Byte(), ByVal transactionTimeout As Integer) As Integer
            ' Set i2c device configuration.
            _slaveDevice.Config = config

            ' create an i2c write transaction to be sent to the device.
            Dim writeXAction As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction() {I2CDevice.CreateWriteTransaction(writeBuffer)}

            SyncLock _slaveDevice
                ' the i2c data is sent here to the device.
                Dim transferred As Integer = _slaveDevice.Execute(writeXAction, transactionTimeout)

                ' make sure the data was sent.
                If transferred <> writeBuffer.Length Then
                    Throw New Exception("Could not write to device.")
                End If

                Return transferred
            End SyncLock
        End Function

        ''' <summary>
        ''' Generic read operation from I2C slave device.
        ''' </summary>
        ''' <param name="config">I2C slave device configuration.</param>
        ''' <param name="readBuffer">The array of bytes that will contain the data read from the device.</param>
        ''' <param name="transactionTimeout">The amount of time the system will wait before resuming execution of the transaction.</param>
        Public Function Read(ByVal config As I2CDevice.Configuration, ByVal readBuffer As Byte(), ByVal transactionTimeout As Integer) As Integer
            ' Set i2c device configuration.
            _slaveDevice.Config = config

            ' create an i2c read transaction to be sent to the device.
            Dim readXAction As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction() {I2CDevice.CreateReadTransaction(readBuffer)}

            SyncLock _slaveDevice
                ' the i2c data is received here from the device.
                Dim transferred As Integer = _slaveDevice.Execute(readXAction, transactionTimeout)

                ' make sure the data was received.
                If transferred <> readBuffer.Length Then
                    Throw New Exception("Could not read from device.")
                End If

                Return transferred
            End SyncLock
        End Function

        ''' <summary>
        ''' Read array of bytes at specific register from the I2C slave device.
        ''' </summary>
        ''' <param name="config">I2C slave device configuration.</param>
        ''' <param name="register">The register to read bytes from.</param>
        ''' <param name="readBuffer">The array of bytes that will contain the data read from the device.</param>
        ''' <param name="transactionTimeout">The amount of time the system will wait before resuming execution of the transaction.</param>
        Public Sub ReadRegister(ByVal config As I2CDevice.Configuration, ByVal register As Byte, ByVal readBuffer As Byte(), ByVal transactionTimeout As Integer)
            Dim registerBuffer As Byte() = {register}
            Write(config, registerBuffer, transactionTimeout)
            Read(config, readBuffer, transactionTimeout)
        End Sub

        ''' <summary>
        ''' Write array of bytes value to a specific register on the I2C slave device.
        ''' </summary>
        ''' <param name="config">I2C slave device configuration.</param>
        ''' <param name="register">The register to send bytes to.</param>
        ''' <param name="writeBuffer">The array of bytes that will be sent to the device.</param>
        ''' <param name="transactionTimeout">The amount of time the system will wait before resuming execution of the transaction.</param>
        Public Sub WriteRegister(ByVal config As I2CDevice.Configuration, ByVal register As Byte, ByVal writeBuffer As Byte(), ByVal transactionTimeout As Integer)
            Dim registerBuffer As Byte() = {register}
            Write(config, registerBuffer, transactionTimeout)
            Write(config, writeBuffer, transactionTimeout)
        End Sub

        ''' <summary>
        ''' Write a byte value to a specific register on the I2C slave device.
        ''' </summary>
        ''' <param name="config">I2C slave device configuration.</param>
        ''' <param name="register">The register to send bytes to.</param>
        ''' <param name="value">The byte that will be sent to the device.</param>
        ''' <param name="transactionTimeout">The amount of time the system will wait before resuming execution of the transaction.</param>
        Public Sub WriteRegister(ByVal config As I2CDevice.Configuration, ByVal register As Byte, ByVal value As Byte, ByVal transactionTimeout As Integer)
            Dim writeBuffer As Byte() = {register, value}
            Write(config, writeBuffer, transactionTimeout)
        End Sub

    End Class


#2 baxter

baxter

    Advanced Member

  • Members
  • PipPipPip
  • 415 posts

Posted 21 September 2012 - 06:04 PM

Have you looked at the datasheets? http://www.ti.com/li...ink/pcf8574.pdf http://www.ti.com/li...nk/pcf8574a.pdf Your post mentions two different parts. Maybe you are using the the wrong interface address. pcf8574 has I2C address = 0100 xxx and pcf8574a has I2C address = 0111 xxx Baxter

#3 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 22 September 2012 - 07:13 AM

Thanks, but at the moment its more a "Code Problem" ^^

Im trying to that the netduino send anything.
I changed the code (no errors in VB), but always crashed, when i try to use it

Im try to see the singals over a Osziliscope.

Here my changed code:
Imports Microsoft.SPOT.Hardware
Imports Microsoft.SPOT.Hardware.I2CDevice

Namespace Programs

    Public Class I2CPlug
        Private Const DefaultClockRate As Integer = 1000
        Private Const TransactionTimeout As Integer = 1600

        Private i2cConfig As Configuration
        Private i2cDevice As I2CDevice

        Public Property Address() As Byte
            Get
                Return m_Address
            End Get
            Private Set(ByVal value As Byte)
                m_Address = value
            End Set
        End Property
        Private m_Address As Byte

        Public Sub New(ByVal address As Byte, ByVal clockRateKhz As Integer)
            Me.Address = address
            Me.i2cConfig = New Configuration(Me.Address, clockRateKhz)
            Me.i2cDevice = New I2CDevice(Me.i2cConfig)
        End Sub
        Public Sub New(ByVal address As Byte)
            Me.New(address, DefaultClockRate)
        End Sub

        Private Sub Write(ByVal writeBuffer As Byte())
            ' create a write transaction containing the bytes to be written to the device
            Dim writeTransaction As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction() {i2cDevice.CreateWriteTransaction(writeBuffer)}

            ' write the data to the device
            Dim written As Integer = Me.i2cDevice.Execute(writeTransaction, TransactionTimeout)

            While written < writeBuffer.Length
                Dim newBuffer As Byte() = New Byte(writeBuffer.Length - written - 1) {}
                Array.Copy(writeBuffer, written, newBuffer, 0, newBuffer.Length)

                writeTransaction = New I2CDevice.I2CTransaction() {i2cDevice.CreateWriteTransaction(newBuffer)}

                written += Me.i2cDevice.Execute(writeTransaction, TransactionTimeout)
            End While

            ' make sure the data was sent
            If written <> writeBuffer.Length Then
                Throw New Exception("Could not write to device.")
            End If
        End Sub
        Private Sub Read(ByVal readBuffer As Byte())
            ' create a read transaction
            Dim readTransaction As I2CDevice.I2CTransaction() = New I2CDevice.I2CTransaction() {i2cDevice.CreateReadTransaction(readBuffer)}

            ' read data from the device
            Dim read As Integer = Me.i2cDevice.Execute(readTransaction, TransactionTimeout)

            ' make sure the data was read
            If read <> readBuffer.Length Then
                Throw New Exception("Could not read from device.")
            End If
        End Sub

        Protected Sub WriteToRegister(ByVal register As Byte, ByVal value As Byte)
            Me.Write(New Byte() {register, value})
        End Sub
        Protected Sub WriteToRegister(ByVal register As Byte, ByVal values As Byte())
            ' create a single buffer, so register and values can be send in a single transaction
            Dim writeBuffer As Byte() = New Byte(values.Length) {}
            writeBuffer(0) = register
            Array.Copy(values, 0, writeBuffer, 1, values.Length)

            Me.Write(writeBuffer)
        End Sub
        Protected Sub ReadFromRegister(ByVal register As Byte, ByVal readBuffer As Byte())
            Me.Write(New Byte() {register})
            Me.Read(readBuffer)
        End Sub
    End Class

    Public Class ExpanderPlug
        Inherits I2CPlug
        Private Const ExpanderPlugAddress As Integer = &H20

        Public Enum Registers
            IODIR
            IPOL
            GPINTEN
            DEFVAL
            INTCON
            IOCON
            GPPU
            INTF
            INTCAP
            GPIO
            OLAT
        End Enum

        Public Sub New()
            MyBase.New(ExpanderPlugAddress)
        End Sub
        Public Sub New(ByVal directions As Byte)
            MyBase.New(ExpanderPlugAddress)
            SetDirections(directions)
        End Sub

        Public Sub SetDirections(ByVal directions As Byte)
            Me.WriteToRegister(CByte(Registers.IODIR), directions)
        End Sub

        Public Sub Write(ByVal values As Byte)
            Me.WriteToRegister(CByte(Registers.GPIO), values)
        End Sub

        Public Function Read() As Byte
            Dim values As Byte() = New Byte(0) {0}

            Me.ReadFromRegister(CByte(Registers.GPIO), values)

            Return values(0)
        End Function
    End Class

End Namespace

And My Code, to use this class:
Public Sub I2C_Control(ByVal Command As String, ByVal Server As TelnetServer)
            ' initialize the expander plug, setting all pins as output
            Dim expanderPlug As New ExpanderPlug(&H0)

            
            If Command.ToLower.Trim = "i2c" Then
                expanderPlug.Write(&HFF)
                ' turn all the pins on
                Thread.Sleep(250)
                ' make the pins stay on for 250 ms
                expanderPlug.Write(&H0)
                ' turn all the pins off
                ' make the pins stay off for 250 ms
                Thread.Sleep(250)
                Server.Print("Done")
            Else
                Server.Print("false command")
            End If

        End Sub

Its working on the Netduino with the TelnetServer.
And here my strange error:
\> i2c
An exception has been triggered: Exception was thrown: System.ArgumentException
\> i2c
An exception has been triggered: Exception was thrown: System.InvalidOperationEx
ception

but it dont say, in wich codeline :S
Need some help please...

mfg & thx

gfc

#4 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 22 September 2012 - 09:21 AM

I think the argument exception is because you have the clock rate value too big (1000), the maximum is 400 in the current implementation of .NET Micro Framework.

#5 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 26 September 2012 - 11:58 AM

I Think, it Works (no errors) Now im waiting for the I2C-IC, to test it ^^ thanks mfg gfcwfzkm

#6 gfcwfzkm

gfcwfzkm

    Advanced Member

  • Members
  • PipPipPip
  • 52 posts
  • LocationBrig-Glis, Switzerland

Posted 03 October 2012 - 06:21 AM

i found a MultiI2C-Class in the Toolbox.NETMF.Hardware.dll

On the website, it looks very easy to use, but i have some problems to "Write" a byte or some bytes...
Dim i2c As New MultiI2C(&H39, 200)
i2c.Write(&H01)  'Here it show a error :/

Here the VB-Error:
Fehler bei der Überladungsauflösung, da keine zugreifbare "Write" mit diesen Argumenten aufgerufen werden kann: "Public Function Write(WriteBuffer() As UShort) As Integer": Der Wert vom Typ "Integer" kann nicht in "1-dimensionales Array von UShort" konvertiert werden. "Public Function Write(WriteBuffer() As Byte) As Integer": Der Wert vom Typ "Integer" kann nicht in "1-dimensionales Array von Byte" konvertiert werden.

Can someone show here a little sample how to Write and Read?
netmftoolbox multiI2C website

thx

mfg

gfc

#7 FVN.Net

FVN.Net

    Member

  • Members
  • PipPip
  • 15 posts
  • LocationCentral Belgium, EU

Posted 03 October 2012 - 07:20 AM

As a coincidence, I was trying about the same thing last night - and failed!
I'm trying to read the card ID from an RFID reader through I²C.

Here's my code:
Dim IIC As New MultiI2C(161, 100)
    Dim outbytes() As Byte = New Byte() {}
    Dim inbytes() As Byte = New Byte() {}
    
    outbytes = New Byte() {161, 1, 1}
    IIC.WriteRead(outbytes, inbytes)

I made an event handler based on the 'card detected' output, fed to an input. This works fine.
The last 2 lines of code are in the interrupt / event handler because it only makes sense to talk to the reader when a card is detected.

And here's where it crashes:
"A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll
Exception was thrown: System.ArgumentException"

Why 161: the datasheet says I need a 7 bit address (default = 80), and the 8th bit (LSB) should be '1' to read.
That gives: 10100001 = 161.

Why {161, 1, 1}: the specs say:
  • Address: 1 byte, 0xA0
  • Len: Byte length counting from Command Code to the last byte of the data, 1 byte.
  • Command: Command Code, 1 byte.
  • Data: Data, variable length depends on the command type.
So read from address 80 = 161, 1 byte length, command = 1

The question is: do I use the VB code in a wrong way, or don't I understand the specs of the I²C protocol?
I can't find any useful information online that combines N+ with VB and I²C. So I need to turn to this forum once again for help...

HELP! :wacko:
- Franki

#8 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 03 October 2012 - 09:06 AM

Why 161: the datasheet says I need a 7 bit address (default = 80), and the 8th bit (LSB) should be '1' to read.

The address in .NET MF does not include the R/W bit, so pass just 80.

#9 FVN.Net

FVN.Net

    Member

  • Members
  • PipPip
  • 15 posts
  • LocationCentral Belgium, EU

Posted 03 October 2012 - 02:06 PM

Thanks but this doesn't get me any further. Does the '80' only apply to the address or also to the command byte?

This gives an error:
outbytes = New Byte() {80, 1, 1}
                IIC.WriteRead(outbytes, inbytes)
And this too:
outbytes = New Byte() {161, 1, 1}
                IIC.WriteRead(outbytes, inbytes)

If I split up the reading from the writing, I get beyond this just fine:
outbytes = New Byte() {80, 1, 1}
                IIC.Write(outbytes)

But then the exception is thrown right after when I try to read into 'inbytes':
A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll
Exception was thrown: System.ArgumentException

So it seems it goes bad when reading.

My problem is A) being new to Netduino and embedded in general, B ) never used I²C and C) not familiar with this particular device (RFID reader).
This means a lot of unknowns in the equation, and I don't know how to code up I²C straight from the µF in VB. Is my VB code bad or do I just send or expect the wrong things from the slave device?

For point B I try to use the Toolbox I2C-helper but I'm doing something wrong obviously.
For point C here's the device (+datasheet): http://www.stronglin...ules/sl030.html

I found some assembler-ish or C-like code samples to interface this device over I²C and hoped to understand it and 'translate' it to my needs but I must admit I don't really get what I'm seeing.

I'm hoping someone out here could show me the way or guide me through the learning process? I'd really appreciate that.
- Franki

EDIT: opened a new topic for this HERE since I think I made a breakthrough.




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.