An ESP8266 Ticker



From the moment I saw the MAX7219 Dot matrix modules I wanted to build a news ticker. I wanted the option to enter my own messages without having to install special Apps on my phone or tablet. So the ticker must be approachable via a web interface. In addition to the messages to be entered by myself, it must also be possible to get the current weather and news items from the Internet and display them on the news ticker. Of course, the time must also be shown!

Een Nederlandse vertaling van deze post kunt u hier vinden.

The Hardware

An ESP8266 with built-in WiFi will suite this project just fine.
The 1of!-Wemos and 1of!-ESP12 processor boards are ideal for small prototype projects of this kind.
To make the intensity of the display dependent on the ambient light, I use a Light-Dependent Resistor (LDR).
As a display, naturly, the MAX7219 Dot Matrix modules are used.

Connecting the parts

The Firmware

For developing firmware for the ESP8266 I use a so-called Framework which contains everything for connecting to WiFi, retrieving the time via NTP a file browser to download- and upload files from the internal files system (SPIFFS) and there is a web server for the User Interface. Also updating the firmware “Over The Air” is part of that Framework in the form of an Update Server.
All that needs to be added is control of the MAX7219 dot matrix display and functions to get the weather and news.

Depending on the type of MAX7219 you use, you must enter the corresponding definition at HARDWARE_TYPE. Depending on how many modules you use you have to adjust the definition of MAX_DEVICES (there are four MAX7219’s on one module). You can use the firmware with one, two, three or four modules. You can also use two modules next to and on top of each other with a BIG Font you can then use double height letters (this is not part of the firmware).

ESP-ticker.h contains a few #define statements that are important:

#define   HARDWARE_TYPE          MD_MAX72XX::FC16_HW
#define   MAX_DEVICES                 8

Of course you have to install the Arduino ESP8266 core (read here how to do that). The ESP ticker has been tested with version 2.6.3.

The User (web) Interface

Entering local messages
Edit settings
FileSystem Explorer
Update Server

Extra Libraries

You need to install the following libraries:

#include <ezTime.h>

#include <TelnetStream.h>      

#include <ModUpdateServer.h>  
// version 0.15.0 -
#include <WiFiManager.h>     

To control the MAX7219 display you also need the following libraries from “Marco Colli”:

- MD_Max72xx
- MD_Parola

You install them with the Arduino Library Manager:

Library Manager


We collect the weather from Here you must register and request an “API key”. The service is free for private use, as long as you do not request the weather too often (fair use). The firmware allows a maximum of one request every 15 minutes.
You enter the API key on the settings page of the web server. Here you also indicate for which place you want the weather (but this is only an indication. In the middle of the Netherlands the weather always comes from De Bilt).


This organisation collects news reports from all over the world. You must also request an “API key” for this service. The service is free for “developers” if you request new messages for less then 500 times a day (note: The delivered messages are at least 15 minutes old!). That is a maximum of 1x per 5 minutes.
You enter the API key on the settings page of the web server.


You can download the firmware from github. It is a bit too much to explain the whole firmware here but the most important things take place in the main loop () function:

