Build a Smart Ultrasonic Distance Scale with Arduino
Build a Smart Distance Scale using Arduino Nano, OLED & Ultrasonic Sensor - perfect for DIY, automation & prototyping with JUSTWAY!
Components and supplies
1
Arduino Nano
1
jumper wires for arduino
1
Ultrasonic Sensor - HC-SR04
1
0.96 OLED display
Apps and platforms
1
Arduino IDE
Project description
Code
Code
c
1// Ultrasonic → SH110x OLED (I2C) Demo 2// Works with SH1106/SH1107 128x64 modules using Adafruit SH110X + GFX 3 4#include <Adafruit_GFX.h> 5#include <Adafruit_SH110X.h> 6#include <Wire.h> 7 8// ===== OLED CONFIG ===== 9#define SCREEN_WIDTH 128 10#define SCREEN_HEIGHT 64 11#define OLED_ADDR 0x3C // Common: 0x3C (sometimes 0x3D) 12 13// For SH1106 (most 128x64 I2C modules): 14Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); 15// If your panel is SH1107, use: 16// Adafruit_SH1107 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); 17 18// ===== ULTRASONIC CONFIG ===== 19// HC-SR04 pins 20const int PIN_TRIG = 9; 21const int PIN_ECHO = 10; 22 23// Measurement params 24const unsigned long ECHO_TIMEOUT_US = 30000UL; // ~5m max (sound one-way ~0.0343 cm/us) 25const uint8_t SAMPLES = 5; // simple moving average 26 27// ===== HELPERS ===== 28float measureDistanceCm() { 29 // Trigger a 10 µs pulse 30 digitalWrite(PIN_TRIG, LOW); 31 delayMicroseconds(2); 32 digitalWrite(PIN_TRIG, HIGH); 33 delayMicroseconds(10); 34 digitalWrite(PIN_TRIG, LOW); 35 36 // Read echo pulse width 37 unsigned long duration = pulseIn(PIN_ECHO, HIGH, ECHO_TIMEOUT_US); 38 if (duration == 0) return NAN; // timeout/no object 39 40 // distance = (duration_us * speed_of_sound_cm_per_us) / 2 41 // speed of sound ≈ 0.0343 cm/us at ~20°C 42 return (duration * 0.0343f) / 2.0f; 43} 44 45float cmToIn(float cm) { 46 return cm * 0.393700787f; 47} 48 49float avgDistanceCm(uint8_t n = SAMPLES) { 50 float sum = 0; 51 uint8_t good = 0; 52 for (uint8_t i = 0; i < n; i++) { 53 float d = measureDistanceCm(); 54 if (!isnan(d)) { sum += d; good++; } 55 delay(20); 56 } 57 if (good == 0) return NAN; 58 return sum / good; 59} 60 61// Draws a horizontal bar (0–maxVal) across the width 62void drawBar(float value, float maxVal) { 63 if (isnan(value) || maxVal <= 0) return; 64 int w = map((int)(value * 100), 0, (int)(maxVal * 100), 0, SCREEN_WIDTH - 4); 65 w = constrain(w, 0, SCREEN_WIDTH - 4); 66 // outline 67 display.drawRect(2, 48, SCREEN_WIDTH - 4, 12, SH110X_WHITE); 68 // fill 69 if (w > 0) display.fillRect(3, 49, w, 10, SH110X_WHITE); 70} 71 72void setup() { 73 pinMode(PIN_TRIG, OUTPUT); 74 pinMode(PIN_ECHO, INPUT); 75 76 Wire.begin(); 77 // For some boards, you may need Wire.setClock(400000); 78 79 display.begin(OLED_ADDR, true); // true = reset 80 display.clearDisplay(); 81 82 display.setTextColor(SH110X_WHITE); 83 display.setTextSize(1); 84 display.setCursor(0, 0); 85 display.println(F("SH110x Ultrasonic")); 86 display.println(F("Initializing...")); 87 display.display(); 88 delay(800); 89} 90 91void loop() { 92 float cm = avgDistanceCm(); 93 float in_ = cmToIn(cm); 94 95 display.clearDisplay(); 96 97 // Title 98 display.setTextSize(1); 99 display.setCursor(0, 0); 100 display.print(F("Ultrasonic Distance")); 101 102 if (isnan(cm)) { 103 display.setCursor(0, 20); 104 display.setTextSize(2); 105 display.println(F("No echo")); 106 display.setTextSize(1); 107 display.setCursor(0, 40); 108 display.println(F("Check wiring/aim")); 109 } else { 110 // Big number (cm) 111 display.setTextSize(2); 112 display.setCursor(0, 18); 113 display.print(cm, 1); 114 display.print(F(" cm")); 115 116 // Smaller line (inches) 117 display.setTextSize(1); 118 display.setCursor(0, 40); 119 display.print(in_, 2); 120 display.println(F(" in")); 121 122 // Bar graph up to a chosen max (e.g., 200 cm) 123 drawBar(cm, 200.0f); 124 } 125 126 display.display(); 127 delay(120); 128}
Comments
Only logged in users can leave comments