olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
4.91k stars 1.03k forks source link

Support for SED1530 (2x) and 33x200 px Display #2377

Closed karlo922 closed 2 months ago

karlo922 commented 4 months ago

Hi,

I have an old radio (Mercedes AUDIO 30 APS) using 2 SED1530 (33x100) controllers to control a 33x200 display with serial interface (CS, A0, CLK, SI) Datasheet can be found here: https://download.epson-europe.com/pub/electronics-de/assp/sed1500/tm_1500.pdf

What do you need from me to help?

Best regards

olikraus commented 4 months ago

It looks like this is indeed similar to the S1D15300 constructor, so maybe try this constructor:

U8G2_S1D15300_LM6023_1_4W_SW_SPI(U8G2_R0, clock, data, cs, dc, reset)

This constructor is actually for a 128x64 display, nevertheless you should be able to "see" something on the display. Maybe some contrast adjustment might be required (or use the ContrastTest.ino for testing)

Please post a picture of the result (HelloWorld.ino) so that we can create a new constructor for your display.

karlo922 commented 4 months ago

Thanks - I will do this as soon I have received the contacts to get it connected.

karlo922 commented 4 months ago

Hi! The display remains black all time - I guess this is due to two reasons:

  1. The voltage regulator circuit selection that may not fit to my display. It does not do any "buzzing" noises which it does when used in the original way of the radio at startup.
  2. It only uses one of the two SED1530 - the selection is done via CS 1/0 in the original one.

I have recorded a startup sequence of the display of the original radio - I hope this helps fixing it. I also attached a screenshot of the SPI communication with A0 = 0

A0 CS HEX BIN Meaning  
0 1 E2 11100010 CS_1 - Reset  
0 0 E2 11100010 CS_0 - Reset  
0 1 B0 10110000 CS_1 - Set Page Adress "0"
0 1 10 00010000 CS_1 - Set Col Adress high "0"
0 1 0 00000000 CS_1 - Set Col Adress low "0"
1 1 00 only   CS_1 - Disp Data "0"
0 0 B0 10110000 CS_0 - Set Page Adress "0"
0 0 10 00010000 CS_0 - Set Col Adress high "0"
0 0 0 00000000 CS_0 - Set Col Adress low "0"
1 0 00 only   CS_0 - Disp Data "0"
0 1 B1 10110001 CS_1 - Set Page Adress "1"
0 1 10 00010000 CS_1 - Set Col Adress high "0"
0 1 0 00000000 CS_1 - Set Col Adress low "0"
1 1 00 only   CS_1 - Disp Data "0"
0 0 B1 10110001 CS_0 - Set Page Adress "1"
0 0 10 00010000 CS_0 - Set Col Adress high "0"
0 0 0 00000000 CS_0 - Set Col Adress low "0"
1 0 00 only   CS_0 - Disp Data "0"
0 1 B2 10110010 CS_1 - Set Page Adress "2"
0 1 10 00010000 CS_1 - Set Col Adress high "0"
0 1 0 00000000 CS_1 - Set Col Adress low "0"
1 1 00 only   CS_1 - Disp Data "0"
0 0 B2 10110010 CS_0 - Set Page Adress "2"
0 0 10 00010000 CS_0 - Set Col Adress high "0"
0 0 0 00000000 CS_0 - Set Col Adress low "0"
1 0 00 only   CS_0 - Disp Data "0"
0 1 B3 10110011 CS_1 - Set Page Adress "3"
0 1 10 00010000 CS_1 - Set Col Adress high "0"
0 1 0 00000000 CS_1 - Set Col Adress low "0"
1 1 00 only   CS_1 - Disp Data "0"
0 0 B3 10110011 CS_0 - Set Page Adress "3"
0 0 10 00010000 CS_0 - Set Col Adress high "0"
0 0 0 00000000 CS_0 - Set Col Adress low "0"
1 0 00 only   CS_0 - Disp Data "0"
0 1 B8 10111000 CS_1 - Set Page Adress "8"
0 1 10 00010000 CS_1 - Set Col Adress high "0"
0 1 0 00000000 CS_1 - Set Col Adress low "0"
1 1 00 only   CS_1 - Disp Data "0"
0 0 B8 10111000 CS_0 - Set Page Adress "8"
0 0 10 00010000 CS_0 - Set Col Adress high "0"
0 0 0 00000000 CS_0 - Set Col Adress low "0"
1 0 00 only   CS_0 - Disp Data "0"
0 1 AF 10101111 CS_1 - Display ON
0 0 AF 10101111 CS_0 - Display ON
0 1 A0 10100000 CS_1 - ADC Select "0"
0 0 A0 10100000 CS_0 - ADC Select "0"
0 1 A6 10100110 CS_1 - Normal Reverse Display "normal"
0 0 A6 10100110 CS_0 - Normal Reverse Display "normal"
0 1 C8 11001000 CS_1 - Set output Status register "1"
0 0 C8 11001000 CS_0 - Set output Status register "1"
0 1 94 10010100 CS_1 - Set Electronic control register 10100
0 0 94 10010100 CS_0 - Set Electronic control register 10100
0 1 2C 00101100 CS_1 - Set Power Control 100
0 0 2C 00101100 CS_0 - Set Power Control 100
0 1 A2 10100010 CS_1 - LCD Bias "0"
0 0 A2 10100010 CS_0 - LCD Bias "0"
0 1 80 10000000 CS_1 - Set Electronic control register 00000
0 0 80 10000000 CS_0 - Set Electronic control register 00000
0 1 AC 10101100 CS_1 - Set Standby "0" - Off
0 0 AC 10101100 CS_0 - Set Standby "0" - Off
0 1 A4 10100100 CS_1 - Entire Display ON/OFF - 0 normal
0 0 A4 10100100 CS_0 - Entire Display ON/OFF - 0 normal

