devesh yadav
Published

VAYU — Exhaust Scrubber That Converts Smoke to Clean Air

4-stage retrofit module for any bike or car. Kills PM2.5, CO & NOₓ using CuO catalysis + electrostatics. Self-powered by waste heat.

IntermediateFull instructions provided84
VAYU — Exhaust Scrubber That Converts Smoke to Clean Air

Things used in this project

Hardware components

ESP32 DevKit V1
×1
SDS011 Nova PM Sensor (×2)
×1
MQ-7 Carbon Monoxide Sensor
×1
TEC1-12706 Thermoelectric Generator Module
×1
Negative Ion Generator Module 12V DC
×1
3V Peristaltic Mini Water Pump
×1
DHT22 temperature-humidity sensor
Adafruit DHT22 temperature-humidity sensor
×1
18650 Li-ion Battery (×3)
×1
TP4056 Battery Charger Module
×1
10W 12V Solar Panel
×1
Stainless Steel Pipe 60mm Diameter
×1
Aluminum Collector Plates 80×60mm (×6)
×1
IP65 Waterproof ABS Enclosure Box
×1
High Voltage 5kV Ionizer Module
×1

Software apps and online services

Arduino IDE
Arduino IDE
ThingSpeak IoT Analytics Platform
Telegram Bot API
MQTT Broker (Mosquitto)

Hand tools and fabrication machines

Angle Grinder
Electric Drill
Soldering iron (generic)
Soldering iron (generic)
Digital Multimeter
Pipe Cutter
Heat Gun

Story

Read more

Code

VAYU_firmware.ino

C/C++
/*
 * VAYU  Vehicle Exhaust Scrubber
 * ESP32 Sensor + Control Firmware v1.0
 *
 * Hardware:
 *   - ESP32 DevKit V1
 *   - 2x SDS011 PM2.5/PM10 sensor (inlet + outlet)
 *   - MQ-7 CO sensor
 *   - DHT22 temperature/humidity
 *   - 3V peristaltic pump (Stage 4 water mist)
 *   - PWM-controlled ionizer relay (Stage 2)
 *   - SD card module (data logging)
 *
 * Power: Self-powered via TEC1-12706 TEG module
 *
 * Author: VAYU Project  Prayagraj, India
 * License: MIT
 */

#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <SPI.h>
#include <time.h>

//  WiFi Credentials 
const char* WIFI_SSID     = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

//  ThingSpeak 
const char* TS_API_KEY    = "YOUR_THINGSPEAK_WRITE_KEY";
const char* TS_URL        = "http://api.thingspeak.com/update";

//  Telegram Bot 
const char* TG_BOT_TOKEN  = "YOUR_TELEGRAM_BOT_TOKEN";
const char* TG_CHAT_ID    = "YOUR_TELEGRAM_CHAT_ID";

//  Pin Definitions 
#define SDS_INLET_RX    16   // SDS011 Inlet: RX pin
#define SDS_INLET_TX    17   // SDS011 Inlet: TX pin
#define SDS_OUTLET_RX   18   // SDS011 Outlet: RX pin
#define SDS_OUTLET_TX   19   // SDS011 Outlet: TX pin
#define MQ7_PIN         34   // MQ-7 analog input
#define DHT_PIN         4    // DHT22 data pin
#define PUMP_PIN        25   // Peristaltic pump relay
#define IONIZER_PIN     26   // Ionizer PWM control
#define SD_CS_PIN       5    // SD card chip select
#define LED_PIN         2    // Onboard LED (status)

//  Constants 
#define DHT_TYPE        DHT22
#define LOG_INTERVAL_MS 60000   // Log every 60 seconds
#define PUMP_ON_MS      30000   // Pump ON for 30 seconds
#define PUMP_OFF_MS     90000   // Pump OFF for 90 seconds
#define ALERT_PM25      80.0    // Telegram alert threshold g/m
#define IONIZER_FULL    255     // PWM full power (0-255)
#define IONIZER_HALF    128     // PWM half power

//  Objects 
DHT dht(DHT_PIN, DHT_TYPE);
SoftwareSerial sdsInlet(SDS_INLET_RX, SDS_INLET_TX);
SoftwareSerial sdsOutlet(SDS_OUTLET_RX, SDS_OUTLET_TX);

//  Data Structures 
struct SensorReading {
  float pm25_in;
  float pm10_in;
  float pm25_out;
  float pm10_out;
  float co_ppm;
  float temperature;
  float humidity;
  float efficiency_pm25;
  float efficiency_pm10;
  unsigned long timestamp;
};

//  State 
SensorReading latest;
unsigned long lastLogTime    = 0;
unsigned long lastPumpToggle = 0;
bool pumpRunning             = false;
bool alertSentThisHour       = false;
int alertHour                = -1;

// 
// SDS011 READER
// 
bool readSDS011(SoftwareSerial &serial, float &pm25, float &pm10) {
  byte buf[10];
  int idx = 0;
  unsigned long start = millis();

  // Flush stale data
  while (serial.available()) serial.read();
  delay(100);

  while (millis() - start < 2000) {
    if (serial.available() >= 10) {
      buf[0] = serial.read();
      if (buf[0] != 0xAA) continue;   // Wait for frame header
      for (int i = 1; i < 10; i++) {
        while (!serial.available());
        buf[i] = serial.read();
      }
      if (buf[9] != 0xAB) continue;   // Check tail byte

      // Verify checksum
      byte checksum = 0;
      for (int i = 2; i <= 7; i++) checksum += buf[i];
      if (checksum != buf[8]) continue;

      pm25 = ((buf[3] << 8) | buf[2]) / 10.0;
      pm10 = ((buf[5] << 8) | buf[4]) / 10.0;
      return true;
    }
  }
  return false;  // Timeout
}

// 
// MQ-7 CO READER
// 
float readCO_PPM() {
  int raw = analogRead(MQ7_PIN);
  // MQ-7 calibration curve (adjust Rs/R0 ratio for your sensor)
  // Approximate: CO ppm = 99.042 * (raw/4095.0)^-1.518
  float ratio = raw / 4095.0;
  if (ratio <= 0) return 0;
  float ppm = 99.042 * pow(ratio, -1.518);
  return constrain(ppm, 0, 2000);
}

