Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Hackaday Europe 2026: Project Gigapixel

20 July 2026 at 13:05

There was once a race to put out cameras with ever higher numbers of megapixels to snare customers eager to take the highest quality digital photos. These days, we know that things like optics, processing, and finer qualities of an image sensor are all very important beyond pure resolution. But, for a time, companies behaved as if megapixels mattered over all else.

But what if you could go farther—shooting not millions, but billions of pixels in a single image? That’s precisely what [Yannick Richter] came to Hackaday Europe to talk about, covering his Project Gigapixel build.

More Pixels

When it comes to building a consumer camera with higher resolution, manufacturers achieve this by creating an image sensor with a greater number of sensing elements. This, of course, can get expensive and difficult the farther you want to scale, particularly if you’re trying to fit more sensing elements into a given standard sensor size.

A scanner sensor has great linear resolution. Pan one behind a high-quality lens, and you can capture images in super high resolution… just hope that nothing moves while you’re capturing a shot!

However, there are other ways to capture images in greater resolution that don’t require a larger image sensor. Namely, you can actually use quite a simple image sensor of limited resolution, and simply move it to various positions, capturing light all the while. Then, all you need to do is stitch the output together and you have a remarkably high resolution image. It might sound complicated, but as [Yannick] explains, it’s a perfectly cromulent way to build a gigapixel image.

[Yannick’s] project began with an old Epson flatbed scanner. This made the perfect donor for such a project, as it came with a linear image sensor with quite good resolution for scanning photographs and documents. The only problem is that it needs to move in a straight path in order to capture a full image. The goal was to build it into a scanner-style camera that was truly portable, which required some reverse engineering and creative design to make it into a practical tool for real-world photography. [Yannick] didn’t want to just stuff the existing scanner in a bodged-together camera body, either. He wanted to interface the sensor directly and build a custom linear-scanning camera from the ground up, with the high-resolution linear sensor mounted behind a nice medium-format Pentax lens.

[Yannick] lashed up a Raspberry Pi to read from the sensor.
The key was that the scanner in question—an Epson V370—used a Sony CCD scanning element, rather than a cheaper CIS element. A proper CCD sensor is more expensive, but produces better output, and is more suitable for the sort of imaging [Yannick] was trying to do with this build. Namely, by running the scanning element behind a medium format lens to capture incredibly high-resolution images at up to 40800 x 80000 pixels, or 3.2 gigapixels if you multiply it out.

The talk covers all the work that [Yannick] did to make this a fully functional camera. That included doing a deep dive into Epson documentation to figure out how to interface the sensor at all. Thankfully, service manuals provided enough detail on how the 12-line RGB sensor works to get the project over the line. Interfacing the sensor was achieved via reusing the ADC and timing generation hardware from the scanner itself, hooked up to a Raspberry Pi 5 and a RP2350.

Plenty of work was required to figure out how to properly offset all the R, G, and B pixels to line up properly into a coherent color image. [Yannick] also dives into the mechanical design, regarding how the sensor was assembled on a 100-millimeter linear drive to scan it behind the lens assembly to capture images. There were also issues generating a live preview that you’d get on any other digital camera, which is not exactly practical to generate from a scanning image sensor. Instead, a standard Raspberry Pi camera was included in the build for live preview to help with lining up a shot.

The camera is capable of taking incredibly high resolution images with rich detail. Of course, image sizes are hefty in turn.

Perhaps the best part of the talk is when [Yannick] shows off the final results. The simple fact is that 3.2 gigapixel images capture a ton of detail when they’re taken well and focused correctly. A simple shot of some benchtop instruments doesn’t look like anything special, until [Yannick] shows that cropping in will let you read the codes off a 0603 SMD resistor. Obviously, the camera is limited when it comes to speed and it can’t really capture moving objects well. However, when it comes to grabbing very high resolution shots of still scenes, it’s a great performer. If taking gorgeously detailed landscapes or stunning architectural shots is your thing, you might find such a build an appealing proposition for your own needs.

Hackaday Europe 2026 – Build A Cable Modem For Your Arduino

16 July 2026 at 10:02

Even for those of us that are quite technically minded, we spend precious little time thinking about the cables that carry our signals and do all the important work we need them to do on a daily basis. A great deal of theory and engineering goes into making things like telephone lines and HDMI cables work, but we mostly just plug them in and get on with whatever we’re doing.

If this is your experience, you might find the Hackaday Europe talk from [Michael Wiebusch] to be particularly interesting. He dives into transmission line theory from an accessible standpoint, explaining how two disparate signals can go in opposite directions on the very same wire. Then he demonstrates the theory by building a cable modem… well, sort of!

Signal

Michael begins his talk by discussing the Telegrapher’s Equation, but only as a fakeout. Given the limited time on offer, he decided a quicker, easier explanation of the physics involved would be more appropriate. Key to this was explaining the difference between cables and transmission lines. To create a true transmission line, by his definition, he explains that there is a necessity to have two conductors that are relatively close together. Such a transmission line is effectively a distributed network of inductances and capacitances all the way down, though often we talk about “lossless” transmission lines for modelling purposes. He also covers the point of coaxial cables, wherein one conductor is wrapped around another to shield a signal from external noise, and to prevent signal from leaking out.

Transmission lines allow signals to pass in opposing directions, much like ripples on a pond will pass through each other, retaining their form. Credit: talk slides

There are several basic facts to remember about transmission lines. They are fundamentally just channels down which EM signals can travel. It’s also good to remember that they delay signals. To a human, the signal may appear to travel instantaneously, but it does take time. This also has other impacts; for example, coax cables are filled with plastic, a material in which the speed of light is roughly 66% of the speed of light in a vacuum.

This slows the rate at which the field of an EM signal can travel to this fundamental limit. [Michael] also notes that transmission lines, as a wave medium, essentially allow waves travelling in different directions to pass each other, much like ripples spreading on the surface of a pond. This is why it’s possible to have bidirectional communication on a single transmission line. It’s also important to terminate a transmission line properly, such that the wave you’re transmitting down it ends where you want it to—at the receiver. Fail to terminate your transmission line, and you’ll have that wave bouncing back and forth which is undesirable for clear transmission.

The coupler allows sending and receiving signals via a single transmission line. Credit: talk slides

[Michael] demonstrates basic transmission line theory by building a sort of cable modem out of an Arduino and some supporting hardware. He notes it’s not really a modem—there is no modulation or demodulation going on. Instead, he’s simply squirting TTL signals into either end of a cable and receiving them on the other end. The “black box” that couples the signals into and out of the transmission line is a simple directional coupler. Built out of resistors and an op-amp, it allows sending a signal down a transmission line, as well as receiving a signal coming the other way. The design works all the way down to DC logic level signals, which let [Michael] use it to send TTL signals up and down 50-ohm and 75-ohm coaxial cables. He notes this has very obvious practical applications where it’s desirable to reduce cable counts when sending signals in multiple directions, relating this directly to his professional work on science experiments.

