Detect change on pin that is output AND input

I try to drive a 4 digit display: it is a grove one driven by TM1637 unit.
Device has two pins:
[ul]a data one which is an output but an input too.
a clock one. No problem with it.
[/ul]

Data pin is used to send command and to receive ACK signal. My problem is with reading ACK signal: I’ve try with an tristate port which seems to be adequat, but Nothing happen. The while loop read infinitely:

Code which use driver:

    public class Program
    {
        public static void Main()
        {
            ProgramSetup();

            while (true)
            {
            }
        }

        private static void ProgramSetup()
        {
            Debug.Print(Resources.GetString(Resources.StringResources.String1));
            Led led = new Led(GHI.Pins.FEZPandaIII.Gpio.D5);
            led.Blink(200, 500);
            Digit4Display digit4=new Digit4Display(GHI.Pins.FEZPandaIII.Gpio.D3,FEZPandaIII.Gpio.D2);
            digit4.Display(0x1,0x08);
            Thread.Sleep(5000);
            led.StopBlink();
        }
    }

Code of driver:

public class Digit4Display
    {
        private OutputPort  _clkPin;
        private TristatePort _dataPin;
        private byte[] TubeTab = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };

        public Digit4Display(Cpu.Pin dataPin, Cpu.Pin clkPin)
        {
            _dataPin = new TristatePort(dataPin, false,false,Port.ResistorMode.Disabled);
            _clkPin = new OutputPort(clkPin, false);
            Init();
        }

        private void _dataPin_OnInterrupt(uint data1, uint data2, DateTime time)
        {
        }

        private void SetDataOutput()
        {
            if (_dataPin.Active==false)
                _dataPin.Active = true;
        }

        private void SetDataInput()
        {
            if (_dataPin.Active==true)
                _dataPin.Active = false;
        }

        private void Init() // OK
        {
            SetDataOutput(); // Set as output
            Clear();
        }

        public void Display(byte addr, byte data)
        {
            byte segData = Coding(data);
            SendStartSignal();
            WriteByte(0x44);
            SendStopSignal();
            SendStartSignal();
            var v = addr | 0xc0;
            WriteByte((byte)v);
            WriteByte(segData); 
            SendStopSignal();
            SendStartSignal();
            WriteByte(0); // Command Display Control
            SendStopSignal();

        }

        private byte Coding(byte data)
        {
            if (data == 0x7f) data = 0;
            else data = TubeTab[data];
            return data;
        }

        public void Clear() // OK
        {
            Display(0x00, 0x7f);
            Display(0x01, 0x7f);
            Display(0x02, 0x7f);
            Display(0x03, 0x7f);
        }

        private void WriteByte(byte data)
        {
            int count=0;
            int mask = 0x01;
            for(int i = 0;i < 8;i++)
            {
                _clkPin.Write(false);
                _dataPin.Write((data & mask) != 0);
                data >>= 1;
                _clkPin.Write(true);
            }
            _clkPin.Write(false);
            _dataPin.Write(true);
            _clkPin.Write(true);

            SetDataInput();
            var d = _dataPin.Read();
            while (d)
            {
                count+=1;
                if (count == 200)
                {
                    SetDataOutput();
                    _dataPin.Write(false);
                    count = 0;
                }
                SetDataInput();
                d = _dataPin.Read();
            }
            SetDataOutput();
        }

        private void SendStartSignal() // OK
        {
            SetDataOutput();
            _clkPin.Write(true);
            _dataPin.Write(true);
            _dataPin.Write(false);
            _clkPin.Write(false);
        }

        private void SendStopSignal() // OK
        {
            _clkPin.Write(false);
            _dataPin.Write(false);
            _clkPin.Write(true);
            _dataPin.Write(true);

        }
    }

@ Bauland - How do you know that the device received the message correctly?

1 Like

Stupid answer: when I receive ACK signal !!!

More accurate answer: your question is true, is my message correctly formatted ?

So currently, I’m starting from scratch and recreate message “by hand” to investigate reception.

So, for giggles, I’m wondering about tying your actual signal to two pins, one output, one input, and reading it that way. Whether that changes your observations. I’m not really sure whether that’s going to be feasible but I would try it…

1 Like

I can’t : data pin is input and output on module. It’s not a one I have made.

@ Bauland - jumper in an extra wire to a pin that you can watch :slight_smile:

2 Likes

yes, exactly. It’s really simple to do what I suggested :wink:

Finally, I’ve used logic analyzer: ACK wasn’t present because frequency was to high and I’ve reversed order of bytes !!!
Now 4 digit displays 1234 correctly.
I can focus on Library.
Thanks again.

2 Likes

Thanks for precision, I’ve not undestand what you meen in first post.
Not an extra wire here, just logic analyzer in addition, board have more than one connector (but it’s another wire, indeed).