Yesterday I received my Netduino 3 WiFi board and wanted to start to connect modules to the three ports on the board. First up was the Temperature and Humidity board developed a while ago. I did not have the original binaries available and so had to recompile the library.
Enter stage left, compilation errors.
It looks like there have been a few nice additions to the GO! Which mean a few software modifications are required.
So let’s look at the original DHT22 module code and the current version. But before I start I need to acknowledge the fact that 40% of the modifications made were me figuring stuff out, the remaining 60% were as a result of looking through Matt Issenhowers driver for the Komodex seven segment display module.
GoSockets are now GoPorts
Trivial change
ModuleGuid Property
This was not required in the first GoBus specification. Not too complicated, it just returned the GUID of the module.
OnInterrupt Event
The initial version of the protocol required that the driver provided an InterruptPort variable which could be used to bind to an
/// <summary> /// Interrupt port which will be connected to the Netduino GO! module. /// </summary> private InterruptPort _irqPort;
In the constructor / initialisation method you would bind the InterruptPort to a pin etc.
// // Now wire up the event handler so that we can respond to interrupts // from the module. // _irqPort = new InterruptPort((Cpu.Pin) socketGpioPin, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow); _irqPort.OnInterrupt += _irqPort_OnInterrupt;
The new code is a lot simpler, the new code becomes an override method:
Protected override void OnInterrupt() { }
The interrupt code previously placed in the _irqPort_OnInterrupt method is now placed in OnInterrupt.
SPI Binding
The first drivers required the driver to bind to the SPI interface like so:
// // Get the resources which have been allocated to this module. // Cpu.Pin socketGpioPin; // IRQ pin. SPI.SPI_module socketSpiModule; // SPI module. Cpu.Pin socketSpiSlaveSelectPin; // CS pin. socket.GetPhysicalResources(out socketGpioPin, out socketSpiModule, out socketSpiSlaveSelectPin); // // Now we know which SPI resources have been allocated to the module we // can create an instance of the SPI bus in order that we can communicate // with it. // _spiConfig = new SPI.Configuration(socketSpiSlaveSelectPin, false, 0, 0, false, false, 10, socketSpiModule); _spi = new SPI(_spiConfig);
The new code appears to do this for you automactically. Less code - always nice
Initialize Method
The Initialize method mandatory but a lot of the code from my previous initialisation method has now been made obsolete. So the original method was:
private void Initialize(GoSocket socket) { if (!base.BindSocket(socket, _moduleGuid)) // Bind to the socket if possible. { throw new ArgumentException(); } // // Get the resources which have been allocated to this module. // Cpu.Pin socketGpioPin; // IRQ pin. SPI.SPI_module socketSpiModule; // SPI module. Cpu.Pin socketSpiSlaveSelectPin; // CS pin. socket.GetPhysicalResources(out socketGpioPin, out socketSpiModule, out socketSpiSlaveSelectPin); // // Now we know which SPI resources have been allocated to the module we // can create an instance of the SPI bus in order that we can communicate // with it. // _spiConfig = new SPI.Configuration(socketSpiSlaveSelectPin, false, 0, 0, false, false, 10, socketSpiModule); _spi = new SPI(_spiConfig); // // Now wire up the event handler so that we can respond to interrupts // from the module. // _irqPort = new InterruptPort((Cpu.Pin) socketGpioPin, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow); _irqPort.OnInterrupt += _irqPort_OnInterrupt; _irqPortInterruptEvent = new AutoResetEvent(false); AlarmInterruptsEnabled = AlarmState.InterruptsEnabled; }
It is now:
protected override void Initialize() { AlarmInterruptsEnabled = AlarmState.InterruptsEnabled; }
The final change is in the way the SPI reads/writes are handled. In the initial drivers this was performed by the developer, the current library has these provided for you. So the original code looked something like this:
private void WriteDataToModule() { for (int index = 0; index < GO_BUS10_FRAME_LENGTH; index++) { _readFrameBuffer[index] = 0; } _writeFrameBuffer[_writeFrameBuffer.Length - 1] = CRC8.Compute8(_writeFrameBuffer, 0, _writeFrameBuffer.Length - 1); _spi.WriteRead(_writeFrameBuffer, _readFrameBuffer); }
And the new code looks like this:
private void WriteDataToModule() { for (int index = 0; index < GO_BUS10_FRAME_LENGTH; index++) { _readFrameBuffer[index] = 0; } _writeFrameBuffer[_writeFrameBuffer.Length - 1] = CRC8.Compute8(_writeFrameBuffer, 0, _writeFrameBuffer.Length - 1); GoBusSpiWriteRead(_writeFrameBuffer, _readFrameBuffer); }
I have added the original and the modified versions of the driver to this post for those who are interested in developing modules.
Hope you find this useful,
Mark