Skip to content

Commit b792e1e

Browse files
committed
Merge branch 'set-vcom-sketch' into dev
2 parents 8bb93d6 + 84502b1 commit b792e1e

File tree

5 files changed

+828
-0
lines changed

5 files changed

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

0 commit comments

Comments
 (0)