DEV Community

Cover image for Ulanzi TC001 - ESP32 Programming / Custom Arduino firmware

Ulanzi TC001 - ESP32 Programming / Custom Arduino firmware

Calum Knott on December 14, 2024

I found quite a lot of tutorials on using the Ulanzi TC001 with a firmware like AWTRIX, but not much information on simply programming it from scra...
Collapse
 
reinout_roels_4ca4a460b83 profile image
Reinout Roels • • Edited

Very useful, thanks! Is there any public info on how to interface with for instance the sensor or the buzzer? I can't seem to find even the pinout.

I would prefer not to take apart my brand new clock just yet :D

EDIT: never mind, found something useful:
github.com/Blueforcer/awtrix3/blob...
templates.blakadder.com/ulanzi_TC0...

Collapse
 
calumk profile image
Calum Knott •

I wasnt aware there was a buzzer! Thanks thats usefull

Collapse
 
reinout_roels_4ca4a460b83 profile image
Reinout Roels •

There's also a dedicated RTC and temp/humidity sensor connected to the I2C bus. I will try to get these working via Arduino in the coming week.

Collapse
 
foggy_ammain_c3e6e27db65 profile image
Foggy am Main •

Hi everyone!
I’m wondering if anyone knows whether it’s possible to reflash the Ulanzi TC001 (ESP32) so that it runs only a simple timer — continuously counting up to 99,999 hours (and displaying it on the LED matrix).
I don’t need any of the other functions — just this one timer running all the time.

Can I program this directly on the ESP32 inside the TC001, or is there any limitation I should be aware of?

Collapse
 
calumk profile image
Calum Knott •

Yes, you can program it directly, should not be too dificult!

Collapse
 
foggy_ammain_c3e6e27db65 profile image
Foggy am Main •

Dear Calum Knott,
Could you please take a look at my code? I would be very grateful!
I’m trying to make a gift for a friend this way.

include

include

include

// Настройки матрицы Ulanzi TC001 (32x8)

define MATRIX_WIDTH 32

define MATRIX_HEIGHT 8

define P_LAT 22

define P_A 19

define P_B 23

define P_C 18

define P_OE 21

PxMatrix display(MATRIX_WIDTH, MATRIX_HEIGHT, P_LAT, P_OE, P_A, P_B, P_C);

// Таймер
unsigned long totalHours = 99999; // начальное время
unsigned long remainingMs;
unsigned long lastUpdate = 0;
unsigned long prevSave = 0;
const unsigned long SAVE_INTERVAL = 600000; // каждые 10 мин сохраняем
const unsigned long HOUR_MS = 3600000UL;

hw_timer_t *timer = NULL;

void IRAM_ATTR display_updater() {
display.display(70);
}

void setup() {
EEPROM.begin(64);

EEPROM.get(0, remainingMs);
if (remainingMs == 0 || remainingMs > totalHours * HOUR_MS) {
remainingMs = totalHours * HOUR_MS;
}

display.begin(16);
display.setBrightness(80);
display.clearDisplay();
display.setFont(&FreeSansBold9pt7b);
display.setTextColor(display.color565(255, 255, 255));

// Аппаратный таймер для обновления дисплея
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &display_updater, true);
timerAlarmWrite(timer, 2000, true);
timerAlarmEnable(timer);

lastUpdate = millis();
}

void loop() {
unsigned long now = millis();
if (remainingMs > 0 && now - lastUpdate >= 1000) {
remainingMs -= 1000;
lastUpdate = now;
}

unsigned long hours = remainingMs / 3600000UL;
unsigned long minutes = (remainingMs / 60000UL) % 60;
unsigned long seconds = (remainingMs / 1000UL) % 60;

display.clearDisplay();

char buffer[16];
sprintf(buffer, "%05luh", hours); // отображаем часы с ведущими нулями
display.setCursor(0, 7);
display.print(buffer);

display.setCursor(0, 16);
sprintf(buffer, "%02lum %02lus", minutes, seconds);
display.print(buffer);

display.showBuffer();

// Сохранение каждые 10 минут
if (now - prevSave > SAVE_INTERVAL) {
EEPROM.put(0, remainingMs);
EEPROM.commit();
prevSave = now;
}

// Когда дошли до 0 — мигаем экраном
if (remainingMs <= 0) {
for (int i = 0; i < 3; i++) {
display.clearDisplay();
display.showBuffer();
delay(500);
display.fillScreen(display.color565(255, 0, 0));
display.showBuffer();
delay(500);
}
}
}

Collapse
 
foggy_ammain_c3e6e27db65 profile image
Foggy am Main •

Or maybe I could pay you to write this code for me? I would be very grateful!!

Thread Thread
 
calumk profile image
Calum Knott •

Sure - Would be happy to, can do it tonight.
You can make some donation later if it works via ko-fi.com/calumk

Thread Thread
 
foggy_ammain_c3e6e27db65 profile image
Foggy am Main •

I’d be very grateful to you! If you could explain it here and send the code, that would be awesome! Or maybe you use other social networks?

Collapse
 
reinout_roels_4ca4a460b83 profile image
Reinout Roels •

In case anyone wants to make use of the other peripherals (temp sensor, light sensor, buzzer, RTC, ...), from a custom Arduino firmware:

github.com/rroels/ulanzi_tc001_har...

I did a quick write-up with working examples for each peripheral in the Ulanzi TC001.

Collapse
 
maxxh profile image
Max H •

Hey Calum,

Thanks for the post. I'm trying to do the same, but I'm new to arduino. How did you manage to connect your TC001 to Arduino IDE? I don't see mine in the port list

Collapse
 
reinout_roels_4ca4a460b83 profile image
Reinout Roels •

For some operating systems, you have to install a driver to communicate with the CH340. This is a usb-to-serial chip that is found on many microcontroller boards, including the Ulanzi TC001.

learn.sparkfun.com/tutorials/how-t...

Also make sure the Ulanzi is turned on. It won't be detected if it's off.

If that doesn't work, try a different USB cable (not all USB cables have data lines, some are only for power).

Collapse
 
calumk profile image
Calum Knott •

Yup - I didnt run into this issue probably because i already had CH340 driver installed from a few years ago