element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
EZ-EV Challenge
  • Challenges & Projects
  • Design Challenges
  • EZ-EV Challenge
  • More
  • Cancel
EZ-EV Challenge
Forum Post 3 Project GEPARD: The Bridge Was Not One Bug
  • News
  • Projects
  • Forum
  • DC
  • Leaderboard
  • Files
  • Members
  • More
  • Cancel
  • New
Join EZ-EV Challenge to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 0 replies
  • Subscribers 59 subscribers
  • Views 29 views
  • Users 0 members are here
Related

Post 3 Project GEPARD: The Bridge Was Not One Bug

UlolKidz
UlolKidz 18 hours ago

How I misunderstood the Arduino UNO Q Bridge three different ways before the architecture finally made sense. 

Special thanks to ralphjy and BigG for taking the time to comment on my original vision post. The significance of your suggestions only became clearer as the project evolved, and they ultimately helped guide me toward the architecture I use today.


You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Sometimes Advice Makes More Sense in Hindsight

When I published my first vision post for Project GEPARD, several members of the Element14 community shared suggestions about how I should approach the software architecture.

One comment suggested looking deeper into the UNO Q Bridge system and the documented examples rather than building a custom communication layer from scratch.

Another highlighted something I had underestimated at the time: the Arduino UNO Q is not simply another Arduino board. It combines a Linux computer and a microcontroller on the same platform, and understanding that distinction is important when designing larger applications.

At the time, those suggestions made sense intellectually, but I had not yet encountered the problems they were trying to help me avoid.

So I continued developing the architecture I had already planned.

For a while, everything seemed to be moving in the right direction. Components came online, code compiled, and individual subsystems appeared to work.

As the project grew, however, the cracks started to appear.

The telemetry architecture became increasingly difficult to reason about.

The control system became harder to debug.

Subsystems that worked independently did not always work together.

Fixing one problem often revealed another.

Eventually I found myself spending more time fighting the architecture than building the rover.

That was when I went back to the documentation, reread the community feedback, studied example projects, and looked more carefully at how the UNO Q was designed to operate.

What I discovered was not that my original ideas were completely wrong.

It was that I was trying to use the UNO Q like a traditional microcontroller platform when it was designed to operate as a dual-processor system.

Once I understood that distinction, several weeks of confusing software issues suddenly started making sense.

This post is about those lessons.

Bridge Issue #1: I Treated It Like a Serial Cable

My original mental model looked something like this:

STM32
↓
Push telemetry
↓
Linux
↓
Dashboard

That seems reasonable.

The microcontroller gathers data and pushes it upward whenever it wants.

That is how I had structured a significant portion of the project.

The UNO Q does not work that way.

The UNO Q Bridge is designed around a request-response model.

The Linux side initiates communication.

The STM32 responds.

Once I finally understood that, the architecture changed from:

Bridge.notify("telemetry", distance, voltage, ticks);

to:

Bridge.provide("get_telemetry", get_telemetry);

and

telemetry = Bridge.call("get_telemetry")

The difference sounds tiny.

The impact was enormous.

Instead of trying to continuously push data upward, the Linux side now requests data when it actually needs it.

That immediately simplified the entire system.

Bridge Issue #2: The Motors Worked in the Test Sketch but Not in the Real Firmware

At one point I had a very confusing problem.

The motors worked perfectly.

Until they didn't.

My simple diagnostic sketch spun the wheels every time.

My "real" firmware did not.

From the outside that sounds like a wiring issue.

It wasn't.

The multimeter eventually gave me the answer:

VM = 10.97 V
STBY = 3.3 V
PWMA = 0 V

The motor driver had power.

The standby pin was enabled.

The PWM signal simply never existed.

That pointed directly at the software stack.

The root cause turned out to be a combination of:

  • Incorrect Bridge architecture
  • Telemetry logic
  • A safety override that was stopping forward motion

Ironically, my safety feature was preventing me from proving the motors worked.

Once I removed the unnecessary override and rebuilt the communication architecture around proper Bridge calls, the motors came back to life.

Bridge Issue #3: Not All Providers Are Equal

This one took me much longer to understand.

I originally treated these as interchangeable:

Bridge.provide(...)

and

Bridge.provide_safe(...)

They are not.

The distinction matters.