grafik

olikraus commented 3 months ago

So also ContrastTest.ino will not at least change the contrast somehow?

karlo922 commented 3 months ago

No - I guess the issue is, that CS needs to be "1" to control the Master. That is visible in the schematic how the two controllers are mounted on the board. It is now "0" which would only activate the slave chip. How can I change CS to be "1" if active?

karlo922 commented 3 months ago

Found the lines in the code I guess:

/* chip_enable_level = */ 1,
  /* chip_disable_level = */ 0,

But it did not help. I also now changed the SPI mode to "3" as CLK is active high in the original one.

karlo922 commented 3 months ago

I see a timing difference after the "soft reset" command from the original one. The original one waits 1ms after sending 0xE2. The display does not provide a RES input, so I cannot make use of

/* post_reset_wait_ms = */ 1, 

How could I achieve a 1ms waiting after the reset command? I also have the Osci raw data if this helps.

olikraus commented 3 months ago

Yes, you have to swap the values here: https://github.com/olikraus/u8g2/blob/ec2559e8466dead8b13dd92cc17ac10e63dab6ac/csrc/u8x8_d_s1d15300.c#L140-L141

This should be already 1ms: https://github.com/olikraus/u8g2/blob/ec2559e8466dead8b13dd92cc17ac10e63dab6ac/csrc/u8x8_d_s1d15300.c#L146

Change it to 2 for 2 ms.

karlo922 commented 3 months ago

If I got your code right, the post_reset_wait_ms is only used after resetting via the reset GPIO pins. I do not have any reset input at the display so I disabled them in the constructor. I guess this time is not used after sending the "soft reset - 0xE2" command. But the original display waits after this command for 1ms.

karlo922 commented 3 months ago

Just to see if I get this anyhow working I now just directly send the commands the original unit sends 1:1 to the SPI bus without using your library - it works! So at least all cables, SPI settings and so on are correct. Now I need to see when it stops working if I remove the part the current implementation of the u8g2 cannot handle with this constructor (the master/slave controllers, maybe the waiting time after soft-reset etc.) I will report as soon as I know where the issue lies. grafik

UPDATE: The findings:

Conclusion:

Somehting else within the library code seems not to work - maybe the buffer of 128x64 is not working with the "half" display of 100x33 (instead of 200x33 when using both controllers)? What would I need to change in the constructor to change this size? I did not get the logic behind:

 /* tile_width = */ 16,     /* width of 16*8=128 pixel */
  /* tile_height = */ 8,

How do I derive that numbers?

karlo922 commented 3 months ago

I got it working "half" with following constructor:

grafik

