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.
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
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...
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.
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.
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...
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.