If you’ve ever wanted to get two devices talking over a single cable in a relatively easy fashion, then [Michael’s] talk may be valuable to you. At the very least, it’s a great way to learn some of the basics of transmission lines and better understand what’s going on when you shoot a signal down a random bit of wire. It’s all good stuff.

How I Built a Hedge-Fund Grade Macro Scanner for Pacifica Exchange

By: SKYFOR
14 July 2026 at 11:22

Hey everyone. If you’ve been trading crypto long enough, you know the harsh reality: technical analysis alone just doesn’t cut it anymore. You can have the most beautiful MACD crossover or RSI divergence, but if J-Powell sneezes at a press conference or some geopolitical drama kicks off, your technical setup gets completely invalidated in seconds.

I’ve been exploring the Pacifica Exchange recently, especially their new global situation and macro tracking dashboards. It got me thinking: what if I could build a custom terminal that inherently correlates technical chart data with real-world macro events?

So, I spent the weekend building exactly that. I call it the Pacifica Super Scanner. Here’s how I built it and how you can do something similar.

The Architecture: Layer 2 vs. Layer 3

To make this work, I split the bot’s logic into two distinct brains:

Layer 2: The Technical Engine

This is your standard quant stuff. I wrote a Python script that hooks directly into Pacifica’s REST API (`https://api.pacifica.fi/api/v1`). It pulls the top 50 active perpetual markets and downloads the historical klines (candles) for the 1D, 4H, and 1H timeframes.

I wrote custom functions to calculate RSI, EMAs, ATR (for dynamic stop losses), and MACD. The trick here is Multi-Timeframe (MTF) confirmation. A 1H breakout is noise; a 1H breakout backed by a 4H and 1D bullish trend is a high-probability setup.

import sys
import time
import json
import os
import requests
from datetime import datetime
from colorama import init, Fore, Style, Back

# Import Layer 3 Macro Engine
from macro_engine import MacroEngine

# Initialize colorama for Windows terminal
init(autoreset=True)

PACIFICA_API = "https://api.pacifica.fi/api/v1"
TOP_N = 50

def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')

def get(url, params=None):
try:
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()
return r.json()
except Exception as e:
return None

# ==========================================
# LAYER 2: TA FUNCTIONS
# ==========================================
def calc_rsi(closes, p=14):
if len(closes) < p + 1: return 50.0
d = [closes[i] - closes[i - 1] for i in range(1, len(closes))]
ag = sum(max(x, 0) for x in d[:p]) / p
al = sum(abs(min(x, 0)) for x in d[:p]) / p
for x in d[p:]:
ag = (ag * (p - 1) + max(x, 0)) / p
al = (al * (p - 1) + abs(min(x, 0))) / p
return round(100.0 if al == 0 else 100 - 100 / (1 + ag / al), 1)

def calc_ema(prices, p):
if len(prices) < p: return [prices[-1]] if prices else [0]
k = 2 / (p + 1)
out = [sum(prices[:p]) / p]
for v in prices[p:]:
out.append(v * k + out[-1] * (1 - k))
return out

def calc_atr(klines, p=14):
if len(klines) < p + 1: return 0.0
trs = []
for i in range(1, len(klines)):
h, l, pc = float(klines[i]['h']), float(klines[i]['l']), float(klines[i-1]['c'])
trs.append(max(h - l, abs(h - pc), abs(l - pc)))
avg = sum(trs[:p]) / p
for t in trs[p:]:
avg = (avg * (p - 1) + t) / p
return avg

def calc_macd(closes):
if len(closes) < 26: return 0.0, 0.0, False
e12 = calc_ema(closes, 12)
e26 = calc_ema(closes, 26)
diff = len(e12) - len(e26)
ml = [e12[diff + i] - e26[i] for i in range(len(e26))]
sig = calc_ema(ml, 9) if len(ml) >= 9 else [ml[-1]]
return ml[-1], sig[-1], ml[-1] > sig[-1]

def analyze_klines(klines):
if len(klines) < 30:
return {"score": 0, "rsi": 50, "trend": "MIXED", "macd_bull": False, "atr": 0, "signals": []}

closes = [float(k['c']) for k in klines]
cur = closes[-1]
rsi = calc_rsi(closes)
e20 = calc_ema(closes, 20)[-1]
e50 = calc_ema(closes, 50)[-1] if len(closes) >= 50 else e20
e200 = calc_ema(closes, 200)[-1] if len(closes) >= 200 else e20
atr_v = calc_atr(klines)
_, _, mb = calc_macd(closes)

score = 0
sigs = []

if rsi < 30: score += 2; sigs.append("RSI Oversold")
elif rsi < 45: score += 1; sigs.append("RSI Buy Zone")
elif rsi > 70: score -= 2; sigs.append("RSI Overbought")
elif rsi > 55: score -= 1; sigs.append("RSI Weak")

if e20 > e50: score += 1; sigs.append("EMA20>50")
else: score -= 1; sigs.append("EMA20<50")

if cur > e200: score += 1; sigs.append(">EMA200")
else: score -= 1; sigs.append("<EMA200")

if mb: score += 1; sigs.append("MACD Bull")
else: score -= 1; sigs.append("MACD Bear")

if e20 > e50 and cur > e200: trend = "BULLISH"
elif e20 < e50 and cur < e200: trend = "BEARISH"
else: trend = "MIXED"

return {"score": max(-5, min(5, score)), "rsi": rsi, "trend": trend, "macd_bull": mb, "atr": atr_v, "signals": sigs, "price": cur}

# ==========================================
# DATA COLLECTION
# ==========================================
def fetch_klines(symbol, interval, lookback_days):
start_time = int((time.time() - (86400 * lookback_days)) * 1000)
data = get(f"{PACIFICA_API}/kline", {"symbol": symbol, "interval": interval, "start_time": start_time})
if data and data.get('success') and 'data' in data:
return data['data']
return []

def get_mtf(symbol):
result = {}
intervals = [("1d", 150), ("4h", 30), ("1h", 10)]

for tf, days in intervals:
kl = fetch_klines(symbol, tf, days)
result[tf] = analyze_klines(kl)
time.sleep(0.1)

scores = [result[tf]["score"] for tf in ["1d", "4h", "1h"] if result[tf]]
avg = sum(scores) / len(scores) if scores else 0
all_bull = len(scores) == 3 and all(s > 0 for s in scores)
all_bear = len(scores) == 3 and all(s < 0 for s in scores)

result["mtf_score"] = round(avg, 1)
result["triple_confirm"] = "BULL" if all_bull else "BEAR" if all_bear else None

if all_bull: result["mtf_score"] += 1
if all_bear: result["mtf_score"] -= 1