// 
// IONIZER CONTROL
// 
void setIonizerPower(float pm25_in) {
  int power;
  if (pm25_in > 150) {
    power = IONIZER_FULL;    // Hazardous  max power
  } else if (pm25_in > 75) {
    power = 200;             // Moderate pollution
  } else {
    power = IONIZER_HALF;    // Low  save energy
  }
  ledcWrite(0, power);
  Serial.printf("[IONIZER] PWM = %d (PM2.5 in = %.1f)\n", power, pm25_in);
}

// 
// PUMP CONTROL
// 
void updatePump() {
  unsigned long now = millis();
  if (!pumpRunning && now - lastPumpToggle >= PUMP_OFF_MS) {
    digitalWrite(PUMP_PIN, HIGH);
    pumpRunning = true;
    lastPumpToggle = now;
    Serial.println("[PUMP] ON");
  } else if (pumpRunning && now - lastPumpToggle >= PUMP_ON_MS) {
    digitalWrite(PUMP_PIN, LOW);
    pumpRunning = false;
    lastPumpToggle = now;
    Serial.println("[PUMP] OFF");
  }
}

// 
// SD CARD LOGGING
// 
void logToSD(SensorReading &r) {
  File f = SD.open("/vayu_log.csv", FILE_APPEND);
  if (!f) {
    Serial.println("[SD] Failed to open log file");
    return;
  }
  // Write CSV row
  f.printf("%lu,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n",
    r.timestamp,
    r.pm25_in, r.pm10_in,
    r.pm25_out, r.pm10_out,
    r.efficiency_pm25, r.efficiency_pm10,
    r.co_ppm,
    r.temperature, r.humidity
  );
  f.close();
  Serial.println("[SD] Logged");
}

void initSDHeader() {
  if (!SD.exists("/vayu_log.csv")) {
    File f = SD.open("/vayu_log.csv", FILE_WRITE);
    if (f) {
      f.println("timestamp,pm25_in,pm10_in,pm25_out,pm10_out,"
                "eff_pm25,eff_pm10,co_ppm,temp_c,humidity");
      f.close();
    }
  }
}

// 
// THINGSPEAK UPLOAD
// 
void uploadThingSpeak(SensorReading &r) {
  if (WiFi.status() != WL_CONNECTED) return;
  HTTPClient http;
  String url = String(TS_URL) +
    "?api_key=" + TS_API_KEY +
    "&field1=" + String(r.pm25_in, 1) +
    "&field2=" + String(r.pm25_out, 1) +
    "&field3=" + String(r.efficiency_pm25, 1) +
    "&field4=" + String(r.co_ppm, 1) +
    "&field5=" + String(r.temperature, 1) +
    "&field6=" + String(r.humidity, 1) +
    "&field7=" + String(r.pm10_in, 1) +
    "&field8=" + String(r.pm10_out, 1);
  http.begin(url);
  int code = http.GET();
  Serial.printf("[TS] Response: %d\n", code);
  http.end();
}

// 
// TELEGRAM ALERT
// 
void sendTelegramAlert(SensorReading &r) {
  if (WiFi.status() != WL_CONNECTED) return;

  // Only alert once per hour max
  struct tm t; getLocalTime(&t);
  if (t.tm_hour == alertHour) return;
  alertHour = t.tm_hour;

  String msg = " *VAYU ALERT*\n"
    "Outlet PM2.5 = " + String(r.pm25_out, 1) + " g/m\n"
    "Inlet PM2.5  = " + String(r.pm25_in, 1) + " g/m\n"
    "Efficiency   = " + String(r.efficiency_pm25, 1) + "%\n"
    "CO           = " + String(r.co_ppm, 0) + " ppm\n"
    "Check Stage 2 plates or Stage 1 ash cup.";

  HTTPClient http;
  String url = "https://api.telegram.org/bot" + String(TG_BOT_TOKEN) +
               "/sendMessage?chat_id=" + String(TG_CHAT_ID) +
               "&text=" + msg + "&parse_mode=Markdown";
  http.begin(url);
  http.GET();
  http.end();
  Serial.println("[TG] Alert sent");
}

