0
\$\begingroup\$

I've been working on a project involving UV sensor readings using both an Arduino Uno and an ATTiny85. However, I've encountered discrepancies in the UV index values obtained from the two different microcontrollers. Below, I'll explain the setup, the code used, and the differences observed.

Setup Overview

  1. Arduino Uno Setup:

    • Reference Voltage: External 3.3V
    • UV Sensor Pin: A0
  2. ATTiny85 Setup:

    • Reference Voltage: Internal 1.1V
    • UV Sensor Pin: Analog pin 3 (corresponds to physical pin 2)
  3. ADAFRUIT GUVA-S12SD

Issue

Using the same UV sensor, the Arduino Uno provides a UV index of 10.25, while the ATTiny85 gives a reading of 8.25 for the same light conditions. Here are the detailed codes and explanations for both setups.

Arduino Uno Code

#ifdef __AVR_ATtiny85__
 #include <TinyWireM.h>
 #define Wire TinyWireM
#else
 #include <Wire.h>
#endif
#include <Tiny4kOLED.h> 
const int sampleCount = 20;
const int delayTime = 50;
float voltageSum, current, power, sum;
const float referenceVoltage = 3.3; // External reference of 3.3V
const int UVPin = A0; // Analog pin used
void setup() {
 // Serial.begin(9600);
 analogReference(EXTERNAL); // Use external reference of 3.3V
 
 oled.begin(); 
 oled.setFont(FONT8X16); 
 oled.clear();
 oled.switchRenderFrame();
 oled.clear();
 oled.switchRenderFrame();
 oled.deactivateScroll(); 
 oled.on(); 
}
void loop() {
 measureADA();
 delay(1000);
}
void measureADA() { 
 oled.clear();
 voltageSum = 0;
 for (int i = 0; i < sampleCount; i++) { 
 voltageSum += analogRead(UVPin); 
 delay(delayTime);
 }
 voltageSum = (voltageSum / sampleCount) * referenceVoltage / 1023.0;
 float correctedVoltage = voltageSum;
 if (correctedVoltage < 0) correctedVoltage = 0;
 current = correctedVoltage / 4.3; // I in uA
 power = current * 1000.0 / 113.0; // UV power in mW/cm2
 float uvIndex = (current * 1000.0 - 83.0) / 21.0;
 if (uvIndex < 0) uvIndex = 0; 
 
 oled.setCursor(1,1); 
 oled.print(uvIndex); 
}

ATTiny85 Code

#ifdef __AVR_ATtiny85__
 #include <TinyWireM.h>
 #define Wire TinyWireM
#else
 #include <Wire.h>
#endif
#include <Tiny4kOLED.h> 
const int sampleCount = 20;
const int delayTime = 50;
float voltageSum, current, power, sum;
const float referenceVoltage = 1.1; // Internal reference of 1.1V
const int UVPin = 3; // Analog pin used
void setup() {
 // Serial.begin(9600);
 analogReference(INTERNAL); // Use internal reference of 1.1V
 
 oled.begin(); 
 oled.setFont(FONT8X16); 
 oled.clear();
 oled.switchRenderFrame();
 oled.clear();
 oled.switchRenderFrame();
 oled.deactivateScroll(); 
 oled.on(); 
}
void loop() {
 measureADA();
 delay(1000);
}
void measureADA() { 
 oled.clear();
 voltageSum = 0;
 for (int i = 0; i < sampleCount; i++) { 
 voltageSum += analogRead(UVPin); 
 delay(delayTime);
 }
 voltageSum = (voltageSum / sampleCount) * referenceVoltage / 1023.0;
 float correctedVoltage = voltageSum;
 if (correctedVoltage < 0) correctedVoltage = 0;
 current = correctedVoltage / 4.3; // I in uA
 power = current * 1000.0 / 113.0; // UV power in mW/cm2
 float uvIndex = (current * 1000.0 - 83.0) / 21.0;
 if (uvIndex < 0) uvIndex = 0; 
 
 oled.setCursor(1,1); 
 oled.print(uvIndex); 
}

Do you see any mistakes?

Thanks

asked Jul 28, 2024 at 0:01
\$\endgroup\$
5
  • \$\begingroup\$ Everything is correct, 1.1 V gives an index of around 8.23. Higher sensor voltages leave the configured ADC conversion range of the Tiny85. \$\endgroup\$ Commented Jul 28, 2024 at 2:19
  • \$\begingroup\$ Also note that the datasheet for the Attiny85 gives a range for the internal reference from 1.0 to 1.2V. It's not exactly a precision reference. \$\endgroup\$ Commented Jul 28, 2024 at 5:44
  • \$\begingroup\$ @Jens so what can i do to have a maximum precision? Because two index différence is a lot for me... Change the attiny for other small MCU? thanks for that \$\endgroup\$ Commented Jul 28, 2024 at 8:38
  • \$\begingroup\$ Can you add a voltage divider between sensor and ADC, e.g. 20 : 10 kohm? In this case you need a voltage correction factor 3 in the code. \$\endgroup\$ Commented Jul 28, 2024 at 13:15
  • \$\begingroup\$ When you encounter this kind of issue, you should always short-circuit (figuratively speaking) any complex calculations by modifying the code to directly view the raw ADC value from the sensor and compare with the measured voltage at the input pin. \$\endgroup\$ Commented Jul 28, 2024 at 14:54

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.