<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Data Archives - Digital Urban</title>
	<atom:link href="https://www.digitalurban.org/blog/tag/data/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.digitalurban.org/blog/tag/data/</link>
	<description>Data, Cities, IoT, Writing, Music and Making Things</description>
	<lastBuildDate>Thu, 13 Nov 2025 12:11:44 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.digitalurban.org/wp-content/uploads/2012/07/Dulogosm-1.png</url>
	<title>Data Archives - Digital Urban</title>
	<link>https://www.digitalurban.org/blog/tag/data/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Stepper Motor Linear Data Gauge</title>
		<link>https://www.digitalurban.org/blog/2025/11/13/stepper-motor-linear-data-gauge/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Thu, 13 Nov 2025 12:01:34 +0000</pubDate>
				<category><![CDATA[Making]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[gauge]]></category>
		<category><![CDATA[iot]]></category>
		<category><![CDATA[stepper]]></category>
		<category><![CDATA[Weather]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=170079124</guid>

					<description><![CDATA[<p>The latest upload to the Open Gauges Github is a Linear Gauge, using a timing belt to provide a full 1 metre range for the data visualisation. It uses a...</p>
<p>The post <a href="https://www.digitalurban.org/blog/2025/11/13/stepper-motor-linear-data-gauge/">Stepper Motor Linear Data Gauge</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The latest upload to the <a href="https://github.com/ucl-casa-ce/Open-Gauges/tree/main">Open Gauges Github</a> is a Linear Gauge, using a timing belt to provide</p>
<div id="attachment_170079126" style="width: 210px" class="wp-caption alignright"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-170079126" class="wp-image-170079126 size-large" src="https://www.digitalurban.org/wp-content/uploads/2025/11/WindStepperLinear-200x1024.png" alt="Linear Stepper Motor Gauge" width="200" height="1024" srcset="https://www.digitalurban.org/wp-content/uploads/2025/11/WindStepperLinear-200x1024.png 200w, https://www.digitalurban.org/wp-content/uploads/2025/11/WindStepperLinear-300x1536.png 300w, https://www.digitalurban.org/wp-content/uploads/2025/11/WindStepperLinear-400x2048.png 400w, https://www.digitalurban.org/wp-content/uploads/2025/11/WindStepperLinear.png 402w" sizes="(max-width: 200px) 100vw, 200px" /><p id="caption-attachment-170079126" class="wp-caption-text">Linear Stepper Motor Gauge</p></div>
<p>a full 1 metre range for the data visualisation. It uses a stepper motor for precise needle movement, and a limit switch for calibration, it can be adapted to any MQTT data feed and any base mount. The example shown uses a 5cm by 10cm peice of wood, cut to 1 metre length and indicates wind speed from 0 to 60 mph.</p>
<p class="p1">The design uses a stepper motor (like the 28BYJ-48) which offers high-precision, 360-degree movement without the jitter or limited range of a standard servo. The limit switch allows the gauge to &#8220;home&#8221; itself on startup, ensuring the pointer always starts at a known zero position.</p>
<p class="p1">The main code &#8211; <span class="s1">WindStepperTimerBeltwithLimitSwitch.ino</span> in the Github has a distance calibration number, adjust for your range.</p>
<p class="p1"><b>Hardware Components</b></p>
<ul class="ul1">
<li class="li1">Arduino-compatible Board: Any board like an Arduino Uno, Nano, or a NodeMCU.</li>
<li class="li1">Stepper Motor: 28BYJ-48 5V stepper motor.</li>
<li class="li1">Stepper Driver: ULN2003 driver board (which often comes with the 28BYJ-48).</li>
<li class="li1">Limit Switch: A small microswitch to detect the pointers zero position.</li>
<li class="li1">Power Supply: USB.</li>
<li class="li1">Timer Belt <a href="https://www.amazon.co.uk/Timing-Pulley-Tensioner-Torsion-Printer/dp/B0C54ZXM88/ref=sxin_15_pa_sp_search_thematic_sspa?content-id=amzn1.sym.0a6bbb1a-ed2d-4392-adfc-40ed1cfcd8e2%3Aamzn1.sym.0a6bbb1a-ed2d-4392-adfc-40ed1cfcd8e2&amp;crid=L07UDXXKCZFX&amp;cv_ct_cx=timing%2Bbelt%2Bgt2&amp;keywords=timing%2Bbelt%2Bgt2&amp;pd_rd_i=B0C54ZXM88&amp;pd_rd_r=12141bbe-35d0-4c0a-8811-d7f399206de4&amp;pd_rd_w=AVwDb&amp;pd_rd_wg=JG5Mx&amp;pf_rd_p=0a6bbb1a-ed2d-4392-adfc-40ed1cfcd8e2&amp;pf_rd_r=H6T6R7VAGD99FGNPH875&amp;qid=1763028887&amp;sbo=RZvfv%2F%2FHxDF%2BO5021pAnSA%3D%3D&amp;sprefix=timer%2Bbelt%2Bgt2%2Caps%2C99&amp;sr=1-5-ad3222ed-9545-4dc8-8dd8-6b2cb5278509-spons&amp;aref=vwr3X339Nm&amp;sp_csd=d2lkZ2V0TmFtZT1zcF9zZWFyY2hfdGhlbWF0aWM&amp;th=1"><span class="s2">GT2 Timer Belt</span></a></li>
</ul>
<p>It is made to be as simple to build/power as possible but also adatable for a number of senarios.</p>
<p>The github provides the mount for the stepper motor, the pointer (which also joins together the timing belt) the limit switch and the end mount for the pulley. These allow the gauge to be adapted to any size required.</p>
<p>At the moment the gauge is sitting on the wall in our lounge and it has become one of our most used guages. The data updates every minute to show the maximum wind gust and due to the nature of the stepper motor, it provides a smooth movement, almost replicating the gust of wind.</p>
<p>&nbsp;</p>
<p>The post <a href="https://www.digitalurban.org/blog/2025/11/13/stepper-motor-linear-data-gauge/">Stepper Motor Linear Data Gauge</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Ships Lamp Wind Speed Gauge</title>
		<link>https://www.digitalurban.org/blog/2025/11/12/ships-lamp-wind-speed-gauge/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Wed, 12 Nov 2025 11:39:29 +0000</pubDate>
				<category><![CDATA[Making]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[iot]]></category>
		<category><![CDATA[micropytho]]></category>
		<category><![CDATA[physical objects]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=170079118</guid>

					<description><![CDATA[<p>Our MicroPython project turns a strip of NeoPixel LEDs into a “ship&#8217;s lamp&#8221; style wind speed gauge. It connects to an MQTT broker to receive real-time wind speed data and...</p>
<p>The post <a href="https://www.digitalurban.org/blog/2025/11/12/ships-lamp-wind-speed-gauge/">Ships Lamp Wind Speed Gauge</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Our MicroPython project turns a strip of NeoPixel LEDs into a “ship&#8217;s lamp&#8221; style wind speed gauge. It connects to an MQTT broker to receive real-time wind speed data and translates it into a flickering, color-coded light.</p>
<p>The light simulates an oil lamp by staying &#8220;steady&#8221; for a random period and then &#8220;flickering&#8221; for a short time by rapidly dimming and brightening &#8211; the flicker speed changes acording to the wind speed. The full code and details are available on <a href="https://github.com/ucl-casa-ce/Open-Gauges">Github as part of the ever growing Open Gauges Project</a>.</p>
<div id="attachment_170079120" style="width: 1034px" class="wp-caption aligncenter"><img decoding="async" aria-describedby="caption-attachment-170079120" class="wp-image-170079120 size-large" src="https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025-1024x768.jpeg" alt="Ships Lamp" width="1024" height="768" srcset="https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025-1024x768.jpeg 1024w, https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025-300x225.jpeg 300w, https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025-768x576.jpeg 768w, https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025-1536x1152.jpeg 1536w, https://www.digitalurban.org/wp-content/uploads/2025/11/shipslamp2025.jpeg 2016w" sizes="(max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-170079120" class="wp-caption-text">Ships Lamp</p></div>
<h2>Features</h2>
<ul>
<li><strong>Real-time Data:</strong> Connects to an MQTT broker to subscribe to a wind speed topic.</li>
<li><strong>Weather Map Gradient:</strong> Displays wind speed using an intuitive &#8220;weather map&#8221; color gradient:
<ul>
<li><strong>0 mph:</strong> Off (Black)</li>
<li><strong>1-10 mph:</strong> Solid Green</li>
<li><strong>10-20 mph:</strong> Fades from Green → Yellow</li>
<li><strong>20-30 mph:</strong> Fades from Yellow → Orange</li>
<li><strong>30-40 mph:</strong> Fades from Orange → Red</li>
<li><strong>40+ mph:</strong> Solid Red</li>
</ul>
</li>
<li><strong>Realistic Flicker Effect:</strong> The light doesn&#8217;t just stay solid; it cycles between a &#8220;steady&#8221; phase (10-60s) and a &#8220;flicker&#8221; phase (5-15s) to simulate a real lamp.</li>
<li><strong>Asynchronous &amp; Resilient:</strong> Built using <code>uasyncio</code> and <code>mqtt_as</code>. The <code>mqtt_as</code> library automatically handles and recovers from WiFi or MQTT broker disconnections, re-subscribing to topics as needed.</li>
<li><strong>Hardware Watchdog:</strong> Uses the Pico&#8217;s built-in <code>machine.WDT</code> (Watchdog Timer) to automatically reboot the device <em>only</em> if the main code loop freezes, ensuring high reliability. (This replaces the old 60-minute timer).</li>
<li><strong>Status LEDs:</strong> Provides a heartbeat flash on one LED and a WiFi status indicator on another.</li>
</ul>
<h2>Hardware Requirements<strong style="font-size: 16px;"><img decoding="async" style="font-weight: 400;" src="https://github.com/ucl-casa-ce/Open-Gauges/raw/main/Contributed/ShipsLamp/shipslamp.jpeg" alt="MQTT Ships Lamp" /></strong></h2>
<ul>
<li><strong>Raspberry Pi Pico W:</strong> (or any Pico with a WiFi-capable board).</li>
<li><strong>NeoPixel LED Strip:</strong> The code is configured for a strip, but can be any WS812B/NeoPixel compatible LEDs.</li>
<li><strong>Power Supply:</strong> A sufficient power supply for your LED strip (a strip of 60 LEDs can draw several amps at full brightness).</li>
<li><strong>A Ships Lamp (old or new).</strong></li>
</ul>
<h3>Default Pinout (Pico W)</h3>
<ul>
<li><strong>NeoPixel Data:</strong> <code>GP15</code></li>
<li><strong>Blue LED (Heartbeat):</strong> <code>blue_led</code> (defined in <code>config.py</code>, often the onboard LED).</li>
<li><strong>WiFi LED:</strong> <code>wifi_led</code> (defined in <code>config.py</code>).</li>
</ul>
<h2>Software &amp; Dependencies</h2>
<p>This project relies on a few key MicroPython libraries that you must have on your Pico:</p>
<ol>
<li><strong><code>neopixel.py</code>:</strong> The standard Adafruit NeoPixel library for MicroPython.</li>
<li><strong><code>mqtt_as.py</code>:</strong> A robust, asynchronous MQTT client. You can find it <a href="https://github.com/peterhinch/micropython-mqtt/blob/master/mqtt_as/mqtt_as.py" target="_blank" rel="noopener noreferrer">here</a>.</li>
<li><strong><code>config.py</code>:</strong> A file you must create to hold your credentials and pin definitions.</li>
</ol>
<h2>Configuration</h2>
<p>You <strong>must</strong> create a <code>config.py</code> file in the root of your Pico&#8217;s filesystem. This file should contain:</p>
<ol>
<li>Your WiFi and MQTT broker credentials.</li>
<li>Definitions for your <code>wifi_led</code> and <code>blue_led</code>.</li>
</ol>
<p>The <code>mqtt_as</code> library expects the <code>config.py</code> to contain a <code>config</code> dictionary.</p>
<p><strong>Example <code>config.py</code>:</strong></p>
<pre class="wp-block-code"><code># config.py
from machine import Pin

# --- WiFi Configuration ---
config['wifi_led'] = Pin("WL_GPIO0", Pin.OUT) # Onboard LED on Pico W
config['ssid'] = 'YOUR_WIFI_SSID'
config['wifi_pw'] = 'YOUR_WWIFI_PASSWORD'

# --- MQTT Configuration ---
# This example is for the open broker mqtt.cetools.org
config['server'] = 'mqtt.cetools.org'
config['port'] = 1884
config['client_id'] = 'pico_ships_lamp' # Or any unique ID

# --- Optional: For Secured Brokers ---
# If your broker requires a username and password, add these lines:
# config['user'] = 'YOUR_MQTT_USER'
# config['password'] = 'YOUR_MQTT_PASSWORD'

# --- Other Hardware ---
# This is for the heartbeat LED
blue_led = Pin(10, Pin.OUT) # Example: an external LED on GP10
</code></pre>
<h2>Running the Project</h2>
<ol>
<li>Upload <code>main.py</code>, <code>neopixel.py</code>, <code>mqtt_as.py</code>, and your <code>config.py</code> to your Raspberry Pi Pico.</li>
<li>Reset the device.</li>
<li>The device will automatically connect to your WiFi and MQTT broker.</li>
<li>It will subscribe to the topic <code>personal/ucfnaps/downhamweather/windSpeed_mph</code>.</li>
<li>As messages are published to that topic, the ship&#8217;s lamp will spring to life!</li>
</ol>
<h2>Customizing</h2>
<ul>
<li><strong>LED Count:</strong> Change the <code>numpix</code> variable at the top of <code>main.py</code> to match your strip.</li>
<li><strong>Data Pin:</strong> Change the <code>15</code> in <code>pixels = Neopixel(numpix, 0, 15, "GRB")</code> to match your data pin.</li>
<li><strong>MQTT Topic:</strong> Change the a topic name in the <code>conn_han</code> function to subscribe to your own data source.</li>
</ul>
<p>The post <a href="https://www.digitalurban.org/blog/2025/11/12/ships-lamp-wind-speed-gauge/">Ships Lamp Wind Speed Gauge</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Just Weather for The Pebble Watch: Making a Data Watch Face</title>
		<link>https://www.digitalurban.org/blog/2025/10/30/just-weather-for-the-pebble-watch-making-a-data-watch-face/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Thu, 30 Oct 2025 12:59:40 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[copilot]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Pebble Watch]]></category>
		<category><![CDATA[Weather]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=170079095</guid>

					<description><![CDATA[<p>The post <a href="https://www.digitalurban.org/blog/2025/10/30/just-weather-for-the-pebble-watch-making-a-data-watch-face/">Just Weather for The Pebble Watch: Making a Data Watch Face</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
		<div id="fws_696f08e018929"  data-column-margin="default" data-midnight="dark"  class="wpb_row vc_row-fluid vc_row top-level"  style="padding-top: 0px; padding-bottom: 0px; "><div class="row-bg-wrap" data-bg-animation="none" data-bg-animation-delay="" data-bg-overlay="false"><div class="inner-wrap row-bg-layer" ><div class="row-bg viewport-desktop"  style=""></div></div></div><div class="row_col_wrap_12 col span_12 dark left">
	<div  class="vc_col-sm-12 wpb_column column_container vc_column_container col no-extra-padding inherit_tablet inherit_phone "  data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-animation="" data-delay="0" >
		<div class="vc_column-inner" >
			<div class="wpb_wrapper">
				
<div class="wpb_text_column wpb_content_element " >
	<div class="wpb_wrapper">
		<p>It&#8217;s an exciting time to be a Pebble fan. After years of being kept alive by the dedicated Rebble community, the Pebble is officially back. The <a href="https://store.repebble.com/">new Pebble 2 Duo watches</a> (the black-and-white model) are officially shipping to the first backers, with the high-resolution color Pebble Time 2 set to follow.</p>
<p>So, I decided to make one myself.</p>
<p>&nbsp;</p>
<h2 class="wp-block-heading">Introducing &#8216;Just Weather&#8217;</h2>
<p>I wanted a face that was clean, digital, and gave me all the key data at a glance, formatted to look great on the 144&#215;168 screen of the Pebble 2. I call it <strong>&#8220;Just Weather.&#8221;</strong></p>
<p>It uses the free Open-Meteo API to pull in a ton of useful, hyperlocal data right to your wrist:</p>
<p>&nbsp;</p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul>
<li>Current Location (from your phone&#8217;s GPS)</li>
<li>Temperature</li>
<li>Current Conditions (&#8220;Partly Cloudy,&#8221; &#8220;Rain,&#8221; etc.)</li>
<li>Barometric Pressure &amp; 3-Hour Trend</li>
<li>Wind Speed &amp; Precipitation</li>
<li>&#8230;and of course, the time!</li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2 class="wp-block-heading">Built with GitHub CoPiliot</h2>
<p>The best part is that the new Pebble development workflow is incredibly modern. I was able to build this using the <strong>CloudPebble IDE</strong>, which now integrates directly with <strong>VS Code in the browser</strong>.</p>
<p>This meant I could use the emerging tools like <strong>GitHub Copilot</strong> to help generate the code and work through the trickiest parts—like making direct HTTPS requests to the weather API, which (after a lot of testing!) we proved is possible from the phone app.</p>
<p>After getting the data, the final step was tweaking the C code to make sure the layout wasn&#8217;t clipped and all the information fit perfectly on the 144&#215;168 screen. It&#8217;s now compatible with watches in the Pebble family, from the original Pebble Time (color) to the new <strong>Pebble 2 Duo</strong> and the upcoming <strong>Pebble Time 2</strong>.</p>
<p>&nbsp;</p>
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="727" class="wp-image-170079097" src="https://www.digitalurban.org/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-12.49.33-1024x727.png" alt="Pebble Watch Face" srcset="https://www.digitalurban.org/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-12.49.33-1024x727.png 1024w, https://www.digitalurban.org/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-12.49.33-300x213.png 300w, https://www.digitalurban.org/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-12.49.33-768x545.png 768w, https://www.digitalurban.org/wp-content/uploads/2025/10/Screenshot-2025-10-30-at-12.49.33.png 1440w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Pebble Watch Face</figcaption></figure>
<p>&nbsp;</p>
<h2 class="wp-block-heading">Available Now</h2>
<p>This project took around 6 hours, with the main issue being that Co-Pilot did not know how to get HTTP requests &#8211; it took me down a lot of rabbit holes, and in the end, it was down to using a simpler call on the data &#8211; XMLHttpRequest. Once this worked it all fell into place and it was simply a case of asking Copilot to add in the data fields, do the geocoding and then take a step back and explain how the code actually works.</p>
<p>If you&#8217;re like me and just want a simple, data-rich weather face, please give it a try&#8230;</p>
<p>&nbsp;</p>
<ul class="wp-block-list">
<li style="list-style-type: none;">
<ul>
<li><strong>Download &#8216;<a href="https://apps.rebble.io/en_US/application/69034d22d004720008412cf1">Just Weather</a>&#8216; from the Rebble Appstore</strong></li>
<li><strong>Check out <a href="https://github.com/digitalurban/just-weather-pebble-watchface">the source code on GitHub</a> for the latest updates &#8211; now includes its own settings page (its become a proper watch face app)&#8230;</strong></li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
	</div>
</div>




			</div> 
		</div>
	</div> 
</div></div><p>The post <a href="https://www.digitalurban.org/blog/2025/10/30/just-weather-for-the-pebble-watch-making-a-data-watch-face/">Just Weather for The Pebble Watch: Making a Data Watch Face</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>MQTT Frame &#8211; Beautifully Framed Live Data</title>
		<link>https://www.digitalurban.org/blog/2025/03/19/mqttframe/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Wed, 19 Mar 2025 18:03:40 +0000</pubDate>
				<category><![CDATA[ios App]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[frame]]></category>
		<category><![CDATA[mqtt]]></category>
		<category><![CDATA[realtime]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=7886</guid>

					<description><![CDATA[<p>The post <a href="https://www.digitalurban.org/blog/2025/03/19/mqttframe/">MQTT Frame &#8211; Beautifully Framed Live Data</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
		<div id="fws_696f08e01ba7e"  data-column-margin="default" data-midnight="dark"  class="wpb_row vc_row-fluid vc_row"  style="padding-top: 0px; padding-bottom: 0px; "><div class="row-bg-wrap" data-bg-animation="none" data-bg-animation-delay="" data-bg-overlay="false"><div class="inner-wrap row-bg-layer" ><div class="row-bg viewport-desktop"  style=""></div></div></div><div class="row_col_wrap_12 col span_12 dark left">
	<div  class="vc_col-sm-12 wpb_column column_container vc_column_container col no-extra-padding inherit_tablet inherit_phone "  data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-animation="" data-delay="0" >
		<div class="vc_column-inner" >
			<div class="wpb_wrapper">
				
<div class="wpb_text_column wpb_content_element " >
	<div class="wpb_wrapper">
		<p><!-- /wp:post-content --></p>
<p><!-- wp:paragraph -->Transform your iPhone into a beautifully framed, dynamic data display with MQTT Frame. Stay informed about environmental conditions, breaking news, or custom live data feeds elegantly presented within a selection of artistic frames.</p>
<p><!-- /wp:paragraph --><br />

<a href='https://www.digitalurban.org/blog/2025/03/19/mqttframe/img_5262/'><img loading="lazy" decoding="async" width="473" height="1024" src="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-473x1024.png" class="attachment-large size-large" alt="" srcset="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-473x1024.png 473w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-139x300.png 139w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-768x1662.png 768w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-710x1536.png 710w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262-947x2048.png 947w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5262.png 1284w" sizes="auto, (max-width: 473px) 100vw, 473px" /></a>
<a href='https://www.digitalurban.org/blog/2025/03/19/mqttframe/img_5261/'><img loading="lazy" decoding="async" width="473" height="1024" src="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-473x1024.png" class="attachment-large size-large" alt="" srcset="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-473x1024.png 473w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-139x300.png 139w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-768x1662.png 768w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-710x1536.png 710w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261-947x2048.png 947w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5261.png 1284w" sizes="auto, (max-width: 473px) 100vw, 473px" /></a>
<a href='https://www.digitalurban.org/blog/2025/03/19/mqttframe/img_5264/'><img loading="lazy" decoding="async" width="473" height="1024" src="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-473x1024.png" class="attachment-large size-large" alt="" srcset="https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-473x1024.png 473w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-139x300.png 139w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-768x1662.png 768w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-710x1536.png 710w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264-947x2048.png 947w, https://www.digitalurban.org/wp-content/uploads/2025/03/IMG_5264.png 1284w" sizes="auto, (max-width: 473px) 100vw, 473px" /></a>
</p>
<h3 class="wp-block-heading">Key Features:</h3>
<p><!-- wp:list --></p>
<ul>
<li style="list-style-type: none;">
<ul><!-- wp:list-item --></ul>
</li>
<li><strong>Dynamic MQTT Integration</strong>: Easily subscribe to any MQTT topic and display live updates.</li>
<li><strong>Customizable Frames</strong>: Choose from multiple high-quality decorative frames to complement your home or office décor.</li>
<li><strong>Clean and Clear Data Display</strong>: Showcase important data such as temperature, pressure, news, and more with clear typography and layout.</li>
<li><strong>Fullscreen Mode</strong>: Tap to seamlessly switch to an immersive fullscreen view, maximizing readability and aesthetics.</li>
<li><strong>Easy Management</strong>: Add, edit, and reorder topics quickly through an intuitive interface.</li>
<li><strong>Instant Updates</strong>: Receive real-time data updates over MQTT, ensuring you’re always in the know.</li>
</ul>
<p><!-- /wp:list-item --></p>
<p><!-- wp:list-item /--></p>
<p><!-- wp:list-item /--></p>
<p><!-- wp:list-item /--></p>
<p><!-- wp:list-item /--></p>
<p><!-- wp:list-item /--><!-- /wp:list --></p>
<p><!-- wp:heading {"level":3} --></p>
<h3 class="wp-block-heading">Perfect For:</h3>
<p><!-- /wp:heading --></p>
<p><!-- wp:list --></p>
<ul>
<li style="list-style-type: none;">
<ul><!-- wp:list-item --></ul>
</li>
<li><strong>Home Assistant/Home Automation Enthusiasts</strong>: Display sensor data, home statuses, or environmental conditions.</li>
<li><strong>Personal Use</strong>: Stay updated with the latest news headlines, weather conditions, or any custom data stream.</li>
</ul>
<p><!-- /wp:list-item --> MQTT Frame merges elegant design with powerful real-time MQTT functionality, creating the perfect smart display for any setting.</p>
<p><!-- /wp:list --></p>
<p><!-- wp:heading {"level":5} --></p>
<h5 class="wp-block-heading">MQTT Frame is currently <a href="https://apps.apple.com/gb/app/mqtt-frame/id6743003699">available for free, on the Apple Store</a>, for support dm @digitalurban on X and bring your data to life in a beautiful new way.</h5>
<p><!-- /wp:heading --></p>
	</div>
</div>




			</div> 
		</div>
	</div> 
</div></div><p>The post <a href="https://www.digitalurban.org/blog/2025/03/19/mqttframe/">MQTT Frame &#8211; Beautifully Framed Live Data</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Make a Scrolling Hub75 Matrix Display using a Pimoroni Interstate75W and MQTT</title>
		<link>https://www.digitalurban.org/blog/2024/07/12/creating-an-scrolling-hub75-matrix-display-with-pimoroni-interstate75w-and-mqtt/</link>
					<comments>https://www.digitalurban.org/blog/2024/07/12/creating-an-scrolling-hub75-matrix-display-with-pimoroni-interstate75w-and-mqtt/#comments</comments>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Fri, 12 Jul 2024 09:30:06 +0000</pubDate>
				<category><![CDATA[Making]]></category>
		<category><![CDATA[Posts]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[home assistant]]></category>
		<category><![CDATA[iot]]></category>
		<category><![CDATA[making]]></category>
		<category><![CDATA[MQTT Scroller]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=7832</guid>

					<description><![CDATA[<p>The post <a href="https://www.digitalurban.org/blog/2024/07/12/creating-an-scrolling-hub75-matrix-display-with-pimoroni-interstate75w-and-mqtt/">Make a Scrolling Hub75 Matrix Display using a Pimoroni Interstate75W and MQTT</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="fws_696f08e01f5bf"  data-column-margin="default" data-midnight="dark"  class="wpb_row vc_row-fluid vc_row"  style="padding-top: 0px; padding-bottom: 0px; "><div class="row-bg-wrap" data-bg-animation="none" data-bg-animation-delay="" data-bg-overlay="false"><div class="inner-wrap row-bg-layer" ><div class="row-bg viewport-desktop"  style=""></div></div></div><div class="row_col_wrap_12 col span_12 dark left">
	<div  class="vc_col-sm-12 wpb_column column_container vc_column_container col no-extra-padding inherit_tablet inherit_phone "  data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-animation="" data-delay="0" >
		<div class="vc_column-inner" >
			<div class="wpb_wrapper">
				
<div class="wpb_text_column wpb_content_element " >
	<div class="wpb_wrapper">
		<p>There are many tutorials online on using an LED Matrix to display data—many of them require wiring up a screen, external power supplies, or flashing boards. We wanted to highlight a slightly more accessible way to get an LED Matrix—in our case, a Hub 75, 32&#215;64 pixel up and running using an <a href="https://shop.pimoroni.com/products/interstate-75-w?variant=40453881299027">Interstate75W from Pimoroni.</a> The benefit of the Interstate is that it plugs indirectly into the matrix and can power a single screen directly from the board.</p>
<div id="attachment_7838" style="width: 310px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7838" class="size-medium wp-image-7838" src="https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-300x300.webp" alt="Interstate75W " width="300" height="300" srcset="https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-300x300.webp 300w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-1024x1024.webp 1024w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-150x150.webp 150w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-768x768.webp 768w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-140x140.webp 140w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-100x100.webp 100w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-500x500.webp 500w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-350x350.webp 350w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-1000x1000.webp 1000w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center-800x800.webp 800w, https://www.digitalurban.org/wp-content/uploads/2024/07/interstate-75-w-2_1500x1500_crop_center.webp 1500w" sizes="auto, (max-width: 300px) 100vw, 300px" /><p id="caption-attachment-7838" class="wp-caption-text">Interstate75W</p></div>
<p>We wanted a way to display any data we wanted on the screen with the screen lighting up and data scrolling up as it arrives and then turning off. To use this we use MQTT to load our data (a test feed is included in the scripts &#8211; which displays Time, News and Environmental Information) &#8211; see below for a demo:</p>
<p>&nbsp;</p>
<div style="text-align: center;"><iframe loading="lazy" src="https://www.youtube.com/embed/kG3OStmfXLk" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></div>
<p>We also incorporate manual brightness control and reconnecting for the MQTT for message handling, making it easy to update the display from anywhere. Setting up your own MQTT is beyond this post, but its easier than you may think and once you have one it can be used to display any data, from external feeds such as weather apis through to data from systems such as Home Assistant. Edit April 2025, we have added additional files to allow use with the new <a href="https://shop.pimoroni.com/products/interstate-75-w?variant=55006518411643">Pimoroni Intersate Starter Kit 128&#215;128 Matrix</a>, allowing a larger format screen, as pictured below.</p>
<div id="attachment_7914" style="width: 1034px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7914" class="wp-image-7914 size-large" src="https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-1024x576.jpeg" alt="Matrix128x128" width="1024" height="576" srcset="https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-1024x576.jpeg 1024w, https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-300x169.jpeg 300w, https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-768x432.jpeg 768w, https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-1536x864.jpeg 1536w, https://www.digitalurban.org/wp-content/uploads/2024/07/Matrix128x128-2048x1152.jpeg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-7914" class="wp-caption-text">Matrix128x128</p></div>
<h3>Features</h3>
<ul>
<li><strong>Scrolling Text Messages:</strong> Display messages that scroll across the HUB75 LED matrix.</li>
<li><strong>Manual Brightness Control:</strong> Adjust the brightness of the display manually.</li>
<li><strong>MQTT Integration:</strong> Receive and display messages via MQTT.</li>
</ul>
<h3>Hardware Requirements</h3>
<p>To get started, you&#8217;ll need the following hardware:</p>
<ul>
<li><a href="https://shop.pimoroni.com/products/interstate-75-w?variant=40453881299027">Pimoroni Interstate75W</a></li>
<li><a href="https://shop.pimoroni.com/products/rgb-led-matrix-panel?variant=42312764298">A HUB75 LED matrix display</a></li>
<li><a href="https://www.printables.com/model/939763-hub75-display-case-for-the-interstate75w-32x64-4mm">3D Printed Case</a></li>
<li>MQTT broker (local or cloud-based) &#8211; we provide our own feed so you can test the set up.</li>
</ul>
<p>There is also room in the 3D printed case to attach a cloth cover, acting a diffuser (a grey t-shirt works well, cut to size):</p>
<div id="attachment_7879" style="width: 1034px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7879" class="wp-image-7879 size-large" src="https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-1024x576.png" alt="LED Matrix with Cloth Cover" width="1024" height="576" srcset="https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-1024x576.png 1024w, https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-300x169.png 300w, https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-768x432.png 768w, https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-1536x864.png 1536w, https://www.digitalurban.org/wp-content/uploads/2024/07/Photoroom_20250128_104636-2048x1152.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><p id="caption-attachment-7879" class="wp-caption-text">LED Matrix with Cloth Cover</p></div>
<h2>Software Requirements</h2>
<p>You&#8217;ll also need the following software &#8211; all available from our GitHub</p>
<ul>
<li>MicroPython</li>
<li>Required MicroPython libraries:
<ul>
<li><code>interstate75</code></li>
<li><code>mqtt_as</code></li>
<li><code>uasyncio</code></li>
</ul>
</li>
</ul>
<h3>Setup</h3>
<h3>1. Clone the Repository</h3>
<p>First, clone the project repository from GitHub, or just download the files directly:</p>
<p>&#8220;`sh<br />
git clone <a href="https://github.com/digitalurban/Interstate75W_MQTT_Scroller">https://github.com/digitalurban/Interstate75W_MQTT_Scroller</a><br />
cd interstate75w-mqtt-display<br />
&#8220;`</p>
<h3>2. Upload the Code</h3>
<p>Next, upload the code to your microcontroller. You can use tools like Thonny or ampy to do this.</p>
<h3>3. Configure WiFi and MQTT</h3>
<p>Update the <code>config.py</code> file with your WiFi credentials, the MQTT details can also be updated if you have your own server, if not then leave them for our demo feed.</p>
<p>&#8220;`python<br />
config = {<br />
&#8216;ssid&#8217;: &#8216;your_wifi_ssid&#8217;,<br />
&#8216;wifi_pw&#8217;: &#8216;your_wifi_password&#8217;,<br />
&#8216;server&#8217;: &#8216;mqtt_broker_address&#8217;,<br />
&#8216;user&#8217;: &#8216;mqtt_user&#8217;,<br />
&#8216;password&#8217;: &#8216;mqtt_password&#8217;,<br />
&#8216;port&#8217;: 1883,<br />
&#8216;keepalive&#8217;: 60,<br />
}<br />
&#8220;`</p>
<h3>Usage</h3>
<h3>Run the Script</h3>
<p>The script will automatically connect to WiFi and the MQTT broker, then start displaying messages &#8211; our MQQ feed displays messages approximatly every 3 minutes.</p>
<h3>Constants and Initial Setup</h3>
<p>The script defines constants for controlling the scrolling text speed, how long the screen says on for after displaying the message and brightness settings. It also initializes the Interstate75W object:</p>
<h4>Constants for controlling scrolling text</h4>
<p>BACKGROUND_COLOUR = (0, 0, 0) # Black background to turn off the screen<br />
HOLD_TIME = 2.0<br />
BLANK_SCREEN_TIME = 10.0<br />
BUFFER_PIXELS = 2 # Increased buffer to ensure full scroll off<br />
SCROLL_SPEED_LEVEL = 8 # Set the desired scrolling speed level (1 to 10)<br />
SCROLL_SPEED = 1 / SCROLL_SPEED_LEVEL # Convert to a delay in seconds</p>
<h4>Brightness settings</h4>
<p>brightness = 50 # Initial brightness (0 to 100)</p>
<p>Do let us know if you make one &#8211; we would love to see images of your own set up and we hope this made it a little easier for anyone new looking to run an LED matrix using MQTT.</p>
	</div>
</div>




			</div> 
		</div>
	</div> 
</div></div>
<p>The post <a href="https://www.digitalurban.org/blog/2024/07/12/creating-an-scrolling-hub75-matrix-display-with-pimoroni-interstate75w-and-mqtt/">Make a Scrolling Hub75 Matrix Display using a Pimoroni Interstate75W and MQTT</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.digitalurban.org/blog/2024/07/12/creating-an-scrolling-hub75-matrix-display-with-pimoroni-interstate75w-and-mqtt/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Enhancing Live Weather Monitoring with MQTT and Chart.js</title>
		<link>https://www.digitalurban.org/blog/2024/06/27/enhancing-live-weather-monitoring-with-mqtt-and-chart-js/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Thu, 27 Jun 2024 15:10:06 +0000</pubDate>
				<category><![CDATA[data]]></category>
		<category><![CDATA[Data Visualisation]]></category>
		<category><![CDATA[Weather]]></category>
		<category><![CDATA[Weather (Live)]]></category>
		<category><![CDATA[Weather Display]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[mqtt]]></category>
		<guid isPermaLink="false">https://www.digitalurban.org/?p=7816</guid>

					<description><![CDATA[<p>Introduction Viewing real-time data from a personal weather station such as a Davis Vantage Pro, a Tempest, or an EcoWhitt device can be complex. However, the majority of systems that...</p>
<p>The post <a href="https://www.digitalurban.org/blog/2024/06/27/enhancing-live-weather-monitoring-with-mqtt-and-chart-js/">Enhancing Live Weather Monitoring with MQTT and Chart.js</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2></h2>
<h3>Introduction</h3>
<p>Viewing real-time data from a personal weather station such as a Davis Vantage Pro, a Tempest, or an EcoWhitt device can be complex. However, the majority of systems that process weather data, such as Weather Display, Weewx, or CumlusMx, all have the ability to output MQTT data. This data can be used to display a real-time graph of the data, keeping you engaged with the latest weather updates, and supplemented with any other data which is MQTT-based.</p>
<p>With this in mind, we&#8217;ve developed a live weather monitoring dashboard as an illustrative example. This dashboard uses MQTT for real-time data updates and Chart.js for dynamic visualization. We&#8217;ve also included a visual indicator for connection status and a brief pulse effect to notify when new data arrives, enhancing the user experience.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-7820 aligncenter" src="https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-300x185.png" alt="MQTT Weather Dashboard" width="600" height="370" srcset="https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-300x185.png 300w, https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-1024x631.png 1024w, https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-768x473.png 768w, https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-1536x946.png 1536w, https://www.digitalurban.org/wp-content/uploads/2024/06/Screenshot-2024-06-27-at-15.48.35-2048x1261.png 2048w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>You can view it live at: <a href="https://finchamweather.co.uk/weathergraph.htm">https://finchamweather.co.uk/weathergraph.htm</a></p>
<p>The data populates as the page loads &#8211; we could of course back load it via a database link, but the aim was to simply use MQTT and have a graphing system that streams in data, its a work in progress but here is how we got it working:</p>
<h3>Setting Up the Environment</h3>
<p>Before we dive into the code, ensure you have the following libraries included in your HTML:</p>
<ul>
<li>Paho MQTT: for MQTT protocol handling &#8211; our MQTT feed is open to use as a test, replace this with your own MQTT details in the main code.</li>
<li>Chart.js: for creating dynamic charts</li>
<li>Chart.js adapter for date-fns: for handling time scales in charts</li>
</ul>
<h3>Initial HTML Setup</h3>
<p>We&#8217;ll start by setting up the basic HTML structure. This includes elements for displaying the connection status, forecast, weather statistics, and the weather chart.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;meta name="apple-mobile-web-app-capable" content="yes"&gt;
    &lt;meta name="apple-mobile-web-app-status-bar-style" content="black"&gt;
    &lt;title&gt;Live Weather Graph&lt;/title&gt;
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.jsdelivr.net/npm/chart.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        #mqttStatus {
            margin-bottom: 20px;
            text-align: left;
            font-size: 1.2em;
        }
        .dot {
            height: 20px;
            width: 20px;
            border-radius: 50%;
            display: inline-block;
        }
        .green {
            background-color: green;
        }
        .red {
            background-color: red;
        }
        .orange {
            background-color: orange;
        }
        .pulse-once {
            animation: pulse-once 1s;
        }
        @keyframes pulse-once {
            0% { transform: scale(1); }
            50% { transform: scale(1.2); }
            100% { transform: scale(1); }
        }
        #forecast {
            margin-bottom: 20px;
            text-align: left;
            font-size: 1.2em;
            font-weight: bold;
        }
        #stats {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 20px;
            font-size: 1.2em;
            font-weight: bold;
        }
        #stats div {
            padding: 10px 20px;
            border: 1px solid #ccc;
            border-radius: 8px;
            box-shadow: 2px 2px 12px #aaa;
            background-color: #f9f9f9;
        }
        canvas {
            border: 1px solid #ccc;
            box-shadow: 2px 2px 12px #aaa;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="mqttStatus"&gt;&lt;span id="connectionDot" class="dot red"&gt;&lt;/span&gt; mqtt: disconnected&lt;/div&gt;
    &lt;div id="forecast"&gt;Forecast: Loading...&lt;/div&gt;
    &lt;div id="stats"&gt;
        &lt;div id="maxWindSpeed"&gt;Max Wind Speed: 0 mph&lt;/div&gt;
        &lt;div id="maxTemp"&gt;Max Temperature: 0 °C&lt;/div&gt;
        &lt;div id="minTemp"&gt;Min Temperature: 0 °C&lt;/div&gt;
        &lt;div id="maxPressure"&gt;Max Pressure: 0 mbar&lt;/div&gt;
        &lt;div id="minPressure"&gt;Min Pressure: 0 mbar&lt;/div&gt;
    &lt;/div&gt;
    &lt;canvas id="weatherChart" width="800" height="400"&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h3>Connecting to MQTT</h3>
<p>Next, we set up the MQTT connection. The MQTT client will connect to the broker, subscribe to the necessary topics, and handle messages when they arrive.</p>
<pre><code>// MQTT connection settings
var mqtt;
var reconnectTimeout = 2000;
var host = "mqtt.cetools.org";
var port = location.protocol === 'https:' ? 8081 : 8080;
var options = {
    timeout: 3,
    onSuccess: onConnect,
    onFailure: onFailure,
    useSSL: location.protocol === 'https:',
};
var clientID = "clientID" + parseInt(Math.random() * 100);

function updateConnectionStatus(status) {
    const dot = document.getElementById("connectionDot");
    if (status === "connected") {
        dot.className = "dot green";
        document.getElementById("mqttStatus").innerHTML = `&lt;span class="dot green" id="connectionDot"&gt;&lt;/span&gt; mqtt: connected`;
    } else if (status === "disconnected") {
        dot.className = "dot red";
        document.getElementById("mqttStatus").innerHTML = `&lt;span class="dot red" id="connectionDot"&gt;&lt;/span&gt; mqtt: disconnected`;
    } else if (status === "reconnecting") {
        dot.className = "dot orange";
        document.getElementById("mqttStatus").innerHTML = `&lt;span class="dot orange" id="connectionDot"&gt;&lt;/span&gt; mqtt: reconnecting`;
    }
}

function pulseDot() {
    const dot = document.getElementById("connectionDot");
    dot.classList.add("pulse-once");
    setTimeout(() =&gt; {
        dot.classList.remove("pulse-once");
    }, 1000); // Duration of the pulse-once animation
}

function onFailure(message) {
    console.log("Connection Attempt to Host " + host + " Failed: ", message.errorMessage);
    updateConnectionStatus("disconnected");
    setTimeout(MQTTconnect, reconnectTimeout);
}

function onConnect() {
    console.log("Connected ");
    updateConnectionStatus("connected");
    mqtt.subscribe("personal/ucfnaps/downhamweather/loop");
    mqtt.subscribe("personal/ucfnaps/eink/met");
}

function MQTTconnect() {
    console.log("Connecting to " + host + " on port " + port);
    updateConnectionStatus("reconnecting");
    mqtt = new Paho.MQTT.Client(host, port, clientID);
    mqtt.onMessageArrived = onMessageArrived;
    mqtt.onConnectionLost = function(responseObject) {
        if (responseObject.errorCode !== 0) {
            console.log("Connection Lost: " + responseObject.errorMessage);
            updateConnectionStatus("disconnected");
            setTimeout(MQTTconnect, reconnectTimeout);  // Attempt to reconnect
        }
    };
    mqtt.connect(options);
}

window.onload = function() {
    MQTTconnect();
}
</code></pre>
<h3>Handling Incoming Messages</h3>
<p>When messages arrive, we process the data and update the chart. We also update the connection dot to pulse briefly, indicating new data has been received.</p>
<pre><code>let lastUpdate = Date.now();  // Initialize to current time
let firstUpdate = true;  // Flag to ensure first update happens immediately

let maxWindSpeed = 0;
let maxTemp = -Infinity;
let minTemp = Infinity;
let maxPressure = -Infinity;
let minPressure = Infinity;

function updateWindSpeed(windSpeed, timestamp) {
    weatherChart.data .labels.push(timestamp);
    weatherChart.data.datasets[0].data.push(windSpeed);

    // Update max wind speed
    if (windSpeed &gt; maxWindSpeed) {
        maxWindSpeed = windSpeed;
        document.getElementById('maxWindSpeed').innerText = `Max Wind Speed: ${maxWindSpeed} mph`;
    }

    // Limit the number of data points to keep the chart responsive
    if (weatherChart.data.labels.length &gt; 1440) { // Assuming 1 data point per minute, keep 24 hours of data
        weatherChart.data.labels.shift();
        weatherChart.data.datasets[0].data.shift();
    }

    weatherChart.update();
}

function updateOtherMetrics(temperature, solarRadiation, rainAmount, pressure, timestamp) {
    weatherChart.data.datasets[1].data.push({x: timestamp, y: temperature});
    weatherChart.data.datasets[2].data.push({x: timestamp, y: solarRadiation});
    weatherChart.data.datasets[3].data.push({x: timestamp, y: rainAmount &gt; 0 ? rainAmount : null});
    weatherChart.data.datasets[4].data.push({x: timestamp, y: pressure});

    // Update max and min temperature
    if (temperature &gt; maxTemp) {
        maxTemp = temperature;
        document.getElementById('maxTemp').innerText = `Max Temperature: ${maxTemp} °C`;
    }
    if (temperature &lt; minTemp) { minTemp = temperature; document.getElementById('minTemp').innerText = `Min Temperature: ${minTemp} °C`; } // Update max and min pressure if (pressure &gt; maxPressure) {
        maxPressure = pressure;
        document.getElementById('maxPressure').innerText = `Max Pressure: ${maxPressure} mbar`;
    }
    if (pressure &lt; minPressure) { minPressure = pressure; document.getElementById('minPressure').innerText = `Min Pressure: ${minPressure} mbar`; } // Limit the number of data points to keep the chart responsive if (weatherChart.data.labels.length &gt; 1440) { // Assuming 1 data point per minute, keep 24 hours of data
        weatherChart.data.datasets[1].data.shift();
        weatherChart.data.datasets[2].data.shift();
        weatherChart.data.datasets[3].data.shift();
        weatherChart.data.datasets[4].data.shift();
    }

    weatherChart.update();
}

function updateForecast(forecast) {
    document.getElementById('forecast').innerText = `Forecast: ${forecast}`;
}

function onMessageArrived(message) {
    console.log("Message Arrived: " + message.destinationName + " : " + message.payloadString);
    if (message.destinationName === "personal/ucfnaps/downhamweather/loop") {
        const data = JSON.parse(message.payloadString);
        const windSpeed = data['windSpeed_mph'];  // Adjust this key according to your data structure
        const temperature = data['outTemp_C'];  // Adjust this key according to your data structure
        const solarRadiation = data['radiation_Wpm2'];  // Adjust this key according to your data structure
        const rainAmount = data['dayRain_mm'];  // Adjust this key according to your data structure
        const pressure = data['pressure_mbar'];  // Adjust this key according to your data structure

        const nowTimestamp = new Date();

        // Update wind speed every time
        updateWindSpeed(windSpeed, nowTimestamp);

        if (firstUpdate || Date.now() - lastUpdate &gt;= 60000) {
            // Update other metrics every minute
            updateOtherMetrics(temperature, solarRadiation, rainAmount, pressure, nowTimestamp);
            lastUpdate = Date.now();
            firstUpdate = false;  // Ensure subsequent updates follow the interval
        }

        // Pulse the dot when new data arrives
        pulseDot();
    } else if (message.destinationName === "personal/ucfnaps/eink/met") {
        const forecast = message.payloadString;
        updateForecast(forecast);
    }
}
</code></pre>
<h3>Chart.js Setup</h3>
<p>Now, let&#8217;s configure Chart.js to visualize the weather data. We will use multiple datasets to display wind speed, temperature, solar radiation, rain amount, and pressure.</p>
<pre><code>// Chart.js setup
const ctx = document.getElementById('weatherChart').getContext('2d');
const weatherChart = new Chart(ctx, {
    type: 'line',
    data: {
        labels: [],  // Time labels
        datasets: [{
            label: 'Wind Speed (mph)',
            data: [],
            borderColor: 'rgba(75, 192, 192, 1)',
            borderWidth: 3,
            fill: false,
            yAxisID: 'y-axis-1',
            tension: 0.1
        },
        {
            label: 'Temperature (°C)',
            data: [],
            borderColor: 'rgba(255, 99, 132, 1)',
            borderWidth: 3,
            fill: false,
            yAxisID: 'y-axis-2',
            tension: 0.1
        },
        {
            label: 'Solar Radiation (W/m²)',
            data: [],
            borderColor: 'rgba(255, 206, 86, 1)',
            borderWidth: 3,
            fill: false,
            yAxisID: 'y-axis-3',
            tension: 0.1
        },
        {
            label: 'Rain Amount (mm)',
            data: [],
            borderColor: 'rgba(54, 162, 235, 1)',
            borderWidth: 3,
            fill: false,
            yAxisID: 'y-axis-4',
            tension: 0.1
        },
        {
            label: 'Pressure (mbar)',
            data: [],
            borderColor: 'rgba(153, 102, 255, 1)',
            borderWidth: 3,
            fill: false,
            yAxisID: 'y-axis-5',
            tension: 0.1
        }]
    },
    options: {
        responsive: true,
        plugins: {
            legend: {
                position: 'top',
            },
            title: {
                display: true,
                text: 'Live Weather Data'
            },
            decimation: {
                enabled: true,
                algorithm: 'lttb',
                samples: 100,  // Adjust this value as needed for performance
            },
        },
        scales: {
            x: {
                type: 'time',
                time: {
                    unit: 'minute'
                },
                title: {
                    display: true,
                    text: 'Time'
                }
            },
            'y-axis-1': {
                type: 'linear',
                position: 'left',
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Wind Speed (mph)'
                }
            },
            'y-axis-2': {
                type: 'linear',
                position: 'right',
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Temperature (°C)'
                },
                grid: {
                    drawOnChartArea: false
                }
            },
            'y-axis-3': {
                type: 'linear',
                position: 'right',
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Solar Radiation (W/m²)'
                },
                grid: {
                    drawOnChartArea: false
                }
            },
            'y-axis-4': {
                type: 'linear',
                position: 'right',
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Rain Amount (mm)'
                },
                grid: {
                    drawOnChartArea: false
                }
            },
            'y-axis-5': {
                type: 'linear',
                position: 'right',
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Pressure (mbar)'
                },
                grid: {
                    drawOnChartArea: false
                }
            }
        },
        interaction: {
            intersect: false,
            mode: 'nearest',
        },
        elements: {
            line: {
                cubicInterpolationMode: 'monotone',
            },
        },
    }
});
</code></pre>
<h3>Conclusion</h3>
<p>By integrating MQTT and Chart.js, it is possible to create a dynamic and real-time weather monitoring dashboard. The connection status indicator provides immediate feedback on the connection state, and the pulsing effect when new data arrives enhances user experience by visually notifying them of updates.</p>
<p>This setup can be further extended by adding more datasets, customizing the chart&#8217;s appearance, or integrating additional sensors. The data of course couple be from any feed, but real-time weather monitoring provides a good example of how IoT and web technologies can be combined to create realtime dashboards.</p>
<p>The post <a href="https://www.digitalurban.org/blog/2024/06/27/enhancing-live-weather-monitoring-with-mqtt-and-chart-js/">Enhancing Live Weather Monitoring with MQTT and Chart.js</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>IoT 3D Printable Devices &#8211; The Spring 2021 Collection</title>
		<link>https://www.digitalurban.org/blog/2021/02/23/iot-3d-printable-devices-the-spring-2021-collection/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Tue, 23 Feb 2021 09:42:01 +0000</pubDate>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[3D Printing]]></category>
		<category><![CDATA[Barograph]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[iot]]></category>
		<category><![CDATA[neopixels]]></category>
		<category><![CDATA[servos]]></category>
		<category><![CDATA[SketchFab]]></category>
		<category><![CDATA[Spring 2021]]></category>
		<guid isPermaLink="false">http://www.digitalurban.org/?p=5898</guid>

					<description><![CDATA[<p>At The Connected Environments Lab, part of The Bartlett Centre for Advanced Spatial Analysis, here at University College London we are designing and building a series of IoT devices to...</p>
<p>The post <a href="https://www.digitalurban.org/blog/2021/02/23/iot-3d-printable-devices-the-spring-2021-collection/">IoT 3D Printable Devices &#8211; The Spring 2021 Collection</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>At <a rel="noreferrer noopener" href="https://connected-environments.org/" target="_blank">The Connected Environments Lab</a>, part of <a href="http://www.casa.ucl.axc.uk" target="_blank" rel="noreferrer noopener">The Bartlett Centre for Advanced Spatial Analysis</a>, here at <a href="http://ucl.ac.uk" data-type="URL" data-id="http://ucl.ac.uk" target="_blank" rel="noreferrer noopener">University College London</a> we are designing and building a series of IoT devices to communicate live data feeds. Using a mix of servo motors, neopixels, LEDs, speech systems, eink and sound we are exploring ways to monitor data within a home/office environment. These form part of a module exploring the ability to build and design devices that not only can be physically made but also exist and run with both Augmented and Virtual Reality. </p>


<p>The YouTube clip below details the collection so far (Spring 2021):</p>


<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="3D Printable IoT Devices  -  Connected Environments,  Spring 2021. UCL, The Bartlett, CASA." width="1080" height="608" src="https://www.youtube.com/embed/MpRavRJTQzI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>


<p>Each of these objects will be explored further and made available to print, insert into 3D worlds and view online. One such example is our &#8216;THE&#8217;  &#8211; Time, Headlines and Environmental Data. </p>


<figure class="wp-block-image size-large"><img decoding="async" src="http://www.digitalurban.org/wp-content/uploads/2019/12/IMG_1883-1024x768.jpeg" alt="THE: eink Time Headlines and Environmental Data" class="wp-image-5854"/></figure>


<p>We have a<a rel="noreferrer noopener" href="https://connected-environments.org/making/the/" target="_blank"> full tutorial on making a &#8216;THE&#8217; over at Connected Environments</a>. A more recent addition is the ability to <a href="https://sketchfab.com/digitalurban/models" target="_blank" rel="noreferrer noopener">upload models to SketchFab and make them available to download</a>. </p>


<figure class="wp-block-image size-large"><a href="https://sketchfab.com/digitalurban/models"><img decoding="async" src="https://www.digitalurban.org/wp-content/uploads/2021/02/Screenshot-2021-02-23-at-09.32.57-2-1024x694.png" alt="IoT Printable Devices" class="wp-image-5899"/></a><figcaption>Spring 2021 Collection on SketchFab</figcaption></figure>


<p>SketchFab also allows models to be embed and viewed directly within a web browser &#8211; below is an example of our 3D Printed Barograph, using realtime data feeds combined with more traditional paper and ink to recreate the Barograph &#8211; click &#8216;Play&#8217; to view the model in 3D.</p>


<center><iframe loading="lazy" sandbox="allow-scripts allow-same-origin allow-popups allow-forms" frameborder="0" width="800" height="640" src="https://sketchfab.com/3d-models/barograph-3d-printable-a2f702cb3aac478b8a4204d0c7275588//embed"></iframe></center>


<p>We will be posting more about the Spring 2021 collection in the coming weeks. Its been a while since our last post over here on Digital Urban, it is good to be back.</p>
<p>The post <a href="https://www.digitalurban.org/blog/2021/02/23/iot-3d-printable-devices-the-spring-2021-collection/">IoT 3D Printable Devices &#8211; The Spring 2021 Collection</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Field</title>
		<link>https://www.digitalurban.org/blog/2013/03/23/the-field-2/</link>
		
		<dc:creator><![CDATA[Andy]]></dc:creator>
		<pubDate>Sat, 23 Mar 2013 17:20:09 +0000</pubDate>
				<category><![CDATA[Food for thought]]></category>
		<category><![CDATA[Art]]></category>
		<category><![CDATA[Awesome]]></category>
		<category><![CDATA[Cars]]></category>
		<category><![CDATA[Classic]]></category>
		<category><![CDATA[Custom]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Epic]]></category>
		<category><![CDATA[Funny]]></category>
		<category><![CDATA[Gaming Tips]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[Standard]]></category>
		<category><![CDATA[ThemeNectar]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[Wordpress]]></category>
		<guid isPermaLink="false">http://themenectar.com/demo/salient/?p=110</guid>

					<description><![CDATA[<p>In varius varius justo, eget ultrices mauris rhoncus non. Morbi tristique, mauris eu imperdiet bibendum, velit diam iaculis velit, in ornare massa enim at lorem. Etiam risus diam, porttitor vitae...</p>
<p>The post <a href="https://www.digitalurban.org/blog/2013/03/23/the-field-2/">The Field</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In varius varius justo, eget ultrices mauris rhoncus non. Morbi tristique, mauris eu imperdiet bibendum, velit diam iaculis velit, in ornare massa enim at lorem. Etiam risus diam, porttitor vitae ultrices quis, dapibus id dolor. Morbi venenatis lacinia rhoncus. <span id="more-6822"></span><br />
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean non enim ut enim fringilla adipiscing id in lorem. Quisque aliquet neque vitae lectus tempus consectetur. Aliquam erat volutpat. Nunc eu nibh nulla, id cursus arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam at velit nisl. Aenean vitae est nisl. Cras molestie molestie nisl vel imperdiet. Donec vel mi sem.</p>
<h4>Luctus fermentum commodo</h4>
<p>Nulla sed mi leo, sit amet molestie nulla. Phasellus lobortis blandit ipsum, at adipiscing eros porta quis. Phasellus in nisi ipsum, quis dapibus magna. Phasellus odio dolor, pretium sit amet aliquam a, gravida eget dui. Pellentesque eu ipsum et quam faucibus scelerisque vitae ut ligula. Ut luctus fermentum commodo. Mauris eget justo turpis, eget fringilla mi. Duis lobortis cursus mi vel tristique. Maecenas eu lorem hendrerit neque dapibus cursus id sit amet nisi. Proin rhoncus semper sem nec aliquet.</p>
<blockquote><p>Nulla facilisi. Vestibulum pretium, dui eu aliquam faucibus, est dui hendrerit nulla, mattis semper turpis mauris eget tellus. Nulla accumsan rutrum nibh, sed eleifend felis blandit.</p></blockquote>
<p>Integer vel libero arcu, egestas tempor ipsum. Vestibulum id dolor aliquet dolor fringilla ornare. Nunc non massa erat. Vivamus odio sem, rhoncus vel bibendum vitae, euismod a urna. Aliquam erat volutpat. Aenean non lorem arcu. Phasellus in neque nulla, sed sodales ipsum. Morbi a massa sed sapien vulputate lacinia. Vivamus et urna vitae felis malesuada aliquet sit amet et metus.</p>
<ul>
<li>Consectetur adipiscing elit vtae elit libero</li>
<li>Nullam id dolor id eget lacinia odio posuere erat a ante</li>
<li>Integer posuere erat dapibus posuere velit</li>
</ul>
<p>Nulla sed mi leo, sit amet molestie nulla. Phasellus lobortis blandit ipsum, at adipiscing eros porta quis. Phasellus in nisi ipsum, quis dapibus magna. Phasellus odio dolor, pretium sit amet aliquam a, gravida eget dui. Pellentesque eu ipsum et quam faucibus scelerisque vitae ut ligula. Ut luctus fermentum commodo. Mauris eget justo turpis, eget fringilla mi. Duis lobortis cursus mi vel tristique. Maecenas eu lorem hendrerit neque dapibus cursus id sit amet nisi. Proin rhoncus semper sem nec aliquet. Aenean lacinia bibendum nulla sed consectetur. Cras mattis consectetur purus sit amet fermentum. Donec id elit non mi porta gravida at eget metus.<br />
<code><br />
.some-style {<br />
width: 960px;<br />
height: 200px;<br />
margin: 0 auto;<br />
background-color: #000000;<br />
}<br />
</code><br />
<strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean non enim ut enim fringilla adipiscing id in lorem. Quisque aliquet neque vitae lectus tempus consectetur. Aliquam erat volutpat. Nunc eu nibh nulla, id cursus arcu.</strong><br />
<em> </em></p>
<p>The post <a href="https://www.digitalurban.org/blog/2013/03/23/the-field-2/">The Field</a> appeared first on <a href="https://www.digitalurban.org">Digital Urban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