return result

# ==========================================
# UI & VISUALIZATION
# ==========================================
def print_header(macro_data):
print(Fore.CYAN + Style.BRIGHT + "+============================================================+")
print(Fore.CYAN + Style.BRIGHT + "|" + Fore.WHITE + " PACIFICA SUPER SCANNER : ACTIVE " + Fore.CYAN + Style.BRIGHT + "|")
print(Fore.CYAN + Style.BRIGHT + "|" + Fore.CYAN + " [ Multi-Timeframe Algorithmic Analysis ] " + Fore.CYAN + Style.BRIGHT + "|")
print(Fore.CYAN + Style.BRIGHT + "+============================================================+")

# LAYER 3 UI BLOCK
bias_color = Fore.GREEN if macro_data['bias'] == 'BULLISH' else Fore.RED if macro_data['bias'] == 'BEARISH' else Fore.YELLOW
risk_color = Fore.RED if macro_data['risk_index'] > 60 else Fore.YELLOW if macro_data['risk_index'] > 40 else Fore.GREEN

print(Fore.MAGENTA + Style.BRIGHT + "| [LAYER 3] GLOBAL SITUATION & MACRO ENGINE |")
print(Fore.MAGENTA + "+------------------------------------------------------------+")
print(Fore.MAGENTA + "| " + Fore.WHITE + f"Global Bias : " + bias_color + Style.BRIGHT + f"{macro_data['bias']:<43}" + Fore.MAGENTA + "|")
print(Fore.MAGENTA + "| " + Fore.WHITE + f"Risk Index : " + risk_color + f"{macro_data['risk_index']}/100" + " " * (39 - len(str(macro_data['risk_index']))) + Fore.MAGENTA + "|")
print(Fore.MAGENTA + "| " + Fore.WHITE + f"Fear & Greed : " + Fore.YELLOW + f"{macro_data['fng']} ({macro_data['fng_class']})" + " " * (33 - len(str(macro_data['fng'])) - len(macro_data['fng_class'])) + Fore.MAGENTA + "|")
print(Fore.MAGENTA + "| " + Fore.WHITE + f"Live Headlines:" + " " * 43 + Fore.MAGENTA + "|")
for i, h in enumerate(macro_data['headlines'][:2]): # Show top 2
text = (h[:54] + '..') if len(h) > 54 else h
print(Fore.MAGENTA + "| " + Fore.WHITE + f" > {text:<54}" + Fore.MAGENTA + "|")
print(Fore.MAGENTA + "+============================================================+\n")

def print_signal(coin, macro_data):
score = coin['mtf_score']

# Layer 2 Technical Direction
if score > 1.5: direction = "LONG"; color = Fore.GREEN; bg = Back.GREEN
elif score < -1.5: direction = "SHORT"; color = Fore.RED; bg = Back.RED
else: return

# LAYER 3 MODIFICATION LOGIC
macro_bias = macro_data['bias']
risk_index = macro_data['risk_index']

macro_conf = "Layer 3 Neutral"
conf_color = Fore.YELLOW

if direction == "LONG":
if macro_bias == "BULLISH" and risk_index < 50:
macro_conf = "+++ L3 ULTRA CONFIRMATION +++"
conf_color = Fore.GREEN
bg = Back.GREEN + Style.BRIGHT
elif macro_bias == "BEARISH" or risk_index > 65:
macro_conf = "!!! L3 MACRO DANGER: REDUCE RISK !!!"
conf_color = Fore.RED
bg = Back.YELLOW + Fore.BLACK # Warning state

elif direction == "SHORT":
if macro_bias == "BEARISH":
macro_conf = "+++ L3 ULTRA CONFIRMATION +++"
conf_color = Fore.GREEN
elif macro_bias == "BULLISH":
macro_conf = "!!! L3 MACRO DANGER: AVOID SHORT !!!"
conf_color = Fore.RED
bg = Back.YELLOW + Fore.BLACK

ta = coin['data'].get("1d", {})
price = ta.get('price', 0)
atr = ta.get('atr', price * 0.02) if ta.get('atr') else price * 0.02

sl = price - (atr * 1.5) if direction == "LONG" else price + (atr * 1.5)
tp = price + (atr * 3.0) if direction == "LONG" else price - (atr * 3.0)

reasons = " + ".join(ta.get('signals', [])[:3])

print(Fore.CYAN + "+------------------------------------------------------------+")
print(Fore.CYAN + "| " + Fore.WHITE + f"TARGET ASSET: {coin['symbol']:<45}" + Fore.CYAN + "|")
print(Fore.CYAN + "+------------------------------------------------------------+")
print(Fore.CYAN + "| " + Fore.WHITE + f"Current Price : " + Fore.YELLOW + f"${price:<41.4f}" + Fore.CYAN + "|")
print(Fore.CYAN + "| " + Fore.WHITE + f"MTF Score : " + color + f"{score:<41}" + Fore.CYAN + "|")
print(Fore.CYAN + "+------------------------------------------------------------+")

signal_box = bg + f" {direction} " + Style.RESET_ALL
print(Fore.CYAN + "| " + Fore.WHITE + f"SIGNAL : {signal_box:<53}" + Fore.CYAN + "|")
print(Fore.CYAN + "| " + Fore.WHITE + f"TA REASON : {reasons:<53}" + Fore.CYAN + "|")
print(Fore.CYAN + "| " + Fore.WHITE + f"MACRO FILTER : {conf_color}{macro_conf:<53}" + Fore.CYAN + "|")
print(Fore.CYAN + "+------------------------------------------------------------+")
print(Fore.CYAN + "| " + Fore.WHITE + f"SUGGESTED SL : " + Fore.MAGENTA + f"${sl:<19.4f} " + Fore.WHITE + f"TP : " + Fore.GREEN + f"${tp:<16.4f}" + Fore.CYAN + "|")
print(Fore.CYAN + "+------------------------------------------------------------+\n")

def main():
clear_screen()
print(Fore.CYAN + "[*] Initializing Layer 3 Macro Engine...")

try:
macro = MacroEngine()
macro_data = macro.analyze_global_situation()
except Exception as e:
print(Fore.RED + f"[-] Macro Engine offline: {e}. Defaulting to Neutral.")
macro_data = {"bias": "NEUTRAL", "risk_index": 50, "fng": 50, "fng_class": "Neutral", "headlines": ["Offline"]}

clear_screen()
print_header(macro_data)

print(Fore.CYAN + "[*] Fetching active markets from Pacifica API...")
info_req = get(f"{PACIFICA_API}/info")

if not info_req or not info_req.get('success'):
print(Fore.RED + "[ERROR] Failed to connect to Pacifica API.")
input("\nPress Enter to exit...")
return

all_markets = info_req.get('data', [])
symbols = [m['symbol'] for m in all_markets if m.get('instrument_type') == 'perpetual'][:TOP_N]

