{"id":405,"date":"2025-02-24T21:54:03","date_gmt":"2025-02-24T21:54:03","guid":{"rendered":"https:\/\/hobbies.wielenga.co.uk\/?p=405"},"modified":"2025-06-17T21:15:42","modified_gmt":"2025-06-17T20:15:42","slug":"news-ticker-for-esp32","status":"publish","type":"post","link":"https:\/\/hobbies.wielenga.co.uk\/index.php\/2025\/02\/24\/news-ticker-for-esp32\/","title":{"rendered":"ESP 32 RSS News Feed Ticker"},"content":{"rendered":"<p dir=\"auto\"><img decoding=\"async\" class=\"wp-image-431 alignnone lazyload\" data-src=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-300x225.jpeg\" alt=\"\" width=\"511\" height=\"383\" data-srcset=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-300x225.jpeg 300w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-1024x768.jpeg 1024w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-768x576.jpeg 768w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-1536x1152.jpeg 1536w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3-1440x1080.jpeg 1440w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled3.jpeg 2048w\" data-sizes=\"(max-width: 511px) 100vw, 511px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 511px; --smush-placeholder-aspect-ratio: 511\/383;\" \/><\/p>\n<p dir=\"auto\">I had some ESP-32 DEVKITs left over and a SH1106 OLED display. I thought wouldn&#8217;t be nice to have a news ticker that would be playing away in the back ground.<\/p>\n<p dir=\"auto\">I am Dutch living in the UK so my feeds are a mixture of Dutch \/UK and international news but as long as you can find the RSS feed, you can display anything you like.<\/p>\n<p>The source code is maintained on my GITHub pages\u00a0 \u00a0<a href=\"https:\/\/github.com\/japywheel\/ESP-32-RSS-News-Feed-Ticker\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/japywheel\/ESP-32-RSS-News-Feed-Ticker<\/a><\/p>\n<p dir=\"auto\"><strong>Prerequisites:<\/strong><\/p>\n<ol dir=\"auto\">\n<li>ESP-32 Devkit or similar<\/li>\n<li>Wifi internet connection \ud83d\ude42<\/li>\n<li>SH1106 OLED screen. (Will work with different different I2C OLEDs but the code needs to be modified<\/li>\n<li>Arduino IDE<\/li>\n<li>Hookup wiring or soldering skills<\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"alignnone wp-image-433 lazyload\" data-src=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-300x225.jpeg\" alt=\"\" width=\"399\" height=\"299\" data-srcset=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-300x225.jpeg 300w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-1024x768.jpeg 1024w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-768x576.jpeg 768w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-1536x1152.jpeg 1536w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2-1440x1080.jpeg 1440w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled-2.jpeg 2048w\" data-sizes=\"(max-width: 399px) 100vw, 399px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 399px; --smush-placeholder-aspect-ratio: 399\/299;\" \/> <img decoding=\"async\" class=\"alignnone size-medium wp-image-432 lazyload\" data-src=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-225x300.jpeg\" alt=\"\" width=\"225\" height=\"300\" data-srcset=\"https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-225x300.jpeg 225w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-768x1024.jpeg 768w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-1152x1536.jpeg 1152w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-1024x1365.jpeg 1024w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2-810x1080.jpeg 810w, https:\/\/hobbies.wielenga.co.uk\/wp-content\/uploads\/2025\/02\/Untitled2.jpeg 1536w\" data-sizes=\"(max-width: 225px) 100vw, 225px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 225px; --smush-placeholder-aspect-ratio: 225\/300;\" \/><\/p>\n<p dir=\"auto\"><strong>Libraries<\/strong><\/p>\n<ol dir=\"auto\">\n<li>WiFi<\/li>\n<li>WiFiClientSecure (which I think is part of WiFi library)<\/li>\n<li>HTTPClient<\/li>\n<li>ArduinoJson<\/li>\n<li>U8g2lib<\/li>\n<\/ol>\n<div class=\"markdown-heading\" dir=\"auto\">\n<h1 class=\"heading-element\" dir=\"auto\" tabindex=\"-1\">Feel free to have a play<\/h1>\n<p>Code :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\/\/ newsticker4.ino file\r\n\r\n#include &lt;WiFi.h&gt;\r\n#include &lt;WiFiClientSecure.h&gt;\r\n#include &lt;HTTPClient.h&gt;\r\n#include &lt;ArduinoJson.h&gt;\r\n#include &lt;U8g2lib.h&gt;\r\n\r\n\/\/ WiFi credentials\r\nconst char* ssid = \"Your SSD\";\r\nconst char* password = \"Your WIFI Password\";\r\n\r\n\/\/ RSS Feed URLs - DEFINE YOUR RSS FEEDS HERE\"\r\nconst char* newsUrls[] = {\r\n\"https:\/\/www.nu.nl\/rss\/Algemeen\",\r\n\"https:\/\/feeds.bbci.co.uk\/news\/rss.xml\",\r\n\/\/\"feeds.nos.nl\/nosnieuwsalgemeen\",\r\n\"https:\/\/feeds.skynews.com\/feeds\/rss\/home.xml\",\r\n\"https:\/\/www.reutersagency.com\/feed\/?best-types=reuters-news-first&amp;post_type=best\"\r\n};\r\nconst int numFeeds = 4; \/\/ DEFINE THE NUMBER OF LIVE RSS FEEDS\r\nint currentFeed = 0; \/\/ START RSS URL\r\n\r\n\/\/ SH1106 Display\r\nU8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, \/* reset=*\/ U8X8_PIN_NONE);\r\n\r\nString headlines[40];\r\nint numHeadlines = 0;\r\nint xOffset = 128; \/\/ Start position off the right side of the display\r\nint speed = 2.5; \/\/ Scrolling speed\r\n\r\nvoid setup() {\r\nSerial.begin(115200);\r\nWiFi.begin(ssid, password);\r\nwhile (WiFi.status() != WL_CONNECTED) {\r\ndelay(1000);\r\nSerial.println(\"Connecting to WiFi...\");\r\n}\r\nSerial.println(\"Connected!\");\r\n\r\nu8g2.begin();\r\nu8g2.setFont(u8g2_font_courR14_tf); \/\/ Use font with Latin-1 support\r\nfetchHeadlines();\r\n}\r\n\r\nvoid loop() {\r\nu8g2.clearBuffer();\r\n\r\n\/\/ Draw all headlines horizontally\r\nint currentX = xOffset;\r\nfor (int i = 0; i &lt; numHeadlines; i++) {\r\nu8g2.drawUTF8(currentX, 40, headlines[i].c_str());\r\ncurrentX += u8g2.getUTF8Width(headlines[i].c_str()) + 10;\r\n}\r\n\r\nu8g2.sendBuffer();\r\n\r\nxOffset -= speed;\r\nif (xOffset &lt; -getTotalWidth() - 10) { \/\/ Check if all headlines have scrolled off\r\nxOffset = 128; \/\/ Reset position\r\ncurrentFeed = (currentFeed + 1) % numFeeds; \/\/ Switch feed\r\nfetchHeadlines();\r\n}\r\n\r\ndelay(1);\r\n}\r\n\r\nvoid fetchHeadlines() {\r\nWiFiClientSecure client;\r\nclient.setInsecure(); \/\/ Ignore SSL certificate validation\r\nHTTPClient http;\r\n\r\nif (http.begin(client, newsUrls[currentFeed])) {\r\nint httpCode = http.GET();\r\nif (httpCode &gt; 0) {\r\nString payload = http.getString();\r\nparseRSS(payload);\r\n}\r\nhttp.end();\r\n}\r\n}\r\n\r\nvoid parseRSS(String xml) {\r\nnumHeadlines = 0;\r\nint pos = 0;\r\nwhile ((pos = xml.indexOf(\"&lt;title&gt;\", pos)) &gt;= 0 &amp;&amp; numHeadlines &lt; 40) {\r\nint endPos = xml.indexOf(\"&lt;\/title&gt;\", pos);\r\nif (endPos &gt; pos) {\r\nString headline = xml.substring(pos + 7, endPos);\r\n\r\n\/\/ Remove CDATA tags\r\nheadline.replace(\"&lt;![CDATA[\", \"\");\r\nheadline.replace(\"]]&gt;\", \"\");\r\n\r\n\/\/ Ensure UTF-8 encoding (needed for U8g2)\r\nheadline = convertToUTF8(headline);\r\n\r\nif (numHeadlines &gt; 0) {\r\nheadlines[numHeadlines] = \"-|- \" + headline;\r\n} else {\r\nheadlines[numHeadlines] = headline;\r\n}\r\n\r\nnumHeadlines++;\r\n}\r\npos = endPos + 8;\r\n}\r\n}\r\n\r\n\/\/ Function to ensure proper UTF-8 encoding\r\nString convertToUTF8(String str) {\r\nstr.replace(\"\u00a3\", \"\\xC2\\xA3\"); \/\/ Pound sign\r\nstr.replace(\"\u00e9\", \"\\xC3\\xA9\"); \/\/ \u00e9\r\nstr.replace(\"\u00eb\", \"\\xC3\\xAB\"); \/\/ \u00eb\r\nstr.replace(\"\u00ef\", \"\\xC3\\xAF\"); \/\/ \u00ef\r\nreturn str;\r\n}\r\n\r\n\/\/ Function to calculate the total width of all headlines combined\r\nint getTotalWidth() {\r\nint totalWidth = 0;\r\nfor (int i = 0; i &lt; numHeadlines; i++) {\r\ntotalWidth += u8g2.getUTF8Width(headlines[i].c_str()) + 10;\r\n}\r\nreturn totalWidth;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I had some ESP-32 DEVKITs left over and a SH1106 OLED display. I thought wouldn&#8217;t be nice to have a news ticker that would be playing away in the back ground. I am Dutch living in the UK so my feeds are a mixture of Dutch \/UK and international news but as long as you&hellip; <br \/> <a class=\"button small blue\" href=\"https:\/\/hobbies.wielenga.co.uk\/index.php\/2025\/02\/24\/news-ticker-for-esp32\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":431,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,1],"tags":[],"class_list":["post-405","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hobby-elelectronics-and-computing","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/405","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=405"}],"version-history":[{"count":13,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/405\/revisions"}],"predecessor-version":[{"id":440,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/405\/revisions\/440"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/media\/431"}],"wp:attachment":[{"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/categories?post=405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hobbies.wielenga.co.uk\/index.php\/wp-json\/wp\/v2\/tags?post=405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}