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
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.


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.


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.
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.
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:
- Install the Arduino IDE and prepare it for programming the M5StickC.
- Install the ATEM Arduino libraries and make them suitable for the ESP32.
- Use the sketch from this article to test the tally light.
- 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.


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).


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


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


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!
A product like this for me.
About the tele lights. Can you explain in another video
how far the wireles work
Thank it worked well we are using it at a church
Hi Andrew, thank you for your message! It’s nice to hear it was useful to you!
Could you explain how to adapt the code if using an ESP8622?
I assume you wouldn’t have to change the .h and .cpp files. I tried modifying the code (removing anything related to the M5Stick and screen color) with no luck.
I just want to light up a red LED on an output pin when say “camera 1” is live and a green LED when it is on preview.
I’m not even sure if it is connecting to the ATEM (running latest SW) properly.
Any help is greatly appreciated!
Hi Adam, I have not tried it with ESP8266 but I will see if I can come up with some example code in a next blog.
Yes, you are right, you should not modify the library files when using ESP8266. You can check if it is connecting to the ATEM by using the serial monitor in the Arduino IDE. You will see status messages and errors there.
Not working with ATEM Constellation 8K Ver 8.3. On ATEM Television Studio HD it worked awesome with an lower Version numer (don´t rember…)
I…am not code-savvy, but I do NEED this! Can do you happen to sell a preprogrammed working setup? I’m happy to purchase it!
Hi Brian, thanks for your message! I am working on both preprogrammed tally lights as well as a more user-friendly DIY version.
If you have any wishes or requirements, please let me know, I will keep those in mind while working on the new versions.
Hi OneGuyOneBlog,
Magnificent work. Thank you very much. Have 2 ideas you may want to consider for future releases.
-Setting up both client and Atem ip on the M5 would be great (also CAM number)
-DHCP option also would be useful.
-Low battery indicator maybe ?
Many thanks again.
Anyone know how long they last for with the built in battery?
I’m working on grabbing the 36 volts from the cat5 cable providing power to the camera then stepping it down to 5v and wiring it to the M5 for constant power. Helpful if your remote cameras are out of reach.
Also thinking about using a relay to switch on “On Air” light when streaming is active, just not code savvy to figure this out
hi,
Nice Work, how long do they last ? After a few internet research, the esp32 is using 160 mA in wifi and the module as 80 mAh, so half an hour only ? Can you confirmed ?
Will it work with the atem mini pro iso ? I don’t see any line that need to be change but to be sure ?
This is great! We have it up and running – however is there a way to modify to the code to allow more than cameras 1-4? We have 5, so we are trying to expand it one more. Possible?
Are you able to get cameras 1,2, 3, and 4 responding to the tally signal, or just camera 4? I believe the line in the code “int cameraNumber = 4;” tells the program to listen for when camera 4 is on program or preview so I would think it would only respond when camera 4 is on program/preview.
What software version are you using for the ATEM? (8.2, 8.3, 8.4?)
Hi there! I know some others have mentioned the same thing, but I would love to hear the solutions some people have come up with to provide continuous power. I have attempted to do this through the type C port, but it hasn’t worked out. Any assistance would be greatly appreciated!
Is there any updated Arduino library for the ATEM Constellation 8K and later firmware versions (>8.1(?
Hey @oneguyoneblog! Thanks so much for this – it works great! I’ve come across one issue with our ATEM TV HD though – this tally system is only working on the SDI inputs on the switcher. It seems super bizarre but I triple checked the code, and even tried a different box to see if it was a dodgy MStick but same result. It connects to the wifi and displays it’s appropriate channel number – but if it’s a HDMI input channel – there is no preview / tally state change. I don’t suppose you have any ideas as to what might cause this? I had to re-patch a camera to sit on an SDI input so the operator had tally today.
Super strange especially as the ATEM mini is all HDMI.
Cheers!
This has been really helpful thanks.
Ordered some m5sticks. Thank you very much, awesome work.
Is it possible to run it for the m5stack atom matrix? It’s cheaper and enough to see the preview/program display
Awesome Work! Waited to have some tally lights for my students for practicing some camera moves.
Question, Do you think this would handle an Intercom as well?? It has Microphone and Voice output is possible?
This is really cool. However, is there a way to get the M5StickC to power up and run the app when USB power is applied to the USB-C connector on the device? I want to put these on three PZT cameras which are not particularly easy to get to.
Thanks
Note the warning on Kasper’s site:
https://www.skaarhoj.com/fileadmin/BMDPROTOCOL.html
August 2018: The free open source SKAARHOJ provided Arduino Libraries will only work with ATEM Software Control firmware versions up to 7.5.0.
The current ATEM SDI switchers are up to version 8.x and no longer work with this code base. If anyone knows of an update/replacement, please share.
Happy to buy them as well, Brian. Want four.
Addendum: I have the BMD SDI Shield for Arduino working with an Adafruit 32U4 RadioShield, using the embedded data in the SDI video stream sent out from the ATEM switcher. The code is little more than the neopixel, RFM69 and BDM Shield Tally tutorial routines from the respective demos glued together – not a very heavy lift. With very little more work, an ESP32 should be usable with the SDI shield over I2C as well, though I have not tried it.
Hi,
I’m not sure wether you are still using that project, but I’m running into an Error on Uploading the Skript to the M5StickC:
‘class ATEMstd’ has no member named ‘begin’
Could you help with this?
I really would like to try this!
Best ruebyi
Hard resetting via RTS pin….
nothing found about this, screen is black, itme does nothing…
Could you help with this ?
Worked great for me with our ATEM Television Studio Pro 4K and it can be powered from the USB port on our camera. I made a mount that can be screwed into the 1/4-20 hole on the top of our BMDPCC camera.
https://www.thingiverse.com/thing:4665169
Works great for me. Thanks for all the work getting this going. I added an ifdef block to get it to work better with the new M5StickCPlus. You just need to add Plus to the .h file, then change the X and Y offsets to 40 and 90. I’m using the 18650 Hat for the StickCs, and they work great. Haven’t yet timed it to see how long the battery would last. I’ll be testing it at an event next Saturday, Dec 5.
Interesting to see the comments about the ATEM TV Studio Pro 4k. I have made this work with an ATEM TV Studio HD but it doesn’t work with our new Studio Pro 4k. What version of software are you running on your 4k?
cool, ths. all work perfect
can you add batery indicator for display
Found the issue – it was a network issue and nothing to do with the code. So working find with the ATEM TV Studio Pro 4K
PCBs and code for a SDI-Shield tally light system that works with the larger ATEM switches using firmware newer than 7.5.x
Built with easily obtainable components from AdaFruit and BMDI
SDI-connected controller: https://www.spcoast.com/pages/ATEM-Tally-SDI.html
On-camera tally light display: https://www.spcoast.com/pages/ATEM-Tally-Camera-Light.html
Arduino sketch for both: ATEM Tally Sketch: https://www.spcoast.com/pages/ATEMTallyLightRadio.html
Open source HW and Sketch – hope it might prove useful to someone 🙂
Any thoughts on why this does not work on a M5stickc Plus? I downloaded the latest ESP32 and , M5Stickc plus libraries and changed the ATEM code as listed. I also ensured I was using the correct board (M5Stick-C) and added the M5StickCPlus.h to my code.
My issues seems to be wifi related as wifi.status continually reports WL_NO_SHIELD. I tried two different units which both showed the same problem.
I updated my case to have an external LED on the G26 pin on the end with a lens so you can see the tally from the front/stage. Works great. See https://www.thingiverse.com/thing:4665169
M5Sitckc Plus – Wifi issue solved.
There appears to be a bug in the Arduino IDE. I determined that the IDE was using the wrong WiFi.h. I solved the problem by changing the reference to “Wifi.h” vs. which caused the IDE to search for the header. It warned me there were two wifi.h files and stated it was going to use the ESP32 version which is what I wanted. Once it had done that I changed the “Wifi.h” back to and its continued to work ever since.
Its an strange problem with an ever stranger solution. With that said, rule 25 says never argue with success.
Battery lifetime
Hi, how long can the m5stickc (plus) last with its built in battery ? I want to use it for my streams on twitch as a tally light but i fear that i need to also power it permanently since i will never stream less than 4 hours.
Hey Mate,
I tried to make a 6 cam setup? However i couldnt make it work with more than 5 cams. Any idea. Also I’d like to do some donations. Can you please contact with me. Thanks
How to rotate Screen?`
Hi there – wouldnt it be convenient if the Text in the Display would rotate according to the orientation of the device ? i would rather want to stick it to a camera horizontal but then the Number of the camera is shown in the wrong orientation in the display.
Any ideas how to make the screen autorotate ?
KR
Stoney
Screen Rotation solution.
Aaron Parecki (https://github.com/aaronpk/atem-tally-controller) wrote a solution specifically for what you want to do.
@Glenn Christiansen you rock mate! Thanks alot! Exactly what i was looking for. Aarons Code also has the “auto-update on orientation change” feature which you can enable if you prefer to have it.
Really cool work by Oneguy and Aaron. You guys make life so much easier 🙂
I can only get three of my sticks (out of four) to connect to the ATEM at any one time. Any ideas on how to solve this?
FYI: There is a limitation with the ATEM switchers that limit you to 5 total IP connections. If you’re using a PC to control the unit, then you can only use 4 of these lights… which is the issue I’m running into.
Damn. I am using a PC with companion to switch. I wonder if we could make this work with companion?
Have a look at Tally Arbiter. I can control a huge number of tally lights from a single IP connection to the PC. They also have an M5StickC sw load.
How are you. I am running into an issue. I have the Atem Mini Pro ISO (10.1.10.123) active on my computer using Atem Software Control.
I’ve double-checked everything and followed all the instructions but my build gets stuck here. Also, the red light is on. What am I missing?
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:M5StickC initializing…OK
Sending connect packet to ATEM switcher on IP 10.1.10.123 from port 55444
Thanks.
Alright, first of all I reeeeeally appreciate your coding!
I was trying out with my newly bought M5StickC and it worked…
I looked into the modified code of Aaron Parecki and put that one on it, which was even better…
But as we don’t need some of the features he was coding because we are using them for classical concerts (so e.g. no need to put the cam on Program with a tally button) I modified his code to fit our needs concerning the built-in LED and the buttons. Now my state is:
– Button A short press: Adjust the screen brightness
– Button B short press: Change orientation (still the same)
– Button B long press: Change camera number (still the same)
– When on Program: Internal LED lighting up
– When on Preview: Internal LED flashing
– When offline: Internal LED off
Additinonally to that I wanna try out to mount a seperate RGB-LED on the back of the Stick. It should do:
– Lighting up green when on Preview
– Lighting up red when on Program
– With a long press on button A the back-tally should be turned on or off (including visual feedback on the display)
I’ll test it out soon with our ATEM, when everything proves to be stable I’ll post a link to my code. I’m a total noob to coding for Arduino, so it might take some time, figuring everything out by trial and error… and a lot of google searches.
does the m5 stick pro work with the same system?
Does this work with the ATEM Television Studio HD on a Mac?
Thanks!
Can I have an installation video?
Which directory is the modified file in?
Connection to ATEM Switcher has timed out – reconnecting! why?
How to add a network disconnect reconnection? Now there is the bug
LeGrebi Your modified code is brilliant. Just the extras I need: change camera number, brightness etc and led for wifi.
Can your link to code be posted please as I’m ready to build.
Many Thanks
John
Alguien tendra la actualización de codigo para la versión M5StickC Plus con codigo modificado de orientación de pantalla.
I have built a similar tally system using the 8266 in wifi mode. It works well but I have noticed that it is very power hungry and not lasting more than 30 min on a 18650. I ended up using power from my comms system down converted to power the tally units at the cameras. Would be interesting to hear how long the other designs last.
boa tarde,
montei o sistema aqui e está funcionando, entretanto quando pressiono o botão AUTO as duas câmeras ficam como program.
Alguma dica de como resolver isso?
I accidentially bought a Mstick5C-Plus and cannot get it properly confgured…
Can anyone from above share the working Arduino code for the Mstick5C-Plus?
If possible for the Production studio 4K?
You need to load the M5StickC Plus library instead of the M5. Obviously you have to load the plus library into your library manager. Then change the code to reflect. For some reason the MPU6886 is defined differently in the plus library as IMU so you have to change that as well.
Change
#include
to
#include
You then need to reference the MPU6886 (display controller) as IMU instead.
Change M5.MPU6886.Init(); to M5.IMU.Init ();
and anywhere else in your sketch that mentions the MPU6886 just change to IMU.
I’m not a programmer. I worked it out with Mr. Google and an error message.
Original comment won’t display properly. In the first line change M5StickC.h to M5StickCPlus.h
Hi, I’m new to this but enjoying it.
I have an ATEM Mini Extreme ISO which I’m trying to use this Package on.
I’ve written the modified sketch to the M5Stick-c but all I get is the black screen.
Now I know this is said to be a wifi connection effor but its connected to the WiFi (I can see it on the router and ping it), It has the right IP as per teh sketch (as does the ATEM) but I still get the black screen – any thoughts please?
thanks so much
Scratch that… Not sure what is different but this: xxxxxxxxxxx Fixed the issue and loce teh screen orientation addon too!!
It’s a bit of a shame that Aaron based his whole project on my work without giving me credit for it or even mentioning this website.