Main Site Documentation

Strange behaviour of MaxO


#1

I’m currently observing a very strange behaviour on a MaxO.

I wrote a small program that keeps a counter, and each time the mainboard button is pressed it turns on the MaxO output (LED in my case) corresponing to the counter value and increases the counter (modulo 32).

What I am observing, given counter values, is:
counter 0: LED 0 is on
counter 1: LED 1 and LED 24 are on
2: 2+25
3: 3+26
4: 4+27
5: 5+28
6…23: working as expected
24…31: nothing happens

First thought: WTF.
What could possibly go wrong here? Was it just bad luck and I got a broken module???

I checkes the cables about ten times and also observed the same behaviour using a volt meter directly at the output pins.


#2

Can you please show got code?


#3

Yes, of course. I wanted to include it in the main post and forgot. Here you are:

using Gadgeteer.Modules.GHIElectronics;
using Gadgeteer.Modules.Mountaineer;
using Microsoft.SPOT;

namespace MaxOCounter {
    public partial class Program {
        private MaxO _maxO;
        private ButtonForMountaineer _button;
        private int _index;

        void ProgramStarted() {
            Debug.Print("Program Started");
            _maxO = new MaxO(5);
            _maxO.NumBoards = 1;
            _button = new ButtonForMountaineer();
            _button.ButtonPressed += (s, e) => ButtonPressed();
        }

        void ButtonPressed() {
            Debug.Print(_index.ToString());
            var byteIndex = _index >> 3;
            var bitIndex = _index & 0x7;
            var mask = (byte)(1 << bitIndex);
            var buffer = new byte[4];
            buffer[byteIndex] = mask;
            _maxO.WriteArray(buffer);

            _index = (_index + 1) % 32;
        }
    }
}

I had strange effects with a much larger program. I wrote this specifically to debug the issue.


#4

Looks about right. Can you try a hardcoded value?

Something like this:
{ 0x02, 0x00, 0x00, 0x00 }

That way there is nothing that is calculated.


#5
using Gadgeteer.Modules.GHIElectronics;
using Gadgeteer.Modules.Mountaineer;
using Microsoft.SPOT;

namespace MaxOCounter {
    public partial class Program {
        private MaxO _maxO;
        private ButtonForMountaineer _button;
        private int _index;

        void ProgramStarted() {
            Debug.Print("Program Started");
            _maxO = new MaxO(5);
            _maxO.NumBoards = 1;
            _button = new ButtonForMountaineer();
            _button.ButtonPressed += (s, e) => ButtonPressed();
        }

        void ButtonPressed() {
            var buffer = new byte[] { 0x02, 0x00, 0x00, 0x00 };
            _maxO.WriteArray(buffer);
        }
    }
}

When I reset the mainboard and press the button, only LED 1 is lighting up - conforming to the bytes we send to the device.

And now comes the interesting part: When I press the button [em]again[/em], LED 25 is [em]also[/em] lighting up!

After some more tests, I have a hint of an idea what might be happening here. When there is a call to WriteArray, the MaxO seems to copy the first 5 bits of byte 0 to the first 5 bits of byte 3, before setting the other bytes. Additionally, LEDS 29-31 seem to never light up. This copying of bits of the old state is [em]consistent with every wrong behaviour I observed[/em].

I ported the MaxO C# code to NETMF 4.3 before all those tests. I don’t think that I messed it up at that part, there were few compiler errors related to creating Spi and DigitalOutput directly, which I resolved using the factories. I am reluctant to downgrade to NETMF 4.2 again, but if you are going to tell me that I should try it then I’ll probably give it a shot…


#6

I would get MaxO driver code and would try to fix it that way.


#7

What exactly do you mean with “driver code”? I swept through the Gadgeteer sources, thats where I found the 4.2 version of the MaxO C# code. So I migrated it to 4.3 and had a close look at it as well. Some of it is a bit overly complex in my taste, but concerning correctness everything feels exactly right. I currently have no Idea where to search further.


#8

Yes you got the driver. I’ll take a look when get home.


#9

I would try to run the same program on a 4.2 board using the driver that comes with our SDK and see if the problem remains.


#10

@ John: At tne moment I don’t have the means to downgrade to 4.2. Upgrading was easy, downgrading does not seem to be

Meanwhile, I found a solution to my Problem. I inlined the MaxO “driver” code into my program, reduced it to the bare minimum and tried some things. I observed that when I pad the array that is send to MaxO with an extra leading 0x00 then everything works as expected.

using Gadgeteer;
using Gadgeteer.Modules;
using Gadgeteer.Modules.Mountaineer;
using Gadgeteer.SocketInterfaces;
using Microsoft.SPOT;

namespace MaxOCounter {
    public partial class Program {
        private ButtonForMountaineer _button;
        private DigitalOutput _enable;
        private Spi _spi;
        private SpiConfiguration _config;
        private Module _module;
        private DigitalOutput _clr;
        private int _index;

        class MyModule : Module { public MyModule() { } }

        void ProgramStarted() {
            Debug.Print("Program Started");
            _module = new MyModule();
            Socket socket = Socket.GetSocket(2, true, _module, null);
            socket.EnsureTypeIsSupported('S', _module);
            _config = new SpiConfiguration(false, 0, 0, false, true, 1000);
            _spi = SpiFactory.Create(socket, _config, SpiSharing.Shared, socket, Socket.Pin.Five, _module);

            _enable = DigitalOutputFactory.Create(socket, Socket.Pin.Three, false, _module);
            _clr = DigitalOutputFactory.Create(socket, Socket.Pin.Four, true, _module);

            _button = new ButtonForMountaineer();
            _button.ButtonPressed += (s, e) => ButtonPressed();
        }

        void ButtonPressed() {
            Debug.Print(_index.ToString());
            var byteIndex = _index >> 3;
            var bitIndex = _index & 0x7;
            var mask = (byte)(1 << bitIndex);
            var buffer = new byte[5]; // resize this to 4 yields the bug

            // SPI's output bytes are reversed
            buffer[buffer.Length - 1 - byteIndex] = mask;

            _enable.Write(true);
            _spi.Write(buffer);
            _enable.Write(false);

            _index = (_index + 1) % 32;
        }
    }
}

GHI, please have a look into this and test MaxO usin 4.3. I am reluctant to believe that I just received an ill-functioning one.