I have a VFD display and I'm trying to control it via an esp32. The display manufacturer provided an official Arduino code that works well, but when I try to port this code to ESP-IDF I cannot make it work. (I even ported the pinMode, digitalWrite and delayMicroseconds functions to IDF based on the arduino-esp32 repository's code).
Here's the original code.
uint8_t din = D10;
uint8_t clk = D8;
uint8_t cs = D1;
uint8_t Reset = D0;
void spi_write_data(unsigned char w_data) {
unsigned char i;
for (i = 0; i < 8; i++) {
digitalWrite(clk, LOW);
// If you use an Arduino device with faster processing speed,
// such as ESP32, please add some delay.
// The VFD SPI clock frequency is 0.5MHZ as described in the manual.
if ((w_data & 0x01) == 0x01) {
digitalWrite(din, HIGH);
} else {
digitalWrite(din, LOW);
}
w_data >>= 1;
digitalWrite(clk, HIGH);
}
}
void VFD_cmd(unsigned char command) {
digitalWrite(cs, LOW);
spi_write_data(command);
digitalWrite(cs, HIGH);
delayMicroseconds(5);
}
void VFD_show(void) {
digitalWrite(cs, LOW); // start transmission
spi_write_data(0xe8); // Open Display Command
digitalWrite(cs, HIGH); // stop transmission
}
void VFD_init() {
digitalWrite(cs, LOW);
spi_write_data(0xe0);
delayMicroseconds(5);
spi_write_data(0x07); // 8 character display 0x07
digitalWrite(cs, HIGH);
delayMicroseconds(5);
// Set the brightness
digitalWrite(cs, LOW);
spi_write_data(0xe4);
delayMicroseconds(5);
spi_write_data(0xff); //0xff max//0x01 min
digitalWrite(cs, HIGH);
delayMicroseconds(5);
}
void VFD_WriteStr(unsigned char x, char *str) {
digitalWrite(cs, LOW); // Start transmission
spi_write_data(0x20 + x); // Starting position of address register
while (*str) {
spi_write_data(*str); // ascii and corresponding character table conversion
str++;
}
digitalWrite(cs, HIGH); // Stop transmission
VFD_show();
}
void setup() {
pinMode(clk, OUTPUT);
pinMode(din, OUTPUT);
pinMode(cs, OUTPUT);
pinMode(Reset, OUTPUT);
delayMicroseconds(100);
digitalWrite(Reset, LOW);
delayMicroseconds(5);
digitalWrite(Reset, HIGH);
VFD_init();
}
void loop() {
VFD_cmd(0xE9); // Full brightness test screen
delay(1000);
VFD_WriteStr(0, "Hello!");
delay(1000);
}
As you can see, it doesn't use the SPI library but handles the communication manually. I tried to mimic the same behavior with ESP-IDF but without luck.
I'm quite lost to be honest and I would like to have this working in IDF if possible, but not really sure what to check anymore. Seems to me that Arduino might be doing some extra steps and configuration behind the scenes that I'm not aware of. Any suggestions or tips are welcome.
VFD_WriteStrafter, it resets the pixels and sets the text, so this is good. Like I said this code works fine in Arduino, so I don't think it's something with the display, probably some issue with clock timing or smth similar, just not sure what.