print(Fore.CYAN + f"[*] Found {len(symbols)} perpetual markets. Analyzing Top {TOP_N}...")

results = []
total = len(symbols)

for idx, sym in enumerate(symbols):
sys.stdout.write(Fore.WHITE + f"\rScanning [{idx+1}/{total}] : {sym:<10}")
sys.stdout.flush()

mtf_data = get_mtf(sym)
results.append({
"symbol": sym,
"mtf_score": mtf_data.get("mtf_score", 0),
"data": mtf_data
})

print(Fore.GREEN + "\n[*] Scan Complete! Routing signals through Macro Engine...\n")

results.sort(key=lambda x: abs(x['mtf_score']), reverse=True)

signals_found = 0
for res in results[:10]:
if abs(res['mtf_score']) > 1.5:
print_signal(res, macro_data)
signals_found += 1

if signals_found == 0:
print(Fore.YELLOW + "[-] No strong setups detected across MTF at this time.")

print(Fore.CYAN + Style.BRIGHT + ">>>" + Fore.WHITE + " [SCAN FINISHED] " + Fore.CYAN + Style.BRIGHT + "<<<")
input(Fore.WHITE + "\nPress Enter to exit...")

if __name__ == "__main__":
main()

Layer 3: The Macro & Fundamental Engine

This is where things get interesting. I wanted the bot to mimic Pacifica’s “Global Situation” dashboard. I built a standalone `macro_engine.py` that does three things:

1. Live News NLP: It pulls RSS feeds from major crypto news outlets and runs them through `TextBlob` for real-time sentiment analysis.

2. Geopolitical Risk Index: It scans live headlines for trigger words (“war”, “SEC”, “inflation”, “CPI”, “crash”). Based on keyword density, it generates a live Risk Index from 0 to 100.

3. Liquidity Check: It pulls the global Fear & Greed Index to gauge retail liquidity.

import requests
import re
from textblob import TextBlob
from colorama import Fore

class MacroEngine:
def __init__(self):
self.news_sources = [
"https://cointelegraph.com/rss",
"https://decrypt.co/feed"
]
self.risk_keywords = [
"war", "conflict", "strike", "nuclear", "hack", "ban", "lawsuit",
"fed", "rate", "inflation", "cpi", "crash", "sec", "investigation"
]
self.bull_keywords = [
"etf", "inflow", "adoption", "approval", "surge", "breakout",
"bull", "mint", "reserves"
]

def fetch_rss_headlines(self):
headlines = []
for url in self.news_sources:
try:
r = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=5)
if r.status_code == 200:
txt = r.text
t = re.findall(r"<title><!\[CDATA\[(.*?)\]\]></title>", txt)
if not t:
t = re.findall(r"<title>(.*?)</title>", txt, re.DOTALL)
headlines.extend([x.strip() for x in t[1:10]]) # Skip main title, get 9 items
except:
pass
return headlines

def get_fng_index(self):
try:
r = requests.get("https://api.alternative.me/fng/?limit=1", timeout=5)
if r.status_code == 200:
data = r.json().get("data", [])
if data:
return int(data[0]["value"]), data[0]["value_classification"]
except:
pass
return 50, "Neutral"

def analyze_global_situation(self):
headlines = self.fetch_rss_headlines()
if not headlines:
headlines = ["Global news feeds currently unavailable."]

# Sentiment Analysis
pols = [TextBlob(h).sentiment.polarity for h in headlines]
avg_pol = sum(pols) / len(pols) if pols else 0.0

# Keyword Risk Analysis
all_text = " ".join(headlines).lower()
risk_hits = sum(1 for w in self.risk_keywords if w in all_text)
bull_hits = sum(1 for w in self.bull_keywords if w in all_text)

# Calculate Global Risk Index (0-100)
base_risk = 30 # Default baseline
risk_index = min(100, base_risk + (risk_hits * 15) - (bull_hits * 5))
risk_index = max(0, risk_index) # Floor at 0

# FNG
fng_val, fng_class = self.get_fng_index()

# Determine Overall Macro Bias
bias = "NEUTRAL"
if avg_pol > 0.15 and fng_val > 55 and risk_index < 50:
bias = "BULLISH"
elif avg_pol < -0.1 or risk_index > 75 or fng_val < 40:
bias = "BEARISH"

return {
"headlines": headlines[:3], # Top 3 for display
"sentiment": avg_pol,
"risk_index": risk_index,
"fng": fng_val,
"fng_class": fng_class,
"bias": bias
}

if __name__ == "__main__":
engine = MacroEngine()
res = engine.analyze_global_situation()
print("--- PACIFICA GLOBAL SITUATION ---")
print(f"Bias: {res['bias']}")
print(f"Risk Index: {res['risk_index']}/100")
print(f"Fear/Greed: {res['fng']} ({res['fng_class']})")
print(f"Sentiment: {res['sentiment']:.2f}")
print("Top News:")
for h in res['headlines']:
print(f" - {h}")

Bringing It All Together

The magic happens when Layer 2 and Layer 3 talk to each other.

Let’s say Pacifica’s API data shows a massive volume breakout on `$SOL`. The Layer 2 engine flags it as a `STRONG LONG`.

Normally, a basic bot would just execute the trade. But my Super Scanner passes that signal to Layer 3 first.

If Layer 3 detects a high Risk Index (e.g., bad inflation data just dropped), it slaps a warning on the trade: `!!! L3 MACRO DANGER: REDUCE RISK !!!`.

If the macro background is bullish, it upgrades the signal to `+++ L3 ULTRA CONFIRMATION +++`.

The Result

I built the UI directly in the terminal using Python’s `colorama` library because, let’s be honest, nothing feels cooler than a dark terminal spitting out colored quantitative data.

It scans 50 coins, cross-references them with global geopolitical risk, calculates dynamic Stop Losses and Take Profits based on ATR, and prints the top 10 best setups — all in about 15 seconds.

If you are building your own tools, here is a piece of advice: Combine your custom API scripts with Pacifica’s native AI tools for maximum alpha. The exchange’s infrastructure is incredibly fast, and their focus on providing macro-level data natively makes it a playground for quants.

I won’t be dropping the full source code just yet (a man has to protect his edge, right?), but the logic is there for you to build your own.

See you on the order books. ✌️

📣 Ready to trade smarter?
app Docs: 👉 Twitter: @pacifica_fi 👉 Discord
Team: @_guynemer @ConstanceWaing @pacifica_intern

P.S First and foremost I’m obligated to disclose that none of this is investment advice, everything I state in this article are my opinions only and actions that I personally take in hopes of achieving certain results. Investments in cryptocurrencies are risky and results are not guarantee


How I Built a Hedge-Fund Grade Macro Scanner for Pacifica Exchange was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.

