Io60p16 usage problem

I know I’m probably missing something simple, but I can’t seem to get the interrupts to work. My preference is to have one interrupt to catch the traffic for all the pins. I am planning on about 30 interrupt inputs and possibly a few digital outputs later, but if I can’t do the digital inputs on this that’s fine. I have a Cerberus board and the io60p16 is on port 7. If I put a breakpoint on the mip.OnInterrupt line and read the value of the port I can see different values so I know it is changing, just not interrupting. Below is my code, any ideas?

        private ModuleInputPort mip;

        void ProgramStarted()
            io60p16.Interrupt += new IO60P16.InterruptEventHandler(io60p16_OnInterrupt);
            mip = io60p16.CreateInputPort(IOPin.Port1_Pin0);
            mip.OnInterrupt += new InterruptHandler(mip_OnInterrupt);

        void io60p16_OnInterrupt(object sender, InterruptEventArgs args)
            Debug.Print(args.Port.ToString() + ":" + args.Pin.ToString());

        void mip_OnInterrupt(uint data1, uint data2, DateTime time)
            Debug.Print("data1: " + data1.ToString() + " - data2: " + data2.ToString());

I assume you’re using my driver and not the GHI one since the GHI driver doesn’t support interrupts? You may want to contact me directly or start a thread on the CodePlex site so as not to cause confusion with others trying to use the GHI driver. I haven’t touched this in months. I’ll start setting up a test with the latest SDK.

