{"id":337,"date":"2021-03-12T09:19:59","date_gmt":"2021-03-12T08:19:59","guid":{"rendered":"https:\/\/waldorf-studio.pl\/?page_id=337"},"modified":"2021-03-12T09:50:47","modified_gmt":"2021-03-12T08:50:47","slug":"atem-tally-kod-zrodlowy","status":"publish","type":"page","link":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/","title":{"rendered":"Atem tally &#8211; kod \u017ar\u00f3d\u0142owy"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>\/*\n    Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com\n\n    This program makes an ESP8266 into a wireless tally light system for ATEM switchers,\n    by using Kasper Sk\u00e5rh\u00f8j's (&lt;https:\/\/skaarhoj.com>) ATEM clinet libraries for Arduino.\n\n    Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl)\n\n    This program is free software: you can redistribute it and\/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see &lt;https:\/\/www.gnu.org\/licenses\/>.\n*\/\n\n\/\/Include libraries:\n#include &lt;ESP8266WiFi.h>\n#include &lt;ESP8266WebServer.h>\n#include &lt;EEPROM.h>\n#include &lt;ATEMmin.h>\n#include &lt;TallyServer.h>\n\n\/\/============== WERSJA STANDARD =============================================\n\/\/Define LED1 color pins\n#define PIN_RED1    D1\n#define PIN_GREEN1  D2\n#define PIN_BLUE1   D4\n\n\/\/Define LED2 color pins\n#define PIN_RED2    D0\n#define PIN_GREEN2  D5\n#define PIN_BLUE2   D6\n\n\/\/Define LED colors\n#define LED_OFF     0\n#define LED_RED     1\n#define LED_GREEN   2\n#define LED_BLUE    3\n#define LED_YELLOW  4\n#define LED_PINK    5\n#define LED_WHITE   6\n\n\/\/Define states\n#define STATE_STARTING                  0\n#define STATE_CONNECTING_TO_WIFI        1\n#define STATE_CONNECTING_TO_SWITCHER    2\n#define STATE_RUNNING                   3\n\n\/\/Define modes of operation\n#define MODE_NORMAL                     1\n#define MODE_PREVIEW_STAY_ON            2\n#define MODE_PROGRAM_ONLY               3\n\n\/\/Initialize global variables\nESP8266WebServer server(80);\n\nATEMmin atemSwitcher;\n\nTallyServer tallyServer;\n\nuint8_t state = STATE_STARTING;\n\n\/\/Define sturct for holding tally settings (mostly to simplify EEPROM read and write, in order to persist settings)\nstruct Settings {\n    char tallyName&#91;32] = \"\";\n    uint8_t tallyNo;\n    uint8_t tallyModeLED1;\n    uint8_t tallyModeLED2;\n    bool staticIP;\n    IPAddress tallyIP;\n    IPAddress tallySubnetMask;\n    IPAddress tallyGateway;\n    IPAddress switcherIP;\n};\n\nSettings settings;\n\nbool firstRun = true;\n\n\/\/Perform initial setup on power on\nvoid setup() {\n    \/\/Init pins for LED\n    pinMode(PIN_RED1, OUTPUT);\n    pinMode(PIN_GREEN1, OUTPUT);\n    pinMode(PIN_BLUE1, OUTPUT);\n\n    pinMode(PIN_RED2, OUTPUT);\n    pinMode(PIN_GREEN2, OUTPUT);\n    pinMode(PIN_BLUE2, OUTPUT);\n\n    setBothLEDs(LED_BLUE);\n\n    \/\/Start Serial\n    Serial.begin(115200);\n    Serial.println(\"########################\");\n    Serial.println(\"Serial started\");\n\n    \/\/save flash memory from being written too without need.\n    WiFi.persistent(false);\n\n    \/\/Read settings from EEPROM. Settings struct takes 68 bytes total (according to sizeof()). WIFI settings are stored seperately by the ESP\n    EEPROM.begin(68); \/\/Needed on ESP8266 module, as EEPROM lib works a bit differently than on a regular arduino\n    EEPROM.get(0, settings);\n\n    Serial.println(settings.tallyName);\n    \/\/Serial.println(sizeof(settings)); \/\/Check size of settings struct\n    if (settings.staticIP) {\n        WiFi.config(settings.tallyIP, settings.tallyGateway, settings.tallySubnetMask);\n    }\n\n    \/\/Put WiFi into station mode and make it connect to saved network\n    WiFi.mode(WIFI_STA);\n    WiFi.begin();\n    WiFi.hostname(settings.tallyName);\n    WiFi.setAutoReconnect(true);\n\n    Serial.println(\"------------------------\");\n    Serial.println(\"Connecting to WiFi...\");\n    Serial.println(\"Network name (SSID): \" + WiFi.SSID());\n\n    \/\/ Initialize and begin HTTP server for handeling the web interface\n    server.on(\"\/\", handleRoot);\n    server.on(\"\/save\", handleSave);\n    server.onNotFound(handleNotFound);\n    server.begin();\n\n    tallyServer.begin();\n\n    \/\/Wait for result from first attempt to connect - This makes sure it only activates the softAP if it was unable to connect,\n    \/\/and not just because it hasn't had the time to do so yet. It's blocking, so don't use it inside loop()\n    WiFi.waitForConnectResult();\n\n    \/\/Set state to connecting before entering loop\n    changeState(STATE_CONNECTING_TO_WIFI);\n}\n\nvoid loop() {\n    switch (state) {\n        case STATE_CONNECTING_TO_WIFI: {\n                if (WiFi.status() == WL_CONNECTED) {\n                    WiFi.mode(WIFI_STA); \/\/ Disable softAP if connection is successful\n                    Serial.println(\"------------------------\");\n                    Serial.println(\"Connected to WiFi:   \" + WiFi.SSID());\n                    Serial.println(\"IP:                  \" + WiFi.localIP().toString());\n                    Serial.println(\"Subnet Mask:         \" + WiFi.subnetMask().toString());\n                    Serial.println(\"Gateway IP:          \" + WiFi.gatewayIP().toString());\n                    changeState(STATE_CONNECTING_TO_SWITCHER);\n                } else if (firstRun) {\n                    firstRun = false;\n                    WiFi.mode(WIFI_AP_STA); \/\/ Enable softAP to access web interface in case of no WiFi\n                    WiFi.softAP(\"Tally Light AP\");\n                    if (WiFi.SSID().length() &lt; 1) {\n                      setBothLEDs(LED_WHITE);\n                      delay(500);\n                      setBothLEDs(LED_RED);\n                      delay(500);\n                      setBothLEDs(LED_GREEN);\n                      delay(500);\n                      setBothLEDs(LED_BLUE);\n                      delay(500);\n                      setBothLEDs(LED_PINK);\n                      delay(500);\n                      setBothLEDs(LED_YELLOW);\n                    } else {\n                      setBothLEDs(LED_WHITE);\n                    }\n                }\n            }\n            break;\n\n        case STATE_CONNECTING_TO_SWITCHER:\n            \/\/ Initialize a connection to the switcher:\n            if (firstRun) {\n                atemSwitcher.begin(settings.switcherIP);\n                \/\/atemSwitcher.serialOutput(0x80); \/\/Makes Atem library print debug info\n                Serial.println(\"------------------------\");\n                Serial.println(\"Connecting to switcher...\");\n                Serial.println((String)\"Switcher IP:         \" + settings.switcherIP&#91;0] + \".\" + settings.switcherIP&#91;1] + \".\" + settings.switcherIP&#91;2] + \".\" + settings.switcherIP&#91;3]);\n                firstRun = false;\n            }\n            atemSwitcher.runLoop();\n            if (atemSwitcher.hasInitialized()) {\n                changeState(STATE_RUNNING);\n                Serial.println(\"Connected to switcher\");\n            }\n            break;\n\n        case STATE_RUNNING:\n            \/\/Handle data exchange and connection to swithcher\n            atemSwitcher.runLoop();\n\n            int tallySources = atemSwitcher.getTallyByIndexSources();\n            tallyServer.setTallySources(tallySources);\n            for (int i = 0; i &lt; tallySources; i++) {\n                tallyServer.setTallyFlag(i, atemSwitcher.getTallyByIndexTallyFlags(i));\n            }\n\n            \/\/Handle Tally Server\n            tallyServer.runLoop();\n\n            \/\/Set tally light accordingly\n            if (atemSwitcher.getTallyByIndexTallyFlags(settings.tallyNo) &amp; 0x01) {              \/\/if tally live\n                setLED1(LED_RED);\n            } else if ((!(settings.tallyModeLED1 == MODE_PROGRAM_ONLY))                             \/\/if not program only\n                       &amp;&amp; ((atemSwitcher.getTallyByIndexTallyFlags(settings.tallyNo) &amp; 0x02)    \/\/and tally preview\n                           || settings.tallyModeLED1 == MODE_PREVIEW_STAY_ON)) {                    \/\/or preview stay on\n                setLED1(LED_GREEN);\n            } else {                                                                            \/\/ If tally is neither\n                setLED1(LED_OFF);\n            }\n\n            \/\/Set tally light LED 2 accordingly\n            if (atemSwitcher.getTallyByIndexTallyFlags(settings.tallyNo) &amp; 0x01) {              \/\/if tally live\n                setLED2(LED_RED);\n            } else if ((!(settings.tallyModeLED2 == MODE_PROGRAM_ONLY))                             \/\/if not program only\n                       &amp;&amp; ((atemSwitcher.getTallyByIndexTallyFlags(settings.tallyNo) &amp; 0x02)    \/\/and tally preview\n                           || settings.tallyModeLED2 == MODE_PREVIEW_STAY_ON)) {                    \/\/or preview stay on\n                setLED2(LED_GREEN);\n            } else {                                                                            \/\/ If tally is neither\n                setLED2(LED_OFF);\n            }\n\n            \/\/Switch state if connection is lost, dependant on which connection is lost.\n            if (WiFi.status() != WL_CONNECTED) {\n                Serial.println(\"------------------------\");\n                Serial.println(\"WiFi connection lost...\");\n                changeState(STATE_CONNECTING_TO_WIFI);\n\n                \/\/Force atem library to reset connection, in order for status to read correctly on website.\n                atemSwitcher.begin(settings.switcherIP);\n\n                \/\/Reset tally server's tally flags, They won't get the message, but it'll be reset for when the connectoin is back.\n                tallyServer.resetTallyFlags();\n\n            } else if (!atemSwitcher.hasInitialized()) { \/\/ will return false if the connection was lost\n                Serial.println(\"------------------------\");\n                Serial.println(\"Connection to Switcher lost...\");\n                changeState(STATE_CONNECTING_TO_SWITCHER);\n\n                \/\/Reset tally server's tally flags, so clients turn off their lights.\n                tallyServer.resetTallyFlags();\n            }\n            break;\n    }\n\n    \/\/Handle web interface\n    server.handleClient();\n}\n\n\/\/Handle the change of states in the program\nvoid changeState(uint8_t stateToChangeTo) {\n    firstRun = true;\n    switch (stateToChangeTo) {\n        case STATE_CONNECTING_TO_WIFI:\n            state = STATE_CONNECTING_TO_WIFI;\n            setBothLEDs(LED_BLUE);\n            break;\n        case STATE_CONNECTING_TO_SWITCHER:\n            state = STATE_CONNECTING_TO_SWITCHER;\n            setBothLEDs(LED_PINK);\n            break;\n        case STATE_RUNNING:\n            state = STATE_RUNNING;\n            setBothLEDs(LED_GREEN);\n            break;\n    }\n}\n\n\/\/Set the color of both LEDs\nvoid setBothLEDs(uint8_t color) {\n    setLED(color, PIN_RED1, PIN_GREEN1, PIN_BLUE1);\n    setLED(color, PIN_RED2, PIN_GREEN2, PIN_BLUE2);\n}\n\n\/\/Set the color of the 1st LED\nvoid setLED1(uint8_t color) {\n    setLED(color, PIN_RED1, PIN_GREEN1, PIN_BLUE1);\n}\n\n\/\/Set the color of the 2nd LED\nvoid setLED2(uint8_t color) {\n    setLED(color, PIN_RED2, PIN_GREEN2, PIN_BLUE2);\n}\n\n\/\/Set the color of a LED using the given pins\nvoid setLED(uint8_t color, int pinRed, int pinGreen, int pinBlue) {\n    switch (color) {\n        case LED_OFF:\n            digitalWrite(pinRed, 0);\n            digitalWrite(pinGreen, 0);\n            digitalWrite(pinBlue, 0);\n            break;\n        case LED_RED:\n            digitalWrite(pinRed, 1);\n            digitalWrite(pinGreen, 0);\n            digitalWrite(pinBlue, 0);\n            break;\n        case LED_GREEN:\n            digitalWrite(pinRed, 0);\n            digitalWrite(pinGreen, 1);\n            digitalWrite(pinBlue, 0);\n            break;\n        case LED_BLUE:\n            digitalWrite(pinRed, 0);\n            digitalWrite(pinGreen, 0);\n            digitalWrite(pinBlue, 1);\n            break;\n        case LED_YELLOW:\n            digitalWrite(pinRed, 1);\n            digitalWrite(pinGreen, 1);\n            digitalWrite(pinBlue, 0);\n            break;\n        case LED_PINK:\n            digitalWrite(pinRed, 1);\n            digitalWrite(pinGreen, 0);\n            analogWrite(pinBlue, 0xff);\n            break;\n        case LED_WHITE:\n            digitalWrite(pinRed, 1);\n            digitalWrite(pinGreen, 1);\n            digitalWrite(pinBlue, 1);\n            break;\n    }\n}\n\n\/\/Serve setup web page to client, by sending HTML with the correct variables\nvoid handleRoot() {\n    String html = \"&lt;!DOCTYPE html> &lt;html> &lt;head> &lt;meta charset=\\\"UTF-8\\\"> &lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"> &lt;title>ATEM Tally ustawienia&lt;\/title> &lt;\/head> &lt;script> function switchIpField(e) { console.log(\\\"switch\\\"); console.log(e); var target = e.srcElement || e.target; var maxLength = parseInt(target.attributes&#91;\\\"maxlength\\\"].value, 10); var myLength = target.value.length; if (myLength >= maxLength) { var next = target.nextElementSibling; if (next != null) { if (next.className.includes(\\\"IP\\\")) { next.focus(); } } } else if (myLength == 0) { var previous = target.previousElementSibling; if (previous != null) { if (previous.className.includes(\\\"IP\\\")) { previous.focus(); } } } } function ipFieldFocus(e) { console.log(\\\"focus\\\"); console.log(e); var target = e.srcElement || e.target; target.select(); } function load() { var containers = document.getElementsByClassName(\\\"IP\\\"); for (var i = 0; i &lt; containers.length; i++) { var container = containers&#91;i]; container.oninput = switchIpField; container.onfocus = ipFieldFocus; } containers = document.getElementsByClassName(\\\"tIP\\\"); for (var i = 0; i &lt; containers.length; i++) { var container = containers&#91;i]; container.oninput = switchIpField; container.onfocus = ipFieldFocus; } toggleStaticIPFields(); } function toggleStaticIPFields() { var enabled = document.getElementById(\\\"staticIP\\\").checked; document.getElementById(\\\"staticIPHidden\\\").disabled = enabled; var staticIpFields = document.getElementsByClassName('tIP'); for (var i = 0; i &lt; staticIpFields.length; i++) { staticIpFields&#91;i].disabled = !enabled; } } &lt;\/script> &lt;body style=\\\"font-family:Verdana; white-space:nowrap;\\\" onload=\\\"load()\\\"> &lt;table cellpadding=\\\"2\\\" style=\\\"width:100%\\\"> &lt;tr bgcolor=\\\"#0066CC\\\" style=\\\"color:#ffffff;font-size:12px;\\\"> &lt;td colspan=\\\"3\\\"> &lt;h1>&amp;nbsp;&lt;a style='color:#ffffff;text-decoration:none'; href='http:\/\/waldorf-studio.pl' target='_blank' rel='noopener'>WALDORF STUDIO&lt;\/a> - ATEM Tally V3&lt;\/h1> &lt;hr> &lt;h2>&amp;nbsp;Status urz\u0105dzenia:&lt;\/h2> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;td>&lt;\/td> &lt;td style=\\\"width: 100%;\\\">&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Status po\u0142\u0105czenia:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    switch (WiFi.status()) {\n        case WL_CONNECTED:\n            html += \"Pod\u0142\u0105czony do sieci\";\n            break;\n        case WL_NO_SSID_AVAIL:\n            html += \"Sie\u0107 nie znaleziona\";\n            break;\n        case WL_CONNECT_FAILED:\n            html += \"Niew\u0142a\u015bciwe has\u0142o\";\n            break;\n        case WL_IDLE_STATUS:\n            html += \"Sprawdzam stan...\";\n            break;\n        case WL_DISCONNECTED:\n            html += \"Praca w trybie softAP\";\n            break;\n        case -1:\n            html += \"Przekroczono czas\";\n            break;\n    }\n\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Nazwa sieci (SSID):&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += WiFi.SSID();\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Si\u0142a sygna\u0142u:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += WiFi.RSSI();\n    html += \" dBm&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Statyczne IP:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += settings.staticIP == true ? \"Tak\" : \"Nie\";\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM Tally - IP:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += WiFi.localIP().toString();\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Maska podsieci: &lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += WiFi.subnetMask().toString();\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Brama: &lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += WiFi.gatewayIP().toString();\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM - stan:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    if (atemSwitcher.hasInitialized())\n        html += \"Po\u0142\u0105czono\";\n    else if (atemSwitcher.isConnected())\n        html += \"Po\u0142\u0105czono - Czekam na inicjalizacj\u0119 - po\u0142\u0105czenie mog\u0142o zosta\u0107 odrzucone\";\n    else if (WiFi.status() == WL_CONNECTED)\n        html += \"Brak po\u0142\u0105czenia - ATEM nie odpowiada\";\n    else\n        html += \"Od\u0142\u0105czono - Czekam na WiFi\";\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM - IP:&lt;\/td> &lt;td colspan=\\\"2\\\">\";\n    html += (String)settings.switcherIP&#91;0] + '.' + settings.switcherIP&#91;1] + '.' + settings.switcherIP&#91;2] + '.' + settings.switcherIP&#91;3];\n    html += \"&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr bgcolor=\\\"#0066CC\\\" style=\\\"color:#ffffff;font-size:12px;\\\"> &lt;td colspan=\\\"3\\\"> &lt;h1>&amp;nbsp;Ustawienia og\u00f3lne:&lt;hr>&lt;\/h1> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;form action=\\\"\/save\\\" method=\\\"post\\\"> &lt;tr> &lt;td>ATEM Tally - nazwa: &lt;\/td> &lt;td> &lt;input type=\\\"text\\\" size=\\\"30\\\" maxlength=\\\"30\\\" name=\\\"tName\\\" value=\\\"\";\n    html += WiFi.hostname();\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM Tally - numer: &lt;\/td> &lt;td> &lt;input type=\\\"number\\\" size=\\\"5\\\" min=\\\"1\\\" max=\\\"41\\\" name=\\\"tNo\\\" value=\\\"\";\n    html += (settings.tallyNo + 1);\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Przednia Lampa Tally - tryb (LED 1):&amp;nbsp;&lt;\/td> &lt;td> &lt;select name=\\\"tModeLED1\\\"> &lt;option value=\\\"\";\n    html += (String) MODE_NORMAL + \"\\\" \";\n    if (settings.tallyModeLED1 == MODE_NORMAL)\n        html += \"selected\";\n    html += \">Normalny&lt;\/option> &lt;option value=\\\"\";\n    html += (String) MODE_PREVIEW_STAY_ON + \"\\\" \";\n    if (settings.tallyModeLED1 == MODE_PREVIEW_STAY_ON)\n        html += \"selected\";\n    html += \">Zostaw w\u0142\u0105czony podgl\u0105d&lt;\/option> &lt;option value=\\\"\";\n    html += (String) MODE_PROGRAM_ONLY + \"\\\" \";\n    if (settings.tallyModeLED1 == MODE_PROGRAM_ONLY)\n        html += \"selected\";\n    html += \">Tylko program&lt;\/option> &lt;\/select> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Tylna Lampa Tally - tryb (LED 2):&lt;\/td> &lt;td> &lt;select name=\\\"tModeLED2\\\"> &lt;option value=\\\"\";\n    html += (String) MODE_NORMAL + \"\\\" \";\n    if (settings.tallyModeLED2 == MODE_NORMAL)\n        html += \"selected\";\n    html += \">Normalny&lt;\/option> &lt;option value=\\\"\";\n    html += (String) MODE_PREVIEW_STAY_ON + \"\\\" \";\n    if (settings.tallyModeLED2 == MODE_PREVIEW_STAY_ON)\n        html += \"selected\";\n    html += \">Zostaw w\u0142\u0105czony podgl\u0105d&lt;\/option> &lt;option value=\\\"\";\n    html += (String) MODE_PROGRAM_ONLY + \"\\\" \";\n    if (settings.tallyModeLED2 == MODE_PROGRAM_ONLY)\n        html += \"selected\";\n    html += \">Tylko Program&lt;\/option> &lt;\/select> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Nazwa sieci (SSID): &lt;\/td> &lt;td> &lt;input type=\\\"text\\\" size=\\\"30\\\" maxlength=\\\"30\\\" name=\\\"ssid\\\" value=\\\"\";\n    html += WiFi.SSID();\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Has\u0142o sieci WiFi: &lt;\/td> &lt;td> &lt;input type=\\\"password\\\" size=\\\"30\\\" maxlength=\\\"30\\\" name=\\\"pwd\\\" pattern=\\\"^$|.{8,32}\\\" value=\\\"\";\n    if (WiFi.isConnected()) \/\/As a minimum security meassure, to only send the wifi password if it's currently connected to the given network.\n        html += WiFi.psk();\n    html += \"\\\" \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr bgcolor=\\\"#0066CC\\\" style=\\\"color:#ffffff;font-size:12px;\\\"> &lt;td colspan=\\\"3\\\"> &lt;h1>&amp;nbsp;Ustawienia sieci:&lt;hr>&lt;\/h1> &lt;h3>&amp;nbsp;UWAGA! Wprowad\u017a uwa\u017cnie parametry IP.&lt;\/h3> &lt;h3>&amp;nbsp;Gdy pozostawiamy statyczne IP nie wolno zapisa\u0107 domy\u015blnych ustawie\u0144 255.255.255.255&lt;\/h3> &lt;h3>&amp;nbsp;W przypadku podania niew\u0142a\u015bciwych parametr\u00f3w i utracenia po\u0142\u0105czenia z ATEM Tally&lt;\/h3> &lt;h3>&amp;nbsp;wprowad\u017a go w stan softAP poprzez wyj\u015bcie z zasi\u0119gu ustawionej sieci WiFi - patrz instrukcja&lt;\/h3>&lt;hr> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>U\u017cyj statycznego IP: &lt;\/td> &lt;td> &lt;input type=\\\"hidden\\\" id=\\\"staticIPHidden\\\" name=\\\"staticIP\\\" value=\\\"false\\\" \/> &lt;input id=\\\"staticIP\\\" type=\\\"checkbox\\\" name=\\\"staticIP\\\" value=\\\"true\\\" onchange=\\\"toggleStaticIPFields()\\\" \";\n    if (settings.staticIP)\n        html += \"checked\";\n    html += \"\/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM Tally - IP: &lt;\/td> &lt;td> &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"tIP1\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyIP&#91;0];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"tIP2\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyIP&#91;1];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"tIP3\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyIP&#91;2];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"tIP4\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyIP&#91;3];\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Maska podsieci: &lt;\/td> &lt;td> &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"mask1\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallySubnetMask&#91;0];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"mask2\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallySubnetMask&#91;1];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"mask3\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallySubnetMask&#91;2];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"mask4\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallySubnetMask&#91;3];\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>Brama: &lt;\/td> &lt;td> &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"gate1\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyGateway&#91;0];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"gate2\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyGateway&#91;1];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"gate3\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyGateway&#91;2];\n    html += \"\\\" required \/>. &lt;input class=\\\"tIP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"gate4\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.tallyGateway&#91;3];\n    html += \"\\\" required \/> &lt;\/td> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td>ATEM - IP: &lt;\/td> &lt;td> &lt;input class=\\\"IP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"aIP1\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.switcherIP&#91;0];\n    html += \"\\\" required \/>. &lt;input class=\\\"IP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"aIP2\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.switcherIP&#91;1];\n    html += \"\\\" required \/>. &lt;input class=\\\"IP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"aIP3\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.switcherIP&#91;2];\n    html += \"\\\" required \/>. &lt;input class=\\\"IP\\\" type=\\\"text\\\" size=\\\"3\\\" maxlength=\\\"3\\\" name=\\\"aIP4\\\" pattern=\\\"\\\\d{0,3}\\\" value=\\\"\";\n    html += settings.switcherIP&#91;3];\n    html += \"\\\" required \/> &lt;\/tr> &lt;tr> &lt;td>&lt;br>&lt;\/td> &lt;\/tr> &lt;tr> &lt;td \/> &lt;td style=\\\"float: right;\\\"> &lt;input type=\\\"submit\\\" value=\\\"Zapisz zmiany\\\" \/> &lt;\/td> &lt;\/tr> &lt;\/form> &lt;\/table> &lt;\/body> &lt;\/html>\";\n\n    server.send(200, \"text\/html\", html);\n}\n\n\/\/Save new settings from client in EEPROM and restart the ESP8266 module\nvoid handleSave() {\n    if (server.method() != HTTP_POST) {\n        server.send(405, \"text\/html\", \"&lt;!DOCTYPE html> &lt;html> &lt;head> &lt;meta charset=\\\"UTF-8\\\"> &lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"> &lt;title>ATEM Tally ustawienia&lt;\/title> &lt;\/head> &lt;body style=\\\"font-family:Verdana;\\\"> &lt;table bgcolor=\\\"#0066CC\\\" border=\\\"0\\\" width=\\\"100%\\\" cellpadding=\\\"1\\\" style=\\\"color:#ffffff;font-size:12px;\\\"> &lt;tr> &lt;td> &lt;h1>&amp;nbsp;ATEM Tally ustawienia&lt;\/h1> &lt;\/td> &lt;\/tr> &lt;\/table>&lt;br>Request without posting settings not allowed&lt;\/body>&lt;\/html>\");\n    } else {\n        String ssid;\n        String pwd;\n        bool change = false;\n        for (uint8_t i = 0; i &lt; server.args(); i++) {\n            change = true;\n            String var = server.argName(i);\n            String val = server.arg(i);\n\n            if (var ==  \"tName\") {\n                val.toCharArray(settings.tallyName, (uint8_t)32);\n            } else if (var ==  \"tModeLED1\") {\n                settings.tallyModeLED1 = val.toInt();\n            } else if (var ==  \"tModeLED2\") {\n                settings.tallyModeLED2 = val.toInt();\n            } else if (var ==  \"tNo\") {\n                settings.tallyNo = val.toInt() - 1;\n            } else if (var ==  \"ssid\") {\n                ssid = String(val);\n            } else if (var ==  \"pwd\") {\n                pwd = String(val);\n            } else if (var ==  \"staticIP\") {\n                settings.staticIP = (val == \"true\");\n            } else if (var ==  \"tIP1\") {\n                settings.tallyIP&#91;0] = val.toInt();\n            } else if (var ==  \"tIP2\") {\n                settings.tallyIP&#91;1] = val.toInt();\n            } else if (var ==  \"tIP3\") {\n                settings.tallyIP&#91;2] = val.toInt();\n            } else if (var ==  \"tIP4\") {\n                settings.tallyIP&#91;3] = val.toInt();\n            } else if (var ==  \"mask1\") {\n                settings.tallySubnetMask&#91;0] = val.toInt();\n            } else if (var ==  \"mask2\") {\n                settings.tallySubnetMask&#91;1] = val.toInt();\n            } else if (var ==  \"mask3\") {\n                settings.tallySubnetMask&#91;2] = val.toInt();\n            } else if (var ==  \"mask4\") {\n                settings.tallySubnetMask&#91;3] = val.toInt();\n            } else if (var ==  \"gate1\") {\n                settings.tallyGateway&#91;0] = val.toInt();\n            } else if (var ==  \"gate2\") {\n                settings.tallyGateway&#91;1] = val.toInt();\n            } else if (var ==  \"gate3\") {\n                settings.tallyGateway&#91;2] = val.toInt();\n            } else if (var ==  \"gate4\") {\n                settings.tallyGateway&#91;3] = val.toInt();\n            } else if (var ==  \"aIP1\") {\n                settings.switcherIP&#91;0] = val.toInt();\n            } else if (var ==  \"aIP2\") {\n                settings.switcherIP&#91;1] = val.toInt();\n            } else if (var ==  \"aIP3\") {\n                settings.switcherIP&#91;2] = val.toInt();\n            } else if (var ==  \"aIP4\") {\n                settings.switcherIP&#91;3] = val.toInt();\n            }\n        }\n\n        if (change) {\n            EEPROM.put(0, settings);\n            EEPROM.commit();\n\n            server.send(200, \"text\/html\", (String)\"&lt;!DOCTYPE html> &lt;html> &lt;head> &lt;meta charset=\\\"ASCII\\\"> &lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"> &lt;title>ATEM Tally ustawienia&lt;\/title> &lt;\/head> &lt;body> &lt;table bgcolor=\\\"#0066CC\\\" border=\\\"0\\\" width=\\\"100%\\\" cellpadding=\\\"1\\\" style=\\\"font-family:Verdana;color:#ffffff;font-size:12px;\\\"> &lt;tr> &lt;td> &lt;h1>&amp;nbsp;ATEM Tally ustawienia&lt;\/h1> &lt;\/td> &lt;\/tr> &lt;\/table>&lt;br>Ustawienia zapisane poprawnie.&lt;\/body>&lt;\/html>\");\n\n            \/\/Delay to let data be saved, and the responce to be sent properly to the client\n            delay(5000);\n\n            if (ssid &amp;&amp; pwd &amp;&amp; (ssid != WiFi.SSID() || pwd != WiFi.psk())) {\n                WiFi.persistent(true);\n                WiFi.begin(ssid, pwd);\n                WiFi.persistent(false);\n            }\n\n            ESP.restart();\n        }\n    }\n}\n\n\/\/Send 404 to client in case of invalid webpage being requested.\nvoid handleNotFound() {\n    server.send(404, \"text\/html\", \"&lt;!DOCTYPE html> &lt;html> &lt;head> &lt;meta charset=\\\"ASCII\\\"> &lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"> &lt;title>ATEM Tally ustawienia&lt;\/title> &lt;\/head> &lt;body style=\\\"font-family:Verdana;\\\"> &lt;table bgcolor=\\\"#0066CC\\\" border=\\\"0\\\" width=\\\"100%\\\" cellpadding=\\\"1\\\" style=\\\"color:#ffffff;font-size:12px;\\\"> &lt;tr> &lt;td> &lt;h1>&amp;nbsp ATEM Tally ustawienia&lt;\/h1> &lt;\/td> &lt;\/tr> &lt;\/table>&lt;br>404 - Page not found&lt;\/body>&lt;\/html>\");\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-337","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j&#039;s () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"WALDORF STUDIO - Elektronika dla bran\u017cy filmowej\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO\" \/>\n\t\t<meta property=\"og:description\" content=\"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j&#039;s () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"250\" \/>\n\t\t<meta property=\"og:image:height\" content=\"100\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2021-03-12T08:19:59+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2021-03-12T08:50:47+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO\" \/>\n\t\t<meta name=\"twitter:description\" content=\"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j&#039;s () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/waldorf-studio.pl\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#listItem\",\"name\":\"Atem tally &#8211; kod \\u017ar\\u00f3d\\u0142owy\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#listItem\",\"position\":2,\"name\":\"Atem tally &#8211; kod \\u017ar\\u00f3d\\u0142owy\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl#listItem\",\"name\":\"Home\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/#organization\",\"name\":\"WALDORF STUDIO\",\"description\":\"Elektronika dla bran\\u017cy filmowej\",\"url\":\"https:\\\/\\\/waldorf-studio.pl\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/waldorf-studio.pl\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/Logo2021A.png\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#organizationLogo\",\"width\":250,\"height\":100},\"image\":{\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#organizationLogo\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#webpage\",\"url\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/\",\"name\":\"Atem tally \\u2013 kod \\u017ar\\u00f3d\\u0142owy - WALDORF STUDIO\",\"description\":\"\\\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\\u00e5rh\\u00f8j's () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\\\/\\\/waldorf-studio.pl) This program is free software: you can redistribute it and\\\/or modify it under the terms\",\"inLanguage\":\"pl-PL\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/index.php\\\/atem-tally-kod-zrodlowy\\\/#breadcrumblist\"},\"datePublished\":\"2021-03-12T09:19:59+01:00\",\"dateModified\":\"2021-03-12T09:50:47+01:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/#website\",\"url\":\"https:\\\/\\\/waldorf-studio.pl\\\/\",\"name\":\"WALDORF STUDIO\",\"description\":\"Elektronika dla bran\\u017cy filmowej\",\"inLanguage\":\"pl-PL\",\"publisher\":{\"@id\":\"https:\\\/\\\/waldorf-studio.pl\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO","description":"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j's () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms","canonical_url":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/waldorf-studio.pl#listItem","position":1,"name":"Home","item":"https:\/\/waldorf-studio.pl","nextItem":{"@type":"ListItem","@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#listItem","name":"Atem tally &#8211; kod \u017ar\u00f3d\u0142owy"}},{"@type":"ListItem","@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#listItem","position":2,"name":"Atem tally &#8211; kod \u017ar\u00f3d\u0142owy","previousItem":{"@type":"ListItem","@id":"https:\/\/waldorf-studio.pl#listItem","name":"Home"}}]},{"@type":"Organization","@id":"https:\/\/waldorf-studio.pl\/#organization","name":"WALDORF STUDIO","description":"Elektronika dla bran\u017cy filmowej","url":"https:\/\/waldorf-studio.pl\/","logo":{"@type":"ImageObject","url":"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png","@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#organizationLogo","width":250,"height":100},"image":{"@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#organizationLogo"}},{"@type":"WebPage","@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#webpage","url":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/","name":"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO","description":"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j's () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms","inLanguage":"pl-PL","isPartOf":{"@id":"https:\/\/waldorf-studio.pl\/#website"},"breadcrumb":{"@id":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/#breadcrumblist"},"datePublished":"2021-03-12T09:19:59+01:00","dateModified":"2021-03-12T09:50:47+01:00"},{"@type":"WebSite","@id":"https:\/\/waldorf-studio.pl\/#website","url":"https:\/\/waldorf-studio.pl\/","name":"WALDORF STUDIO","description":"Elektronika dla bran\u017cy filmowej","inLanguage":"pl-PL","publisher":{"@id":"https:\/\/waldorf-studio.pl\/#organization"}}]},"og:locale":"pl_PL","og:site_name":"WALDORF STUDIO - Elektronika dla bran\u017cy filmowej","og:type":"article","og:title":"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO","og:description":"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j's () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms","og:url":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/","og:image":"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png","og:image:secure_url":"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png","og:image:width":250,"og:image:height":100,"article:published_time":"2021-03-12T08:19:59+00:00","article:modified_time":"2021-03-12T08:50:47+00:00","twitter:card":"summary_large_image","twitter:title":"Atem tally \u2013 kod \u017ar\u00f3d\u0142owy - WALDORF STUDIO","twitter:description":"\/* Copyright (C) 2020 Aron N. Het Lam, aronhetlam@gmail.com This program makes an ESP8266 into a wireless tally light system for ATEM switchers, by using Kasper Sk\u00e5rh\u00f8j's () ATEM clinet libraries for Arduino. Polish translation and modifications: Waldorf-Studio 2021 (https:\/\/waldorf-studio.pl) This program is free software: you can redistribute it and\/or modify it under the terms","twitter:image":"https:\/\/waldorf-studio.pl\/wp-content\/uploads\/2021\/02\/Logo2021A.png"},"aioseo_meta_data":{"post_id":"337","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2025-05-28 23:07:54","updated":"2025-06-06 21:28:17","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/waldorf-studio.pl\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tAtem tally \u2013 kod \u017ar\u00f3d\u0142owy\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/waldorf-studio.pl"},{"label":"Atem tally &#8211; kod \u017ar\u00f3d\u0142owy","link":"https:\/\/waldorf-studio.pl\/index.php\/atem-tally-kod-zrodlowy\/"}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/pages\/337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/comments?post=337"}],"version-history":[{"count":0,"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/pages\/337\/revisions"}],"wp:attachment":[{"href":"https:\/\/waldorf-studio.pl\/index.php\/wp-json\/wp\/v2\/media?parent=337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}