static const u8x8_display_info_t u8x8_s1d15300_lm6023_display_info =
{
  /* chip_enable_level = */ 1,
  /* chip_disable_level = */ 0,

  /* post_chip_enable_wait_ns = */ 250, /*  */
  /* pre_chip_disable_wait_ns = */ 120, /*  */
  /* reset_pulse_width_ms = */ 1, 
  /* post_reset_wait_ms = */ 1, 
  /* sda_setup_time_ns = */ 200,        /* */
  /* sck_pulse_width_ns = */ 200,   /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
  /* sck_clock_hz = */ 1000000UL,   /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
  /* spi_mode = */ 3,       /* active high, rising edge */
  /* i2c_bus_clock_100kHz = */ 4,
  /* data_setup_time_ns = */ 200,   /* st7565 datasheet, table 24, tds8 */
  /* write_pulse_width_ns = */ 200, /* st7565 datasheet, table 24, tcclw */
  /* tile_width = */ 12,        /* width of 12*8=96 pixel */
  /* tile_height = */ 4,
  /* default_x_offset = */ 0,
  /* flipmode_x_offset = */ 4,
  /* pixel_width = */ 96,
  /* pixel_height = */ 32
};

And following init procedure:

static const uint8_t u8x8_d_s1d15300_lm6023_init_seq[] = {

    U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */

    U8X8_C(0x0e2), /* soft reset */
    U8X8_C(0x0af), /* display on */
    U8X8_C(0x0a0), /* ADC set to normal */
    U8X8_C(0x0a6), /* Display normal */
    U8X8_C(0x0c8), /* Set output Status register "1" */
    U8X8_C(0x094), /* Set Electronic control register 10100 */
    U8X8_C(0x02c), /* Set Power Control 100 */
    U8X8_C(0x0a2), /* CS_1 - LCD Bias "0" */
    U8X8_C(0x080), /* Set Electronic control register 00000 */
    U8X8_C(0x0ac), /* Set Standby "0" - Off */
    U8X8_C(0x0a4), /* all point normal */
    U8X8_C(0x0a6), /* Display normal */
    U8X8_C(0x0b0), /* set page address */
    U8X8_C(0x010), /* set column address upper */
    U8X8_C(0x000), /* set column address lower */

    U8X8_END_TRANSFER(), /* disable chip */
    U8X8_END()           /* end of sequence */  
};