Ultra-Long Range Flights To Ease Australian Air Travel

6 July 2026 at 13:00

Pity the poor Australians. Isolated on a jagged hunk of land far from everywhere else, these industrious people have to take two-legged flights (or more) to reach a great many destinations in the northern hemisphere. It’s expensive, time consuming, and makes planning a trip a complete headache when wars break out around popular hub airports.

One airline is trying to solve this problem. The nation’s flag carrier, Qantas, has been hard at work on Project Sunrise. The goal is to run some of the longest non-stop commercial passenger flights ever, with great effort going into solving the technical and economic challenges involved.

No Stops

When travelling from Australia’s major capital cities, flights to destinations like London, the rest of Europe, or the US, all involve stopovers in intermediate airports along the way. A great many routes stop in Dubai or Qatar, while others transit through Hong Kong, Singapore, or Thailand. The need for stopovers complicates air travel for the passenger, particularly when delays cause missed connections or baggage gets lost from one flight to another. It can also just be tedious—sometimes a stopover can last 10 hours or more, which is an incredibly uncomfortable amount of time to spend in even the nicest airport. The reason behind stopovers is simple enough—the average commercial airliner just doesn’t have the fuel range to haul many hundreds of passengers from Australia to Europe in a single hop.

Qantas has formerly run long-range routes with Boeing 787-9 aircraft, but they lack the legs to make it from east-coast capitals to major international destinations. Credit: Qantas media resources

Qantas has been trying to improve Australia’s passenger airline links for quite some time by finding ways to eliminate these tedious stopovers entirely. Thus was born Project Sunrise, which hoped to find more direct routes between popular world cities and suitable airliners that could fly those routes without stopping.

An early 2019 test flight probed the practicality of flying from New York to Sydney in a single hop. Due to the limitations of contemporary aircraft, sacrifices were made to get the flight over the line. Where the Boeing 787-9 would normally carry up to 280 passengers, the test flight would only haul 40 to save weight, and thus save fuel. No cargo was on board, and the tanks were brimmed to ensure maximum range was available. Even then, the 16,250 km route was considered to be at 115% of the plane’s normal range, and there was only 90 minutes of contingency  when it came to fuel onboard if something went awry. Despite the challenges, the test was a success, and provided useful learnings on how to handle things like crew fatigue on a 19-hour continuous flight.

Qantas was also experimenting with practical revenue services at this time, too. In 2018, the airline had established a direct route from Perth to London, flying the Boeing 787-9 in a 236-seat configuration. Flying the 14,484-kilometer route was just within the practical range of the aircraft. It was a useful route that made travel easier for passengers departing Australia’s west coast, but far from the golden ideal of allowing direct flights to major international destinations from the major capitals of Melbourne and Sydney. The route has also since fell victim to geopolitical strife, as the Iran War shut down large swathes of airspace in early 2026. Qantas was forced to alter its flight paths, which added 30 to 45 minutes to the usual flight time—just enough to tip the route over the practical limitations of the aircraft’s range.

Future Goals

However, the crowing achievement of Project Sunrise is still yet to come. 39% of Australia’s population is concentrated in Sydney and Melbourne alone, with both capitals situated on the country’s east coast. It would be most advantageous from a business perspective for these cities to have direct links to major world destinations, and it would benefit the broadest swathe of Qantas’s customer base. Only, the problem comes back to geography, with these two capitals being over 16,000 kilometers from popular destinations like New York and London.

Aviation Photographer London - Stuart Bailey Photography
The A350-1000ULR is key to Qantas’s efforts to launch non-stop services to far-flung destinations. Picture Credit: Stuart Bailey, via Qantas media resources

Qantas has risen to the challenge, regardless. The airline challenged both Boeing and Airbus to develop aircraft intended to fly routes from Sydney, Melbourne, and Brisbane, to destinations like New York, London, Cape Town, Paris, and Rio de Janeiro. This was later whittled down to a narrower focus on the Sydney to New York and Sydney to London routes. Airbus would come out victorious, with Qantas ordering twelve examples of the Airbus A350-1000ULR. The specially-configured model features an additional rear centre fuel tank and a higher maximum take-off weight in order to fly routes up to 22 hours non-stop, along with a reduced seat configuration serving just 238 passengers. The extra range makes for a huge difference compared to more conventional routes out of Australia, which often pair two flights up to 14 hours each. The extra range of the new aircraft saves passengers both hours of flight time, along with the hours normally spent sitting around on layover in a hub airport along the way.

The new aircraft has been undertaking test flights ahead of a planned 2027 launch of revenue services. Credit: Qantas media resources

A typical flight from Sydney to New York or Sydney to London is expected to take 19 to 22 hours. The no-stop nature of the route will enable 99% of Australians to access either destination either direct, or with one-stop—such as by flying in from another major capital on a domestic flight. The flights are expected to run with a higher-than-usual ratio of premium seats, based on the expected demand for these services.

The main thing holding back the new service is aircraft delivery. Production is underway in earnest, with the first A350-1000ULR to be delivered in April 2027. Daily non-stop flights between Sydney and London will begin from October 2027, with tickets to be on sale from February.

Aircraft cabins will be optimized to have more space and amenity to keep passengers comfortable on ultra-long-range routes.

The new Project Sunrise services will be a gamechanger for many people travelling to and from Sydney, and other Australian capitals. It will relieve a major pain point—layovers—that have become a dreaded fact of life for Australians headed far abroad. It will still perhaps be some time before Australians get more direct services to a wider range of destinations, because these new services will have to prove themselves. If the passenger numbers aren’t there, the services won’t make money, and it may not prove worth the hassle to operate these ultra-long-range routes. If, however, convenience truly is king, then there may be much greater investment in this area to link Sydney and Melbourne with more cities directly. The only losers in this case will be the hub airports across the world, which will grow just a little quieter for the loss of Aussie accents in the terminal.

Hackaday Europe 2026: Is Your Blood Pressure Monitor Lying To You?

6 July 2026 at 10:02

Blood pressure is one of the so-called “vital signs” that medical practitioners use to determine the basic state of a patient in any given moment. It’s exactly what it sounds like—a measurement of the pressure of the blood flowing through the body, with some complications to account for the pulsatile nature of human blood flow.

You might think measuring blood pressure is a solved concern, and it mostly is. With that said, some blood pressure monitors out there aren’t quite doing their job properly, and [Milos Rasic] came to Hackaday Europe 2026 to spell out the problem.

Under Pressure