I am pretty sure I am using the GHI driver, I did not know I needed a different one and the interrupt stuff is all visible there. I’ll see if I can find your driver and give it a try.
Subject on tiny:
:slight_smile: But with this driver i am having some problems. Didn’t have the time to debug yet. (

Oh… Perhaps you are using the older 4.1 driver which was based on my driver. The latest 4.2 driver was re-written and does not have interrupt support.

The object is Gadgeteer.Modules.GHIElectronics.IO60P16.

Anyone from GHI know when the GHI driver that supports interrupts will be ready?

ianlee74’s driver could probably work, but it uses an I socket instead of an X socket.

From source:

            var types = new[] {'I'};
            var types = new[] { 'X', 'Y' };

Just recompile the code without HARDWARE_I2C conditional compilations symbol (in project properties on build tab).
You can find the source code here (

Thanks Makla, did that and have it running, but still no interrupt firing. Again, if I put a breakpoint on the last line of the constructor I can see the value change by calling .Read in the immediate window. When I bought these I thought the driver would be as seamless as they are for the rest of the GHI modules.

        private GTM.GHIElectronics.IO60P16.InterruptPort ip;

        void ProgramStarted()
            io60p16.SetDirection(GTM.GHIElectronics.IO60P16.IOPin.Port2_Pin3, GTM.GHIElectronics.IO60P16.PinDirection.Input);
            io60p16.SetInterruptEnable(GTM.GHIElectronics.IO60P16.IOPin.Port2_Pin3, true);
            ip = io60p16.CreateInterruptPort(GTM.GHIElectronics.IO60P16.IOPin.Port2_Pin3);
            ip.OnInterrupt += new GTM.GHIElectronics.IO60P16.InterruptHandler(ip_OnInterrupt);

        void ip_OnInterrupt(uint data1, uint data2, DateTime time)
            Debug.Print("data1: " + data1.ToString() + " - data2: " + data2.ToString());

I didn’t finish getting my test setup last night (was distracted with some shiny new digiSparks…). I’ll try and contribute something tonight. The chip on the IO60P16 is finicky and has been plagued with SoftwareI2C issues in the past. A good test is to reroute the pins on the socket using an Extender module so that it aligns properly with an “I” socket and then compile & run it as HARDWARE_I2C. If that works then you know you are still having SoftwareI2C issues. If you don’t know how to set it up to run as “I”, browse through the driver development thread. I’m fairly certain I posted a picture there at one time.

I tried it on an I socket and got hardware errors in Program.generated.cs when it tried to load other objects. I also don’t have an I socket available for later so I need it as an X. this is going to connect to a CerbuinoBee that already has an I2C display connected.

@ PintSize.Me - Do you really need interrupt ?
The Ian’s driver works fine with 3 different way of I2C management. It supports, depending on compiler define settings:

  1. Hardware i2c (need rewiring and socket I)
  2. Gadgeteer software I2C (socket X/Y)
  3. .NETMF software I2C (socket X/Y)

On cerberus class of board the .netmf i2c works fine, some problem arise with Hydra board. Interrupt is a mess because the chip itself manage it in very bad way. I spent a lot of time on Int and it “mostly” works in very easy environment, but if you go to complex threading or very fast output/input pin state changes you get in troubles.
There’s a very long discussion thread on this board, if you search the forum.

Yes, I really need interrupts. It will not have complex threading or fast (by computing standards) state changes. I did finally find the other thread, but it did not have a solid fix either.

I may just have to switch back to Phidgets for this one. :frowning:

@ PintSize.Me - if you only need 30 inputs with interrupt capability, you could consider taking a look at the DL40 I will need to double check but I am reasonably certain it would cover you. You would need a custom firmware on the DL40 but it would be quite simple and I would be happy to write it and put it up on codeshare.

@ taylorza - I don’t even understand what the DL40 really is, but if it’s pins can be used as interrupts then I don’t see why it wouldn’t work. If it can do a large number of digital input interrupts I don’t see why it wouldn’t work, or why it wouldn’t get use from other people. I’ll take whatever works.

@ PintSize.Me - Here is a link to the module (I am sure you saw that already)

And the tutorial

Basically the DL40 is a board with a LPC1113 Cortex-M0 chip on it and two Gadgeteer sockets, one side connected to the mainboard and the other can be used to daisy chain another DL40 using the DaisyLink protocol. The chip can execute code and either receive instructions from the mainboard and notify the mainboard that something happened through an interrupt interface specified for the DaisyLink protocol.

In addition to the two Gadgeteer sockets, there are 40 connection points many of which expose the MCU’s pins, some are GND and VCC etc. Hopefully enough of the pins are exposed to give you 30 interrupt capable pins, the nice thing about the LPC1113 is that all I/O pins are interrupt capable. But if there are not enough pins on one module, then you could daisy chain a second and third etc.

I have not tested the performance characteristics and the latency of the interrupts, but I doubt you are going to be able to do 100’s per second to be honest, but that is just a gut feeling based on the mechanics involved with communicating between the Mainboard and the module. Maybe Gus or someone from GHI has some stats on this.

To do all of this, you need to write a custom firmware to load onto the chip, the default firmware is a very generic DaisyLink implementation which controls the state of the pins, but it does not handle interrupts etc. However the stock firmware is an excellent starting point as it implements all the core protocol stuff and all that is required is to integrate your custom portion into that.

The firmware can be written to the DL40 module using the mainboard, the sample is an application for the Spider, but I am sure it can quite easily be modified to run on one of the other boards, this I have not tried personally, but I cannot see why it would not work and I would be happy to confirm it if you like, I have a Hydra and a Cerberus that I could test it out on.

Sorry for the long post, but of all the modules I am most excited about the DL40. It is like a little native co-processor that you can easily off-load all kinds of work too while the mainboard takes care of the orchestration.

I have read through both of them, but I still am not entirely understanding exactly what it is other than something that lets you do some pretty flexible extending.

I am not needing a high frequency of interrupts (in terms of computer speeds), I would not see one pin doing more than 2, possibly 3 changes per second (think opening and closing a door), and not more than 2 or 3 pins activating at the same time. Overall I would expect less than 200 total interrupts per day, so definately lower volume changes, but I need the interrupt model because it may only be 500ms between triggers and I need to capture that. Trying to do a sleep loop with a frequency high enough to catch those quick events would have some load issues.

I plan one thread for network communication, one thread for XBee communication, and then one for everything else.

At that rate, couldn’t you poll the device/s and raise your own event? Since you have such a rate, how fast do you need to know about the interrupt and react, is that also relatively slow?

That is exactly what it is. But now in your example you could have the module monitoring the interrupts and then when an interrupt is detected raise that to the mainboard. As an example, the Pulse In/Out module is an example of a full blown module built using the design of the DL40

I counted the pins on the module that are not associate with anything else and by my count there are 29 pins you can use freely, the count might actually be higher because I excluded the SWD pins which I used during development but in actual fact they will be available in production.

Just to be clear, the DL40 will handle interrupts at a decent rate it is just the latency to propagate that back to the mainboard that I was/am concerned about. But with what you are talking about this will not be an issue at all.