TM1637 Driver (Spin)

JonnyMacJonnyMac Posts: 6,428
edited 2019-12-23 - 16:14:50 in Propeller 1
Playing with the TM1638 caused me to try the '1637 as well. The attached demo code was tested on this display:

-- https://www.amazon.com/gp/product/B06WWN9Z6J

tm1637_btns.png

...but will work on 4-digit displays with decimal points. I don't know if it's a bad pcb design or I received a defective module, but the button input pins (9-pin header) do not work as expected; on one of the eight button inputs seems to be connected to the TM1637. In my button demo code I can see buttons 1-6 (onboard) and button 16; none of the others work. The TM1637 is designed to sense one-of-16 buttons.

Added a demo for the wr_buf() method.

Comments

  • JonnyMacJonnyMac Posts: 6,428
    edited 2019-12-17 - 22:34:34
    I modified the str() method to run faster when decimal points appear in the string. The old version would read the character bits, add the decimal point, then write them back. The new version uses a look-ahead to check if the current character has a trailing decimal point. If that is the case the DP is set then which prevents a secondary character write. While fractionally slower when the string has no decimal points, it is much faster when they occur.

    I also added a clock demo to the code for 4-digit displays that are configured 00:00.
  • JonnyMacJonnyMac Posts: 6,428
    edited 2019-12-19 - 07:08:36
    While converting my Spin object to a C library I re-thought the str() method and have increased its speed again (by about 2x over last improvement). It's faster and handles decimal points more appropriately. If a decimal point trails another character, it will modify the preceding character, otherwise it will print on its own.
  • @ JonnyMac

    That's a interesting display. I will order one in the New Year and try you code. Thanks for the code.
  • Peter JakackiPeter Jakacki Posts: 8,924
    edited 2019-12-23 - 12:23:37
    @JonnyMac - Interestingly somebody had already written some Spin code for this almost 2 years ago! Seems circuit4u did a 3-part write-up.
    https://medium.com/@circuit4us/write-spin-code-for-tm1637-and-tm1638-part-i-f5568d2fe05b

    Those modules do seem awfully expensive for a simple 6-digit LED display + buttons though.

    BTW, you wouldn't want to see my Tachyon code for it, it's not complicated enough to be proper code :)
  • JonnyMacJonnyMac Posts: 6,428
    edited 2019-12-23 - 16:31:41
    Interestingly somebody had already written some Spin code for this almost 2 years ago! Seems circuit4u did a 3-part write-up.
    Some Spin code, yes, but not a full object as I did.
    Those modules do seem awfully expensive for a simple 6-digit LED display + buttons though.
    Agreed, but there are plenty of people who don't mind waiting a month for a cheap module from Ebay.

    I wrote the objects for the TM163x chips as material for a book on Spin programming that I am writing.
  • MJBMJB Posts: 1,146
    BTW, you wouldn't want to see my Tachyon code for it, it's not complicated enough to be proper code :)

    the code must be so small, that I could not find it in your latest dropbox ...
    or my search is not working correctly
  • Peter JakackiPeter Jakacki Posts: 8,924
    edited 2019-12-24 - 01:21:22
    @JonnyMac - I meant that is was interesting that somebody who didn't seem to be a forumista had used the Prop and Spin rather than C and an Arduino, and that they had done this almost 2 years ago.

    @MJB I'm working outside of my Dropbox and I also don't have a display to check it on although it is easy to check the timing. This TM1637 is weird and you would think that it could have been a lot easier to communicate with in terms of "commands". One of the reasons that also contribute to the code being so small is because I don't try to have all these named methods, I just treat it as a character I/O device rather than have special methods just for strings and decimal point is set automatically within the previous character etc. Buttons come back as make and break characters too. So it just treats the TM1637 the same as if it were a physical serial character device which means there is no change to the application code. Even so the application only has to select the device with "TM" and PRINT" Hello World" anyway (in 7-seg "characters"). Printing "12.34" results in the decimal point being set for the previous "2".

    Remember we did something like this for a 7-seg display you had once.

    Here is the simple write function in Tachyon which could be made much simpler again but this version tries to bear some similarity to Jon's code simply as a comparison. I like to see where Tachyon can be improved, and these little exercises are good for that.

    Tachyon code ( needs an active TMDLY to slow it down )
    pub tm1637_write ( byte -- ack )
    	8 FOR 
    	 ( get next lsb and float/low )
    	  DUP 1&  IF *DIO FLOAT ELSE *DIO LOW THEN 
    	  *CLK HIGH TMDLY
    (  must float DIO after last data for ack - so just do it everytime )
    	  *CLK LOW *DIO FLOAT TMDLY
    	  2/
    	NEXT DROP
    	*CLK HIGH *DIO PIN@ NOT TMDLY ( ackbit )
    	*CLK LOW TMDLY
    	;
    


    Original C Code (seems to leave last data bit bit not floating when clock is low in prep for ack)
    uint8_t tm1637_write(uint8_t b)
    {
      uint8_t ackbit;
    
      for (uint8_t i = 0; i < 8; i++) {                             // write 8 bits
        if (b & 0x01 == 1)                                          // get lsb, if 1
          DIRA &= ~dmask;                                           //  float DIO
        else                                                        // else
          DIRA |= dmask;                                            //  DIO low (0)
        b >>= 1;
        DIRA &= ~cmask;
        tm1637_bit_delay();
        DIRA |= cmask;
        tm1637_bit_delay();
      }
    
      DIRA &= ~dmask;                                               // DIO to input
      DIRA &= ~cmask;                                               // CLK high
      tm1637_bit_delay();
      if (INA & dmask)                                              // get ACK bit
        ackbit = 1;
      else
        ackbit = 0;
      DIRA |= cmask;                                                // CLK low
      tm1637_bit_delay();
    
      return ackbit;
    }
    
  • JonnyMacJonnyMac Posts: 6,428
    edited 2019-12-24 - 21:40:36
    Original C Code (seems to leave last data bit bit not floating when clock is low in prep for ack)
    The first line of the second block of code explicitly sets the DIO pin to input. Ack bit sampling happens after. It's open drain on both sides so no harm, no foul.
Sign In or Register to comment.