Der UV Sensor GYML8511 dient zum Messen der UV-Strahlung.
Was ist UV-Strahlung?
Ultraviolettstrahlung, kurz Ultraviolett, UV oder UV-Strahlung, umgangssprachlich ultraviolettes Licht, seltener und fälschlich Infraviolett-Strahlung, ist die für den Menschen unsichtbare elektromagnetische Strahlung mit Wellenlängen, die kürzer als das sichtbare Licht sind. Im elektromagnetischen Wellenspektrum schließt sich, ausgehend vom für den Menschen sichtbaren Bereich, dem Licht- oder Farbspektrum, an das Ultraviolett die Röntgenstrahlung an.
Die Bezeichnung ultraviolett (etwa „jenseits von Violett“) beruht darauf, dass sich das UV-Spektrum zu kürzeren Wellenlängen an Violett anschließt. Letzteres ist definitionsgemäß der für Menschen gerade noch wahrnehmbare Farbreiz. Wahrgenommen werden jene indirekt durch ultraviolette Strahlung zum Leuchten im sichtbaren Bereich angeregten fluoreszierenden Stoffe. Aus diesem Zusammenhang entstand für UV der umgangssprachliche Begriff Schwarzlicht. Scheinbar ohne Einfluss von Licht (vermeintlich schwarz) „leuchten“ Fluoreszenzflächen im Dunklen hell.
Seite „Ultraviolettstrahlung“. In: Wikipedia, Die freie Enzyklopädie. Bearbeitungsstand: 11. Mai 2017, 09:07 UTC. URL: https://de.wikipedia.org/w/index.php?title=Ultraviolettstrahlung&oldid=165405719(Abgerufen: 18. Mai 2017, 11:06 UTC)
Technische Daten
- Betriebsspannung 3,3 V
- max. Stromaufnahme 300µA
- Ruhestrom 0,1µA
Bezug
Der UV Sensor kann zum Beispiel über Amazon bezogen werden.
Schaltung
Das Modul verfügt über 5 PINs welche wie folgt mit dem Arduino Leonardo verbunden werden:
GYML8511 PIN | Arduino Leonardo |
---|---|
VIN | -bleibt frei- |
3V3 | 3,3V |
GND | Ground |
OUT | A0 |
EN | 3,3V |

