#include <OneWire.h>
#include <DallasTemperature.h>
#include <math.h>
// === Pin Assignments ===
#define PIN_ABSORB 6 // LDR AO for Absorbance
#define PIN_FLUOR 5 // LDR AO for Fluorescence
#define PIN_TURBID 4 // LDR AO for Turbidity
#define PIN_PH 7 // Potentiometer simulating pH
#define PIN_SAL 15 // Potentiometer simulating Salinity
#define PIN_TEMP 16 // DS18B20 Data pin
// === LED Pins for Optical Sources ===
#define LED_ABSORB 21
#define LED_FLUOR 20
#define LED_TURBID 19
// === DS18B20 Setup ===
OneWire oneWire(PIN_TEMP);
DallasTemperature tempSensor(&oneWire);
// === Smoothing function (EMA) ===
float smooth(float prev, float sample, float alpha = 0.1) {
return prev + alpha * (sample - prev);
}
// === Variables to hold smoothed readings ===
float absorbSm = 0, fluorSm = 0, turbidSm = 0, phSm = 0, salSm = 0;
// === Calibration constants ===
float baselineAbsorb = 3000; // Blank reference ADC for absorbance
void setup() {
Serial.begin(115200);
tempSensor.begin();
// Setup LEDs as outputs
pinMode(LED_ABSORB, OUTPUT);
pinMode(LED_FLUOR, OUTPUT);
pinMode(LED_TURBID, OUTPUT);
// Turn LEDs ON (continuous light sources)
digitalWrite(LED_ABSORB, HIGH);
digitalWrite(LED_FLUOR, HIGH);
digitalWrite(LED_TURBID, HIGH);
}
void loop() {
// === Read Analog Sensors ===
int rawAbsorb = analogRead(PIN_ABSORB);
int rawFluor = analogRead(PIN_FLUOR);
int rawTurbid = analogRead(PIN_TURBID);
int rawPH = analogRead(PIN_PH);
int rawSal = analogRead(PIN_SAL);
// === Apply smoothing ===
absorbSm = smooth(absorbSm, rawAbsorb);
fluorSm = smooth(fluorSm, rawFluor);
turbidSm = smooth(turbidSm, rawTurbid);
phSm = smooth(phSm, rawPH);
salSm = smooth(salSm, rawSal);
// === Convert to Engineering Units ===
// Absorbance (A = -log10(I/I0))
float T = (baselineAbsorb > 0) ? absorbSm / baselineAbsorb : 1;
if (T <= 0) T = 1e-6;
float absorbance = -log10(T);
// Fluorescence (%)
float fluorescence = map(fluorSm, 0, 4095, 0, 100);
// Turbidity (mock NTU)
float turbidity = map(turbidSm, 0, 4095, 0, 1000);
// pH (mock 0–14)
float pH = map(phSm, 0, 4095, 0, 140) / 10.0;
// Salinity (mock PSU 0–50)
float salinity = map(salSm, 0, 4095, 0, 50);
// Temperature (real DS18B20)
tempSensor.requestTemperatures();
float tempC = tempSensor.getTempCByIndex(0);
// === Print list with units ===
Serial.println("---- Sensor Readings ----");
Serial.print("Absorbance: "); Serial.print(absorbance, 3); Serial.println(" A (dimensionless)");
Serial.print("Fluorescence: "); Serial.print(fluorescence, 1); Serial.println(" %");
Serial.print("Turbidity: "); Serial.print(turbidity, 1); Serial.println(" NTU");
Serial.print("pH: "); Serial.println(pH, 2);
Serial.print("Salinity: "); Serial.print(salinity, 1); Serial.println(" PSU");
Serial.print("Temperature: "); Serial.print(tempC, 2); Serial.println(" °C");
Serial.println("-------------------------\n");
delay(1000); // 1s update
}