// 
// SETUP
// 
void setup() {
  Serial.begin(115200);
  Serial.println("\n=== VAYU v1.0 BOOTING ===");

  // GPIO setup
  pinMode(PUMP_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(PUMP_PIN, LOW);

  // PWM for ionizer (channel 0, 5kHz, 8-bit)
  ledcSetup(0, 5000, 8);
  ledcAttachPin(IONIZER_PIN, 0);
  ledcWrite(0, IONIZER_HALF);

  // Sensors
  dht.begin();
  sdsInlet.begin(9600);
  sdsOutlet.begin(9600);

  // SD card
  if (SD.begin(SD_CS_PIN)) {
    Serial.println("[SD] Card OK");
    initSDHeader();
  } else {
    Serial.println("[SD] Card FAIL  continuing without logging");
  }

  // WiFi
  Serial.printf("[WiFi] Connecting to %s", WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    delay(500); Serial.print(".");
    attempts++;
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\n[WiFi] Connected: " + WiFi.localIP().toString());
    configTime(19800, 0, "pool.ntp.org");  // IST = UTC+5:30
  } else {
    Serial.println("\n[WiFi] Offline  local logging only");
  }

  lastPumpToggle = millis();
  Serial.println("=== VAYU READY ===\n");
  digitalWrite(LED_PIN, HIGH);
}

// 
// MAIN LOOP
// 
void loop() {
  unsigned long now = millis();

  //  Pump cycle 
  updatePump();

  //  Read and process every LOG_INTERVAL_MS 
  if (now - lastLogTime >= LOG_INTERVAL_MS) {
    lastLogTime = now;
    digitalWrite(LED_PIN, LOW);

    SensorReading r;
    r.timestamp = now / 1000;

    // Read PM sensors
    bool inOk  = readSDS011(sdsInlet,  r.pm25_in,  r.pm10_in);
    bool outOk = readSDS011(sdsOutlet, r.pm25_out, r.pm10_out);

    if (!inOk)  { r.pm25_in  = -1; r.pm10_in  = -1; }
    if (!outOk) { r.pm25_out = -1; r.pm10_out = -1; }

    // Efficiency (only if both sensors valid)
    if (inOk && outOk && r.pm25_in > 0) {
      r.efficiency_pm25 = ((r.pm25_in - r.pm25_out) / r.pm25_in) * 100.0;
      r.efficiency_pm10 = ((r.pm10_in - r.pm10_out) / r.pm10_in) * 100.0;
      r.efficiency_pm25 = constrain(r.efficiency_pm25, 0, 100);
      r.efficiency_pm10 = constrain(r.efficiency_pm10, 0, 100);
    } else {
      r.efficiency_pm25 = 0;
      r.efficiency_pm10 = 0;
    }

    // CO and environment
    r.co_ppm     = readCO_PPM();
    r.temperature = dht.readTemperature();
    r.humidity    = dht.readHumidity();

    // Adjust ionizer based on inlet pollution
    if (inOk) setIonizerPower(r.pm25_in);

    // Print to Serial monitor
    Serial.println("");
    Serial.printf("PM2.5 in : %.1f g/m\n", r.pm25_in);
    Serial.printf("PM2.5 out: %.1f g/m\n", r.pm25_out);
    Serial.printf("Eff PM2.5: %.1f%%\n",      r.efficiency_pm25);
    Serial.printf("PM10  in : %.1f g/m\n", r.pm10_in);
    Serial.printf("PM10  out: %.1f g/m\n", r.pm10_out);
    Serial.printf("Eff PM10 : %.1f%%\n",      r.efficiency_pm10);
    Serial.printf("CO       : %.0f ppm\n",    r.co_ppm);
    Serial.printf("Temp     : %.1f C\n",     r.temperature);
    Serial.printf("Humidity : %.1f %%\n",     r.humidity);
    Serial.println("");

    latest = r;

    // Log and upload
    logToSD(r);
    uploadThingSpeak(r);

    // Alert if outlet PM2.5 exceeds threshold
    if (outOk && r.pm25_out > ALERT_PM25) {
      sendTelegramAlert(r);
    }

    digitalWrite(LED_PIN, HIGH);
  }

  delay(10);
}

VAYU_schematic.html

HTML (Ruby)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{width:1100px;height:780px;background:#0a0f0a;overflow:hidden;font-family:'Courier New',monospace}
</style>
</head>
<body>
<svg width="1100" height="780" viewBox="0 0 1100 780" style="background:#0a0f0a">
<defs>
  <marker id="arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto">
    <path d="M2 2L8 5L2 8" fill="none" stroke="#00cc66" stroke-width="1.5" stroke-linecap="round"/>
  </marker>
  <marker id="arrR" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto">
    <path d="M2 2L8 5L2 8" fill="none" stroke="#cc4422" stroke-width="1.5" stroke-linecap="round"/>
  </marker>
  <marker id="arrB" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto">
    <path d="M2 2L8 5L2 8" fill="none" stroke="#4488cc" stroke-width="1.5" stroke-linecap="round"/>
  </marker>
  <marker id="arrY" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto">
    <path d="M2 2L8 5L2 8" fill="none" stroke="#ddaa22" stroke-width="1.5" stroke-linecap="round"/>
  </marker>
</defs>

<!-- Title -->
<text x="30" y="34" font-family="Courier New" font-size="14" fill="#00e87a" letter-spacing="4">VAYU  WIRING SCHEMATIC v1.0</text>
<text x="30" y="52" font-family="Courier New" font-size="9" fill="#1a4a2a" letter-spacing="2">ESP32  SDS0112  MQ-7  DHT22  TEG  PUMP  IONIZER  SD CARD</text>

<!--  ESP32 (center)  -->
<rect x="420" y="260" width="260" height="280" rx="6" fill="#0a1a0a" stroke="#00cc66" stroke-width="1.5"/>
<text x="550" y="282" text-anchor="middle" font-family="Courier New" font-size="11" fill="#00e87a" letter-spacing="2">ESP32 DevKit V1</text>
<line x1="420" y1="290" x2="680" y2="290" stroke="#00cc66" stroke-width="0.5" opacity="0.4"/>

<!-- ESP32 left pins -->
<text x="428" y="314" font-family="Courier New" font-size="8" fill="#2a6a3a">3V3</text>
<text x="428" y="330" font-family="Courier New" font-size="8" fill="#2a6a3a">GND</text>
<text x="428" y="346" font-family="Courier New" font-size="8" fill="#4488cc">GPIO16 RX2</text>
<text x="428" y="362" font-family="Courier New" font-size="8" fill="#4488cc">GPIO17 TX2</text>
<text x="428" y="378" font-family="Courier New" font-size="8" fill="#cc8822">GPIO18 RX</text>
<text x="428" y="394" font-family="Courier New" font-size="8" fill="#cc8822">GPIO19 TX</text>
<text x="428" y="410" font-family="Courier New" font-size="8" fill="#cc4422">GPIO34 ADC</text>
<text x="428" y="426" font-family="Courier New" font-size="8" fill="#aa6622">GPIO4</text>
<text x="428" y="442" font-family="Courier New" font-size="8" fill="#2a6a3a">GPIO25</text>
<text x="428" y="458" font-family="Courier New" font-size="8" fill="#aa22aa">GPIO26 PWM</text>
<text x="428" y="474" font-family="Courier New" font-size="8" fill="#888888">GPIO5 CS</text>
<text x="428" y="490" font-family="Courier New" font-size="8" fill="#888888">GPIO23 MOSI</text>
<text x="428" y="506" font-family="Courier New" font-size="8" fill="#888888">GPIO19 MISO</text>
<text x="428" y="522" font-family="Courier New" font-size="8" fill="#888888">GPIO18 SCK</text>

<!-- pin dots left -->
<g fill="#00cc66">
  <circle cx="420" cy="311" r="3"/><circle cx="420" cy="327" r="3"/>
  <circle cx="420" cy="343" r="3"/><circle cx="420" cy="359" r="3"/>
  <circle cx="420" cy="375" r="3"/><circle cx="420" cy="391" r="3"/>
  <circle cx="420" cy="407" r="3"/><circle cx="420" cy="423" r="3"/>
  <circle cx="420" cy="439" r="3"/><circle cx="420" cy="455" r="3"/>
  <circle cx="420" cy="471" r="3"/><circle cx="420" cy="487" r="3"/>
  <circle cx="420" cy="503" r="3"/><circle cx="420" cy="519" r="3"/>
</g>

<!-- ESP32 right pins -->
<text x="596" y="314" font-family="Courier New" font-size="8" fill="#2a6a3a">VIN 5V</text>
<text x="596" y="330" font-family="Courier New" font-size="8" fill="#2a6a3a">GND</text>
<text x="596" y="346" font-family="Courier New" font-size="8" fill="#888888">GPIO2 LED</text>
<text x="596" y="362" font-family="Courier New" font-size="8" fill="#4488cc">GPIO0</text>
<text x="596" y="378" font-family="Courier New" font-size="8" fill="#888888">GPIO13</text>

<g fill="#00cc66">
  <circle cx="680" cy="311" r="3"/><circle cx="680" cy="327" r="3"/>
  <circle cx="680" cy="343" r="3"/>
</g>

<!--  TEG / POWER (top center)  -->
<rect x="430" y="80" width="240" height="100" rx="5" fill="#0f0a00" stroke="#ddaa22" stroke-width="1.2"/>
<text x="550" y="100" text-anchor="middle" font-family="Courier New" font-size="10" fill="#ddaa22" letter-spacing="2">TEG POWER SYSTEM</text>
<line x1="430" y1="108" x2="670" y2="108" stroke="#ddaa22" stroke-width="0.4" opacity="0.4"/>
<text x="440" y="124" font-family="Courier New" font-size="8" fill="#8a6010">TEC1-12706  TP4056  186503</text>
<text x="440" y="140" font-family="Courier New" font-size="8" fill="#8a6010">Hot side: 250350C (Stage 3 wall)</text>
<text x="440" y="156" font-family="Courier New" font-size="8" fill="#8a6010">Output: 36W, 5V regulated via buck</text>
<text x="440" y="172" font-family="Courier New" font-size="8" fill="#ccaa22">5V  ESP32 VIN  12V  Ionizer</text>

<!-- TEG to ESP32 power line -->
<line x1="550" y1="180" x2="550" y2="260" stroke="#ddaa22" stroke-width="1.5" marker-end="url(#arrY)" stroke-dasharray="5 3"/>
<text x="558" y="225" font-family="Courier New" font-size="7" fill="#6a4a10">5V power</text>

<!--  SDS011 INLET (top left)  -->
<rect x="40" y="80" width="210" height="110" rx="5" fill="#060a18" stroke="#4488cc" stroke-width="1.2"/>
<text x="145" y="100" text-anchor="middle" font-family="Courier New" font-size="10" fill="#4488cc" letter-spacing="2">SDS011  INLET</text>
<line x1="40" y1="108" x2="250" y2="108" stroke="#4488cc" stroke-width="0.4" opacity="0.4"/>
<text x="50" y="124" font-family="Courier New" font-size="8" fill="#2a5080">PIN 1 (5V)   3V3/5V rail</text>
<text x="50" y="140" font-family="Courier New" font-size="8" fill="#2a5080">PIN 2 (GND)  GND</text>
<text x="50" y="156" font-family="Courier New" font-size="8" fill="#4488cc">PIN 4 (RX)   GPIO17 TX2</text>
<text x="50" y="172" font-family="Courier New" font-size="8" fill="#4488cc">PIN 5 (TX)   GPIO16 RX2</text>

<!-- SDS Inlet wires to ESP32 -->
<path d="M250 156 Q360 156 420 359" fill="none" stroke="#4488cc" stroke-width="1.2" marker-end="url(#arrB)"/>
<path d="M250 172 Q355 172 420 343" fill="none" stroke="#4488cc" stroke-width="1.2" marker-end="url(#arrB)"/>

<!--  SDS011 OUTLET (top right)  -->
<rect x="840" y="80" width="220" height="110" rx="5" fill="#060a18" stroke="#cc8822" stroke-width="1.2"/>
<text x="950" y="100" text-anchor="middle" font-family="Courier New" font-size="10" fill="#cc8822" letter-spacing="2">SDS011  OUTLET</text>
<line x1="840" y1="108" x2="1060" y2="108" stroke="#cc8822" stroke-width="0.4" opacity="0.4"/>
<text x="850" y="124" font-family="Courier New" font-size="8" fill="#805020">PIN 1 (5V)   5V rail</text>
<text x="850" y="140" font-family="Courier New" font-size="8" fill="#805020">PIN 2 (GND)  GND</text>
<text x="850" y="156" font-family="Courier New" font-size="8" fill="#cc8822">PIN 4 (RX)   GPIO19 TX</text>
<text x="850" y="172" font-family="Courier New" font-size="8" fill="#cc8822">PIN 5 (TX)   GPIO18 RX</text>

<!-- SDS Outlet wires to ESP32 -->
<path d="M840 156 Q760 156 680 391" fill="none" stroke="#cc8822" stroke-width="1.2" marker-end="url(#arrY)"/>
<path d="M840 172 Q755 172 680 375" fill="none" stroke="#cc8822" stroke-width="1.2" marker-end="url(#arrY)"/>

<!--  MQ-7 CO (left mid)  -->
<rect x="40" y="290" width="210" height="100" rx="5" fill="#180606" stroke="#cc4422" stroke-width="1.2"/>
<text x="145" y="310" text-anchor="middle" font-family="Courier New" font-size="10" fill="#cc4422" letter-spacing="2">MQ-7 CO SENSOR</text>
<line x1="40" y1="318" x2="250" y2="318" stroke="#cc4422" stroke-width="0.4" opacity="0.4"/>
<text x="50" y="334" font-family="Courier New" font-size="8" fill="#803020">VCC  5V rail</text>
<text x="50" y="350" font-family="Courier New" font-size="8" fill="#803020">GND  GND</text>
<text x="50" y="366" font-family="Courier New" font-size="8" fill="#cc4422">AOUT  GPIO34 (ADC)</text>
<text x="50" y="382" font-family="Courier New" font-size="8" fill="#803020">DOUT  NC</text>

<!-- MQ-7 wire -->
<path d="M250 366 Q360 366 420 407" fill="none" stroke="#cc4422" stroke-width="1.2" marker-end="url(#arrR)"/>

<!--  DHT22 (left lower)  -->
<rect x="40" y="440" width="210" height="90" rx="5" fill="#100810" stroke="#aa6622" stroke-width="1.2"/>
<text x="145" y="460" text-anchor="middle" font-family="Courier New" font-size="10" fill="#aa8030" letter-spacing="2">DHT22 SENSOR</text>
<line x1="40" y1="468" x2="250" y2="468" stroke="#aa6622" stroke-width="0.4" opacity="0.4"/>
<text x="50" y="484" font-family="Courier New" font-size="8" fill="#6a4020">VCC  3V3</text>
<text x="50" y="500" font-family="Courier New" font-size="8" fill="#6a4020">GND  GND</text>
<text x="50" y="516" font-family="Courier New" font-size="8" fill="#aa8030">DATA  GPIO4 (10k pull-up)</text>

<!-- DHT wire -->
<path d="M250 516 Q360 516 420 423" fill="none" stroke="#aa8030" stroke-width="1.2" marker-end="url(#arrY)"/>

<!--  PUMP (right mid)  -->
<rect x="840" y="290" width="220" height="100" rx="5" fill="#060f08" stroke="#44aa66" stroke-width="1.2"/>
<text x="950" y="310" text-anchor="middle" font-family="Courier New" font-size="10" fill="#44aa66" letter-spacing="2">PERISTALTIC PUMP</text>
<line x1="840" y1="318" x2="1060" y2="318" stroke="#44aa66" stroke-width="0.4" opacity="0.4"/>
<text x="850" y="334" font-family="Courier New" font-size="8" fill="#2a6a3a">+3V  NPN transistor (BC547)</text>
<text x="850" y="350" font-family="Courier New" font-size="8" fill="#2a6a3a">Base  GPIO25 via 1k</text>
<text x="850" y="366" font-family="Courier New" font-size="8" fill="#2a6a3a">GND  GND</text>
<text x="850" y="382" font-family="Courier New" font-size="8" fill="#1a4a2a">Flyback diode across motor</text>

<path d="M840 350 Q760 350 680 439" fill="none" stroke="#44aa66" stroke-width="1.2" marker-end="url(#arr)"/>

<!--  IONIZER (right lower)  -->
<rect x="840" y="440" width="220" height="100" rx="5" fill="#0a0618" stroke="#aa44aa" stroke-width="1.2"/>
<text x="950" y="460" text-anchor="middle" font-family="Courier New" font-size="10" fill="#cc66cc" letter-spacing="2">5kV IONIZER</text>
<line x1="840" y1="468" x2="1060" y2="468" stroke="#aa44aa" stroke-width="0.4" opacity="0.4"/>
<text x="850" y="484" font-family="Courier New" font-size="8" fill="#6a2a8a">12V IN  TEG 12V output</text>
<text x="850" y="500" font-family="Courier New" font-size="8" fill="#6a2a8a">PWM ctrl  GPIO26 via MOSFET</text>
<text x="850" y="516" font-family="Courier New" font-size="8" fill="#6a2a8a">GND  GND</text>
<text x="850" y="526" font-family="Courier New" font-size="8" fill="#4a1a6a"> HV output  insulate all leads</text>

<path d="M840 500 Q760 500 680 455" fill="none" stroke="#aa44aa" stroke-width="1.2" marker-end="url(#arr)"/>

<!--  SD CARD (bottom center)  -->
<rect x="360" y="620" width="380" height="110" rx="5" fill="#0a0a0a" stroke="#666666" stroke-width="1.2"/>
<text x="550" y="640" text-anchor="middle" font-family="Courier New" font-size="10" fill="#888888" letter-spacing="2">SD CARD MODULE</text>
<line x1="360" y1="648" x2="740" y2="648" stroke="#666666" stroke-width="0.4" opacity="0.4"/>
<text x="370" y="664" font-family="Courier New" font-size="8" fill="#555555">VCC    3V3</text>
<text x="370" y="680" font-family="Courier New" font-size="8" fill="#555555">GND    GND</text>
<text x="370" y="696" font-family="Courier New" font-size="8" fill="#888888">CS     GPIO5</text>
<text x="370" y="712" font-family="Courier New" font-size="8" fill="#888888">MOSI   GPIO23</text>
<text x="560" y="664" font-family="Courier New" font-size="8" fill="#888888">MISO   GPIO19</text>
<text x="560" y="680" font-family="Courier New" font-size="8" fill="#888888">SCK    GPIO18</text>
<text x="560" y="696" font-family="Courier New" font-size="8" fill="#444444">FAT32 formatted  logs CSV</text>
<text x="560" y="712" font-family="Courier New" font-size="8" fill="#444444">vayu_log.csv</text>

<!-- SD to ESP32 lines -->
<line x1="550" y1="620" x2="550" y2="540" stroke="#666666" stroke-width="1" marker-end="url(#arr)" stroke-dasharray="4 2"/>

<!--  LEGEND  -->
<rect x="40" y="600" width="280" height="130" rx="4" fill="#080808" stroke="#1a2a1a" stroke-width="1"/>
<text x="52" y="618" font-family="Courier New" font-size="9" fill="#2a4a2a" letter-spacing="2">WIRE LEGEND</text>
<line x1="52" y1="634" x2="100" y2="634" stroke="#4488cc" stroke-width="1.5"/>
<text x="108" y="638" font-family="Courier New" font-size="8" fill="#4488cc">SDS011 Inlet UART</text>
<line x1="52" y1="652" x2="100" y2="652" stroke="#cc8822" stroke-width="1.5"/>
<text x="108" y="656" font-family="Courier New" font-size="8" fill="#cc8822">SDS011 Outlet UART</text>
<line x1="52" y1="670" x2="100" y2="670" stroke="#cc4422" stroke-width="1.5"/>
<text x="108" y="674" font-family="Courier New" font-size="8" fill="#cc4422">MQ-7 Analog Signal</text>
<line x1="52" y1="688" x2="100" y2="688" stroke="#ddaa22" stroke-width="1.5"/>
<text x="108" y="692" font-family="Courier New" font-size="8" fill="#ddaa22">TEG 5V Power</text>
<line x1="52" y1="706" x2="100" y2="706" stroke="#44aa66" stroke-width="1.5"/>
<text x="108" y="710" font-family="Courier New" font-size="8" fill="#44aa66">Pump Control</text>
<line x1="52" y1="724" x2="100" y2="724" stroke="#aa44aa" stroke-width="1.5"/>
<text x="108" y="728" font-family="Courier New" font-size="8" fill="#aa44aa">Ionizer PWM</text>

<!-- Notes -->
<rect x="760" y="600" width="300" height="130" rx="4" fill="#080808" stroke="#1a2a1a" stroke-width="1"/>
<text x="772" y="618" font-family="Courier New" font-size="9" fill="#2a4a2a" letter-spacing="2">NOTES</text>
<text x="772" y="636" font-family="Courier New" font-size="7.5" fill="#3a5a3a">All GNDs share common ground rail</text>
<text x="772" y="652" font-family="Courier New" font-size="7.5" fill="#3a5a3a">Use shielded cable for SDS011 UART</text>
<text x="772" y="668" font-family="Courier New" font-size="7.5" fill="#cc4422"> Ionizer: use MOSFET gate driver</text>
<text x="772" y="684" font-family="Courier New" font-size="7.5" fill="#cc4422"> 5kV output  insulate all wires</text>
<text x="772" y="700" font-family="Courier New" font-size="7.5" fill="#3a5a3a">MQ-7 needs 3min warmup before read</text>
<text x="772" y="716" font-family="Courier New" font-size="7.5" fill="#3a5a3a">TEG buck converter: XL4016 (5V/3A)</text>
<text x="772" y="732" font-family="Courier New" font-size="7.5" fill="#555555">github.com/yourhandle/vayu-scrubber</text>
</svg>
</body>
</html>

VAYU_CAD.html

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{width:1100px;height:820px;background:#f5f2ed;overflow:hidden;font-family:'Courier New',monospace}
</style>
</head>
<body>
<svg width="1100" height="820" viewBox="0 0 1100 820" style="background:#f5f2ed">

<!-- Title block -->
<rect x="0" y="0" width="1100" height="820" fill="none" stroke="#2a2a2a" stroke-width="2"/>
<line x1="0" y1="760" x2="1100" y2="760" stroke="#2a2a2a" stroke-width="1.5"/>
<line x1="700" y1="760" x2="700" y2="820" stroke="#2a2a2a" stroke-width="1"/>
<line x1="850" y1="760" x2="850" y2="820" stroke="#2a2a2a" stroke-width="1"/>
<text x="714" y="786" font-family="Courier New" font-size="10" fill="#2a2a2a" letter-spacing="1">PROJECT: VAYU</text>
<text x="714" y="800" font-family="Courier New" font-size="9" fill="#555" letter-spacing="1">Exhaust Scrubber v1.0</text>
<text x="714" y="814" font-family="Courier New" font-size="8" fill="#888">Prayagraj  Open Hardware</text>
<text x="858" y="786" font-family="Courier New" font-size="9" fill="#2a2a2a">SCALE: NTS</text>
<text x="858" y="800" font-family="Courier New" font-size="9" fill="#2a2a2a">UNITS: mm</text>
<text x="858" y="814" font-family="Courier New" font-size="8" fill="#888">MIT LICENSE</text>
<text x="20" y="780" font-family="Courier New" font-size="22" fill="#2a2a2a" letter-spacing="3" font-weight="700">VAYU</text>
<text x="20" y="800" font-family="Courier New" font-size="9" fill="#555" letter-spacing="2">CUSTOM PARTS  FABRICATION DRAWING</text>
<text x="20" y="814" font-family="Courier New" font-size="8" fill="#888">Sheet 1 of 1  All dims in millimeters</text>

<!--  MAIN PIPE ASSEMBLY (top, full width cross-section)  -->
<!-- Header -->
<text x="30" y="36" font-family="Courier New" font-size="11" fill="#2a2a2a" letter-spacing="2" font-weight="700">1. MAIN PIPE ASSEMBLY  CROSS SECTION</text>
<line x1="30" y1="42" x2="1070" y2="42" stroke="#2a2a2a" stroke-width="0.5"/>

<!-- Outer pipe -->
<rect x="60" y="70" width="980" height="120" rx="6" fill="none" stroke="#2a2a2a" stroke-width="2"/>
<!-- Inner bore -->
<rect x="60" y="82" width="980" height="96" rx="4" fill="#e8e8e8" stroke="#888" stroke-width="0.5"/>

<!-- Stage dividers -->
<line x1="305" y1="70" x2="305" y2="190" stroke="#2a2a2a" stroke-width="1.5"/>
<line x1="550" y1="70" x2="550" y2="190" stroke="#2a2a2a" stroke-width="1.5"/>
<line x1="795" y1="70" x2="795" y2="190" stroke="#2a2a2a" stroke-width="1.5"/>

<!-- Stage fills -->
<rect x="61" y="83" width="243" height="94" fill="#d0d8e0" opacity="0.6"/>
<rect x="306" y="83" width="243" height="94" fill="#f0e0b0" opacity="0.6"/>
<rect x="551" y="83" width="243" height="94" fill="#f0c8b0" opacity="0.6"/>
<rect x="796" y="83" width="243" height="94" fill="#b0c8e0" opacity="0.6"/>

<!-- Stage labels inside -->
<text x="183" y="126" text-anchor="middle" font-family="Courier New" font-size="9" fill="#445566" letter-spacing="1">STAGE 1</text>
<text x="183" y="139" text-anchor="middle" font-family="Courier New" font-size="8" fill="#667788">Cyclone / Mesh</text>
<text x="428" y="126" text-anchor="middle" font-family="Courier New" font-size="9" fill="#664400" letter-spacing="1">STAGE 2</text>
<text x="428" y="139" text-anchor="middle" font-family="Courier New" font-size="8" fill="#886622">Electrostatic</text>
<text x="673" y="126" text-anchor="middle" font-family="Courier New" font-size="9" fill="#662200" letter-spacing="1">STAGE 3</text>
<text x="673" y="139" text-anchor="middle" font-family="Courier New" font-size="8" fill="#884422">CuO Catalyst</text>
<text x="918" y="126" text-anchor="middle" font-family="Courier New" font-size="9" fill="#002244" letter-spacing="1">STAGE 4</text>
<text x="918" y="139" text-anchor="middle" font-family="Courier New" font-size="8" fill="#224466">Wet Scrubber</text>

<!-- Dimension line: total length -->
<line x1="60" y1="204" x2="1040" y2="204" stroke="#2a2a2a" stroke-width="0.8"/>
<line x1="60" y1="198" x2="60" y2="210" stroke="#2a2a2a" stroke-width="0.8"/>
<line x1="1040" y1="198" x2="1040" y2="210" stroke="#2a2a2a" stroke-width="0.8"/>
<text x="550" y="218" text-anchor="middle" font-family="Courier New" font-size="9" fill="#2a2a2a">1200 mm TOTAL LENGTH</text>

<!-- Dimension: pipe OD -->
<line x1="1050" y1="70" x2="1085" y2="70" stroke="#888" stroke-width="0.6"/>
<line x1="1050" y1="190" x2="1085" y2="190" stroke="#888" stroke-width="0.6"/>
<line x1="1070" y1="70" x2="1070" y2="190" stroke="#2a2a2a" stroke-width="0.8"/>
<line x1="1064" y1="70" x2="1076" y2="70" stroke="#2a2a2a" stroke-width="0.8"/>
<line x1="1064" y1="190" x2="1076" y2="190" stroke="#2a2a2a" stroke-width="0.8"/>
<text x="1082" y="134" font-family="Courier New" font-size="8" fill="#2a2a2a"> 70</text>
<text x="1082" y="145" font-family="Courier New" font-size="7" fill="#888">OD mm</text>

<!-- Stage widths -->
<text x="183" y="232" text-anchor="middle" font-family="Courier New" font-size="8" fill="#445566">245 mm</text>
<text x="428" y="232" text-anchor="middle" font-family="Courier New" font-size="8" fill="#664400">245 mm</text>
<text x="673" y="232" text-anchor="middle" font-family="Courier New" font-size="8" fill="#662200">245 mm</text>
<text x="918" y="232" text-anchor="middle" font-family="Courier New" font-size="8" fill="#002244">245 mm</text>

<!--  COLLECTOR PLATE (bottom left)  -->
<text x="30" y="270" font-family="Courier New" font-size="10" fill="#2a2a2a" letter-spacing="2" font-weight="700">2. COLLECTOR PLATE (6)  AL6061</text>
<line x1="30" y1="276" x2="370" y2="276" stroke="#2a2a2a" stroke-width="0.5"/>

<!-- Plate front view -->
<rect x="60" y="296" width="200" height="150" rx="2" fill="#f8f4e8" stroke="#2a2a2a" stroke-width="1.5"/>
<!-- bolt holes -->
<circle cx="80" cy="316" r="5" fill="none" stroke="#2a2a2a" stroke-width="1"/>
<circle cx="240" cy="316" r="5" fill="none" stroke="#2a2a2a" stroke-width="1"/>
<circle cx="80" cy="426" r="5" fill="none" stroke="#2a2a2a" stroke-width="1"/>
<circle cx="240" cy="426" r="5" fill="none" stroke="#2a2a2a" stroke-width="1"/>
<!-- centerlines -->
<line x1="60" y1="371" x2="260" y2="371" stroke="#2a2a2a" stroke-width="0.3" stroke-dasharray="6 3"/>
<line x1="160" y1="296" x2="160" y2="446" stroke="#2a2a2a" stroke-width="0.3" stroke-dasharray="6 3"/>

<!-- Plate dims -->
<line x1="60" y1="460" x2="260" y2="460" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="60" y1="454" x2="60" y2="466" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="260" y1="454" x2="260" y2="466" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="160" y="474" text-anchor="middle" font-family="Courier New" font-size="8" fill="#2a2a2a">100 mm</text>

<line x1="274" y1="296" x2="274" y2="446" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="268" y1="296" x2="280" y2="296" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="268" y1="446" x2="280" y2="446" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="286" y="374" font-family="Courier New" font-size="8" fill="#2a2a2a">150 mm</text>

<!-- Plate side view (thickness) -->
<rect x="300" y="360" width="12" height="150" rx="1" fill="#e8e4d8" stroke="#2a2a2a" stroke-width="1.5"/>
<line x1="326" y1="360" x2="360" y2="360" stroke="#888" stroke-width="0.5"/>
<line x1="326" y1="510" x2="360" y2="510" stroke="#888" stroke-width="0.5"/>
<line x1="340" y1="360" x2="340" y2="510" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="334" y1="360" x2="346" y2="360" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="334" y1="510" x2="346" y2="510" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="350" y="440" font-family="Courier New" font-size="8" fill="#2a2a2a">2 mm</text>
<text x="296" y="296" font-family="Courier New" font-size="7" fill="#888">SIDE</text>
<text x="64" y="293" font-family="Courier New" font-size="7" fill="#888">FRONT</text>

<!-- Bolt hole detail -->
<text x="60" y="492" font-family="Courier New" font-size="7.5" fill="#444">Bolt holes:  6mm, M6 clearance</text>
<text x="60" y="504" font-family="Courier New" font-size="7.5" fill="#444">Material: Al6061-T6, anodized face</text>
<text x="60" y="516" font-family="Courier New" font-size="7.5" fill="#444">Gap between plates: 8 mm</text>

<!--  MESH FILTER DISC (bottom center)  -->
<text x="420" y="270" font-family="Courier New" font-size="10" fill="#2a2a2a" letter-spacing="2" font-weight="700">3. MESH FILTER DISC (3)  SS316</text>
<line x1="420" y1="276" x2="740" y2="276" stroke="#2a2a2a" stroke-width="0.5"/>

<!-- Disc front view -->
<circle cx="570" cy="400" r="95" fill="#f0f0f0" stroke="#2a2a2a" stroke-width="1.5"/>
<!-- inner bore -->
<circle cx="570" cy="400" r="5" fill="none" stroke="#2a2a2a" stroke-width="1" stroke-dasharray="3 2"/>
<!-- mesh hatch -->
<g opacity="0.35" stroke="#555" stroke-width="0.5">
  <line x1="490" y1="320" x2="490" y2="480"/><line x1="510" y1="310" x2="510" y2="490"/>
  <line x1="530" y1="306" x2="530" y2="494"/><line x1="550" y1="305" x2="550" y2="495"/>
  <line x1="570" y1="305" x2="570" y2="495"/><line x1="590" y1="305" x2="590" y2="495"/>
  <line x1="610" y1="306" x2="610" y2="494"/><line x1="630" y1="310" x2="630" y2="490"/>
  <line x1="650" y1="320" x2="650" y2="480"/>
  <line x1="480" y1="380" x2="660" y2="380"/><line x1="475" y1="400" x2="665" y2="400"/>
  <line x1="480" y1="420" x2="660" y2="420"/><line x1="488" y1="360" x2="652" y2="360"/>
  <line x1="488" y1="440" x2="652" y2="440"/><line x1="498" y1="340" x2="642" y2="340"/>
  <line x1="498" y1="460" x2="642" y2="460"/><line x1="512" y1="322" x2="628" y2="322"/>
  <line x1="512" y1="478" x2="628" y2="478"/>
</g>
<!-- rim detail -->
<circle cx="570" cy="400" r="88" fill="none" stroke="#888" stroke-width="0.5" stroke-dasharray="4 2"/>

<!-- Disc dims -->
<line x1="475" y1="508" x2="665" y2="508" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="475" y1="502" x2="475" y2="514" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="665" y1="502" x2="665" y2="514" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="570" y="524" text-anchor="middle" font-family="Courier New" font-size="8" fill="#2a2a2a"> 190 mm (OD)   56 mm (bore ID)</text>

<!-- Thickness callout -->
<text x="440" y="296" font-family="Courier New" font-size="7.5" fill="#444">Thickness: 3 mm</text>
<text x="440" y="308" font-family="Courier New" font-size="7.5" fill="#444">Mesh: 20-mesh (0.8mm wire)</text>
<text x="440" y="320" font-family="Courier New" font-size="7.5" fill="#444">Press-fit into pipe ID groove</text>
<text x="440" y="332" font-family="Courier New" font-size="7.5" fill="#444">Material: SS316 woven wire cloth</text>

<!--  PELLET BASKET (bottom right)  -->
<text x="780" y="270" font-family="Courier New" font-size="10" fill="#2a2a2a" letter-spacing="2" font-weight="700">4. CuO PELLET BASKET  SS304</text>
<line x1="780" y1="276" x2="1070" y2="276" stroke="#2a2a2a" stroke-width="0.5"/>

<!-- Basket cross section -->
<rect x="820" y="296" width="220" height="170" rx="4" fill="#f8f0e8" stroke="#2a2a2a" stroke-width="1.5"/>
<!-- perforations -->
<g fill="none" stroke="#888" stroke-width="0.8" opacity="0.6">
  <circle cx="848" cy="324" r="4"/><circle cx="870" cy="324" r="4"/><circle cx="892" cy="324" r="4"/>
  <circle cx="914" cy="324" r="4"/><circle cx="936" cy="324" r="4"/><circle cx="958" cy="324" r="4"/>
  <circle cx="980" cy="324" r="4"/><circle cx="1002" cy="324" r="4"/>
  <circle cx="848" cy="350" r="4"/><circle cx="870" cy="350" r="4"/><circle cx="892" cy="350" r="4"/>
  <circle cx="914" cy="350" r="4"/><circle cx="936" cy="350" r="4"/><circle cx="958" cy="350" r="4"/>
  <circle cx="980" cy="350" r="4"/><circle cx="1002" cy="350" r="4"/>
  <circle cx="848" cy="376" r="4"/><circle cx="870" cy="376" r="4"/><circle cx="892" cy="376" r="4"/>
  <circle cx="914" cy="376" r="4"/><circle cx="936" cy="376" r="4"/><circle cx="958" cy="376" r="4"/>
  <circle cx="980" cy="376" r="4"/><circle cx="1002" cy="376" r="4"/>
  <circle cx="848" cy="402" r="4"/><circle cx="870" cy="402" r="4"/><circle cx="892" cy="402" r="4"/>
  <circle cx="914" cy="402" r="4"/><circle cx="936" cy="402" r="4"/><circle cx="958" cy="402" r="4"/>
  <circle cx="980" cy="402" r="4"/><circle cx="1002" cy="402" r="4"/>
  <circle cx="848" cy="428" r="4"/><circle cx="870" cy="428" r="4"/><circle cx="892" cy="428" r="4"/>
  <circle cx="914" cy="428" r="4"/><circle cx="936" cy="428" r="4"/><circle cx="958" cy="428" r="4"/>
  <circle cx="980" cy="428" r="4"/><circle cx="1002" cy="428" r="4"/>
  <circle cx="848" cy="454" r="4"/><circle cx="870" cy="454" r="4"/><circle cx="892" cy="454" r="4"/>
  <circle cx="914" cy="454" r="4"/><circle cx="936" cy="454" r="4"/><circle cx="958" cy="454" r="4"/>
  <circle cx="980" cy="454" r="4"/><circle cx="1002" cy="454" r="4"/>
</g>
<!-- flanged rim top/bottom -->
<rect x="812" y="296" width="236" height="10" rx="2" fill="#e8e4d8" stroke="#2a2a2a" stroke-width="1"/>
<rect x="812" y="456" width="236" height="10" rx="2" fill="#e8e4d8" stroke="#2a2a2a" stroke-width="1"/>

<!-- Basket dims -->
<line x1="820" y1="482" x2="1040" y2="482" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="820" y1="476" x2="820" y2="488" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="1040" y1="476" x2="1040" y2="488" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="930" y="496" text-anchor="middle" font-family="Courier New" font-size="8" fill="#2a2a2a">220 mm LENGTH</text>

<line x1="1052" y1="296" x2="1052" y2="466" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="1046" y1="296" x2="1058" y2="296" stroke="#2a2a2a" stroke-width="0.7"/>
<line x1="1046" y1="466" x2="1058" y2="466" stroke="#2a2a2a" stroke-width="0.7"/>
<text x="1062" y="385" font-family="Courier New" font-size="8" fill="#2a2a2a">60 mm</text>
<text x="1062" y="396" font-family="Courier New" font-size="7" fill="#888">height</text>

<!-- Basket specs -->
<text x="820" y="516" font-family="Courier New" font-size="7.5" fill="#444">Material: SS304 perforated sheet (1.5mm)</text>
<text x="820" y="528" font-family="Courier New" font-size="7.5" fill="#444">Hole dia: 3mm, 6mm pitch staggered</text>
<text x="820" y="540" font-family="Courier New" font-size="7.5" fill="#444">Flanged rim (10mm) for press-fit seal</text>
<text x="820" y="552" font-family="Courier New" font-size="7.5" fill="#444">Fill: 200g CuO pellets, 3mm dia.</text>
</svg>
</body>
</html>

Credits

devesh yadav
1 project • 1 follower

Comments