-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tm1680 #2
Comments
Hi Dima, sorry for the late reply. Apparently I don't get notifications by e-mail. |
Just checked after few months: Oct 2019: USD 0,70 with LCSC and 10 for USD 5 + shipping at aliexpress |
Hello Bollie, good find! Thanks for the tip. When I was searching for TM1680 on AliExpress I could find none. As it seems now the "Best results" sorting order shows all kind of other items, but when I sort on price, they do appear. |
Hello, any way to help to get the TM1680 supported? There is also a new datasheet version 1.4: |
Hello Stephan, thank you for contributing the new datasheet and for providing me the context to your question. I have some questions for you:
In the mean while I'll do some searching to see if I can find a chip for development and testing. However, ordering from Ali usually takes 4-8 weeks. Edit: fixed typo. LQFP52 chip is 32x8 - 24x16) Kind regards. |
FYI: I just ordered 5 LQFP52 chips at Ali. I'm not sure if I also have a 13x4 breakout board. To be continued... BTW. I also saw in the datasheet that this chip uses I2C. Recently I worked on support for the HT16K33 LED driver chip, which also uses I2C. (That chip is not by Titan Micro, but by Holtek. It supports 16x8 and I have a 15-segment x 4 character module, which I can now use with the TM16xx API to display alpha-numeric characters). |
Hello, The connector has 6 pins, whereby 2 are used for ground, 2 for 5V and then 1 for SDA and 1 for SCL I connected my old LA into it and recorded some startups / fancy blinking: |
Hi Stephan, thank you for your efforts to support this development. Thank you also for providing these pictures. That helps a lot. I will have a further look at your I2C capture one of these days. Does making this capture mean that your device is still working? What was the reason for you to take it apart? Is the bluetooth defective or do you just want to reuse an obsolete yet working device? The fact that the device has a dedicated LED module is very promising. The datasheet mentions separate power for the LEDs, so that explains the dual power lines. As soon as I have time, I will take a closer look at your material and let you know my findings (need to do other things first). Bye for now... |
Hi Stephan, I took a closer look at your pictures of the PCB and at the datasheet:
As for the LED layout; the resistors used suggest 24/3=8 rows by 16 columns. That would then allow for 128 RGB LEDs max. The PCB title matches that number. 11 x 11 LEDs is a total of 121 LEDs, Mapping those to the available 128 positions may have required some creative PCB skills and associated software translation in the device firmware. BTW. Is your device is still working? What was the reason for you to take it apart? Is the Bluetooth function defective or do you just want to reuse an unused yet working device? |
Hi again, Next I looked at your I2C captures, I used the PulseView captures, as my version of Logic is outdated.
Initialisation sequence:
Edit: fixed A4=16COM mode, matching PCB layout and data RAM size. Clearing display sequence:
Image writing sequence:
The startup RAM write capture may come to be quite useful to figure out the LED layout. As the device starts up, it always shows these images:
|
Hello, The device still works as it should, but the "sound" from it is not what i expected and therefore i want to re-use it as a display. Yes its running in 24x16 mode and the smd resistors are 20 Ohm. On your startup sequence the A4 is 16COM, besides this i can confirm it! I went ahead and hooked a arduino to it, but just found that the write bit is crucial. This is with the write bit 0, there is a NACK and the code halts: // Init the TM1680, same sequence as captured by logic analyczer:
Wire.beginTransmission(0x73); // transmit to device 73
Wire.write(0x80); // SYS DIS
Wire.write(0xA4); // COM option 01
Wire.write(0x9A); // RC Master Mode 1
Wire.write(0x81); // SYS EN
Wire.write(0x83); // LED ON
Wire.write(0xBF); // PWM Duty Max
Wire.write(0x88); // Blink Off
Wire.endTransmission(); // stop transmitting When i request, write bit 1, it sends a ACK, but then the arduino polls endless as the TM1680 not actually sends: // Init the TM1680, same sequence as captured by logic analyczer:
Wire.requestFrom(0x73, 0); // "request" to device 73
Wire.write(0x80); // SYS DIS
Wire.write(0xA4); // COM option 01
Wire.write(0x9A); // RC Master Mode 1
Wire.write(0x81); // SYS EN
Wire.write(0x83); // LED ON
Wire.write(0xBF); // PWM Duty Max
Wire.write(0x88); // Blink Off
Wire.endTransmission(); // stop transmitting How can this write bit set to 1? Can the official wire lib even do this? |
Hi Stephan, Thank you for your correction on the A4 command being 16COM mode. Earlier I did mention 16COM and this matches the resistor count and the size of the RAM data sent. (I edited my earlier post to avoid confusion). As your Arduino captures illustrates, in the I2C standard the r/w bit in the address is 1 for a read command. This would suggest that unshifted 0x73 is write, whereas unshifted 0xE7 is read, The shifted 7-bit address would always read as 0x73 (see shift option in PulseView). In some forumpost I read that the Arduino wire library always uses 7-bit addresses. However; the speaker device sends 1, even when writing. I was assuming the TM1680 simply ignores this bit and interprets it all as a write. That assumption may be wrong. Perhaps the TM1680 requires that bit to be 1. I'm not quite sure how exactly I2C is implemented in the Arduino library and how you can send the full 8-bit address 0xE7 while still writing data. I would need to do some experimenting first. So I think I need to do some experiments on my own to be able to give you definite answers. I found a local supplier for the Denver BTL-350 and bought myself a brand new device! BTW: I personally liked the sound which is much better than that from my tablet, but I was disappointed to see they used this matte-black plasti-dip finish all over the back-cover. Brand new it has a satin look that is very susceptible to greasy fingerprints and in a few years that stuff gunks up and transforms into a sticky messy material that requires nasty chemicals to remove... I'll see if I can collect some more info on I2C. Some time ago I had some promising results on making an I2C bridge for the TM16xx family, based on the Atmel ATtiny13A MCU, which has some challenging limitations on RAM and flash size. Edit: In the mean time, here are some links to articles that may be interesting:
To be continued... |
Hello, is the teardown going well? Based on your input on the I2C Addressing i went now a another route, i pulled A0 low to make it match with the write command: And now it reacts to the init sequence: And shure enough, leds can be turned on 😊 i wrote a loop that pushes 1 bit through all places, but it does light up looking a bit random, and some do not light up at all. So there is more to be found on how to control it. The test code: https://gist.github.com/designer2k2/9d62e085ca3b069f6fb57de772c8d489 And a LA record in PulseView from the init and first bit of the code from above running: |
Hi Stephan, this is excellent! Great idea to use A0 to match the write command! Creative thinking out of the box.... Nice job on soldering this pull-down directly to the chip. Past days I had other things to work at, but this weekend I hope to progress on this project. I will try to replicate your setup and try your code. What MCU are you using now? |
BTW. I did manage to open the speaker without too much damage (thank you for telling me how), but have not done any soldering yet... |
Further more: I read that the Arduino wire library uses a 32-byte buffer. This means the total bytes send upon endTransmission() should be no more than 32 bytes, I guess including address. Every time you send data to the RAM, you should first send the I2C-address (using beginTransmission), followed by a write of the RAM address command, and then maximum of 30 bytes of display data. I haven't looked at your sketch, so I don't now if you took that into account. |
Hi Stephan, Today I did some soldering and have some interesting results. I'll keep it to some main points as I'm still testing:
FYI: I'm using a LGT8F328P 5V, 32MHz, 100k i2c. I haven't used my Logical Analyzer yet. |
Hello, The 32byte limit had me on my initial code, the link from above is now updated to take care of it. It shows now a fully white panel, and then every led is driven ☀️ Yes the 3.3V from the ESP32 i will check later, i hope i can get away with modifying the resistors. If not i will use a level shifter and supply it with 5V. Right now im using a Duemilanove. |
Hi Stephan, I just tested your second version. Very nice result! I like how you changed your code to send the frame in two parts. My own attempt was much more complicated. I delayed your loop to be able to see for myself that indeed each and every LED got lit once and only once. (In my own code I was kind-of messing the nibbles around only to create a greater mess...) FYI: my ATtiny13A I2C slave configuration tool came in handy to send test sequences (such as the blink command) as well as to test the speed of the TM1680. It tested a maximum speed of above 600kHz. That's quite nice. The datasheet mentions max 400 kz at 3.0V-5.5V, (The ATtiny runs at 9.6MHz, barely enough to implement 100kHz I2C in software as it has no USI) . If your ESP32 doesn't work properly at 3,3v, I suggest you to first try 100kHz I2C and make sure to use short connections with minimal contact points. Due to the not-very-standard led layout, it will probably take some time to make a TM16xx compatible library. Usually I start with simple 7-segment support, upgrade then to 15 segment support and finally do the matrix support. For the 7-segment I wait for Ali to deliver the bare chips. RGB matrix is not supported yet by the base class so that requires some changes. I guess a more practical next step for this display would be to make a library to support some graphics. To make it compatible with Adafruit GFX the main thing to implement is a setpixel function, which probably requires a bit more fiddling to derive a proper mapping table. |
Hi Stephan, just a short message to let you know that I'm working on a setPixel function. My progress so far is promising I've mapped about half of the pixels and can display them in proper order. My code is probably a bit clumsy and making the conversion table is a lot of work (121*3 bit positions). Once working there will probably a lot of room for optimization. I'll keep on dragging in a compile/edit/test loop until the sun rises I guess.... Edit: finished before sunrise. Time to get some sleep... |
Wow, that is very good! And the speed you got this is impressive! 👍 I did try to make sense of the addressing for some time now, but something was wrong as i got so many duplicated entrys. To break the compile/edit/test loop i wrote a serial command receiver into the arduino code and a python gui that sends the bytes. But in the end i spend more time debugging this than the actual addressing 😕 So im looking forward to give your code a testrun! |
I have removed some clutter and made a trimmed down example sketch (testing now, uploading soon...). Once done, the addressing makes slightly more sense, but getting there was quite painful, cumbersome and time-consuming. Nevertheless, I like the result for now, although I'm sure there are many clever ways to optimize this code and perhaps do much better using a different approach. |
Here is my setPixel test sketch: Note: code is not optimized in any way, I wasn't even bothered to use PROGMEM for the ridiculously large conversion table.... |
For completeness here are some findings (also mentioned in the comments of the setPixel tryout sketch):
|
The coming week I won't have much time for further work on this. Thank you for your cooperation. I think that working together, we reached some nice results in a fairly short timeframe. Eventually I would like to put an ESP32 (or ESP8266) in the speaker and have it control the buttons to switch off the BTL-display after powering up, while still supporting the Bluetooth speaker functionality. That will probably require some more connections, eg. to the speaker buttons and the powersupply. The ESP then would take control of the display, enabling me to use it and show text and bitmaps, such as time and other info. Another nice addition would include an I2S decoder, connected to the audio circuit, to allow the ESP to make sound, eg. for internet radio or use as a streaming server. |
It works! I have all the color X´s showing up 🤩 The code is cool, and well commented so its good to catch the idea behind! This is more than i have hoped for, thank you! With 1270bytes memory its not easy, but even a the Duemilanove (ATmega328) is only 62% filled, a ESP32 even less, just 4%. I would not spend a lot of time to reduce the footprint... I will continue with the ESP32 integration. My rough plan is to "cut out" the logic from the existing board but keep the power handling part. Maybe even drive the speaker from it as there are ESP32 audio libs: https://github.com/pschatzmann/ESP32-A2DP |
Cool! Thank you for letting me know. The conversion table should definitely move to PROGMEM to save 3x11x11x2 bytes of RAM. Having a static table in RAM is just wasteful and moving it to PROGMEM Flash memory is not too hard. I think I'll do that when I make it into an Adafruit GFX compatible library, which I will use in my ESP speaker project. Other than that your framebuffer uses some RAM. Only 48 bytes though, so that's just fine. (The framebuffer is essential to be able to combine/split-up different pixel LEDs). If I have more progress, I'll post it here (the original issue is a bit hijacked by this project, so once I received the bare chips from Ali, I'll probably return to the original subject...) |
Yes the TM1680 support is for here, but the specific BTL-350 should really be somewhere else. With the default wire libs A0 must be low, thats the only limitation for the support. With only A1 just 2 can be on the same bus, but who will do this? Not many... Official supplier link: http://www.titanmec.com/product/display-drivers/led-panel-display-driver-chip/20220817109.html Im looking forward for the GFX lib :-) |
Hello, |
Hi @Polyphe , thank you for your contribution! Nice to know of other use cases. I see that thermostat priced at 120 euro's and up, It probably has more interesting components. Not something to just throw away when it breaks. Is yours broken too or did you just pull it of the wall to see what's inside? ;-) BTW. I got some bare LQFP52 chips from China, capable of driving 24x16 or 32x8 LEDs. As soon as I find time to build my own massive matrix, I intend to add support for this chip to the library. Might take a while though... |
Hi @maxint-rd, Thank you for your feedback. To reply at your question, and after my analyse, there are several interesting components (BS816A for the three capacitive touch, L9110 for the relay, one input for 9-24V DC or AC, one input battery 3xAAA (buck power supply), STM8L151-C8 (8bit microcontroller), SD3502 (Z-wave microcontroller based 8051), SHT20 temperature and humidity sensor. In fact, my pcb is not broken, but I am curious by nature ;), and more I would like to improve this thermostat because I found this one has not been used to its real potential (matrix, thermostat functions, and so on). As I don't know this specific TM1680 device, and that the data sheet only seems in Chinese, it is difficult to find a solution versus all your excellent work for this universal library of TM16xx... When I would find time to do some tries, I would inform you Thank you again ! |
Always nice to see such curiosity in action. I just uploaded a translation of the TM1680 datasheet for your pleasure. Perhaps not the best translation, but usable I guess. Good luck with it! BTW. I also like to be able to improve my devices. Often it' a time-consuming endeavor, not always successful, but most often still interesting. At the moment the TM1680 Bluetooth speaker is on top of my device improvement wish-list. As i have plenty other projects and wishes it may become a work-in-progress forever sleeping on a shelf; who knows... |
Hi @maxint-rd, |
MH3901-Z_pattern_pulseview.zip Hi @maxint-rd, After the 40 bytes of the display occurs 25.7 (all the 12ms). The designer of the PCB only uses COM0 to 6 for the rows of 6, 5, 4, 3, 9, 8, 7 respectively, and COM12 to 14 for the rows 2, 1, 0 (10 rows, in considering the row 0 at the bottom, and row 9 at the top). It is totally crazy...The computer scientist had to have fun programming numbers and drawings :D The LEDs of the 3 buttons are independent of the TM1680 (6 LEDs, 2 by buttons). Another application of the TM1680, where the program designer had to adapt his software in function the PCB designer (Haha). What I didn't understand, why the frame is send all the 80Hz, the RAM normally keeps the pattern ? |
Sorry for the late reply. I didn't have time to look in more detail, so just a short answer: yes, the display does have RAM to hold the pattern. I think they update at 80Hz to show current status really often. Not needed I guess, but still they did... |
is there any hope for creating and publishing a library for tm1680?
Thank you
The text was updated successfully, but these errors were encountered: