Same Arduino esp32 code doesn't work with ESP-IDF

jozefcipa
Posts: 3
Joined: Wed Mar 05, 2025 11:09 pm

Same Arduino esp32 code doesn't work with ESP-IDF

Postby jozefcipa » Wed Mar 05, 2025 11:15 pm

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.

Code: Untitled.c Select all


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.

Sprite
Espressif staff
Espressif staff
Posts: 10609
Joined: Thu Nov 26, 2015 4:08 am

Re: Same Arduino esp32 code doesn't work with ESP-IDF

Postby Sprite » Wed Mar 05, 2025 11:58 pm

That is hard to say, especially since we can't see your re-implementation of those Arduino commands. Do you have a digital oscilloscope or logic analyzer to look at the SPI data that's actually sent? Otherwise you're kind-of debugging in the dark.

jozefcipa
Posts: 3
Joined: Wed Mar 05, 2025 11:09 pm

Re: Same Arduino esp32 code doesn't work with ESP-IDF

Postby jozefcipa » Thu Mar 06, 2025 8:00 am

yeah, sorry, my bad. Here are the functions. Unfortunately, I don't have an oscilloscope or a logic analyzer.
In the worst case I'll have to go with the Arduino version, but I'd really prefer the IDF.

Code: Untitled.c Select all



#define NOP() asm volatile("nop")

void digitalWrite(uint8_t pin, uint8_t val) {
gpio_set_level((gpio_num_t)pin, val);
}

void pinMode(uint8_t pin, gpio_mode_t mode) {
gpio_config_t conf = {
.pin_bit_mask = (1ULL << pin), /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
.mode = GPIO_MODE_OUTPUT, /*!< GPIO mode: set input/output mode */
.pull_up_en = GPIO_PULLUP_DISABLE, /*!< GPIO pull-up */
.pull_down_en = GPIO_PULLDOWN_DISABLE, /*!< GPIO pull-down */
};
// if (mode < 0x20) { //io
// conf.mode = mode & (INPUT | OUTPUT);
// if (mode & OPEN_DRAIN) {
// conf.mode |= GPIO_MODE_DEF_OD;
// }
// if (mode & PULLUP) {
// conf.pull_up_en = GPIO_PULLUP_ENABLE;
// }
// if (mode & PULLDOWN) {
// conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
// }
// }
if (gpio_config(&conf) != ESP_OK) {
ESP_LOGE("GPIO", "IO %i config failed", pin);
return;
}
}

void IRAM_ATTR delayMicroseconds(uint32_t us) {
uint64_t m = (uint64_t)esp_timer_get_time();
if (us) {
uint64_t e = (m + us);
if (m > e) { //overf0
while ((uint64_t)esp_timer_get_time() > e) {
NOP();
}
}
while ((uint64_t)esp_timer_get_time() < e) {
NOP();
}
}
}
This is how I found them defined in https://github.com/espressif/arduino-esp32.

Btw, this is the display https://www.aliexpress.com/item/1005002932421503.html I'm using, just for the context

jozefcipa
Posts: 3
Joined: Wed Mar 05, 2025 11:09 pm

Re: Same Arduino esp32 code doesn't work with ESP-IDF

Postby jozefcipa » Thu Mar 06, 2025 9:51 am

Solution: I found out that since I don't use the official ESP32, the pin numbers are different (!), so I use this config

Code: Untitled.c Select all


uint8_t din = D10;
uint8_t clk = D8;
uint8_t cs = D1;
uint8_t Reset = D0;
I checked the XIAO_ESP32C3 variant file (https://github.com/espressif/arduino-es ... _arduino.h) and I found out this

Code: Untitled.c Select all


static const uint8_t D0 = 2;
static const uint8_t D1 = 3;
So in my ESP-IDF code I'm now using

Code: Untitled.c Select all


#define PIN_NUM_CS    GPIO_NUM_3 // D1   // Chip Select (CS)
#define PIN_NUM_RESET GPIO_NUM_2 // D0 // Reset (Reset)
and it works 🎉

Who is online

Users browsing this forum: No registered users and 2 guests