1+ /*
2+ Inkplate10_Set_VCOM sketch for Soldered Inkplate 10.
3+ For this sketch you will need USB and Inkplate 10.
4+ Select "e-radionica Inkplate 10" or "Soldered Inkplate10" from Tools -> Board menu.
5+ Don't have "e-radionica Inkplate10" or "Soldered Inkplate10" option? Follow our tutorial and add it:
6+ https://soldered.com/learn/add-inkplate-6-board-definition-to-arduino-ide/
7+
8+ WARNING! - VCOM voltage is written in EEPROM, which means it can be set a limited number of
9+ times, so don't run this sketch repeteadly! VCOM should be set once and then left as is.
10+ Use with caution!
11+
12+ Want to learn more about Inkplate? Visit https://soldered.com/documentation/inkplate/
13+ Looking to get support? Write on our forums: https://forum.soldered.com/
14+ 29 July 2025 by Soldered
15+ */
16+
17+ // Next 3 lines are a precaution, you can ignore those, and the example would also work without them
18+ #if !defined(ARDUINO_INKPLATE10) && !defined(ARDUINO_INKPLATE10V2)
19+ #error \
20+ " Wrong board selection for this example, please select e-radionica Inkplate10 or Soldered Inkplate10 in the boards menu."
21+ #endif
22+
23+ #include < EEPROM.h>
24+ #include < Inkplate.h>
25+ #include < Wire.h>
26+
27+ Inkplate display (INKPLATE_3BIT); // Create an object on Inkplate library and also set the grayscale to 3bit.
28+
29+
30+ double currentVCOM; // Stores the current VCOM value stored on EEPROM
31+ const int EEPROMAddress=0 ; // Should leave the address as it is for correct EEPROM reading later
32+ double vcomVoltage;
33+
34+ double readPanelVCOM ();
35+ double getVCOMFromSerial (double *_vcom);
36+ uint8_t writeVCOMToEEPROM (double v);
37+ void displayTestImage ();
38+ void writeReg (uint8_t reg, float data);
39+ uint8_t readReg (uint8_t reg);
40+
41+ void setup () {
42+ Serial.begin (115200 ); // Start serial at 115200 baud
43+ EEPROM.begin (512 ); // Initialize EEPROM
44+ Wire.begin (); // Initialize I2C buss
45+ display.begin (); // Initialize the Inkplate
46+ Serial.println (" The optimal VCOM Voltage for your Inkplate's panel can sometimes be found written on the flat cable connector" );
47+ Serial.println (" Write VCOM voltage from epaper panel. \r\n Don't forget negative (-) sign!\r\n Use dot as the decimal point.\r\n For example -1.23\n " );
48+ displayTestImage ();
49+ }
50+
51+ void loop () {
52+
53+ if (Serial.available ()){
54+ // Serial.println("Enter VCOM value, it must be [-5, 0]");
55+ do {
56+ getVCOMFromSerial (&vcomVoltage);
57+ Serial.println (vcomVoltage, 2 );
58+ display.display ();
59+ if (vcomVoltage < -5.0 || vcomVoltage > 0.0 ){
60+ Serial.println (" VCOM out of range! [-5, 0]" );
61+ }
62+ }while (vcomVoltage <-5.0 || vcomVoltage > 0.0 );
63+
64+ // Program the panel EEPROM
65+ display.pinModeInternal (IO_INT_ADDR, display.ioRegsInt , 6 , INPUT_PULLUP);
66+ if (writeVCOMToEEPROM (vcomVoltage)){
67+ EEPROM.put (EEPROMAddress, vcomVoltage);
68+ EEPROM.commit ();
69+ }
70+ displayTestImage ();
71+ }
72+
73+ }
74+
75+ double readPanelVCOM (){
76+ delay (10 ); // Wake up TPS65186 so registers respond
77+ uint8_t vcomL=readReg (0x03 ); // REad low 8 bits from register 0x03
78+ uint8_t vcomH = readReg (0x04 ) & 0x01 ; // Read full byte, mask off all but bit 0 (MSB)
79+ delay (10 ); // Power down driver
80+ int raw=(vcomH << 8 ) | vcomL; // Value between 0 - 511
81+ return -(raw/100.0 );
82+ }
83+
84+ double getVCOMFromSerial (double *_vcom){
85+ double vcom=0 ;
86+ char buff[32 ];
87+ unsigned long start;
88+ while (!Serial.available ());
89+ start=millis ();
90+ int idx=0 ;
91+ while ((millis ()-start)<500 && idx<sizeof (buff)-1 ){
92+ if (Serial.available ()){
93+ char c=Serial.read ();
94+ buff[idx++]=c;
95+ start=millis ();
96+ }
97+ }
98+ buff[idx]=' \0 ' ;
99+ sscanf (buff, " %lf" , &vcom);
100+ *_vcom=vcom;
101+ return vcom;
102+ }
103+
104+ uint8_t writeVCOMToEEPROM (double v){
105+ // Build a 9-bit raw value (0 - 511)
106+ int raw=int (abs (v)*100 )&0x1FF ;
107+ uint8_t lsb=raw & 0xFF ;
108+ uint8_t msb=(raw >> 8 )&0x01 ;
109+
110+ display.einkOn ();
111+ delay (10 );
112+
113+ writeReg (0x03 , lsb);
114+ uint8_t r4=readReg (0x04 )&~0x01 ;
115+ writeReg (0x04 , r4 | msb);
116+ writeReg (0x04 , (r4 | msb) | (1 << 6 ));
117+ while ( display.digitalReadInternal (IO_INT_ADDR, display.ioRegsInt , 6 ) ) {
118+ delay (1 );
119+ }
120+ readReg (0x07 ); // clear interrupt flag
121+ writeReg (0x03 , 0 );
122+ writeReg (0x04 , 0 );
123+ display.einkOff (); // WAKEUP low
124+ delay (10 );
125+ display.einkOn (); // WAKEUP high
126+ delay (10 );
127+ uint8_t vL = readReg (0x03 );
128+ uint8_t vH = readReg (0x04 ) & 0x01 ;
129+ int check = (vH << 8 ) | vL;
130+ if (check != raw) {
131+ Serial.printf (" Verification failed: got %d, want %d\n " , check, raw);
132+ return 0 ;
133+ }
134+ Serial.println (" VCOM EEPROM PROGRAMMING OK" );
135+ return 1 ;
136+ }
137+ void writeReg (uint8_t reg, float data){
138+ Wire.beginTransmission (0x48 );
139+ Wire.write (reg);
140+ Wire.write ((uint8_t )data);
141+ Wire.endTransmission ();
142+ }
143+ uint8_t readReg (uint8_t reg){
144+ Wire.beginTransmission (0x48 );
145+ Wire.write (reg);
146+ Wire.endTransmission (false );
147+ Wire.requestFrom ((uint8_t )0x48 , (uint8_t )1 );
148+ return Wire.read ();
149+ }
150+ void displayTestImage () {
151+ display.clearDisplay ();
152+ currentVCOM = readPanelVCOM ();
153+
154+ display.setTextColor (BLACK);
155+ display.setTextSize (2 );
156+ display.setCursor (5 , 5 );
157+ display.print (" Current VCOM: " );
158+ display.print (currentVCOM, 2 );
159+ display.print (" V" );
160+
161+ for (int i = 0 ; i < 8 ; i++) {
162+ int x = (display.width () / 8 ) * i;
163+ display.drawRect (x, 40 , display.width () / 8 , display.height (), i);
164+ display.fillRect (x, 40 , display.width () / 8 , display.height (), i);
165+ }
166+ display.display ();
167+ }
0 commit comments