Quellcode
Einfacher Ausbau zum Messen der UV-Strahlung
Um „nur“ einfach die UV-Strahlung zu messen & im seriellen Monitor auszugeben bedarf es folgenden einfachen Sketch.
int uvSensorIn = A0; //Analoger Eingang A0 const float inMin = 0.99; const float inMax = 2.9; const float outMin = 0.0; const float outMax = 15.0; const byte numberOfReadings = 8; void setup(){ pinMode(uvSensorIn, INPUT); Serial.begin(9600); //Starten der Seriellen Kommunikation mit 9600 baud } void loop(){ int uvLevel = averageAnalogRead(UVsensorIn); float outputVoltage = 3.3 * uvLevel/1024; float uvIntensity = mapfloat(outputVoltage, inMin, inMax, outMin, outMax); Serial.print(" UV Intensität: "); Serial.print(uvIntensity); Serial.println(" mW/cm^2"); delay(200); //Pause von 200ms. } //Ließt den PIN x mal und berechnet aus der Anzahl der gelesenen Werte den //Durchschnittswert und liefert diesen zurück. int averageAnalogRead(int pinToRead){ unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++){ runningValue += analogRead(pinToRead); } return(runningValue / numberOfReadings); } //Arduino map Funktion unterstützt kein Float daher wurde diese neu implementiert //(eine Kopie aus dem Arduino Forum) 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; }
Projekt „UV-A & UV-B Strahlung messen von 24h.“
Hier nun ein kleines Projekt mit dem Data logging Shield, welches ich hier schon beschrieben habe. Für dieses Projekt habe ich vom Arduino Leonardo zum Arduino Uno gewechselt.
Das Ganze wird natürlich schön wetterfest „eingetuppert“.
Und dann draußen positioniert.
Quellcode
Hier nun der Quellcode zum Projekt. Ich messe erstmal im 5min. Takt und auch nur über einen kurzen Zeitraum denn das Wetter oder vielmehr die Sonnenstrahlung ist zzt. nicht besonders daher wiederhole ich den Test im Juni / Juli wo die Werte wohl mehr Aussagekraft haben werden.
#include <SD.h> //SD Card Bibliothek #include <SPI.h> //Bibliothek zum zugriff auf die SPI Schnittstelle des Arduinos #include <Wire.h> #include <TimeLib.h> #include <DS1307RTC.h> File outFile; // Die Datei welche geschrieben bzw. gelesen werden soll int pinCS = 53; // Chip Select Pin 10 auf dem Arduino Uno String filename = "uvwert.csv"; //Dateiname der zu lesenden bzw. schreibenden Datei int uvSensorIn = A0; //Output from the sensor int REF_3V3 = A1; //3.3V power on the Arduino board int val; int dat; int index = 0; const float inMin = 0.99; const float inMax = 2.9; const float outMin = 0.0; const float outMax = 15.0; const byte numberOfReadings = 8; const char *monthName[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; tmElements_t tm; void setup() { Serial.begin(9600); //Serielle Kommunikation mit 9600 Baud beginnen pinMode(uvSensorIn, INPUT); pinMode(REF_3V3, INPUT); pinMode(pinCS, OUTPUT); if (SD.begin()){ //Wenn die SD Card initialisiert werden konnte dann.... Serial.println("SD Karte konnte erfolgreich geladen werden!"); //Ausgabe des Textes auf der Seriellen Schnittstelle } else { //Dieser Block wird ausgeführt wenn die SD Card nicht initialisiert werden konnte. Serial.println("SD Karte konnte NICHT erfolgreich geladen werden!"); //Ausgabe des Textes auf der Seriellen Schnittstelle Serial.println("---Programm wird beendet!"); //Ausgabe des Textes auf der Seriellen Schnittstelle return; //vorzeitiges beenden der setup Methode } } String getTimestamp(){ tmElements_t tm; String timestamp = "-error-"; //Meldung wenn die Zeit nicht gelesen werden konnte. if (RTC.read(tm)) { //Lesen der aktuellen Zeit timestamp = ""; timestamp += get2digits(tm.Day); //Tag timestamp += "."; timestamp += get2digits(tm.Month); //Monat timestamp += "."; timestamp += get2digits(tmYearToCalendar(tm.Year)); //Jahr timestamp += " "; timestamp += get2digits(tm.Hour); //Stunde timestamp += ":"; timestamp += get2digits(tm.Minute); //Minute timestamp += ":"; timestamp += get2digits(tm.Second); //Sekunde } return timestamp; } //Die Funktion liefert einen String Wert zurück welcher bei Zahlen < 10 mit führender Null beginnt. String get2digits(int number) { String val = ""; if (number >= 0 && number < 10) { val += "0"; } val += String(number); return val; } void writeContent(float uvIntensity, float uvLevel){ outFile = SD.open(filename, FILE_WRITE); //Öffnet bzw. erzeugt die Datei im Modus schreibend if (outFile) { //Wenn die Datei existiert dann... outFile.print(++index); //1. Spalte INDEX outFile.print(","); outFile.print(uvIntensity); //2. Spalte UV Intensität outFile.print(","); outFile.print(uvLevel); //3. Spalte UV Intensität outFile.print(","); outFile.print(getTimestamp()); //4. Spalte Zeitstempel outFile.println(""); outFile.close(); //Schließen der Datei (Dieses ist wichtig da sonst beim beenden des Sketches dies Daten verloren gehen können.) } else { //Dieser Block wird ausgeführt wenn die Datei nicht erzeugt werden konnte. Serial.println("Fehler beim öffnen der Datei test.txt"); //Ausgabe des Textes auf der Seriellen Schnittstelle } } //Liefert den WErt für die UV Intensität float readUVIntensityValue(){ int refLevel = averageAnalogRead(REF_3V3); int uvLevel = readUVLevelValue(); float outputVoltage = 3.3 / refLevel * uvLevel; float uvIntensity = mapfloat(outputVoltage, inMin, inMax, outMin, outMax); String value = " UV Intensity: "; value += uvIntensity; value += " mW/cm^2"; return uvIntensity; } //Liefert den Wert für den UV Level float readUVLevelValue(){ int uvLevel = averageAnalogRead(uvSensorIn); return uvLevel; } //Ließt den Wert vom analogen Eingang n mal und gibt den Durchschnittswert zurück. int averageAnalogRead(int pinToRead){ unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++){ runningValue += analogRead(pinToRead); } return (runningValue / numberOfReadings); //Berechnung des Durchschnittswertes. } 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 loop(){ //Schreibt die Werte vom UV Sensor auf die SD Card. writeContent(readUVIntensityValue(),readUVLevelValue()); delay(300000); // 5min. Pause bis zum nächsten durchlauf. }
Auswerten der Daten
Die Werte aus der CSV Datei müssen zuerst bearbeitet werden, denn das Dezimaltrennzeichen ist ein Komma „,“ und nicht ein Punkt „.“.
Dieses lässt sich in Microsoft Excel bzw. OpenOffice Calc durch „Suchen und Ersetzen“ lösen, oder man schreibt den Quellcode gleich so das die „Richtigen Werte“ geschrieben werden, dabei muss man jedoch darauf achten dass, das Trennzeichen für die CSV Datei dann als Semikolon „;“ gesetzt wird.
String formatFloatToGermanFloat(float value){ String strValue = String(value); char arr[strValue.length()]; strcpy(arr, strValue.c_str()); String result = ""; for(int i=0;i<sizeof(arr);i++){ Serial.println(arr[i]); if(arr[i] == '.'){ result += ","; } else { result += String(arr[i]); } } return result; }
Nachdem die Änderung nun vorgenommen wurde kann das Diagramm erzeugt werden. Ich nutze dafür OpenOffice Calc.