Now there stay 2 questions:

  1. How can I use the full left half display (now 96x32 as I think the tile_width etc. need to be multiplied by 8, but 100x33 is not dividable by 8?
  2. How can I enable the right half of the display which is controlled by the second SED1530 using CS=0? I guess we would need to check if x>100 and if yes, use CS=0, else use CS=1 for sending the commands to the controllers. But I currently do not know where to put that to have not too much code changes...
olikraus commented 3 months ago

How can I use the full left half display (now 96x32 as I think the tile_width etc. need to be multiplied by 8, but 100x33 is not dividable by 8?

Just increase the "tile_width" to 13 and assign the correct pixel value 100 into "pixel_width".

How can I enable the right half of the display which is controlled by the second SED1530 using CS=0?

The best way would be to create a second u8g2 object for the second display. Is it correct, that the CS line is inverted for the other display?

karlo922 commented 3 months ago

The best way would be to create a second u8g2 object for the second display. Is it correct, that the CS line is inverted for the other display?

Yes, CS is inverted (0 instead of 1 for left half) for the right half of the display. It's only the other half of the same display, so it would be great if the code automatically would invert CS when x > 100. If I would just create a second u8g2 object, I could not easily draw text over the full size of the display.

karlo922 commented 3 months ago

Just to be sure we have the same understanding: The two controllers are mounted in "Master/Slave" configuration on the board behind the display - so you have only 4 wires for driving both controllers simultaneously: DAT, CLK, CS and A0.

The controllers itself have two CS inputs: !CS1 & CS2

With that configuration, "master controller" will be active if CS = high and "slave controller" will be active if CS = low. This connection is also mentionned within the controller datasheet: https://download.epson-europe.com/pub/electronics-de/assp/sed1500/tm_1500.pdf Excerpt from the docs:

grafik

This is like done on my display, but as it is only 200x33, the 33 COM pins are not connected from the slave controller to the display (they are left unconnected). The 33 rows are only connected to master.

grafik

From the recorded original codes sent from the radio to the right display, I have attached the commands and data which was sent to show "ENTER CODE NUMBER" (like shown in one of the above pictures). You also see that the data for the slave controller is always one byte shorter than for the master.

Init sequence commands sent to both controllers
(A0=0, each command will be sent twice, once with CS = 1 once with CS = 0)
- 0xAF,0xA0,0xA6,0xC8,0x94,0x2C,0xA2,0x80,0xAC,0xA4

Data sent for display content:
- CS=1
- Command (A0=0): 0xB0,0x10,0x00 
- Data (A0=1):  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

- CS=0
- Command (A0=0): 0xB0,0x10,0x00
- Data (A0=1):  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00            

- CS=1
- Command (A0=0): 0xB1,0x10,0x00
- Data (A0=1):  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,
                0x88,0x88,0x88,0x08,0x00,0x00,0xF8,0x70,0xE0,0xC0,0x80,0x00,0xF8,0x00,0x00,0x08,0x08,0x08,0xF8,0xF8,0x08,0x08,0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,
                0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,0xF8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF0,0x18,0x08,0x08,0x08,0x10,0x00,0x00,0xE0,0xF0,0x18,0x08,0x08,
                0x18,0xF0,0xE0,0x00,0x00,0xF8,0xF8,0x08,0x08,0x18

- CS=0
- Command (A0=0): 0xB1,0x10,0x00
- Data (A0=1):  0xF0,0xE0,0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x70,0xE0,0xC0,0x80,0x00,0xF8,0x00,0x00,0xF8,0xF8,0x00,0x00,
                0x00,0xF8,0xF8,0x00,0x00,0xF8,0x70,0xE0,0xC0,0xC0,0x60,0xF0,0xF8,0x00,0x00,0xF8,0xF8,0x88,0x88,0xF8,0xF0,0x00,0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,
                0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,0xF8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

- CS=1
- Command (A0=0): 0xB2,0x10,0x00
- Data (A0=1):  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,
                0x08,0x08,0x08,0x08,0x00,0x00,0x0F,0x00,0x00,0x01,0x03,0x07,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x0F,0x0F,0x08,0x08,0x08,0x08,
                0x00,0x00,0x0F,0x0F,0x01,0x03,0x06,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0C,0x08,0x08,0x08,0x04,0x00,0x00,0x03,0x07,0x0C,0x08,0x08,
                0x0C,0x07,0x03,0x00,0x00,0x0F,0x0F,0x08,0x08,0x0C

- CS=0
- Command (A0=0): 0xB2,0x10,0x00
- Data (A0=1):  0x07,0x03,0x00,0x00,0x0F,0x0F,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x01,0x03,0x07,0x0F,0x00,0x00,0x03,0x07,0x0C,0x08,
                0x0C,0x07,0x03,0x00,0x00,0x0F,0x00,0x00,0x01,0x00,0x00,0x0F,0x0F,0x00,0x00,0x0F,0x0F,0x08,0x08,0x08,0x0F,0x07,0x00,0x00,0x0F,0x0F,0x08,0x08,0x08,0x08,
                0x00,0x00,0x0F,0x0F,0x01,0x03,0x06,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
olikraus commented 3 months ago

Thanks for all the input. However I don't know when I will find time to work on this.

karlo922 commented 3 months ago

Thanks - I maybe try to find out a little bit myself... I guess a starting point could be the one special thing you already have using 3 "displays" u8x8_d_hd44102.c There you use 2 CS lines, I think this is near to what I need with the change that I need SPI and only one CS. But there you already "split" the output after x > threshold.

olikraus commented 3 months ago

ok... I just decided to look at this a little bit closer.

karlo922 commented 3 months ago

even better! Thanks!

olikraus commented 3 months ago

As of now I have created two constructors: U8G2_S1D15300_100X33 U8G2_S1D15300_100X33I

The I version has an inverted CS1 input. Can you check whether the two constructors are working as expected? I also tookover the config from your trace with one exception: I have used 0x02f instead of 0x2c for the power setup.

You can download the latest U8g2 beta release from here: https://github.com/olikraus/U8g2_Arduino/archive/master.zip Arduino IDE:

  1. Remove the existing U8g2_Arduino library (https://stackoverflow.com/questions/16752806/how-do-i-remove-a-library-from-the-arduino-environment)
  2. Install the U8g2_Arduino Zip file via Arduino IDE, add zip library menu (https://www.arduino.cc/en/Guide/Libraries).

PlatformIO: platformio.ini (https://docs.platformio.org/en/latest/projectconf/section_env_library.html#lib-deps) should include

lib_deps =
  u8g2=https://github.com/olikraus/U8g2_Arduino/archive/master.zip
olikraus commented 3 months ago

U8g2 has powerfull clipping procedure, so drawing the same content twice on both displays shouldn't be a big delay. Example taken from here: https://github.com/olikraus/u8g2/issues/1351


U8G2_S1D15300_100X33_2_4W_HW_SPI u8g2_0(U8G2_R0, /* cs=*/ 1, /* dc=*/ 2, /* reset=*/ 3);
U8G2_S1D15300_100X33I_2_4W_HW_SPI u8g2_1(U8G2_R0, /* cs=*/ 1, /* dc=*/ 2, /* reset=*/ 3);

U8G2 *u8g2_current;
u8g2_uint_t offset;

void setLeftSide() {
  u8g2_current = &u8g2_0;
  offset = 0;
}
void setRightSide() {
  u8g2_current = &u8g2_1;
  offset = 100;
}

void drawStr(u8g2_uint_t x, u8g2_uint_t y, const char *s) {
  u8g2_current->drawStr(x-offset,y,s);
}

void drawWelcome() {
  u8g2_current->setFont(u8g2_font_ncenB08_tr);
  drawStr(120, 40, "Welcome");
}

void setup(void) {
    Serial.begin(115200);

    u8g2_0.begin();
    u8g2_0.setFlipMode(0);
    u8g2_0.setContrast(255);
    u8g2_0.setFont(u8g2_font_ncenB08_tr);

    u8g2_1.begin();
    u8g2_1.setFlipMode(1);
    u8g2_1.setContrast(255);
    u8g2_1.setFont(u8g2_font_ncenB08_tr);

    Serial.println("Lanuching test...");
}

void loop(void) {

    setLeftSide();
    u8g2_current->firstPage();
    do { drawWelcome(); } 
    while (u8g2_current->nextPage());

    setRightSide();
    u8g2_current->firstPage();
    do { drawWelcome(); } 
    while ( u8g2_current->nextPage());
}
karlo922 commented 3 months ago

U8G2_S1D15300_100X33I_2_4W_HW_SPI: grafik

If I use the one without "I" nothing is shown.

karlo922 commented 3 months ago

To be more precise: If the left display part has worked, right after uploading, the right display will show something: grafik

But after a power-up, only left dsiplay (when using "I") or nothing is active. Text should be "Linkes Display oder rechts"

olikraus commented 3 months ago

Can it be that you did not update the u8g2.h? it does not find it

Usually this is updated automatically

If the left display part has worked, right after uploading, the right display will show something:

ok... maybe you can also send the code, which should produce this result.

"Linkes Display oder rechts"

hmm, the display seems to be mirrored, right?

karlo922 commented 3 months ago

This is the code. Once with "I" once without

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

//U8G2_S1D15300_100X33_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X33I_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2.begin();  
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
  } while ( u8g2.nextPage() );
  //delay(1000);
}

Forget about the .h file comment - my fault. Everything is good.

Yes it is mirrored. It wasn't when I manually changed the constructor myself.

olikraus commented 3 months ago

It wasn't when I manually changed the constructor myself.

strange, I didn't change this part.

Nevertheless, to fix the mirror topic, can you do a u8g2.sendF("c", 0x0a1); right after u8g2.begin()? Will this fix the mirrored display?

karlo922 commented 3 months ago

No it does not fix it

olikraus commented 3 months ago

What about this? You can change 0x0a0 to 0x0a1 also. It actually should have an effect... hmmm

void setup(void) {
  u8g2.begin();  
  u8g2.sendF("c", 0x0a0);
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
  } while ( u8g2.nextPage() );
  //delay(1000);
}
karlo922 commented 3 months ago

It mirrors it, but actually it is rotated by 180 degrees

karlo922 commented 3 months ago

a1 grafik

a0 grafik

olikraus commented 3 months ago

Thanks for the pics. In between i am studiing the datasheet... I think we have to play around also with the 0x0c0 command. There are four combinations:

u8g2.sendF("cc", 0x0a0, 0x0c0);
u8g2.sendF("cc", 0x0a0, 0x0c8);
u8g2.sendF("cc", 0x0a1, 0x0c0);
u8g2.sendF("cc", 0x0a1, 0x0c8);

Which of the four settings will lead to a correct image?

karlo922 commented 3 months ago

This one works: u8g2.sendF("cc", 0x0a0, 0x0c8);

grafik

karlo922 commented 3 months ago

But still the right part will not really work from power on. I guess the issue is, that without enabling the "master" controller, it will not push any data to the "slave" controller

olikraus commented 3 months ago

... then let's have a look at the second display.

U8G2_S1D15300_100X33_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X33I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin();  // start with the I display
  u8g2i.sendF("cc", 0x0a0, 0x0c8);
  u8g2.begin();  
  u8g2.sendF("cc", 0x0a0, 0x0c8);
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
  } while ( u8g2.nextPage() );
}

