Sorry for the late reply but there isn't any answer posted.
Yup, it is charlieplexed for sure because I figure it out by placing one display unit on a breadboard and test all individual pins one by one with a buttoncell. Wrote down the results into a table and test the table with an Arduino Nano. Excellent! Seems to work perfectly.
Some photo's:


![Testing table on breadboard with an Arduino Nano]](https://i.sstatic.net/TcBSZ.png)
To test I connected D2..D8 with pin #1.. pin #7, very straight forward, easy to do. Didn't solder headers, made some jumpers instead because I want to use this Nano for another project. Works great.
The code I wrote to test it (so you can try it yourself):
#define F_CPU 16000000UL // Set cpu speed to calculate right delay
#include <util/delay.h>
// includes
//#include "Timer.h"
/*
35 segment display:
____________________________
| |
| |> USB FM |
| 8 8 : 8 8 |
| || SD MP3 |
|____________________________|
| | | | | | |
0 1 2 3 4 5 6
1 2 3 4 5 6 7
Bits: Hex:
-- 0 -- -- 01 --
| | | |
5 1 20 02
| | | |
-- 6 -- -- 40 --
| | | |
4 2 10 04
| | | |
-- 3 -- -- 08 --
*/
#define PIN_PLUS 0x01
#define PIN_MIN 0x00
#define PIN_OFF 0xFF
#define PIN_HIGH HIGH
#define PIN_LOW LOW
#define PIN_ONBOARDLED_OUT 13
#define SCP_LEDS_OFF_DISABLED 255
#define SCP_LEDS_RESET -2
#define SCP_LEDS_SHOW_ENABLED -1
#define CP_MAX_LED 35
#define CP_CNT_LED 35
#define CP_MAX_PIN 7
#define CP_CNT_PIN 7
#define XTM_NOPROGMEM
#if defined(XTM_NOPROGMEM) || !defined(PROGMEM) || !defined(pgm_read_byte)
#pragma message("Compiling file: PROGMEM off, data tables in memory")
#ifndef XTM_NOPROGMEM
#define XTM_NOPROGMEM
#endif
#define XTM_MEM_ALLOC_TYPE static
#define XTM_GET_DIGIT(x) XTM_DIGITS[x]
#define XTM_GET_LEDPIN(x) CP_LED_PIN[x]
#define XTM_GET_LEDPIN_CFG(x,y) CP_LED_PINS_CFG[x,y]
#else
#define XTM_MEM_ALLOC_TYPE PROGMEM
#define XTM_GET_DIGIT(x) pgm_read_byte( &XTM_DIGITS[x] )
#define XTM_GET_LEDPIN(x) pgm_read_byte( &CP_LED_PIN[x] )
#define XTM_GET_LEDPIN_CFG(x,y) pgm_read_byte( &CP_LED_PINS_CFG[x,y] )
#endif
XTM_MEM_ALLOC_TYPE const uint8_t CP_LED_PINS[CP_MAX_PIN] = { 2, 3, 4, 5, 6, 7, 8 }; /* Digital PWM PINS only */
static bool bLedDirSwap = false;
//true;
XTM_MEM_ALLOC_TYPE const uint8_t CP_LED_PINS_CFG[CP_MAX_LED][CP_MAX_PIN] =
{
/* LED name: -> 1 2 3 4 5 6 7
| | | | | | |
+ Base: 1000000 */
/* 01. FIRST_SEG_0 */ { PIN_PLUS , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1100000 */
/* 02. FIRST_SEG_2 */ { PIN_PLUS , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1010000 */
/* 03. FIRST_SEG_4 */ { PIN_PLUS , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1001000 */
/* 04. SD */ { PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF }, /* 1000100 */
/* 05. PLAY */ { PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF }, /* 1010010 */
/* + */ /* Base: 0100000 */
/* 06. FIRST_SEG_5 */ { PIN_MIN , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1100000 */
/* 07. SECOND_SEG_0 */ { PIN_OFF , PIN_PLUS , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0110000 */
/* 08. SECOND_SEG_2 */ { PIN_OFF , PIN_PLUS , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0101000 */
/* 09. SECOND_SEG_4 */ { PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF }, /* 0100100 */
/* 10. SECOND_SEG_3 */ { PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF }, /* 0100010 */
/* + */ /* Base: 0010000 */
/* 11. FIRST_SEG_6 */ { PIN_MIN , PIN_OFF , PIN_PLUS, PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1010000 */
/* 12. SECOND_SEG_5 */ { PIN_OFF , PIN_MIN , PIN_PLUS, PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0110000 */
/* 13. COLON : */ { PIN_OFF , PIN_OFF , PIN_PLUS, PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0011000 */
/* 14. THIRD_SEG_1 */ { PIN_OFF , PIN_OFF , PIN_PLUS, PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF }, /* 0010100 */
/* 15. PAUSE */ { PIN_OFF , PIN_OFF , PIN_PLUS, PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF }, /* 0010010 */
/* 16. MP3 */ { PIN_OFF , PIN_OFF , PIN_PLUS, PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN }, /* 0010001 */
/* + */ /* Base: 0001000 */
/* 17. FIRST_SEG_2 */ { PIN_MIN , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF }, /* 1001000 */
/* 18. SECOND_SEG_6 */ { PIN_OFF , PIN_MIN , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0101000 */
/* 19. THIRD_SEG_5 */ { PIN_OFF , PIN_OFF , PIN_MIN , PIN_PLUS , PIN_OFF , PIN_OFF , PIN_OFF }, /* 0011000 */
/* 20. THRID_SEG_2 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_MIN , PIN_OFF , PIN_OFF }, /* 0001100 */
/* 21. FIFTH_SEG_4 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_MIN , PIN_OFF }, /* 0001010 */
/* + */ /* Base: 0000100 */
/* 22. FIRST_SEG_3 */ { PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF }, /* 1000100 */
/* 23. SECOND_SEG_2 */ { PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF }, /* 0100100 */
/* 24. THIRD_SEG_6 */ { PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_OFF }, /* 0010100 */
/* 25. THIRD_SEG_0 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_PLUS , PIN_OFF , PIN_OFF }, /* 0001100 */
/* 26. FIFTH_SEG_2 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_MIN , PIN_OFF }, /* 0000110 */
/* 27. FIFTH_SEG_6 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF , PIN_MIN }, /* 0000101 */
/* + */ /* Base: 0000010 */
/* 28. THIRD_SEG_3 */ { PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF }, /* 1000010 */
/* 29. USB */ { PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF }, /* 0100010 */
/* 30. THIRD_SEG_4 */ { PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_OFF }, /* 0010010 */
/* 31. FIFTH_SEG_3 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_PLUS , PIN_OFF }, /* 0001010 */
/* 32. FIFTH_SEG_5 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_PLUS , PIN_OFF }, /* 0000110 */
/* 33. FIFTH_SEG_1 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS , PIN_MIN }, /* 0000011 */
/* + Base: 0000001 */
/* 34. FM */ { PIN_OFF , PIN_OFF , PIN_MIN , PIN_OFF , PIN_OFF , PIN_OFF , PIN_PLUS },/* 0010001 */
/* 35. FIFTH_SEG_0 */ { PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_OFF , PIN_MIN , PIN_PLUS } /* 0000011 */
};
#define XTM_CHAR_ERR 0x49
// Special characters
#define XTM_MINUS 0x40
#define XTM_PLUS 0x44
#define XTM_BLANK 0x00
#define XTM_DEGREES 0x63
#define XTM_UNDERSCORE 0x08
#define XTM_EQUALS 0x48
#define XTM_LEFT 0x70
#define XTM_RIGHT 0x46
#define XTM_BRACKET_LEFT 0x39
#define XTM_BRACKET_RIGHT 0x0F
#define XTM_GREATER_LEFT 0x46
#define XTM_GREATER_RIGHT 0x70
#define XTM_ACCOLADE_LEFT XTM_GREATER_LEFT
#define XTM_ACCOLADE_RIGHT XTM_GREATER_RIGHT
#define XTM_COLON 0x09
#define XTM_PARENTHESIS_LEFT XTM_BRACKET_LEFT
#define XTM_PARENTHESIS_RIGHT XTM_BRACKET_RIGHT
#define XTM_QUESTION_MARK 0x53+0x80
#define XTM_SPECIAL_CHAR_OFFSET 0x24
// Font table:
XTM_MEM_ALLOC_TYPE const uint8_t XTM_DIGITS[] =
{
// Numbers
// 0 1 2 3 4 5 6 7 8 9
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, //(10)
// Hex
// A B C D E F
0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, //(06)
// Letters ( * = same as H )
// G H I J *K L M n O P Q r
0x3D, 0x76, 0x06, 0x1F, 0x76, 0x38, 0x15, 0x54, 0x3F, 0x73, 0x67, 0x50,//(12)
// S t U V W *X Y Z
0x6D, 0x78, 0x1C, 0x3E, 0x2A, 0x76, 0x6E, 0x5B, //(08)
// Special chars, offset = 0x24 (36)
(uint8_t)'-', XTM_MINUS,
(uint8_t)'+', XTM_PLUS,
(uint8_t)' ', XTM_BLANK,
(uint8_t)'^', XTM_DEGREES,
(uint8_t)'_', XTM_UNDERSCORE,
(uint8_t)'=', XTM_EQUALS,
(uint8_t)'[', XTM_BRACKET_LEFT,
(uint8_t)']', XTM_BRACKET_RIGHT,
(uint8_t)'<', XTM_GREATER_LEFT,
(uint8_t)'>', XTM_GREATER_RIGHT,
(uint8_t)'{', XTM_ACCOLADE_LEFT,
(uint8_t)'}', XTM_ACCOLADE_RIGHT,
(uint8_t)':', XTM_COLON,
(uint8_t)'(', XTM_PARENTHESIS_LEFT,
(uint8_t)')', XTM_PARENTHESIS_RIGHT,
(uint8_t)'?', XTM_QUESTION_MARK,
0x00
};
void __setCharlieLed( uint8_t iLed )
{
bool bOffDisable = ( iLed == SCP_LEDS_OFF_DISABLED );
if( !bOffDisable && iLed >= CP_CNT_LED )
{ return; }
uint8_t iPin = CP_CNT_PIN;
while( iPin-- )
{
if( bOffDisable || CP_LED_PINS_CFG[iLed][iPin] == PIN_OFF )
{
digitalWrite( CP_LED_PINS[iPin], PIN_LOW );
//pinMode( CP_LED_PINS[iPin], INPUT_PULLUP );
pinMode( CP_LED_PINS[iPin], INPUT );
//analogWrite( CP_LED_PINS[iPin], HIGH );
}
else {
pinMode( CP_LED_PINS[iPin], OUTPUT );
digitalWrite( CP_LED_PINS[iPin], (CP_LED_PINS_CFG[iLed][iPin] == PIN_PLUS)?PIN_HIGH:PIN_LOW );
}
}
}
void setCharlieLed( uint8_t iLed, bool bDirSwap = false )
{
if( bDirSwap )
{ bDirSwap=!bLedDirSwap; }
else { bDirSwap = bLedDirSwap; }
__setCharlieLed( bDirSwap?CP_CNT_LED-1-iLed:iLed );
}
void setAllLedsOffDisabled()
{
__setCharlieLed( SCP_LEDS_OFF_DISABLED );
}
void setAllLedsOnEnabled() // this might not be working with all kind of leds
{
uint8_t iPin = CP_CNT_PIN;
while( iPin-- )
{ __setCharlieLed( iPin ); }
}
void setLedEnabled( int iLed = SCP_LEDS_SHOW_ENABLED, bool bEnable = true, bool bReverse = false ) // must be called in a loop sequence to be functional
{
static bool aleEnabledLeds[CP_CNT_LED];
static bool bleInitLedArray = true;
static uint8_t ileCurrentLed = 0;
static uint8_t ileEnabledLeds = 0;
// To be sure memory locations are init with false or init with false when reset requested (< -1)
if( bleInitLedArray || iLed <= SCP_LEDS_RESET )
{
bleInitLedArray = false;
uint8_t i = CP_CNT_LED;
while( i-- )
{ aleEnabledLeds[i] = false; }
ileEnabledLeds = 0;
}
if( iLed >= 0 && iLed < CP_CNT_LED && aleEnabledLeds[iLed] != bEnable )
{
aleEnabledLeds[iLed] = bEnable;
ileEnabledLeds+=bEnable?1:-1;
//if( bEnable )
// { ileCurrentLed = iLed; }
}
if( ileEnabledLeds > 0 || bReverse )
{
if( (!bReverse && aleEnabledLeds[ileCurrentLed]) || (bReverse && !aleEnabledLeds[ileCurrentLed]) )
{ setCharlieLed( ileCurrentLed ); }
++ileCurrentLed;
if( ileCurrentLed >= CP_CNT_LED )
{ ileCurrentLed = 0; }
}
else { setAllLedsOffDisabled(); }
}
void showCharlieLedsEnabled( bool bReverse = false )
{ setLedEnabled( SCP_LEDS_SHOW_ENABLED, false, bReverse ); }
void resetCharlieLedsEnabled()
{ setLedEnabled( SCP_LEDS_RESET ); }
void set1MhzClockSpeed()
{
noInterrupts();
CLKPR = 1 << CLKPCE;
CLKPR = 0b00000100; // prescaler 16
}
void setup()
{
//set1MhzClockSpeed();
}
void loop()
{
static uint8_t i = 0;
//static TTimer tprgTimer = TTimer( 1000, (bool)true, (bool)false );
//if( tprgTimer.isTime() )
{
setLedEnabled( i );
++i;
if( i >= CP_CNT_LED )
{
i = 0;
//setAllLedsOffDisabled();
}
}
}
Notice:
- The code above is just a quick example (need some work), just to figure out how the display
works. The table however, it explain how the display is organized but
is not the most efficient way to do it, still usable though.
- I don't understand the way it is organized, it a little messy when you look at the order or placement of 'groups'.
- You can display LED's at the same time when they are in the same 'group' but makes it more complex to manage and requires more power. The cheap china sound module doesn't do this either, display individual segments one by one and it operates at a lower update frequency comparing to the Nano (wiggle it to see the difference between both).
- There is a font table in the example above, a mission I want to do, not working in this example. PROGMEM also needs some work.
- I didn't use resistors because it is charlieplexed and just one led at a time is on at one cycle. Don't expect issue's with this.
The next thing to do / figure out:
Like I explained in the question earlier, I want to communicate with the module by reading the display. I think it is possible by knowing how the display works. Perhaps it need some more work to achieve this but doesn't seem impossible.
For now, I qualify this post as an answer.