NederlandsKlik deze knop voor de Nederlandstalige website

Tally light ESP32 for Blackmagic ATEM switcher

In the previous article, I wrote about setting up a low-budget studio for streaming live video during the Corona (COVID-19) lockdown. The studio has since undergone a few upgrades. For example, we now also have a Blackmagic Design ATEM Mini Pro video switcher with 4 cameras. These are consumer cameras without tally light. In this blog I show how you can make ESP32 Tally lights yourself with the help of an ESP32 microcontroller, in this case, an M5StickC from VNGsystems in Gouda.

Tally light ESP32 for Blackmagic ATEM switcher: inactive/preview/program
Tally light ESP32 for Blackmagic ATEM switcher: inactive/preview/program
M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Tested and recommended by OneGuyOneBlog.com:

M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Banggood.com

Tally Light

A “tally light” (Wikipedia) is a red indicator light usually found on top of professional video cameras. It is mainly used when recording with multiple cameras. The light indicates whether a camera is “live” (“program”). This is useful for both people in front of the camera and the cameraman himself to know. The cameraman then knows, for example, that he has to keep his camera still, and the people in front of the camera know which camera to look at.

Tally light on a camera
Tally light on a camera (source: https://en.wikipedia.org/wiki/Tally_light)

Sometimes, in addition to red, the color green is also used to indicate that the image of the camera is active as a “preview”. The tally lights are controlled by the video switcher. In this case, we use a Blackmagic Design ATEM Mini Pro and the communication goes wireless via WiFi.

Blackmagic Design ATEM Mini Pro video switcher

The Blackmagic Design ATEM Mini Pro video switcher is a complete video production and streaming studio in a small box. There are, among others, inputs for 4 HDMI sources and output for HDMI preview. You can use the ATEM Mini in, for example, OBS Studio as a video source by means of the USB connector. The computer sees the ATEM Mini as a webcam each you can add to a scene in OBS Studio.

Tally light with ESP32: Blackmagic Design ATEM mini
Tally light with ESP32: Blackmagic Design ATEM mini

You can control the ATEM Mini with the buttons, or remotely with a PC or Mac with the Blackmagic video switcher software via LAN. We will use communication via LAN for this tally light project.

Blackmagic Design ATEM Mini HDMI Live Switcher
Tested and recommended by OneGuyOneBlog.com:

Blackmagic Design ATEM Mini HDMI Live Switcher
Amazon.com

M5StickC: ESP32 development module

For the first version of this Tally Light project, I use an M5StickC ESP-32 development module. With this module, you can quickly and easily develop and test projects. In addition to an ESP32 microcontroller (with built-in WiFi and Bluetooth), the module has a small TFT LCD, battery, and LED. I have previously used this module for the project COVID-19 CORONA Tracker: ESP32 & Arduino IDE.

M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Tested and recommended by OneGuyOneBlog.com:

M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Banggood.com

ATEM Arduino libraries

We use the well-known Arduino IDE to program the M5StickC. We also use Arduino libraries developed by Kasper Skårhøj from SKAARHOJ. Kasper not only created a library but also documented the communication protocol of the ATEM switchers. At the time of writing, the libraries are only suitable for an Arduino (with ethernet shield) or ESP8266 (WiFi), so we need to make a few minor adjustments to make it work with the ESP32.

ESP32 Tally light with M5StickC

This was enough information, for now, we are now getting started. For this project we will go through the following steps:

  1. Install the Arduino IDE and prepare it for programming the M5StickC.
  2. Install the ATEM Arduino libraries and make them suitable for the ESP32.
  3. Use the sketch from this article to test the tally light.
  4. Adjust the sketch to your own taste and improve it.

Install the Arduino IDE, ESP32 core and M5StickC libraries

As usual, install the Arduino IDE with the ESP32 core. When using the M5StickC, you also install the M5StickC libraries. For more information, see the blog “Programming the M5StickC with the Arduino IDE”. If you use another ESP32 module, read the blog “ESP32 with Arduino IDE on Linux and Windows“.

Install the ATEM Arduino libraries

First, download the ZIP-file from the SKAARHOJ open projects files from Github.

Download the libraries ZIP-file from GitHub
Download the libraries ZIP-file from GitHub

You now have a file called “SKAARHOJ-Open-Engineering-master.zip”. Open the ZIP-file, open the folder “SKAARHOJ-Open-Engineering-master” and look for the folder “ArduinoLibs” (not the ZIP).

Find the ArduinoLibs folder
Find the ArduinoLibs folder

From the ArduinoLibs folder, you need to copy these three folders to the libraries folder of your Arduino IDE:

  • ATEMbase
  • ATEMstd
  • SkaarhojPgmspace
Copy these folders from the Skaarhoj library
Copy these folders from the Skaarhoj library

So you should end up with (at least) three folders inside your Arduino libraries folder:

  • M5StickC (this was installed in the first step)
  • ATEMbase
  • ATEMstd
  • SkaarhojPgmspace
The Arduino IDE libraries folder containing the required libraries
The Arduino IDE libraries folder containing the required libraries

Modify the Skaarhoj library files for use with ESP32

The library is compatible with Arduino (with Ethernet shield) and the ESP8266 (WiFi), but not yet with the ESP32. This is easily remedied by making a total of 3 changes to the two files ATEMbase.cpp and ATEMbase.h.

In libraries/ATEMbase/ATEMbase.cpp, around line 50:

Search for

		// Set up Udp communication object:
	#ifdef ESP8266
	WiFiUDP Udp;
	#else
	EthernetUDP Udp;
	#endif

and replace by:

		// Set up Udp communication object:
	WiFiUDP Udp;

 

In the second file, libraries/ATEMbase/ATEMbase.h, around line 35:

#ifdef ESP8266
#include <WifiUDP.h>
#else
#include <EthernetUdp.h>
#endif

replace this with the following line (mind the uppercase and lowercase):

 #include <WiFiUdp.h>

 

The second change in this file, around line 60, look for this snippet:

  	#ifdef ESP8266
  	WiFiUDP _Udp;
  	#else
	EthernetUDP _Udp;					// UDP object for communication, see constructor.
	#endif

and replace it with:

  	WiFiUDP _Udp;

You can now use the ATEM library in your ESP32 projects.

Sample sketch tally light with ESP32 for Arduino IDE

As an example, I made the sketch below. Before you can upload it to your ESP32 you need to adjust the following settings:

  • ssid: the SSID of your wireless network
  • password: the password of the network
  • cameraNumber: the number of the camera (1-4) for which you will use the ESP32 as a tally light
  • the IP address of the ESP32 (each module needs a free IP address)
  • the IP address of the ATEM switcher

When all this has been adjusted you can upload the sketch to your ESP32. Look at the serial monitor for any error messages. If the core of the M5StickC remains black, connecting to WiFi has failed. Then check the SSID and password.

/*****************
  Tally light ESP32 for Blackmagic ATEM switcher

  Version 2.0

  A wireless (WiFi) tally light for Blackmagic Design
  ATEM video switchers, based on the M5StickC ESP32 development
  board and the Arduino IDE.

  For more information, see:
  https://oneguyoneblog.com/2020/06/13/tally-light-esp32-for-blackmagic-atem-switcher/

  Based on the work of Kasper Skårhøj:
  https://github.com/kasperskaarhoj/SKAARHOJ-Open-Engineering

******************/

#include <M5StickC.h>
#include <WiFi.h>
#include <SkaarhojPgmspace.h>
#include <ATEMbase.h>
#include <ATEMstd.h>

IPAddress clientIp(192, 168, 178, 170);        	// IP address of the ESP32
IPAddress switcherIp(192, 168, 178, 173);	      // IP address of the ATEM switcher
ATEMstd AtemSwitcher;

// http://www.barth-dev.de/online/rgb565-color-picker/
#define GRAY  0x0020 //   8  8  8
#define GREEN 0x0200 //   0 64  0
#define RED   0xF800 // 255  0  0

const char* ssid = "yournetwork";
const char* password =  "yourpassword";

int cameraNumber = 4;
int ledPin = 10;

int PreviewTallyPrevious = 1;
int ProgramTallyPrevious = 1;

void setup() {

  Serial.begin(9600);

  // Start the Ethernet, Serial (debugging) and UDP:
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");

  // initialize the M5StickC object
  M5.begin();

  pinMode(ledPin, OUTPUT);  // LED: 1 is on Program (Tally)
  digitalWrite(ledPin, HIGH); // off

  // Initialize a connection to the switcher:
  AtemSwitcher.begin(switcherIp);
  AtemSwitcher.serialOutput(0x80);
  AtemSwitcher.connect();
}

void loop() {

  // Check for packets, respond to them etc. Keeping the connection alive!
  AtemSwitcher.runLoop();

  int ProgramTally = AtemSwitcher.getProgramTally(cameraNumber);
  int PreviewTally = AtemSwitcher.getPreviewTally(cameraNumber);

  if ((ProgramTallyPrevious != ProgramTally) || (PreviewTallyPrevious != PreviewTally)) { // changed?

    if ((ProgramTally && !PreviewTally) || (ProgramTally && PreviewTally) ) { // only program, or program AND preview
      drawLabel(RED, BLACK, LOW);
    } else if (PreviewTally && !ProgramTally) { // only preview
      drawLabel(GREEN, BLACK, HIGH);
    } else if (!PreviewTally || !ProgramTally) { // neither
      drawLabel(BLACK, GRAY, HIGH);
    }

  }

  ProgramTallyPrevious = ProgramTally;
  PreviewTallyPrevious = PreviewTally;
}

void drawLabel(unsigned long int screenColor, unsigned long int labelColor, bool ledValue) {
  digitalWrite(ledPin, ledValue);
  M5.Lcd.fillScreen(screenColor);
  M5.Lcd.setTextColor(labelColor, screenColor);
  M5.Lcd.drawString(String(cameraNumber), 15, 40, 8);
}

If the upload is successful and a connection to the network and the ATEM switcher is established, the M5StickC will display the status of the camera specified in the code:

  • The display shows the number of the camera (1-4);
  • When the camera is not active, the display will be dark;
  • If the camera is active as “preview”, the display will turn green;
  • If the camera is active as “program” the display will turn red and the built-in red LED of the M5StickC will light up.

This code is also available on GitHub.

Adjust and improve the sketch

As usual on this blog, this information is only intended as a starting point for your own project. With this sketch and instructions, you can quickly put together something simple, and then adjust and perfect it according to your own wishes. Have you made something interesting? Let us know in the comments below this article!

VNG Systems

M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Tested and recommended by OneGuyOneBlog.com:

M5StickC ESP32 PICO Color LCD Mini IoT Development Board
Banggood.com

Blackmagic Design ATEM Mini HDMI Live Switcher
Tested and recommended by OneGuyOneBlog.com:

Blackmagic Design ATEM Mini HDMI Live Switcher
Amazon.com
62 Comments