Will this work?

karlo922 commented 3 months ago

Right after upload, some artifacts: grafik

after power latch: grafik

olikraus commented 3 months ago

ok, then we need to see the borders of the display, let's draw a frame:

U8G2_S1D15300_100X33_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X33I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin();  // start with the I display
  u8g2i.sendF("cc", 0x0a0, 0x0c8);
  u8g2.begin();  
  u8g2.sendF("cc", 0x0a0, 0x0c8);
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
    u8g2i.drawFrame(0,0,100,33);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
    u8g2.drawFrame(0,0,100,33);
  } while ( u8g2.nextPage() );
}
karlo922 commented 3 months ago

grafik the line in the middle is okay, but behind this plastic strip

olikraus commented 3 months ago

... hmmm more reverse engineering required, than expected...

The goal is to make the frame fully visible. It looks like the frame is moved somehow in x and y, this must be fixed Moreover I am missing the lower line of the frame. Are you sure that this is a 100x33 display, instead it could be 100x32

Lets rotate the text and frame by 180 degree. How will it look?

U8G2_S1D15300_100X33_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X33I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin();  // start with the I display
  u8g2i.sendF("cc", 0x0a1, 0x0c0);
  u8g2.begin();  
  u8g2.sendF("cc", 0x0a1, 0x0c0);
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
    u8g2i.drawFrame(0,0,100,33);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
    u8g2.drawFrame(0,0,100,33);
  } while ( u8g2.nextPage() );
}
karlo922 commented 3 months ago