Before exploring the issue, it’s worth first understanding how blood pressure is actually measured. On a baseline level, it’s the same as pressure being measured in any other fluid. Specifically, though, when it comes to blood, it’s important to measure the pressure at two points. There is the peak, when the heart muscle is contracting, referred to as systolic pressure, and the low point, when the heart relaxes, referred to as diastolic pressure. Thus, blood pressure is referred to with two numbers, such as “140 over 90” or 140/90, referring to systolic and diastolic pressures respectively. It’s sometimes important to track the mean arterial pressure, too. Typically, nominal blood pressure would be considered around 120/80 mmHg. High blood pressure, or hypertension, starts at figures over 130/80 mmHg, while low blood pressure, or hypotension, would be considered relevant below 90/60 mmHg.

Blood pressure can be monitored in a number of ways. Most of the time, non-invasive methods are preferred, whether in the doctor’s office or at home. [Milos] notes that the classic hand-pumped blood pressure cuff device (sphygmomanometer) and a stethoscope is still a perfectly excellent way to measure blood pressure in a clinical scenario. This is referred to as the Korotkoff method, where the doctor listens for pulsations in the artery to begin as the pressure of the cuff slowly drops below the systolic pressure, and then later ease as it reduces below the diastolic pressure, monitoring pressure in the cuff on a gauge as they go. Then there are digital versions of arm cuff blood pressure monitors, which [Milos] notes can have some problems. Meanwhile, there are advanced technologies in development to do live measurement with things like mmWave radar devices or ultrasonic tricks, but they’re still emerging and less established in clinical contexts.

Many cheap electronic blood pressure monitors use the oscillometric method to measure blood pressure. Few manufacturers share the algorithms they use, but [Milos] has found many use something similar to the above, approximating systolic and diastolic pressures from measurements taken to find the mean arterial pressure. Credit: presentation slides
[Milos’s] talk focuses on the digital oscillometric analysis that is behind cheap electronic blood pressure monitors that commonly retail for $30-50. These devices start by pumping up an arm cuff to well above typical systolic pressures, before slowly letting it deflate. A sensor hooked up to the cuff is used to monitor the pressure during deflation. When the cuff is below systolic pressure but above diastolic pressure, the pressure in the cuff will oscillate with the pulsing of the blood flow. When isolated from the overall pressure loss from deflation, the amplitude of this oscillatory signal is maximum at the mean arterial pressure. According to [Milos], it’s common for electronic blood pressure monitors to then take some figure like 40% and 80% of the amplitude of the oscillation envelope, and grab the systolic and diastolic pressure values at those points. As far as accuracy goes, this method isn’t exactly perfect, being more of a useful approximation rather than something that’s rooted in a true direct measurement. Furthermore, [Milos] notes that, for example, Category A blood pressure monitors are only expected to land within a +/- 15 mmHg range, for 85% of their measurements. That’s not fantastic.

[Milos] has invested a great deal of time into the Open Cardiography Digital Measuring Device, hoping to better investigate alternative methods of measuring blood pressure in a non-invasive manner.
[Milos] notes that it’s important to allow the patient to sit still for five minutes before measurement if numbers are to be at all comparable between checks, as many factors can influence blood pressure in the moment.
The method used by these electronic devices tends to be a little inaccurate compared to the traditional clinical methods performed by trained professionals. For that reason, [Milos] developed the Open Cardiography Signal Measuring Device. It is specifically designed to test different algorithms for blood pressure measurement. It can measure pressure in an arm cuff, and also takes signals from a photopletyzmography (PPG) clamp for measuring blood oxygen saturation.  There are also inputs for ECG and digital stethoscope signals, too. [Milos] has published the device’s design on Github for anyone to explore as desired. His talk explains how the device came together, and how he has been using it to evaluate the accuracy of off-the-shelf monitors and the use of alternative algorithms to those used in such units. He also discusses the challenges of measuring blood pressure accurately in this way when dealing with, for example, patients with less stable heart rates.

It’s an interesting exploration of a very specific part of vital sign measurement that few of us ever think about in detail. Sometimes it pays to know how the machines that you’re getting measurements from actually work, and whether you can trust what they’re saying. In the world of blood pressure measurement, [Milos] has done just that.

Homelab Gets Linksys Themed Aesthetic

5 July 2026 at 04:00

If you’re building a homelab rig, you could just use off-the-shelf hardware in standard cases and slap it all in a rack like the normies do. Or, you could follow the example of [Justin Garrison] and build a more oddball setup.

This particular homelab is, at its heart, built from familiar components. There are two Raspberry Pi 5s, two Raspberry Pi 4s, a GMKtec NucBox M6 Mini with an ASUS GeForce RT 2060 GPU, a LattePanda IOTA, an NVidia DGX Spark, and an HP Z4 G4 mini PC. These machines are all laced together with a TP-Link LS108GB PoE switch. [Justin] has the mini PC running the control plane components, with the rig as a whole running Talos and Kubernetes workloads. What makes this build particularly appealing, though, is the aesthetics of the rig. [Justin] documents how he hacked this hardware to fit into a bunch of old Linksys router cases, which provides a pleasant early 2000s look to the build. This included a bit of hackery to get status LEDs flickering as they should be. [Justin] also took the time to make the power buttons accessible.

If you want to stunt on your friends with a rad homelab, you either have to go for maximum power, or maximum style. This build would be the latter. Video after the break.

Building A Wireless Fingerprint Authorization Device

4 July 2026 at 01:00

Once upon a time, there was a bit of a fad for fingerprint authentication in laptops and desktop computers. It has long since faded, but [superdog] wanted just such a device for Linux and Mac machines. Thus, it was time to build one.

[superdog] designed the device, nicknamed immurok, as a tool for people who use external keyboards, and do lots of terminal work on Mac and Linux machines. Repeat password requests can interrupt one’s flow when hustling at the keys, so immurok was designed to ease this pain.

The device is based on a WCH CH592F microcontroller, which comes with Bluetooth connectivity out of the box. This allows immurok to connect wirelessly to the machine of your choice, advertising itself as a standard Bluetooth HID keyboard device. Fingerprint-wise, scanning is done with an R559S capacitive sensor, which verifies the match locally so there’s no transmitting biometric data anywhere. On the computer side, Linux is setup to use a CLI/TUI app plus PAM integration to handle authorization for system logins and sudo in the terminal. On the Mac platform, it’s used with a menu bar app, with PAM integration for admin prompts. There’s also a separate helper path for using it with the lock screen.

If you’re sick of entering your password all the time and wish unlocking your PC was more like unlocking your phone, this might be the project for you. We’ve seen similar projects before, too. If you’re whipping up fun gear for biometric auth, don’t hesitate to let us know on the tipsline.

DIY SI5351 Radio Tunes In SW, MW, And More

2 July 2026 at 16:00

There are plenty of radios you can buy that pick up MW and SW bands if that’s what you’re into. Or, you can follow [mircemk]’s example, and whip one up yourself instead.

