Modulino Distance + UNO Q – Proximity Meter
Live Time-of-Flight distance readings stream from the Modulino Distance to the UNO Q with a visual proximity bar that grows as an object gets closer.
Devices & Components
1
Modulino™ Distance
1
Arduino® UNO™ Q 2GB
Software & Tools
Arduino App Lab
Project description
Code
main
python
python main file
1import json 2import os 3 4from arduino.app_utils import App, Bridge 5from arduino.app_bricks.web_ui import WebUI 6 7_ui_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "ui") 8ui = WebUI(assets_dir_path=_ui_dir) 9 10state = {"distance_mm": 0, "in_range": 0} 11 12 13def _call_mcu(method, *args): 14 try: 15 return json.loads(Bridge.call(method, *args)) 16 except Exception as exc: 17 print(f"[bridge] {method} error: {exc}") 18 return None 19 20 21def _broadcast(new_state, room=None): 22 if new_state and "error" not in new_state: 23 state.update(new_state) 24 ui.send_message("state_update", state, room=room) 25 26 27def on_connect(sid): 28 _broadcast(_call_mcu("get_state"), room=sid) 29 30 31def on_distance_reading(distance_mm: int, in_range: int): 32 state["distance_mm"] = distance_mm 33 state["in_range"] = in_range 34 ui.send_message("state_update", state) 35 36 37ui.on_connect(on_connect) 38Bridge.provide("distance_reading", on_distance_reading) 39 40App.run()
sketch
cpp
Arduino sketch
1#include <Arduino_RouterBridge.h> 2#include <Arduino_Modulino.h> 3#include <math.h> 4 5ModulinoDistance distance; 6 7String buildState(int dist_mm, int in_range) { 8 return "{\"distance_mm\": " + String(dist_mm) + 9 ", \"in_range\": " + String(in_range) + "}"; 10} 11 12String rpc_get_state() { 13 distance.available(); 14 float val = distance.get(); 15 int in_range = isnan(val) ? 0 : 1; 16 int dist_mm = in_range ? (int)val : 0; 17 return buildState(dist_mm, in_range); 18} 19 20void setup() { 21 Bridge.begin(); 22 Modulino.begin(); 23 distance.begin(); 24 25 Bridge.provide("get_state", rpc_get_state); 26} 27 28void loop() { 29 if (distance.available()) { 30 float val = distance.get(); 31 int in_range = isnan(val) ? 0 : 1; 32 int dist_mm = in_range ? (int)val : 0; 33 Bridge.notify("distance_reading", dist_mm, in_range); 34 } 35}
index
markup
html file
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Modulino Distance – Proximity Meter</title> 7 <link rel="stylesheet" href="styles.css" /> 8</head> 9<body> 10 <header> 11 <h1>📏 Modulino Distance – Proximity Meter</h1> 12 <span id="status" class="status connecting">Connecting…</span> 13 </header> 14 15 <main> 16 <section class="card readout-card"> 17 <div class="distance-primary" id="distance-primary">— mm</div> 18 <div class="distance-secondary" id="distance-secondary">— cm</div> 19 </section> 20 21 <section class="card"> 22 <h2>Proximity</h2> 23 <div class="bar-track"> 24 <div class="bar-fill" id="bar-fill"></div> 25 </div> 26 <div class="bar-labels"> 27 <span>Far (1300 mm)</span> 28 <span>Close (0 mm)</span> 29 </div> 30 </section> 31 </main> 32 33 <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script> 34 <script src="app.js"></script> 35</body> 36</html>
styles
css
style file
1:root { 2 --bg: #0f1117; 3 --surface: #1c1f2a; 4 --border: #2e3244; 5 --accent: #4fa3e0; 6 --text: #e2e8f0; 7 --muted: #8892a4; 8 --green: #22c55e; 9 --red: #ef4444; 10 --radius: 10px; 11} 12 13* { box-sizing: border-box; margin: 0; padding: 0; } 14 15body { 16 font-family: 'Segoe UI', system-ui, sans-serif; 17 background: var(--bg); 18 color: var(--text); 19 min-height: 100vh; 20 padding: 1rem; 21} 22 23header { 24 display: flex; 25 flex-direction: column; 26 align-items: center; 27 gap: 0.5rem; 28 margin-bottom: 1.5rem; 29 text-align: center; 30} 31 32header h1 { font-size: 1.35rem; letter-spacing: -0.02em; } 33 34.status { 35 font-size: 0.8rem; 36 font-weight: 600; 37 padding: 0.25rem 0.75rem; 38 border-radius: 999px; 39 letter-spacing: 0.04em; 40 text-transform: uppercase; 41} 42 43.status.connected { background: var(--green); color: #fff; } 44.status.disconnected { background: var(--red); color: #fff; } 45.status.connecting { background: var(--muted); color: #fff; } 46 47main { display: flex; flex-direction: column; gap: 1.25rem; } 48 49.card { 50 background: var(--surface); 51 border: 1px solid var(--border); 52 border-radius: var(--radius); 53 padding: 1.25rem 1.5rem; 54} 55 56.card h2 { 57 font-size: 0.95rem; 58 font-weight: 600; 59 color: var(--muted); 60 text-transform: uppercase; 61 letter-spacing: 0.06em; 62 margin-bottom: 1rem; 63} 64 65/* Primary readout card */ 66.readout-card { 67 display: flex; 68 flex-direction: column; 69 align-items: center; 70 gap: 0.4rem; 71 text-align: center; 72} 73 74.distance-primary { 75 font-size: 3.5rem; 76 font-weight: 700; 77 font-variant-numeric: tabular-nums; 78 color: var(--accent); 79 line-height: 1; 80} 81 82.distance-secondary { 83 font-size: 1.1rem; 84 color: var(--muted); 85 font-variant-numeric: tabular-nums; 86} 87 88/* Proximity bar */ 89.bar-track { 90 width: 100%; 91 height: 20px; 92 background: var(--border); 93 border-radius: 999px; 94 overflow: hidden; 95 margin-bottom: 0.5rem; 96} 97 98.bar-fill { 99 height: 100%; 100 width: 0%; 101 background: var(--accent); 102 border-radius: 999px; 103 transition: width 0.2s ease; 104} 105 106.bar-labels { 107 display: flex; 108 justify-content: space-between; 109 font-size: 0.75rem; 110 color: var(--muted); 111} 112 113@media (min-width: 600px) { 114 main { max-width: 700px; margin: 0 auto; } 115}
app
js
Javascript file
1var socket = io(); 2 3var statusEl = document.getElementById("status"); 4var distancePrimary = document.getElementById("distance-primary"); 5var distanceSecondary = document.getElementById("distance-secondary"); 6var barFill = document.getElementById("bar-fill"); 7 8var MAX_RANGE_MM = 1300; 9 10// Connection status 11socket.on("connect", function () { statusEl.className = "status connected"; statusEl.textContent = "● Connected"; }); 12socket.on("disconnect", function () { statusEl.className = "status disconnected"; statusEl.textContent = "● Disconnected"; }); 13socket.on("connect_error", function () { statusEl.className = "status connecting"; statusEl.textContent = "Connecting…"; }); 14 15// State from server 16socket.on("state_update", function (data) { 17 if (data) applyState(data); 18}); 19 20function applyState(state) { 21 if (!state.in_range) { 22 distancePrimary.textContent = "Out of range"; 23 distanceSecondary.textContent = "—"; 24 barFill.style.width = "0%"; 25 return; 26 } 27 28 var mm = state.distance_mm; 29 var cm = (mm / 10).toFixed(1); 30 31 distancePrimary.textContent = mm + " mm"; 32 distanceSecondary.textContent = cm + " cm"; 33 34 // Bar grows as object gets closer: 0 mm → 100%, 1300 mm → 0% 35 var pct = Math.max(0, Math.min(100, (1 - mm / MAX_RANGE_MM) * 100)); 36 barFill.style.width = pct.toFixed(1) + "%"; 37}
Arduino App Lab
Modulino Distance – Proximity Meter
Live Time-of-Flight distance readings with a visual proximity bar.
📏
Modulino Distance – Proximity Meter
Comments
Only logged in users can leave comments