0

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.

2
  • So, it didn't seem important to mention what display you're using, or what went wrong when you ran this code???? Based on my best guess as to the actual display, it looks like you're never turning off the "Full brightness test screen", so there's no possibility of the string you write later to actually be visible. Commented Mar 6 at 4:48
  • sorry, the display I use is this one aliexpress.com/item/1005002932421503.html It's Futaba VFD 8-character. And not sure what went wrong, because nothing shows up on the display. The brightness test screen only turns on all the pixels, so when I call VFD_WriteStr after, 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. Commented Mar 6 at 7:56

1 Answer 1

0

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

uint8_t din = D10;
uint8_t clk = D8;
uint8_t cs = D1;
uint8_t Reset = D0;

I checked the XIAO_ESP32C3 variant file and I found out this

static const uint8_t D0 = 2;
static const uint8_t D1 = 3;

So in my ESP-IDF code I'm now using

#define PIN_NUM_CS    GPIO_NUM_3 // D1   // Chip Select (CS)
#define PIN_NUM_RESET GPIO_NUM_2 // D0   // Reset (Reset)

and it works 🎉

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.