with

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
    u8g2i.drawFrame(0,0,100,32);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
    u8g2.drawFrame(0,0,98,32);
  } while ( u8g2.nextPage() );
}

at the right, 2 columns are on in parallel at the left, it does not use the full space the middle is 2 lines next to each other ->correct I guess

grafik

grafik

karlo922 commented 3 months ago

... hmmm more reverse engineering required, than expected...

The goal is to make the frame fully visible. It looks like the frame is moved somehow in x and y, this must be fixed Moreover I am missing the lower line of the frame. Are you sure that this is a 100x33 display, instead it could be 100x32

Lets rotate the text and frame by 180 degree. How will it look?

U8G2_S1D15300_100X33_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X33I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin();  // start with the I display
  u8g2i.sendF("cc", 0x0a1, 0x0c0);
  u8g2.begin();  
  u8g2.sendF("cc", 0x0a1, 0x0c0);
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
    u8g2i.drawFrame(0,0,100,33);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
    u8g2.drawFrame(0,0,100,33);
  } while ( u8g2.nextPage() );
}

like that: grafik

I will look at the manual again, may be x32 display indeed

karlo922 commented 3 months ago

At the Master Controller, COM1...COM32 and COMS are connected to the display. Should be 33 height, shouldn't it? https://docplayer.org/5028242-Service-manual-version-1-0-deutsch-audio-30-aps-navigation-schaltplan-bestueckungsplan-testprogramm-reset-code-eingabe.html Page 26 I have no real information about the display itself

karlo922 commented 3 months ago

You are right, we have only 32 COM Pins connected -> 32 height

olikraus commented 3 months ago

Yes... the indicator COMS is not supported by u8g2. Anyway it is probably not usable for the graphcis area. Still the question is, how to get rid of the 2-pixel left gap.