void loop()
  //--- het heeft geen zin om het weer op te halen als je geen API-key hebt --
  if ((millis() > weerTimer) && (strlen(settingWeerLiveAUTH) > 5))
    weerTimer = millis() + (settingWeerLiveInterval * (60 * 1000)); // Interval in Minutes!
  //--- het heeft geen zin om nieuws op te halen als je geen API-key hebt --
  if ((millis() > newsapiTimer) && (strlen(settingNewsAUTH) > 5))
    newsapiTimer = millis() + (settingNewsInterval * (60 * 1000)); // Interval in Minutes!
  if (P.displayAnimate()) // done with animation, ready for next message
    DebugTf("msgType[%d]\r\n", msgType);
      case 1:   if (!(millis() > timeTimer))  return;
                inFX  = random(0, ARRAY_SIZE(effect));
                outFX = random(0, ARRAY_SIZE(effect));
                snprintf(actMessage, LOCAL_SIZE, weekDayName[weekday()]);
                P.displayText(actMessage, PA_CENTER, (MAX_SPEED - settingTextSpeed), 1000
                                                            , effect[inFX], effect[outFX]);
                DebugTf("Animate IN[%d], OUT[%d] %s\r\n", inFX, outFX, actMessage);
      case 2:   if (!(millis() > timeTimer))  return;
                timeTimer = millis() + 60000;
                inFX  = random(0, ARRAY_SIZE(effect));
                outFX = random(0, ARRAY_SIZE(effect));
                sprintf(actMessage, "%s", updateTime());
                P.displayText(actMessage, PA_CENTER, (MAX_SPEED - settingTextSpeed), 2000
                                                            , effect[inFX], effect[outFX]);
                DebugTf("Animate IN[%d], OUT[%d] %s\r\n", inFX, outFX, actMessage);
      case 3:
      case 6:   nextLocalBericht();
                P.setTextEffect(PA_SCROLL_LEFT, PA_NO_EFFECT);
      case 4:            
      case 5:            
      case 7:            
      case 8:   nextNieuwsBericht();
                P.setTextEffect(PA_SCROLL_LEFT, PA_NO_EFFECT);
      case 9:   snprintf(actMessage, LOCAL_SIZE, "** %s **", tempMessage);
                P.setTextEffect(PA_SCROLL_LEFT, PA_NO_EFFECT);
      case 10:  nextNieuwsBericht();
      default:  msgType = 0;
    } // switch()

    valueIntensity = calculateIntensity(); // read analog input pin A0
    DebugTf("Intensity set to [%d]\r\n", valueIntensity);
    // Tell Parola we have a new animation

  } // dislayAnimate()
} // loop()

The “switch” statement ensures that alternate local messages (entered via the web interface) or news messages are displayed. If the msgType is 1 or 2, the day name and time are printed respectively. If the msgType is greater than 10 then all will be displayed again.

For the firmware to compile correctly you need the following IDE settings:


After flashing the firmware don’t forget to also flash SPIFFS! Here you find a Dutch post on how to do that.


I like to be able to see the interior of my “projects”. That’s why I often use plexiglass for the structure or cabinet and why would I deviate from that for the ESP ticker?

I used two pieces of plexiglass (30x24cm and 30x6cm). Plexiglas can be easily cut with a fine hacksaw. By heating it locally with hot air (300 * C) you can bend it well (around the corner of a table, for example). The 1of!-Wemos board and the MAX7219 displays (2 pieces) are screwed onto the rectangular piece of plexiglass of 30x6cm. In order to properly mount the MAX7219’s, it is easiest to remove the two outer 8×8 display units from the PCB. That is quite simple because they are in a socket. You must be very careful not to bend the legs. Now you can screw the unit to the Plexiglas with four M2.5 or M3 bolts and nuts. On the other side you screw the processor board.
Make a hole for the LDR and glue it with, for example, hot-glue.
It is wise to test the unit now. The MD_parola library is very rigid in what is left and right and top and bottom. You don’t want the newspaper to be “turned upside down” when you’ve put it all together!

The larger piece of Plexiglas is bent in a U-shape serves as a cover.

The LDR is glued to the rectangular base with hot glue
This entry was posted in Arduino, ESP8266, Hardware, WiFi and tagged , , , , , , , . Bookmark the permalink.