The build employs an ESP32 as the brains of the operation. It’s hooked up to a rotary encoder and a small colour TFT screen, which displays an old-school style tuning dial for choosing the desired frequency. This setup is paired with an Si5351—a capable clock generator chip that can deliver just about any frequency from <8KHz up to 150+ MHz on command. There’s naturally a bunch of supporting analog hardware for the radio end of things, plus a NE612 mixer IC and a PAM8403 class D audio amplifier board, hooked up to a small 0.25W speaker for audio output. [mircemk] has set up the rig to act as a simple radio set, or, with the flick of a switch, it can be configured for SDR use with an attached computer.

It’s a handsome build, and one that likely proves a pleasant way to browse the MW and SW bands on a rainy afternoon. We’ve looked at other hardware in this category before, too. Video after the break.

A Light-Up Map Of Monaco

2 July 2026 at 11:30

If you want to get around Monaco, a map — digital or otherwise — is probably the best way to navigate. But if you just want to appreciate the city’s form in a more artistic way, you might enjoy [Terence Grover’s] latest project—a backlit topographic map of the unique principality.

The touch mode allows one to draw patterns across the map.

The project started with a QGIS mesh of Monaco, with the data fed through the Open-Meteo elevation API, which takes into account building heights. This was used as the basis for the heights of 179 pieces of 20 mm x 20 mm acrylic. These were assembled into a laser cut steel base, and were sanded on all sides but the base in order to allow them to diffuse light more effectively.

Strips of CS8812 LEDs are used to light the plastic towers, driven by a pair of Adafruit Feather RP2040 Scorpio boards. They’re fed pixel data from a Raspberry Pi 5, which runs a Flask panel accessed over an iPad. This allows control over the LED map display, showing things like civic data, highlighted events, and weather. There’s even a touch-sensitive mode that lets one paint fun patterns across the representation of the city.

We love a good artistic map, particularly when they’re full of LEDs and represent useful information.

How Airspeed Sensors Work

30 June 2026 at 10:00

When you’re driving your car, you’re probably regularly looking at the speedometer to make sure you comply with the local speed limits. The method by which it works is simple enough: the rotation of the wheels is sent mechanically via a cable to a dial on the dash, or an electronic sensor counts the rotations of the drivetrain and an electronically-controlled needle or display shows the speed.

But what about if you were in an aircraft, and the wheels had nothing to do with how fast you were going? How would you even begin to measure speed? There are two ways: there’s a convenient solution to this problem rooted in simple fluid mechanics, and a far-more-complex modern solution. Today, we’ll explore how planes and helicopters are able to figure out how fast they’re going, by the old ways and the new.

Classical Methods

Measuring airspeed can be achieved by measuring stagnation pressure with a pitot tube, and comparing this to static pressure. This can be done at different points on the aircraft, or a pitot-static tube can be used, which measures both stagnation pressure and static pressure in a single probe. Credit: Chaos386, CC BY-SA 3.0

A key thing most aviators want to know is how fast their aircraft is going. Specifically, it’s nice to know how fast it’s moving relative to the airstream around it, which is referred to as airspeed. This is important, because it’s the aircraft’s velocity relative to the flow, such as wind, that determines the performance of the airfoils, how much lift is generated, and whether or not the aircraft is approaching a stall condition where it might fall out of the sky.

Bernoulli’s equation, rearranged to find airspeed (u), by subtracting static pressure from stagnation pressure, multiplying it by 2, dividing by fluid density, and taking the square root of that result.

Measuring airspeed is most commonly achieved with the use of a device called a Pitot tube. The pitot tube is a tube with a hole in one end that points directly into the airflow in the direction of travel of the aircraft.

As air flows in, it reaches a dead end and the flow slows to a stop, or stagnates, since it has nowhere to go. This allows a pressure sensor or a manometer or other device to measure the stagnation pressure at this point. The stagnation pressure measurement is related to the flowspeed of the incoming air since the kinetic energy of the flow is converted to pressure as the flow comes to a halt.

A secondary tube, pointing perpendicular to the airflow, is then used to measure the static pressure of the surrounding air, without the ram effect of the air being forced in by the aircraft’s forward motion. Then, it’s possible to calculate the velocity of the aircraft relative to the airstream by plugging the stagnation pressure and static pressure into a rearranged Bernoulli’s equation.  If the pitot tube and static tube are hooked up to electronic sensors, the airspeed can be calculated electronically, and fed to a display or digital gauge.

A classic airspeed indicator has the pitot tube and static tube feeding right into the gauge in the cockpit. The pressure differential causes the diaphragm to expand as the airspeed increases, which mvoes a mechanism causing the needle to move on the gauge. Credit: FAA, public domain

Alternatively, it’s possible to effectively do this “calculation” mechanically. In earlier days, static and stagnation pressure captured by each tube would be fed to a gauge. Inside, the stagnation pressure would be fed to a diaphragm which moved due to the difference relative to the static pressure which is fed into the gauge body, and the movement of the diaphragm would, via a simple mechanism, shift the needle on the gauge.

A small General Aviation aircraft might mount a single pitot tube on the aircraft, feeding the air speed instrument in the cockpit. Commercial aircraft might mount two or more for safety’s sake, in case one becomes inoperable, while large airliners may have four or even more to provide a high level of redundancy and error checking. Heaters are commonly included on pitot tubes to ensure they can be kept free of ice, which can otherwise completely block a tube and make it impossible to obtain an airspeed reading.

Pitot tubes sticking out in the airstream underneath a Boeing 777-381. Credit: Cassiopeia sweet, public domain

For pilots, not knowing how fast (or slow) the aircraft is going can be highly dangerous, as it can lead to entering unstable flight regimes such as stall. Thus, it’s imperative that the pitot tubes remain unobstructed and functional for safe flight. Many aircraft accidents have occurred because of blocked or malfunctioning pitot tubes or airspeed instruments.

The New Way

Of course, you could fuss about with pitot tubes and pressure sensors and deicing measures, but that’s all very fiddly and old hat. There is an entirely different way to figure out a plane’s speed, though it’s only been available for the last few decades. It’s as simple as throwing a GNSS receiver on the aircraft.

Yes, whether your particular poison is GPS, Baidou, GLONASS, or Galileo, any major satellite navigation system will be able to tell you the speed of your receiver. Simply measuring the change in the receiver’s position over time is enough to calculate out the speed, and any off-the-shelf receiver will present this information as standard. It’s generally not used as a primary indicator in aircraft, because it reports ground speed, not airspeed, the latter being more relevant for aviation purposes. Still, it can prove to be a useful sense check when traditional airspeed indicators are non-operative or reporting confusing data, and GNSS devices are widely used on many aircraft today.

Flying High

Many modern aircraft have so-called “glass cockpit” displays that include feeds from GNSS receivers, which can provide supplementary data such as satellite-based ground speed measurements. However, these readings are generally not used for the primary task of flying the aircraft. Credit: Bluedisk, CC BY-SA 3.0