Functions that touch hardware:

digitalWrite(...)

analogWrite(...)

should use:

Bridge.provide_safe(...)

Examples:

set_drive()
set_estop()
test_module()

These affect the physical world.

Motors move.

Sensors trigger.

Pins change state.

Those belong in the safe execution context.

On the other hand:

get_telemetry()

should ideally be a read-only operation.

That means it can use:

Bridge.provide(...)


if it remains short and thread-safe.

That led directly into the next mistake.

Bridge Issue #4: My Telemetry Function Wasn't Actually Read-Only

I thought this function was simple:

get_telemetry()

It wasn't.

Inside it I was:

  • Triggering ultrasonic pulses
  • Reading I2C sensors
  • Waiting on pulse timing
  • Accessing hardware directly

Which meant the function wasn't actually just returning telemetry.

It was collecting telemetry on demand.

That sounds harmless until you realize the ultrasonic routine alone can block for milliseconds.

The fix was to separate two jobs.

Instead of:

Request → Read Sensors → Return

I moved to:

Loop()
↓

Sample everything continuously
↓
Cache data
get_telemetry()
↓
Return cached copy

Now the microcontroller continuously updates a telemetry cache and the Bridge simply serves the latest values.

The function became short.

Predictable.

Thread-safe.

And much easier to reason about.

The Surprise Bug: The Sketch Wasn't Even the Main Problem

At one point I became convinced the firmware itself was broken.

But after rebuilding the project structure I discovered that many issues were actually App Lab configuration problems.

Things that changed included:

Old Architecture

Laptop application
UDP transport
Custom dashboard
Mixed project structure

New Architecture

UNO Q Linux application

Official WebUI Brick
Bridge RPC
App Lab project structure

I also discovered things like:

  • Project structure matters more than I thought.
  • UNO Q examples assume a specific layout.
  • The WebUI Brick was solving problems I was manually creating.
  • I was fighting the platform instead of using it.

That was a humbling realization.

The Comment I Should Have Listened To

Looking back, the most frustrating part is that several people had effectively pointed me toward the solution weeks earlier.

Not the exact solution.

But the correct direction.

I had not yet encountered the problems that made those suggestions valuable.

I tend to learn in a very stubborn way:

  1. Build the thing.
  2. Assume the thing should work.
  3. Watch it fail.
  4. Spend hours troubleshooting.
  5. Finally accept that the original assumption was wrong.
  6. Open the documentation.

I joke about it, but Project GEPARD has forced me to become better at step 6.

The Architecture We Settled On

After all of the redesigns, experimentation, broken assumptions, and late-night troubleshooting sessions, the architecture finally became simple.

Browser HUD
│
▼
UNO Q Linux (Brain)
│
Bridge.call()
│
▼
STM32 (Spine)
│
▼
Motors, sensors, hardware

The responsibilities are now clear.

The Spine (STM32)

  • Reads sensors
  • Controls motors
  • Handles hardware timing
  • Provides telemetry

The Brain (Linux)

  • Collects telemetry
  • Hosts the WebUI dashboard
  • Runs autonomy logic
  • Interfaces with future AI systems

The Browser

  • Displays the tactical HUD
  • Shows telemetry
  • Sends commands
  • Works from a laptop or phone

The architecture finally matches the way the UNO Q was designed to work.

Current Status

White check mark Motors responding

White check mark Bridge architecture redesigned

White check mark WebUI architecture established

White check mark Ultrasonic testing functional

White check mark Individual subsystem testing implemented

White check mark Brain / spine architecture finalized

Warning️ INA226 still being validated

Warning️ MPU6050 still being validated

Warning️ Encoder tuning still required

Wrench Final assembly underway

Final Thoughts

I think one of the most important lessons from this challenge is that being wrong is not the problem.

Staying wrong is.

The UNO Q Bridge was not one bug.

It was a chain of misunderstandings:

  • Wrong communication model
  • Wrong assumptions about providers
  • Wrong telemetry strategy
  • Wrong project architecture

Each fix revealed the next problem underneath it.

And honestly, that is probably the most realistic description of engineering I can give.

You don't usually solve the problem.

You solve enough problems that eventually only the real problem remains.

More soon.

The Bridge works. Mostly. Rocket


  • Sign in to reply
  • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube