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