If you’ve ever wondered how an aircraft measures its speed as it floats through the amorphous gas cloud we call an atmosphere, now you know. Even to this day, where electronics and computer wizardry control our fanciest aircraft, airspeed measurements are still done with the same simple physics, just with some fancier sensors for help. The fundamentals haven’t changed at all. Now you know, you can always dig deeper into the many other rich applications of Bernoulli’s equation and fluid mechanics in general. Happy learning.

Hard Drive Speakers Crank Out Classic Demo

29 June 2026 at 19:00

Second Reality is a legendary demoscene release by Future Crew, which won Assembly 1993 with its technical and artistic mastery. [Niv Singer] decided to give the classic demo a spin on a rather unconventional sound system with a particuarly techy twist.

Hard drives are great for storing data. They’re designed for this purpose. What they’re not designed for is acting as speakers, but you can hack them into acting that way if you’re so inclined. For this project, [Niv] pulled apart a whole stack of drives, so they could be repurposed in this way. The principle is simple enough—just feed audio to the coil driving the head, and it will vibrate and wiggle around, creating soundwaves in the air. It’s not particularly effective, and you get limited volume with a terrible frequency response, but that’s half the fun. [Niv] actually took some of this into account, too. Four Western Digital Caviar 500GB drives were chosen for this build, two for the left channel, and two for the right. Each channel had a crossover, allowing one drive to handle low frequencies while the other handled higher ones. For a further nice touch, the platters spin with the beat as well, with [Niv] providing a great explanation on how this was achieved with the use of some nifty PWM tricks.

Files are on Github for the curious. We’ve featured plenty of hard drive speakers before, too. Video after the break.

Hackaday Europe 2026 – Building A Retro PC From Scratch

29 June 2026 at 13:05

If you’re big into retrocomputing, you probably spend a lot of time chasing parts and machines on online classifieds or through local swap meets. But what if there was a different way to build a classic retro PC? What if you could put one together from bare chips, from the ground up?

[Jeroen Domburg] is no stranger to the pages of Hackaday. You might know him by his alias, [sprite_tm], under which he’s shared many projects, from miniaturizing old hardware to unearthing the secrets of undocumented commercial hardware. Now, he’s turning his considerable skills to figuring out how to build a retro PC in today’s world, and came to Hackaday Europe 2026 to show us all how it’s done.

Game On

[Jeroen’s] goal was simple—to build a powerful retro gaming PC from the ground up. The first thing to decide was which era to target, with [Jeroen] deciding that 1995 seemed the most personally relevant to his interests. This was the peak of the MS-DOS gaming era, before things like DirectX came in and the culture shifted to Windows gaming and the domination of 3D over all else.

What does a good 1995 machine look like? It was probably rocking a 486, or maybe a Pentium, with somewhere between 8-16 MB of RAM. You had a simple video card primarily built for 2D graphics, and a sound card that was probably some variant of Sound Blaster or other. [Jeroen] wanted to build such a machine with as much real silicon as possible, rather than just emulating hardware from this era, and he wanted to do this himself at the component level, rather than just plugging in bits and pieces from eBay. Building a vintage-style PC motherboard from scratch and getting it up and running is a bit of a job, but luckily [Jeroen] has the skills to make it possible.

[Jeroen]’s first attempt had issues, mostly because it was difficult to properly solder the big BGA CPU package.
While [Jeroen] was looking to the past, he also wanted to take advantage of modern quality of life improvements, mainly by eliminating mechanical parts. Old hard drives and floppy drives from this era are seriously showing their age by now, and becoming particularly unreliable. There are better storage solutions available today that are faster and easier to use. The choice was also made to use modern peripherals, rather than relying on 30-year-old keyboards and mice.

The core of the build was an AMD Elan SC520, running at 133 MHz. This was one of the so-called “586” chips that were spawned following the 486 era, in [Jeroen’s] words, being a “486 but a bit souped up.” This chip came out in 2000, a full six years after Intel curtailed 486 production, a time when the Pentium III was already hitting 1 GHz clock speeds. It’s an anachronistic choice for a 1995 machine, but [Jeroen] picked it for good reason. The Elan SC520 was more of a system-on-chip, integrating lots of supporting low-level hardware onto the CPU itself, like the real-time clock and programmable interval timer (PIT), which would make his build easier. [Jeroen] threw this on a board with an FPGA and an ESP32 and a smattering of support components, and got a general purpose machine up together in a tiny form factor. If you’re thinking of a Raspberry Pi built with a knockoff 486, you’re not far off the money.

There was an early focus on just getting the basics up and running to get to a DOS prompt, before fleshing out the project and making it more feature complete. Credit: project slides

This first build had some issues that caused a lot of stress. Namely, the Elan SC520 was a large BGA, and it was difficult to verify if it was perfectly soldered or not. This meant that as [Jeroen] worked on the board and spun up the supporting FPGA and such, it was very difficult to know if things weren’t working because of his own code or because of a missing solder ball or a short. This led him to return to the drawing board.

The second attempt had a cleaner design, using a classic CPU instead of a later-model system-on-chip. This proved far easier to solder. 

The second attempt involved a regular CPU rather than the difficult-to-wrangle AMD system-on-chip. Namely, a classic i486 DX4-100 and AM486DX5-133 were sourced as potential CPU options. A C&T F65545 VGA chip was enlisted to handle graphical duties, being a laptop chipset that integrated lots of necessary support hardware into the one package. The plan was to throw just about everything else into an ECP5 LFE5UM-45 FPGA chipset, plus an ESP32-S3 to act as a peripheral interface. [Jeroen] decided to use SDRAM, which was much newer than that typically used with a 486, but this was chosen for being easy to integrate with the FPGA. With a goal to just get to a DOS prompt, [Jeroen] eliminated as much extraneous hardware as possible to get the project moving forward quickly. After spinning up a PCB, learning all about what it takes to bring up a 486-based machine, and working up the FPGA-based chipset, things all came together. A bit of cribbing from MiSTer projects helped, too. [Jeroen] eventually had his new old machine displaying a basic BIOS, then running some benchmarks, and then even running games like Commander Keen. The talk goes on to explain all the other little bits and pieces that come together, like storage, MIDI support, sound, and networking. Seeing it then turned into a portable game station named the Vapourdeck is just the icing on the cake.

Further work saw the single-board machine integrated into a gaming handheld that [Jeroen] has nicknamed the Vapourdeck.
If you just want to play some retro games, your quickest route will still be emulation or just purchasing components to build a 90s spec machine. If you want to really learn what makes a classic 486-era machine work, though, it’s hard to beat this approach. [Jeroen] even notes that taking a similar approach to his could let you build something up to the 500 MHz range or so, based on the chipsets and CPUs available from way back when. If you want to learn more or pursue this yourself, it’s well worth poring over the talk and checking out the project files online. Happy hacking.

❌
❌