I have created a new release with a new constructor, so

U8G2_S1D15300_100X32_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X32I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin(); 
  u8g2.begin();  
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"i DISPLAY i DISPLAY");
    u8g2i.drawFrame(0,0,100,32);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Linkes Display oder rechts");
    u8g2.drawFrame(0,0,100,32);
  } while ( u8g2.nextPage() );
}

should work, but I don't know how to fix the left gap

latest release:

You can download the latest U8g2 beta release from here: https://github.com/olikraus/U8g2_Arduino/archive/master.zip Arduino IDE:

  1. Remove the existing U8g2_Arduino library (https://stackoverflow.com/questions/16752806/how-do-i-remove-a-library-from-the-arduino-environment)
  2. Install the U8g2_Arduino Zip file via Arduino IDE, add zip library menu (https://www.arduino.cc/en/Guide/Libraries).

PlatformIO: platformio.ini (https://docs.platformio.org/en/latest/projectconf/section_env_library.html#lib-deps) should include

lib_deps =
  u8g2=https://github.com/olikraus/U8g2_Arduino/archive/master.zip

edit: fixed constructor name

karlo922 commented 3 months ago

The new constructor name is not found

karlo922 commented 3 months ago

From the service manual, I also think the left display has 100x32 (COM1..32 connected and SEG0..99) but the right one only has SEG0...98 connected, so this should be a 99x32. The we would have a full 199x32 display

olikraus commented 3 months ago

The new constructor name is not found

Seems to be too late...

I created another release...

karlo922 commented 3 months ago

lib\U8g2_Arduino-master\src\U8x8lib.h:8798:27: error: 'u8x8_d_s1d15300_100x32i' was not declared in this scope I guess we should work on this another day ;)

karlo922 commented 3 months ago

After fixing the names, I get this. Last for today: grafik

olikraus commented 3 months ago

lib\U8g2_Arduino-master\src\U8x8lib.h:8798:27: error: 'u8x8_d_s1d15300_100x32i' was not declared in this scope

argl, i have created another release...

karlo922 commented 3 months ago

I have tried a little bit around. To see whats happening, I only activated the frame on the "right" display. It's worse than we thought:

8G2_S1D15300_100X32_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);
U8G2_S1D15300_100X32I_F_4W_HW_SPI u8g2i(U8G2_R0, /* cs=*/ 9, /* dc=*/ 7, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  u8g2i.begin(); 
  u8g2.begin();  
}

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"Links");
    //u8g2i.drawFrame(0,0,100,32);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Rechts");
    u8g2.drawFrame(0,0,98,32);
  } while ( u8g2.nextPage() );
}

99 width: grafik

The left one works as expected, u8g2i.drawFrame(0,0,100,32); starts at the third column from left, and shows a clean frame.

Conclusion:

I guess this means we change the "non-i" variant to 97x32 (remove the 2x2 columns at outer left/right which cannot be used single) and just ignore those "missing" 4 columns.

void loop(void) {
  u8g2i.firstPage();
  do {
    u8g2i.setFont(u8g2_font_ncenB10_tr);
    u8g2i.drawStr(0,24,"Links");
    u8g2i.drawFrame(0,0,100,32);
  } while ( u8g2i.nextPage() );
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Rechts");
    u8g2.drawFrame(0,0,97,32);
  } while ( u8g2.nextPage() );
}

produces: grafik

olikraus commented 3 months ago

Looks like a strange HW configuration :-D

I have created another release with additioanl "U8G2_S1D15300_97X32_F_4W_HW_SPI" constructor

You can download the latest U8g2 beta release from here: https://github.com/olikraus/U8g2_Arduino/archive/master.zip Arduino IDE:

  1. Remove the existing U8g2_Arduino library (https://stackoverflow.com/questions/16752806/how-do-i-remove-a-library-from-the-arduino-environment)
  2. Install the U8g2_Arduino Zip file via Arduino IDE, add zip library menu (https://www.arduino.cc/en/Guide/Libraries).

PlatformIO: platformio.ini (https://docs.platformio.org/en/latest/projectconf/section_env_library.html#lib-deps) should include

lib_deps =
  u8g2=https://github.com/olikraus/U8g2_Arduino/archive/master.zip