Any recommendations for expanding the Netduino for more digital I/O.? I am confused with all the Artuino shields...which one is compatible? When will the gobus version be ready?
More Digital I/O
#1
Posted 28 September 2015 - 07:53 PM
#2
Posted 29 September 2015 - 05:27 AM
I cannot comment on the Arduino Shields but if you are OK with putting your own circuit together then a driver for the MCP23s08/MCP23S17 has been released. I think it is still draft form at the moment.
If you want output only then the 74H595 is popular and there are many examples on this site. For input there is also the 74H165 (I think).
If you want a Go Bus example of the 74H595 output module well I put together full instructions on building a 595 output module including source code a while ago.
Regards,
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
Posted 04 October 2015 - 12:19 AM
Hello,
I agree completely with Mark, if you just need a few extra outputs or inputs, 74H shift-registers are excellent and simple. If you want something that's a bit more capable (ports can be configured as inputs or outputs, they have pull-up resistors, and there are interrupts), I've found MCP23S08/MCP23S17 to be very useful, and they don't require any additional components, just like a 74HC595, it only needs a few extra pin connections to the Netduino, and you can add sixteen extra ports with one chip.
If you do use one of the expanders and have any questions let me know, and good luck!
#4
Posted 09 October 2015 - 05:05 AM
Do you have a schematic using MCP23S08/MCP23S17?
#5
Posted 12 October 2015 - 04:01 PM
I'm afraid I don't, but here's the hookups you need for the MCP23S08:
MCP23S08 Netduino
SCK (1) --> 13 (SPCK)
SI (2) --> 11 (MOSI)
SO (3) --> 12 (MISO)
A1 (4) --> GND
A0 (5) --> GND
RESET (6) --> 3.3V
CS (7) --> 10
INT (8) Not connected (optional)
VSS (9) --> GND
VDD (18) --> 3.3V
The MCP23S17 is much the same (except the pin numbers are different) but it has an additional address pin A2 that is connected to ground. The address pins (A0, A1) define the address of the chip, and are used when initializing the chip like so:
// Use "new MCP23S08(CS pin, address)" to initialize an expander MCP23S08 expander = new MCP23S08(Pins.GPIO_PIN_D10, 0x00);
When A0 and A1 are both connected to ground, the address is 0x00. Here's a table of addresses for the MCP23S08:
A0 A1 Address
GND GND 0x00
3.3V GND 0x01
GND 3.3V 0x02
3.3V 3.3V 0x03
- TechnoGuy likes this
#7
Posted 27 October 2015 - 04:55 AM
I am programming in vb.net. Is it possible to use your driver without converting it?
#8
Posted 27 October 2015 - 06:56 AM
I am programming in vb.net. Is it possible to use your driver without converting it?
I know you can do this with standard C# and VB. I'd normally do something like:
- Create a new project in your VB solution with the C# code in it and compile the code to a DLL.
- Next make sure the C# code is CLS compliant. I think there is an attribute for this. Yes there is - add [assembly:CLSCompliant(true)] under your using statements. You will get errors if the code is not compliant.
- Reference the DLL in your VB project.
BTW - if you really need to convert the code then Telerik have a free online converter.
Regards,
Mark
- TechnoGuy likes this
To be or not to be = 0xFF
Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life
Follow @nevynuk on Twitter
#9
Posted 30 October 2015 - 05:22 AM
I have another question. I am using a Netduino 3 and am using digital I/O pins 11,12,13 for MOSI, MISO, and SPCK. What should I use for CS??
#10
Posted 30 October 2015 - 06:36 AM
Hi Greg,
You're talking about using SPI - the Serial Peripheral Interface. That's an interface where you can connect up multiple slave devices in a bus-type configuration.
For example you'd use the Netduino as MASTER (controller) and you could have (say) 3 devices as SLAVES.
To hook everything together, you'd make the connections as follows:
- Connect MOSI (Digital 11) on Netduino to the MOSI pins on each of the slaves "Master Output / Slave Input"
- Connect MISO (Digital 12) on Netduino to the MISO pins on each of the slaves "Master Input / Slave Output"
- Connect SPCK (Digital 13) on Netduino to the clock pins on each of the slaves "SPI Clock"
- Connect power & ground as well
Then you'd need to use 1 additional Digital Pin on the Netduino as "Slave Select" (SS) for EACH of the 3 slaves. You'd connect a separate wire from the Netduino to EACH of the 3 slaves. On the SPI devices that I have, the corresponding pin on the slave is marked "CS" (chip select).
For "Slave Select", you can just use any digital pin (on the Netduino) that isn't already being used for something else. There is not a specific pin to be used. I have seen in the Arduino world that they have suggested pins to be used for different things - e.g. SD Card Reader, TFT Display, etc. That's just a convention. It's basically to avoid conflicts when stacking ready-made shields & to reduce the need to have to go into canned code & customize values.
I found an interesting SPI & I2C tutorial on Youtube the other day that was created by Pete Dokter of SparkFun Electronics. He's very knowledgeable on these things. You might want to check it out.
SparkFun According to Pete: SPI & I2C
Lastly, I've found that the there are sometimes alternative names used on devices (both slaves & masters) for the pins. I've seen "DOUT" used (for example) as an alternative name for MOSI and "DIN" as an alternate name for "MISO". There's a good conversion table on Wikipedia, here.
Good luck.
- ShVerni likes this
- Ian
My Current Dev Boards:
- 3 x Netduino Plus 2
- 1 x Netduino 3 WiFi
#11
Posted 30 October 2015 - 07:36 AM
Also, if you only have one device then you can tie the CS pin to either high or low to permanently select the device. Similarly, if you have a chain of devices where the serial out of one goes to the serial in of the next then these could all have the CS pin set to permanently select the device chain, The 74595 is a good example of this.
Regards,
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
#12
Posted 02 November 2015 - 06:49 PM
Thanks Mark, the VB converter is fantastic. It is the route I am using since I am making modifications to the original driver by ShVerni. His code is very impressive. I will post again when I get it working.
#13
Posted 02 November 2015 - 10:25 PM
Please do keep us posted, I'd be interested to see what changes you make to the driver, as I'm certain it could use some improvements!
#14
Posted 03 November 2015 - 09:51 PM
Does anyone have any recommendations for producing a board? what are some good board manufactures and what kind of board layout software should I use?
#15
Posted 03 November 2015 - 10:23 PM
I really like to use OSH Park, and have had excellent results from them. They prefer you use Eagle from Cadsoft, but they accept gerber files from any PCB design program. You can find details here:
https://oshpark.com/guidelines
#16
Posted 04 November 2015 - 12:48 AM
Success! I have 16 additional digital I/O per MCP23S17 chip. Since there is a three bit address, I can multiply that by 8. Very cool...
Thank you ShVerni and Mark....
I used the Telerik converter to get the code to VB.net. Worked great. I ran into two issues. First, for some reason, the version of .NET that I have does not support shift operation so I had to write my own subroutine. Second, ShVerni's original code had some addressing issues with MCP23S17 since he was using a different chip for his project. I had to modify the addressing to track the 16 bits. Other than that, it works great.
Here is the code for anyone interested. You can copy it into a class module and call it from your main module as recommended by ShVerni.
Imports System Imports Microsoft.SPOT Imports Microsoft.SPOT.Hardware ''' <summary> ''' Driver for a MCP23S17 I/O expander (http://www.microchip.com/wwwproducts/Devices.aspx?product=MCP23S17) ''' </summary> Public Class MCP23S17 ' Enumeration of the GPIOs: 0-7 (GPA0-GPA7), 8-15 (GPB0-GPB7) Public Enum ports As Byte GP0 = &H0 ' GPA0 GP1 = &H1 GP2 = &H2 GP3 = &H3 GP4 = &H4 GP5 = &H5 GP6 = &H6 GP7 = &H7 ' GPA7 GP8 = &H8 ' GPB0 GP9 = &H9 GP10 = &HA GP11 = &HB GP12 = &HC GP13 = &HD GP14 = &HE GP15 = &HF ' GPB7 End Enum ' <summary> ' Device configuration settings ' </summary> Public Enum settings As UShort ' gc, to get logic right ' gc, if bit needs to be a 1, then all other bits are 0 ' gc, if bit needs to be a 0, the all other are 1 ' Set to two 8-bit banks BANK_SEP = &H8080 ' Set to one 16-bit bank (this driver is configured for 16-bit use) BANK_SAME = &H7F7F ' Enable mirroring of interrupt ports MIRROR_ENABLE = &H4040 ' Disable mirroring of interrupt ports MIRROR_DISABLE = &HBFBF ' Enable sequential operation mode (not recommended) SEQOP_ENABLE = &HDFDF ' Disable sequential operation mode SEQOP_DISABLE = &H2020 ' Enable slew control for SDA pins DISSLW_ENABLE = &HEFEF ' Disable slew control for SDA pins DISSLW_DISABLE = &H1010 ' Enable hardware address pins (allows multiple MCP23S17 on one chip select pin) HAEN_ENABLE = &H808 ' Disable hardware address pins HAEN_DISABLE = &HF7F7 ''' Set the interrupt pin to be open-drain ODR_OPEN_DRAIN = &H404 ' Set the interrupt pin to active driver ODR_ACTICE_DRIVER = &HFBFB ' Set interrupt pin to active high when in active driver mode INTPOL_ACTIVE_HIGH = &H202 ' Set interrupt pin to active low when in active driver mode INTPOL_ACTIVE_LOW = &HFDFD End Enum ' Port configuration settings Public Enum portConfig As Byte ' gc, assigned additional valus for B side ' set port as output OUTPUT = &H0 ' Set port as input INPUT = &H1 ' Set the polarity of the input to the same as the port state (i.e. a high port state is reported as 1, and vice versa) INPUT_POLARITY_SAME = &H2 ' Set the polarity of the input to the opposite as the port state (i.e. a high port state is reported as 0, and vice versa) INPUT_POLARITY_OPP = &H3 ' Enable interrupt on port ENABLE_INTERRUPT = &H4 ' Disable interrupt on port DISABLE_INTERRUPT = &H5 ' Set the port interrupt state to low INTTERUPT_LOW = &H6 ' Set the port interrupt state to high INTTERUPT_HIGH = &H7 ' Set the port interrupt state to both (i.e. change) INTERRUPT_BOTH = &H8 ' Enable port pull-up resistor (input only) PULL_UP_ENABLE = &H9 ' Disable port pull-up resistor (input only) PULL_UP_DISABLE = &HA End Enum ' Register map, see the data sheet for details Private Enum register As Byte IODIRA = &H0 IPOLA = &H2 GPINTENA = &H4 DEFVALA = &H6 INTCONA = &H8 IOCONA = &HA GPPUA = &HC INTFA = &HE INTCAPA = &H10 GPIOA = &H12 OLATA = &H14 'gc, added for addressing B side IODIRB = &H1 IPOLB = &H3 GPINTENB = &H5 DEFVALB = &H7 INTCONB = &H9 IOCONB = &HB GPPUB = &HD INTFB = &HF INTCAPB = &H11 GPIOB = &H13 OLATB = &H15 End Enum ' Store some settings Private _MCP23S17 As SPI ' MultiSPI can be swapped with regular SPI if using one device Private _opcodeW As Byte, _opcodeR As Byte ''' <summary> ''' Constructs a MCP23S17 object ''' </summary> ''' <param name="cs">The chip select pin used</param> ''' <param name="address">The address defined by pins A0, A1, and A2</param> Public Sub New(cs As Cpu.Pin, address As Byte) ' Can be replaced with regular SPI if using one device _MCP23S17 = New SPI(New SPI.Configuration(ChipSelect_Port:=cs, ChipSelect_ActiveState:=False, ChipSelect_SetupTime:=0, ChipSelect_HoldTime:=0, Clock_IdleState:=False, Clock_Edge:=True, Clock_RateKHz:=4800, SPI_mod:=SPI.SPI_module.SPI1)) ' The opcode is a combination 4 bit fix 0100 code plus a 3 bit address and 1 bit = 0 (write) or 1 (read) '_opcodeW = CByte((&H4 << 4) Or (address << 1)) 'gc, hardcoded since this will never change. _opcodeW = &H40 ' address set by hardware '_opcodeR = CByte(_opcodeW + 1) _opcodeR = &H41 ' ' 0 - gc, set up the 16 bits configure(MCP23S17.settings.BANK_SAME, 0) ' 1 -gc, mirror enables - int bit tied together - I am not using interrupts so it doesn't matter configure(MCP23S17.settings.MIRROR_ENABLE, 0) ' 1 -Disable sequential operation mode as this driver is not configured to use it configure(MCP23S17.settings.SEQOP_DISABLE, 0) ' 1 -gc, disable the slew rate configure(MCP23S17.settings.DISSLW_DISABLE, 0) ' 1 -Set up the expander to use its address by default configure(MCP23S17.settings.HAEN_ENABLE, 0) ' 0 gc, interrupt active driver, don't care configure(MCP23S17.settings.ODR_ACTICE_DRIVER, 0) ' 1 -gc, interrupt polarity as active high configure(MCP23S17.settings.INTPOL_ACTIVE_HIGH, 0) ' 0 - gc, set up the 16 bits configure(MCP23S17.settings.BANK_SAME, 1) ' 1 -gc, mirror enables - int bit tied together - I am not using interrupts so it doesn't matter configure(MCP23S17.settings.MIRROR_ENABLE, 1) ' 1 -Disable sequential operation mode as this driver is not configured to use it configure(MCP23S17.settings.SEQOP_DISABLE, 1) ' 1 -gc, disable the slew rate configure(MCP23S17.settings.DISSLW_DISABLE, 1) ' 1 -Set up the expander to use its address by default configure(MCP23S17.settings.HAEN_ENABLE, 1) ' 0 gc, interrupt active driver, don't care configure(MCP23S17.settings.ODR_ACTICE_DRIVER, 1) ' 1 -gc, interrupt polarity as active high configure(MCP23S17.settings.INTPOL_ACTIVE_HIGH, 1) End Sub ' Public Function bsu(ByVal value As UShort, ByVal shiftvalue As UShort) As UShort For i As Integer = 0 To CInt(shiftvalue) - 1 value = CUShort(value) * CUShort(2) Next i Return value End Function ' Configure settings for the MCP23S17 ' <param name="set">The setting to apply</param> Public Sub configure(sett As settings, AorB As Integer) Dim config As UShort If AorB = 0 Then config = read(register.IOCONA) Else config = read(register.IOCONB) End If Select Case CUShort(sett) Case &H8080 If CUShort(sett) = &H8080 Then config = config Or CUShort(sett) Else config = config And CUShort(sett) End If Case Else If CUShort(sett) < &H8080 Then ' gc, clever trick to distinguish setting a 1 or 0 ' gc, works for all cases except 8080 config = config Or CUShort(sett) Else config = config And CUShort(sett) End If End Select If AorB = 0 Then write(register.IOCONA, config) Else write(register.IOCONB, config) End If End Sub ' Configure the settings of a port ' <param name="port">The port to configure</param> ' gc, port is a single bit that you want to change ' gc, this technique will change only one bit amoung 8 bits ' <param name="config">The setting to apply</param> Public Sub setupPort(port As ports, config As portConfig) Dim buffer As UShort Dim offsetport As UShort Select Case config Case portConfig.OUTPUT If port < &H8 Then buffer = read(register.IODIRA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.IODIRA, buffer) Else buffer = read(register.IODIRB) offsetport = &H8 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.IODIRB, buffer) End If Case portConfig.INPUT If port < &H8 Then buffer = read(register.IODIRA) offsetport = &H0 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.IODIRA, buffer) Else buffer = read(register.IODIRB) offsetport = &H8 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CByte(port) - offsetport + CUShort(&H8)) write(register.IODIRB, buffer) End If Case portConfig.PULL_UP_DISABLE If port < &H8 Then buffer = read(register.GPPUA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.GPPUA, buffer) Else buffer = read(register.GPPUB) offsetport = &H8 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.GPPUB, buffer) End If Case portConfig.PULL_UP_ENABLE If port < &H8 Then buffer = read(register.GPPUA) offsetport = &H0 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.GPPUA, buffer) Else buffer = read(register.GPPUB) offsetport = &H8 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.GPPUB, buffer) End If Case portConfig.INPUT_POLARITY_SAME If port < &H8 Then buffer = read(register.IPOLA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.IPOLA, buffer) Else buffer = read(register.IPOLB) offsetport = &H8 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.IPOLB, buffer) End If Case portConfig.INPUT_POLARITY_OPP If port < &H8 Then buffer = read(register.IPOLA) offsetport = &H0 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.IPOLA, buffer) Else buffer = read(register.IPOLB) offsetport = &H8 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.IPOLB, buffer) End If Case portConfig.DISABLE_INTERRUPT If port < &H8 Then buffer = read(register.GPINTENA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.GPINTENA, buffer) Else buffer = read(register.GPINTENB) offsetport = &H8 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.GPINTENB, buffer) End If Case portConfig.ENABLE_INTERRUPT If port < &H8 Then buffer = read(register.GPINTENA) offsetport = &H0 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.GPINTENA, buffer) Else buffer = read(register.GPINTENB) offsetport = &H8 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.GPINTENB, buffer) End If Case portConfig.INTTERUPT_LOW If port < &H8 Then buffer = read(register.DEFVALA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.DEFVALA, buffer) buffer = read(register.INTCONA) 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.INTCONA, buffer) Else buffer = read(register.DEFVALB) offsetport = &H8 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.DEFVALB, buffer) buffer = read(register.INTCONB) 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.INTCONB, buffer) End If Case portConfig.INTTERUPT_HIGH If port < &H8 Then buffer = read(register.DEFVALA) offsetport = &H0 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.DEFVALA, buffer) buffer = read(register.INTCONA) 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.INTCONA, buffer) Else buffer = read(register.DEFVALB) offsetport = &H8 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.DEFVALB, buffer) buffer = read(register.INTCONB) 'buffer = buffer Or CUShort(1 << CByte(port)) buffer = buffer Or bsu(1, CUShort(port) - offsetport + CUShort(&H8)) write(register.INTCONB, buffer) End If Case portConfig.INTERRUPT_BOTH If port < &H8 Then buffer = read(register.INTCONA) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.INTCONA, buffer) Else buffer = read(register.INTCONB) offsetport = &H0 'buffer = buffer And CUShort(Not (1 << CByte(port))) buffer = buffer And (Not bsu(1, CUShort(port) - offsetport + CUShort(&H8))) write(register.INTCONB, buffer) End If End Select End Sub ' Set the states of the port latches, which correspond to the states of the ouput ports ' <param name="portSettings">The latch settings to apply to the ports</param> Public Sub writePorts(portSettings As UShort, AorB As Integer) If AorB = 0 Then write(register.OLATA, portsettings) Else write(register.OLATB, portsettings) End If End Sub ' Read the states of all the GPIO ports or the port latches ' <param name="latch">If true, returns the latch states for the ports instead of the port states</param> ' <returns>A ushort where each bit repersents the state of the corresponding port</returns> Public Function readPorts(Optional latch As Boolean = False, Optional AorB As Integer = 0) As UShort If AorB = 0 Then If latch Then Return read(register.OLATA) Else Return read(register.GPIOA) End If Else If latch Then Return read(register.OLATB) Else Return read(register.GPIOB) End If End If End Function '' Retrieves the parameters related to an interrupt event '' <returns>A ushort array containing two ushorts corresponding to the INTF and INTCAP registers respectively. See the data sheet for details</returns> 'Public Function checkInterrupt() As UShort() ' Dim buffer As UShort() = New UShort(1) {} ' buffer(0) = read(register.INTFA) ' buffer(1) = read(register.INTCAPA) ' Return buffer 'End Function ' Reads the data from a register ' <param name="reg">The register to read</param> ' <returns>The data in the register</returns> Private Function read(reg As register) As UShort 'Dim bufferW As UShort() = {CUShort((_opcodeR << 8) Or CByte(reg))} Dim bufferW As UShort() = {CUShort(&H4100 Or CByte(reg))} Dim bufferR As UShort() = New UShort(0) {} ' Need to wait for the opcode and register address to be sent before beginning to read data _MCP23S17.WriteRead(bufferW, bufferR, 1) Return bufferR(0) End Function ' Writes data to a register ' <param name="reg">The register to write</param> ' <param name="data">The data to write</param> Private Sub write(reg As register, data As UShort) 'If reg = register.INTCAP OrElse reg = register.INTF Then ' Throw New System.ArgumentException("INTCAP and INTF are read-only", "reg") 'End If 'Dim opcode As UShort = CUShort((_opcodeW << 8) Or CByte(reg)) Dim opcode As UShort = CUShort(&H4000 Or CByte(reg)) Dim buffer As UShort() = {opcode, data} _MCP23S17.Write(buffer) End Sub ' End Class ' Class for using the MCP23S17 ports like native input ports Public Class ExpandedInputPort ' Store some settings Private _port As UShort Private _expander17 As MCP23S17 = Nothing Private portAB As Byte ' Creates an input port on a MCP23S17 expander ' </summary> ' The port to use</param> '<param name="resistor">Enable the 100kOhm pull-up resistor</param> ' <param name="expander">The MCP23S17 with the port</param> Public Sub New(port__1 As MCP23S17.ports, resistor As Port.ResistorMode, expander As MCP23S17) '_port = CUShort(1 << CByte(port__1)) Dim portoffset As UShort If port__1 < &H8 Then portoffset = &H0 Else portoffset = &H8 End If _port = bsu(1, CUShort(port__1) - portoffset + CUShort(&H8)) _expander17 = expander _expander17.setupPort(port__1, MCP23S17.portConfig.INPUT) portAB = port__1 Select Case resistor Case Port.ResistorMode.Disabled _expander17.setupPort(port__1, MCP23S17.portConfig.PULL_UP_DISABLE) Exit Select Case Port.ResistorMode.PullUp _expander17.setupPort(port__1, MCP23S17.portConfig.PULL_UP_ENABLE) Exit Select Case Else Throw New System.NotSupportedException("Pull-down resistors not supported") End Select End Sub ' Public Function bsu(ByVal value As UShort, ByVal shiftvalue As UShort) As UShort For i As Integer = 0 To CInt(shiftvalue) - 1 value = CUShort(value) * CUShort(2) Next i Return value End Function ' Read the state of the port ' </summary> ' <returns>The state of the port</returns> Public Function Read() As Boolean Dim buffer As UShort If portAB < &H8 Then buffer = _expander17.readPorts(False, 0) 'very important to use false to set reading GPIO rather than Latches Else buffer = _expander17.readPorts(False, 1) End If Return _port = (buffer And _port) End Function ' Public Sub tester1() _expander17.setupPort(MCP23S17.ports.GP7, MCP23S17.portConfig.INPUT) End Sub ' Disposes of the port Public Sub Dispose() _expander17 = Nothing End Sub Protected Overrides Sub Finalize() Try Dispose() Finally MyBase.Finalize() End Try End Sub End Class ' Class for using the MCP23S08/MCP23S17 ports like native output ports Public Class ExpandedOuputPort ' Store some settings Private _port As UShort Private _expander17 As MCP23S17 = Nothing Private portAB As Byte ' Creates an output port on a MCP23S17 expander ' <param name="port">The port to use</param> ' <param name="initialState">The initial state of the port</param> ' <param name="expander">The MCP23S08 with the port</param> Public Sub New(port As MCP23S17.ports, initialState As Boolean, expander As MCP23S17) _expander17 = expander _expander17.setupPort(port, MCP23S17.portConfig.OUTPUT) portAB = port Dim buffer As UShort Dim portoffset As UShort If port < &H8 Then portoffset = &H0 '_port = CUShort(1 << CByte(port)) _port = bsu(1, CUShort(port) - portoffset + CUShort(&H8)) buffer = _expander17.readPorts(True, 0) If initialState Then buffer = buffer Or _port Else buffer = buffer And CUShort(Not _port) End If _expander17.writePorts(buffer, 0) Else portoffset = &H8 '_port = CUShort(1 << CByte(port)) _port = bsu(1, CUShort(port) - portoffset + CUShort(&H8)) buffer = _expander17.readPorts(True, 1) If initialState Then buffer = buffer Or _port Else buffer = buffer And CUShort(Not _port) End If _expander17.writePorts(buffer, 1) End If End Sub ' Public Function bsu(ByVal value As UShort, ByVal shiftvalue As UShort) As UShort For i As Integer = 0 To CInt(shiftvalue) - 1 value = CUShort(value) * CUShort(2) Next i Return value End Function ' Read the state of the port ' <returns>The state of the port</returns> Public Function Read() As Boolean Dim buffer As UShort If portAB < &H8 Then buffer = _expander17.readPorts(True, 0) Else buffer = _expander17.readPorts(True, 1) End If Return _port = (buffer And _port) End Function ' Write the state of the port ' <param name="state">The state to write</param> Public Sub Write(state As Boolean) Dim buffer As UShort If portAB <= &H8 Then buffer = _expander17.readPorts(True, 0) If state Then buffer = buffer Or _port Else buffer = buffer And CUShort(Not _port) End If 'buffer = _port _expander17.writePorts(buffer, 0) Else buffer = _expander17.readPorts(True, 1) If state Then buffer = buffer Or _port Else buffer = buffer And CUShort(Not _port) End If 'buffer = _port _expander17.writePorts(buffer, 1) End If End Sub ' Disposes of the port Public Sub Dispose() _expander17 = Nothing End Sub Protected Overrides Sub Finalize() Try Dispose() Finally MyBase.Finalize() End Try End Sub ' Public Sub tester() '_expander17.configure(MCP23S17.settings.BANK_SAME, 0) '1 -gc, mirror enables - int bit tied together - I am not using interrupts so it doesn't matter '_expander17.configure(MCP23S17.settings.MIRROR_ENABLE, 1) ' 1 -Disable sequential operation mode as this driver is not configured to use it '_expander17.configure(MCP23S17.settings.SEQOP_DISABLE, 0) ' 1 -gc, disable the slew rate '_expander17.configure(MCP23S17.settings.DISSLW_DISABLE, 0) ' 1 -Set up the expander to use its address by default '_expander17.configure(MCP23S17.settings.HAEN_ENABLE, 0) ' 0 gc, interrupt active driver, don't care '_expander17.configure(MCP23S17.settings.ODR_ACTICE_DRIVER, 0) ' 1 -gc, interrupt polarity as active high '_expander17.configure(MCP23S17.settings.INTPOL_ACTIVE_HIGH, 0) End Sub End Class '======================================================= 'Service provided by Telerik (www.telerik.com) 'Conversion powered by NRefactory. 'Twitter: @telerik 'Facebook: facebook.com/telerik '=======================================================
?
- ShVerni likes this
#17
Posted 04 November 2015 - 06:23 AM
Does anyone have any recommendations for producing a board? what are some good board manufactures and what kind of board layout software should I use?
I use iTead, their service is cheap but takes about two weeks, one week for production and then another week for shipping. They are good at processing the gerbers when they arrive though. I have previously submitted boards with issues and they have told me about it within 24 hours.
For board design I have used Designspark on the PC but I have recently moved to a Mac and so I am now using KiCAD. Both are free and reasonably easy to use. Unlike Eagle, they are free for boards of any size. Eagle has limits for the free version but most hobbyists are producing boards within the free limits.
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
#18
Posted 04 November 2015 - 07:45 AM
bit shifting in VB:
' X * 2 ^ Y for << left shifting
' X / 2 ^ Y for >> right shifting
'so 4 << 7 = new syntax 4 * 2 ^ 7
'so 5 >> 3 = new syntax 5 / 2 ^ 3
(a positive note, the workaround is much faster)
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users