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+ This sketch is intended to help calibrate the VCOM display voltage.
9+ It should not be run frequently, as doing so may damage internal components.
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 ;
32+ double vcomVoltage;
33+
34+ double readPanelVCOM ();
35+ double getVCOMFromSerial (double *_vcom);
36+ uint8_t writeVCOMToEEPROM (double v);
37+ void displayTestImage ();
38+ template <typename T>
39+ void writeReg (uint8_t reg, T data);
40+ uint8_t readReg (uint8_t reg);
41+
42+ void setup () {
43+ Serial.begin (115200 ); // Start serial at 115200 baud
44+ EEPROM.begin (512 ); // Initialize EEPROM
45+ Wire.begin (); // Initialize I2C buss
46+ display.begin (); // Initialize the Inkplate
47+ display.einkOn ();
48+ Serial.println (" Enter VCOM value, it must be [-5, 0]" );
49+ displayTestImage ();
50+ }
51+
52+ void loop () {
53+
54+ if (Serial.available ()){
55+ // Serial.println("Enter VCOM value, it must be [-5, 0]");
56+ do {
57+ getVCOMFromSerial (&vcomVoltage);
58+ Serial.println (vcomVoltage, 2 );
59+ display.display ();
60+ if (vcomVoltage < -5.0 || vcomVoltage > 0.0 ){
61+ Serial.println (" VCOM out of range! [-5, 0]" );
62+ }
63+ }while (vcomVoltage <-5.0 || vcomVoltage > 0.0 );
64+
65+ // Program the panel EEPROM
66+ display.pinModeInternal (IO_INT_ADDR, display.ioRegsInt , 6 , INPUT_PULLUP);
67+ if (writeVCOMToEEPROM (vcomVoltage)){
68+ EEPROM.put (EEPROMAddress, vcomVoltage);
69+ EEPROM.commit ();
70+ }
71+ displayTestImage ();
72+ }
73+
74+ }
75+
76+ double readPanelVCOM (){
77+ delay (10 ); // Wake up TPS65186 so registers respond
78+ uint8_t vcomL=readReg (0x03 ); // REad low 8 bits from register 0x03
79+ uint8_t vcomH = readReg (0x04 ) & 0x01 ; // Read full byte, mask off all but bit 0 (MSB)
80+ delay (10 ); // Power down driver
81+ int raw=(vcomH << 8 ) | vcomL; // Value between 0 - 511
82+ return -(raw/100.0 );
83+ }
84+
85+ double getVCOMFromSerial (double *_vcom){
86+ double vcom=0 ;
87+ char buff[32 ];
88+ unsigned long start;
89+ while (!Serial.available ());
90+ start=millis ();
91+ int idx=0 ;
92+ while ((millis ()-start)<500 && idx<sizeof (buff)-1 ){
93+ if (Serial.available ()){
94+ char c=Serial.read ();
95+ buff[idx++]=c;
96+ start=millis ();
97+ }
98+ }
99+ buff[idx]=' \0 ' ;
100+ sscanf (buff, " %lf" , &vcom);
101+ *_vcom=vcom;
102+ return vcom;
103+ }
104+
105+ uint8_t writeVCOMToEEPROM (double v){
106+ // Build a 9-bit raw value (0 - 511)
107+ int raw=int (abs (v)*100 )&0x1FF ;
108+ uint8_t lsb=raw & 0xFF ;
109+ uint8_t msb=(raw >> 8 )&0x01 ;
110+
111+ display.einkOn ();
112+ delay (10 );
113+
114+ writeReg (0x03 , lsb);
115+ uint8_t r4=readReg (0x04 )&~0x01 ;
116+ writeReg (0x04 , r4 | msb);
117+ writeReg (0x04 , (r4 | msb) | (1 << 6 ));
118+ while ( display.digitalReadInternal (IO_INT_ADDR, display.ioRegsInt , 6 ) ) {
119+ delay (1 );
120+ }
121+ readReg (0x07 ); // clear interrupt flag
122+ writeReg (0x03 , 0 );
123+ writeReg (0x04 , 0 );
124+ display.einkOff (); // WAKEUP low
125+ delay (10 );
126+ display.einkOn (); // WAKEUP high
127+ delay (10 );
128+ uint8_t vL = readReg (0x03 );
129+ uint8_t vH = readReg (0x04 ) & 0x01 ;
130+ int check = (vH << 8 ) | vL;
131+ if (check != raw) {
132+ Serial.printf (" Verification failed: got %d, want %d\n " , check, raw);
133+ return 0 ;
134+ }
135+ Serial.println (" VCOM EEPROM PROGRAMMING OK" );
136+ return 1 ;
137+ }
138+ template <typename T>
139+ void writeReg (uint8_t reg, T data){
140+ Wire.beginTransmission (0x48 );
141+ Wire.write (reg);
142+ Wire.write ((uint8_t )data);
143+ Wire.endTransmission ();
144+ }
145+ uint8_t readReg (uint8_t reg){
146+ Wire.beginTransmission (0x48 );
147+ Wire.write (reg);
148+ Wire.endTransmission (false );
149+ Wire.requestFrom ((uint8_t )0x48 , (uint8_t )1 );
150+ return Wire.read ();
151+ }
152+ void displayTestImage () {
153+ display.clearDisplay ();
154+ currentVCOM = readPanelVCOM ();
155+
156+ display.setTextColor (BLACK);
157+ display.setTextSize (2 );
158+ display.setCursor (5 , 5 );
159+ display.print (" Current VCOM: " );
160+ display.print (currentVCOM, 2 );
161+ display.print (" V" );
162+
163+ for (int i = 0 ; i < 8 ; i++) {
164+ int x = (display.width () / 8 ) * i;
165+ display.drawRect (x, 40 , display.width () / 8 , display.height (), i);
166+ display.fillRect (x, 40 , display.width () / 8 , display.height (), i);
167+ }
168+ display.display ();
169+ }
0 commit comments