10 Responses to An ESP8266 Ticker

  1. Arie says:

    Leuk project waar ik een paar toepassingen voor heb bij het jeugdwerk. Als het net zo eenvoudig werkte als de meteruitlezer zou dat geweldig zijn.

    Helaas met het compileren krijg ik een error melding en een exit status 1 in de restAPI.
    restAPI:146:3: error: expected primary-expression before ‘)’ token
    Op regel 133 word netjes het haakje geopend en gevolgd door wat #ifdef / #endif.

    Helaas mijn onvoldoende programmeer kennis of de warmte van voorbije week speelt mij parten

    • Willem Aandewiel says:


      Je hebt bij de board selectie waarschijnlijk iets als Wemos geselecteerd. Je moet iedere ESP8266 gewoon als “generic esp8266” instellen óf je moet een #if #endif maken voor het specifieke board dat je gebruikt. In alle gevallen is de selectie van een “generic esp8266” het eenvoudigst.

  2. Arie Moret says:

    Hallo Willem,

    Klopt dat ik een voorhanden zijnde Wemos probeer te flashen.

    Bedankt voor je super snelle reactie, ik zat al een paar dagen naar het scherm en de code te staren, waarbij door de warmte soms de ogen dicht gingen.
    Ik ga er mee aan de gang.

    Vriendelijke groet,


  3. Ruud vd Meer says:

    Hallo Willem,
    Mooi ontwerp, opgebouwd en voor een groot deel werkt het ook.
    Alle settings die je heb aangegeven overgenomen, ESP8266 op versie 2.6.3 gezet.
    Ik heb lopende tekst, na opstart het IP adres, hierna dag en tijd, hierna ESP_ticker en de (c) mededeling. Als ik brows op het adres krijg is weinig info:
    ESP – lichtKrant – [version] 00:00
    2020 © Willem Aandewiel
    Meer niet, ook in de bron vrijwel geen info. (Chrome)
    Mijn vraag: wat kan er mis zijn?
    Ook begrijp ik niet, ik geef geen inloggegevens in en toch haalt hij tijd op en is hij bereikbaar via de browser?
    Op de serieele monitor zie ik de logging lopen, maar ik heb omdat ik geen API’s kan instellen geen verdere info. Hoe kan ik het oplossen, ik gebruik IDE Versie 1.8.13.
    Alvast bedankt, en het ziet er geweldig uit.

    • Willem Aandewiel says:

      Hi Ruud,

      Ik dénk dat je SPIFFS niet hebt geflashed!

      Dan is het systeem een beetje kreupel .. maar ik zie dat ik dat niet in mijn post vertelt heb (nu wel).

  4. Ruud vd Meer says:

    Frontview van het display. Zie bovenstaande vraag…

    • Willem Aandewiel says:

      Wat een vreselijk mooi frame heb je voor de lichtkrant!
      Zelf gemaakt of kun je dat zo ergens kopen?

  5. Ruud vd Meer says:

    Het browser scherm met wel wat weinig info.

  6. Ruud vd meer says:

    Het klopt dat ik de ESP8266 niet heb geflashed ik heb daar een speciale tool van de fabrikant, dat gaat via de seriële poort. Ik heb echt geen idee hoe dit via de webtool moet doen, je vermeld dat je eerst iets moet saven?
    Sorry ik begrijp het niet. Zou je dit aan willen geven.
    Ik begrijp ook niet hou hij keurig inlogt om m’n internet en ik heb geen naam en paswoord ingegeven. Wondere wereld.
    Het kastje is van printplaat, ik maak daar al jaren kastjes mee, lekker stevig, past altijd en veel mooier dan 3D kastjes. Spuitbusje goud, doet wonderen.
    Ik gebruik voor het front, 3mm rood perspex, of rode folie welke voor spots (pars) wordt gebruikt. Op de foto een ander printplaat kastje in de maak. Mooi materiaal.

  7. Ruud vd Meer says:

    Prima gelukt om een een versie met 12 (3×4) te maken.
    In blauw, met een alluminium behuizing, gemaakt met een strook aluminium van 30mm breed. Beetje 2 comp lijm, spuitbus goud en….
    Instellen op een andere locatie, ander netwerk gaat ook prima.
    Mooi project. Compliment!

Leave a Reply

Your email address will not be published. Required fields are marked *

The maximum upload file size: 4 MB.
You can upload: image, other.
Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded.

This site uses Akismet to reduce spam. Learn how your comment data is processed.