G400D / TH Touch screen issue

The Newhaven capacitive touch display connected using “Display NHVN Module” and “GXP Gadgeteer Bridge” works perfectly on my FEZ Cobra III. But when connected to G400D /TH it’s only working for a few touches after startup and stops.

It does fires touchInterrupt.OnInterrupt but there is something wrong with I2CDevice readings (after few working touches, it falls into “break;” or “TouchDownEvent” and never “TouchUpEvent”).
Do I need to do something different when on G400?


        private InterruptPort touchInterrupt;
        private I2CDevice i2cBus;
        private I2CDevice.I2CTransaction[] transactions;
        private byte[] addressBuffer;
        private byte[] resultBuffer;

        private CapacitiveTouchController(Cpu.Pin portId)
        {
            transactions = new I2CDevice.I2CTransaction[2];
            resultBuffer = new byte[1];
            addressBuffer = new byte[1];
            i2cBus = new I2CDevice(new I2CDevice.Configuration(0x38, 400));
            touchInterrupt = new InterruptPort(portId, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            touchInterrupt.OnInterrupt += (a, b, c) => this.OnTouchEvent();
        }

        private void OnTouchEvent()
        {
            for (var i = 0; i < 5; i++)
            {
                var first = this.ReadRegister((byte)(3 + i * 6));
                var x = ((first & 0x0F) << 8) + this.ReadRegister((byte)(4 + i * 6));
                var y = ((ReadRegister((byte)(5 + i * 6)) & 0x0F) << 8) + ReadRegister((byte)(6 + i * 6));

                if (x == 4095 && y == 4095)
                    break;

                if (((first & 0xC0) >> 6) == 1)
                    GlideTouch.RaiseTouchUpEvent(null, new GHI.Glide.TouchEventArgs(new GHI.Glide.Geom.Point(x, y)));
                else
                    GlideTouch.RaiseTouchDownEvent(null, new GHI.Glide.TouchEventArgs(new GHI.Glide.Geom.Point(x, y)));
            }
        }

        private byte ReadRegister(byte address)
        {
            addressBuffer[0] = address;

            transactions[0] = I2CDevice.CreateWriteTransaction(addressBuffer);
            transactions[1] = I2CDevice.CreateReadTransaction(resultBuffer);

            i2cBus.Execute(this.transactions, 1000);

            return this.resultBuffer[0];
        }

Do I need to contact GHI to replace the board or am I doing something wrong?

Connection cannot be an issue in this case as the “GXP Gadgeteer Bridge” connected to the G400D with a 40 pin 0.1" header and the “Display NHVN Module” connected to the “GXP Gadgeteer Bridge” using standard Gadgeteer cables.

@ EvoMotors -
Try to separate Write and Read transaction to see what happen.
We will take a look then if it stilt doesn’t work well.

private byte ReadRegister(byte address)
        {
            I2CDevice.I2CTransaction[] my_transactions = new I2CDevice.I2CTransaction[1];
			
			addressBuffer[0] = address;

            my_transactions = I2CDevice.CreateWriteTransaction(addressBuffer);
			if (i2cBus.Execute(this.transactions, 1000))
			{
				my_transactions = I2CDevice.CreateReadTransaction(resultBuffer);
				if (i2cBus.Execute(this.transactions, 1000))
				{
					return this.resultBuffer[0];
				}
			}
            return 0;
        }

@ Dat - Still the same results.

This is complete code for touch controller and results of “Debug.Print(string.Concat(“i=”, i, " first=”, first, " X{", x, “} Y{”, y, “} status=”, status));" on the end of OnTouchEvent. The result of the “(first & 0xC0) >> 6)” always 0

    public class CapacitiveTouchController
    {
        private InterruptPort touchInterrupt;
        private I2CDevice i2cBus;
        private I2CDevice.I2CTransaction[] transactions;
        private byte[] addressBuffer;
        private byte[] resultBuffer;

        private static CapacitiveTouchController _this;

        public static void Initialize(Cpu.Pin PortId)
        {
            if (_this == null)
                _this = new CapacitiveTouchController(PortId);
        }

        private CapacitiveTouchController()
        {
        }

        private CapacitiveTouchController(Cpu.Pin portId)
        {
            transactions = new I2CDevice.I2CTransaction[2];
            resultBuffer = new byte[1];
            addressBuffer = new byte[1];
            i2cBus = new I2CDevice(new I2CDevice.Configuration(0x38, 400));
            touchInterrupt = new InterruptPort(portId, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            touchInterrupt.OnInterrupt += (a, b, c) => OnTouchEvent();
        }

        private void OnTouchEvent()
        {
            for (var i = 0; i < 5; i++)
            {
                var first = ReadRegister((byte)(3 + i * 6));
                var x = ((first & 0x0F) << 8) + ReadRegister((byte)(4 + i * 6));
                var y = ((ReadRegister((byte)(5 + i * 6)) & 0x0F) << 8) + ReadRegister((byte)(6 + i * 6));

                if (x == 4095 && y == 4095)
                    return; // break;

                var status = first >> 6;

                if (((first & 0xC0) >> 6) == 1)
                    GlideTouch.RaiseTouchUpEvent(null, new GHI.Glide.TouchEventArgs(new GHI.Glide.Geom.Point(x, y)));
                else
                    GlideTouch.RaiseTouchDownEvent(null, new GHI.Glide.TouchEventArgs(new GHI.Glide.Geom.Point(x, y)));

                Debug.Print(string.Concat("i=", i, " first=", first, " X{", x, "} Y{", y, "} status=", status));
            }
        }

        private byte ReadRegister(byte address)
        {
            I2CDevice.I2CTransaction[] my_transactions = new I2CDevice.I2CTransaction[1];

            addressBuffer[0] = address;

            my_transactions[0] = I2CDevice.CreateWriteTransaction(addressBuffer);
            if (i2cBus.Execute(my_transactions, 1000) != 0)
            {
                my_transactions[0] = I2CDevice.CreateReadTransaction(resultBuffer);
                if (i2cBus.Execute(my_transactions, 1000) != 0)
                {
                    return this.resultBuffer[0];
                }
            }
            return 0;
        }

        //private byte ReadRegister(byte address)
        //{
        //    this.addressBuffer[0] = address;

        //    this.transactions[0] = I2CDevice.CreateWriteTransaction(_this.addressBuffer);
        //    this.transactions[1] = I2CDevice.CreateReadTransaction(_this.resultBuffer);

        //    this.i2cBus.Execute(_this.transactions, 1000);

        //    return this.resultBuffer[0];
        //}
    }


Debug.Print(string.Concat(“i=”, i, " first=", first, " X{", x, “} Y{”, y, “} status=”, status)); results for a single tap:

i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{518} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1280} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2843} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0
i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0

With glitchFilter set to true, there are less results

i=0 first=3 X{772} Y{1286} status=0
i=1 first=9 X{2314} Y{2828} status=0
i=2 first=15 X{3856} Y{274} status=0
i=3 first=21 X{1302} Y{1816} status=0
i=4 first=27 X{2844} Y{3358} status=0

@ Dat - Also note that the values for X and Y always the same, no matter where I tap. And just to verify that the GXP Gadgeteer Bridge, Display NHVN Module and the Touchscreen are working I just pulled out the GXP Gadgeteer Bridge of the G400 and hooked up to FEZ Cobra III. On the Cobra all still works.

There was an issue with the G400 I2C many moons ago and I switched to using the software I2C and have not switched back to the hardware one yet.

Can you PM me your email address and I will send you the code I use on the G400 with the software I2C and see if that works. It’s very different to the one you are using but it does work. It was original written by Simon on here but his was the hardware I2C. That works fine on the G120.

If that works for you I will put it in Codeshare.

1 Like

@ Dat - Any other ideas?

You can try SoftwareI2C. On G400 the speed is fast enough same as hardwareI2C

I’ve sent him a copy of the driver I use from Simon that was converted to use the software driver. If that works it means there is still an issue with the hardware driver on the G400.

1 Like

I will try SoftwareI2C, but this is not permanent solution, if there is a hardware driver on the G400 issue, it need to get fixed or build-int IC2 support needs to be removed from the list of advertised futures of G400 module

We can develop our project using multiple different ways, some of them correct and some not, and using SoftwareI2C on the hardware I2C enables module is one of the incorrect ways.

I switched to G400 module to gain performance and now I have to loose some because one of the advertized futures is not working. Besides that it stated in the documentation that performance will not be the same:

[quote]It is possible to simulate an independent I2C bus on any two GPIO pins with the appropriate resistors though the
software I2C class, but performance will be lower.

[/quote]

It’s like buying a car that can get you only half of the destination distance. And the dealership says that is not a big deal, you can still get to your destination by walking the second half!

Can I use the same 2 hardware I2C pins for SoftwareI2C? I cannot use any other pins as my touchscreen is connected through “GXP Gadgeteer Bridge” and I already have plans for all other pins.

@ Dave McLaughlin - Your code works perfectly. For a couple of 7 to 10 touches and then is the same issue. Exactly the same. If I disconnect power for 10 to 15 seconds it works again, but no guarantee how for many touches.
Looks like the pin PD5 is fine as it always triggers interrupt, but one or both I2C pins (PA30 and PA31) are misbehaving? I checked, double-checked and triple-checked soldering points on GXP Header pins and they are perfect.

Should I contact GHI for a replacement or can I check something else?

Looking at the schematic, GHI has brought out the reset pin. I don’t use this with my designs and rely on the internal reset so I have this pin tied high. The GHI design shows this to have no pull up and I don’t see anything in their driver that sets this pin.

With my driver you will have to put this into a suitable level in your own code. I don’t do it. Set the port that it is connected to HIGH and see if the touch works better.

It’s started kind of working only when:
I initialize the “reset pin” with initial state = true, and cycle “reset pin” low and back to high after each Touch Interrupt, and set at least 150ms pause after reading each finger. Kind of working meaning 25% of the time I have to tap button twice.

EDIT
Both software and hardware I2C works the same 75% of the time if all 3 actions above are set.

DO NOT reset every time. You only need to do this on startup. Do not do this in every interrupt otherwise you will lose the data.

Just set it high and then see if it is stable after this.

I know I’m not supposed to reset every time
That’s what I’m trying to say, it works only when I reset. If I just set the pin to high at a startup it doesn’t work at all.

Forgive me if you have installed them but you do have pull up resistors on the I2C lines don’t you?

The G400TH does not have them but the Cobra 3 does.

1 Like

I did not install the resistors, it looks like they are already installed on the “Display NHVN Module”
https://www.ghielectronics.com/downloads/schematic/Display_NHVN_Module_SCH.pdf

EDIT:
I think I got it wrong :-[