Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Onderdelen en benodigdheden

Arduino Nano R3 Aantal: 1
Texas Instruments ML-8511 UV-sensor Aantal: 1
128x64 OLED-display (SSD1306) Aantal: 1
MT3608 DC-DC step-up converter Aantal: 1
CR2 (3V) batterij Aantal: 1
CR2 batterijhouder Aantal: 1

Over dit project

Omdat ik mijn niet aan de zon kon blootstellen door een dermatologisch probleem, besteedde ik de tijd die ik anders op het strand had doorgebracht aan het bouwen van een ultraviolette-stralenmeter: de UltraV.

Het apparaat is gebouwd om een Arduino Nano rev3, met een UV-sensor, een DC/DC-converter om de 3V-batterijspanning op te voeren, en een klein OLED-display. Mijn hoofddoel was draagbaarheid: op elk moment en op elke plaats de UV-index kunnen aflezen.

Stap 1: Onderdelen

  • Microcontroller Arduino Nano rev.3
  • ML8511 UV-sensor
  • 128×64 OLED-display (SSD1306)
  • MT3608 DC-DC step-up converter
  • CR2-batterij
  • CR2-batterijhouder
  • Schakelaar
  • Behuizing

Stap 2: De sensor (ML8511)

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

De ML8511 (Lapis Semiconductors) is een UV-sensor geschikt voor binnen- en buitenshuis. De sensor heeft een ingebouwde operationele versterker die fotostroom omzet in spanning afhankelijk van de UV-intensiteit. Dit biedt een eenvoudige interface voor externe circuits zoals een ADC. In standby-modus is de stroomverbruik slechts 0,1 µA – ideaal voor lange batterijduur.

Kenmerken:

  • Fotodiode gevoelig voor UV-A en UV-B
  • Ingebouwde operationele versterker
  • Analoge spanninguitgang
  • Laag stroomverbruik (300 µA typ.) en lage standby-stroom (0,1 µA typ.)
  • Klein SMD-behuizing (4,0 × 3,7 × 0,73 mm, 12-pin keramische QFN)
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Let op: Ik kon geen UV-doorlatend materiaal vinden om de sensor te beschermen. Elke geteste afdekking (plastic, glas) dempt de UV-metingen. Kwarts glas zou ideaal zijn, maar was te duur. Ik besloot de sensor open in de lucht te monteren.

Stap 3: Bediening

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Om te meten: schakel het apparaat in, richt het naar de zon voor enkele seconden (uitgelijnd met de zonnestralen), en lees het display af.

  • Linkerwaarde (INSTANT): Directe meting (elke 200 ms).
  • Rechterwaarde (MAXIMUM): Hoogste waarde tijdens deze sessie – dit is de waarde die je gebruikt.
  • Linksonder (WHO-categorie): Laag, Matig, Hoog, Zeer hoog, Extreem – volgens WHO UV-index standaarden.

Stap 4: Batterijspanning en meting

Ik koos een CR2-batterij (800 mAh) omwille van formaat en capaciteit. Na een zomer lang gebruik meet de batterij nog 2,8 V – uitstekend. Het circuit trekt ~100 mA tijdens meting, maar een meting duurt slechts seconden. Omdat de nominale spanning 3V is, voegde ik een DC-DC step-up converter toe om de spanning naar 9V te brengen en op de Vin-pin aan te sluiten.

Voor batterijspanningsindicatie op het display gebruikte ik een analoge ingang (A2). Arduino analoge ingangen meten 0-5V, maar vereisen calibratie:

  1. Voed het circuit met de definitieve CR2-batterij (niet via USB).
  2. Meet de 5V op de Arduino 5V-pin (deze spanning is de ADC-referentie).
  3. Vul de gemeten waarde in de sketch in (voorbeeld: 5,023V):
voltage = ((long)sum / (long)NUM_SAMPLES * 5023) / 1024.0;

In de sketch wordt het gemiddelde over 10 samples genomen.

Stap 5: Schema en verbindingen

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Stap 6: Software

Voor het display gebruik ik de U8g2lib, zeer flexibel en krachtig voor OLED-displays met veel fonts en positioneringsopties.

Voor de spanningsmeting van de ML8511 gebruik ik de 3,3V referentiepins van de Arduino (nauwkeurigheid binnen 1%) als basis voor de ADC. Door een ADC-conversie op de 3,3V-pin (aangesloten op A1) en deze te vergelijken met de sensorlezing, verkrijgen we een accurate meting ongeacht de VIN-spanning (mits > 3,4V).

int uvLevel = averageAnalogRead(UVOUT);
int refLevel = averageAnalogRead(REF_3V3);
float outputVoltage = 3.3 / refLevel * uvLevel;

Download de volledige code (UltraV_OLED.ino.zip)

Stap 7: Behuizing

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Na mislukte pogingen een commercieel plastic doosje handmatig uit te zagen, ontwierp ik mijn eigen behuizing in CAD. Om het zo compact mogelijk te houden, monteerde ik de CR2-batterij extern aan de achterkant (batterijhouder gelijmd op de doos).

Download het STL-bestand voor de behuizing (UltraV.stl.zip)

Stap 8: Mogelijke toekomstige verbeteringen

  • Een UV-spectrometer gebruiken om echte real-time UV-indexwaarden te meten onder diverse omstandigheden (zeer duur).
  • Gelijktijdig de ML8511-output registreren met de Arduino.
  • Algoritme schrijven om ML8511-output te relateren aan echte UVI-waarde in real-time onder diverse atmosferische condities.

Stap 9: Afbeeldingen

UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting
UltraV: Draagbare UV-Index Meter voor Veilige Zonnbelichting

Stap 10: Credits

Code

UltraV (C/C++)

/* Fabio Marzocca @ 2018
   ADC-conversies zijn volledig afhankelijk van VCC. We nemen aan 5V, maar via USB kan dit 4,75-5,25V zijn.
   Oplossing: gebruik de accurate onboard 3,3V referentie (binnen 1%).
   Door ADC op 3,3V-pin (A1) te doen en te vergelijken met sensorlezing, krijgen we accurate meting ongeacht VIN (>3,4V).
   v2.0.0 - Juli 2018 - van 16x2 LCD naar OLED
   v2.0.1 - Sept 2018 - batterijleesfunctie gewijzigd */
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);

#define FIRST_ROW_Y 16
#define FIRST_ROW_X 16
#define BOX_H 38

const int UVOUT = A0;
const int REF_3V3 = A1;
const int VBATT = A2;
float maxUV = 0;

void setup() {
  pinMode(UVOUT, INPUT);
  pinMode(REF_3V3, INPUT);
  pinMode(VBATT, INPUT);
  u8g2.begin();
}

void loop() {
  u8g2.firstPage();
  do {
    int uvLevel = averageAnalogRead(UVOUT);
    int refLevel = averageAnalogRead(REF_3V3);
    float outputVoltage = 3.3 / refLevel * uvLevel;
    float uvIntensity = mapfloat(outputVoltage, 0.99, 2.6, 0.0, 15.0);
    readBattery();
    if (maxUV < uvIntensity) maxUV = uvIntensity;

    u8g2.drawFrame(0, FIRST_ROW_Y+1, 128, BOX_H);
    u8g2.setFont(u8g2_font_logisoso18_tf);
    u8g2.setCursor(10, 40); u8g2.print(uvIntensity); // INSTANT
    u8g2.setCursor(70, 40); u8g2.print(maxUV);      // MAXIMUM
    u8g2.setFont(u8g2_font_u8glib_4_tf);
    u8g2.setCursor(10, 52); u8g2.print(F("INSTANT"));
    u8g2.setCursor(75, 52); u8g2.print(F("MAXIMUM"));
    showUVCategory();
    u8g2.setCursor(88, 64); u8g2.print(F("F.Marzocca"));
  } while (u8g2.nextPage());
  delay(200);
}

void showUVCategory() {
  char strCat[12];
  byte categ = (byte)(maxUV + 0.5); // afronden
  if (categ >= 0 && categ < 3) strcpy(strCat, "LOW");
  else if (categ >= 3 && categ < 6) strcpy(strCat, "MODERATE");
  else if (categ >= 6 && categ < 8) strcpy(strCat, "HIGH !");
  else if (categ >= 8 && categ < 10) strcpy(strCat, "VERY HIGH!");
  else if (categ >= 11) strcpy(strCat, "EXTREME!");
  u8g2.setCursor(0, 64); u8g2.print(strCat);
}

int averageAnalogRead(int pinToRead) {
  byte numberOfReadings = 16;
  unsigned int runningValue = 0;
  for (int x = 0; x < numberOfReadings; x++) runningValue += analogRead(pinToRead);
  runningValue /= numberOfReadings;
  return runningValue;
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void readBattery() {
  long battery = readBattVcc();
  long VccMin = 2300;
  byte batteryBar;
  int barStep = 140;
  batteryBar = (battery - VccMin) / barStep;
  
  u8g2.setFont(u8g2_font_open_iconic_embedded_2x_t);
  u8g2.drawGlyph(1, FIRST_ROW_Y, 73); // batterij-icoon
  u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
  for (byte i = 1; i <= batteryBar; i++) {
    u8g2.drawGlyph(128 - 9*i, FIRST_ROW_Y - 4, 75); // vulling
  }
  u8g2.setFont(u8g2_font_freedoomr10_tu);
  u8g2.setCursor(25, FIRST_ROW_Y);
  u8g2.print(float(battery)/1000, 3); // spanning in V
}

long readBattVcc() {
  int sum = 0, sample_count = 0;
  long voltage = 0;
  #define NUM_SAMPLES 10
  while (sample_count < NUM_SAMPLES) {
    sum += analogRead(VBATT);
    sample_count++;
    delay(2);
  }
  // 5020 mV = gecalibreerde referentiespanning voor dit project
  voltage = ((long)sum / (long)NUM_SAMPLES * 5020) / 1024.0;
  return voltage; // in millivolt
}

Productieproces

  1. Draagbare puntlasmachines: definitie, werking en voordelen
  2. Kiezen tussen vaste en draagbare CMM-meetmachines: Wat u moet weten
  3. De Essentiële Rol van Automotive Accu's: Uw Voertuig Voeden
  4. Hoe Uw Dynamo Te Testen: Expert Methodes voor Betrouwbare Resultaten
  5. 7 duidelijke signalen dat uw dynamo defect is
  6. Spanningsdeler Lab: Ontwerp, Meting en Verificatie van Kirchhoffs Spanningswet
  7. Een Aardappelbatterij Bouwen: Stapsgewijze Handleiding voor DIY Elektrochemische Energie
  8. Meetapparaatontwerp begrijpen: van klassieke galvanometers tot moderne digitale displays
  9. Multimeters: van analog naar digitaal – een uitgebreide gids
  10. Batterijconstructie fundamenteel: cellen, interne weerstand, en connectiviteit
  11. Batterijcapaciteit begrijpen: Ampère-uur waarden en conditietesten