Components and supplies
Arduino Nano R3
CR2 (3v) battery
CR2 battery holder
MT3608 DC-DC stup-up converter
128x64 OLED display
ML-8511
Project description
Code
UltraV
c_cpp
Code
1 /* 2 Fabio Marzocca @ 2018 3 Analog to digital conversions rely completely on VCC. We assume 4 this is 5V but if the board is powered from USB this may be as high as 5.25V or as low as 4.75V: 5 http://en.wikipedia.org/wiki/USB#Power Because of this unknown window it makes the ADC fairly inaccurate 6 in most cases. To fix this, we use the very accurate onboard 3.3V reference (accurate within 1%). So by doing an 7 ADC on the 3.3V pin (A1) and then comparing this against the reading from the sensor we can extrapolate 8 a true-to-life reading no matter what VIN is (as long as it's above 3.4V). 9 10v. 2.0.0 - July 2018 11 - moved from 16x2 LCD to OLED 12v. 2.0.1 - Sept 2018 13 - changed read battery function 14*/ 15 16#include <Arduino.h> 17#include <U8g2lib.h> 18#include <Wire.h> 19 20U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display 21 22#define FIRST_ROW_Y 16 23#define FIRST_ROW_X 16 24#define BOX_H 38 25 26//Hardware pin definitions 27const int UVOUT = A0; //Output from the sensor 28const int REF_3V3 = A1; //3.3V power on the Arduino board 29const int VBATT = A2; //Battery voltage 30 31float maxUV = 0; //Max UV index read 32 33 34void setup() 35{ 36 pinMode(UVOUT, INPUT); 37 pinMode(REF_3V3, INPUT); 38 pinMode(VBATT, INPUT); 39 40 u8g2.begin(); 41 42} 43 44void loop() 45{ 46 u8g2.firstPage(); 47 do { 48 int uvLevel = averageAnalogRead(UVOUT); 49 int refLevel = averageAnalogRead(REF_3V3); 50 51 //Use the 3.3V power pin as a reference to get a very accurate output value from sensor 52 float outputVoltage = 3.3 / refLevel * uvLevel; 53 54 float uvIntensity = mapfloat(outputVoltage, 0.99, 2.6, 0.0, 15.0); //Convert the voltage to a UV intensity level 55 56 readBattery(); 57 if (maxUV < uvIntensity) { 58 maxUV = uvIntensity; 59 } 60 u8g2.drawFrame(0,FIRST_ROW_Y+1,128,BOX_H); 61 u8g2.setFont(u8g2_font_logisoso18_tf); 62 63 //Instant UV 64 u8g2.setCursor(10,40); 65 u8g2.print(uvIntensity); 66 //UV Max 67 u8g2.setCursor(70,40); 68 u8g2.print(maxUV); 69 70 u8g2.setFont(u8g2_font_u8glib_4_tf); 71 u8g2.setCursor(10,52); u8g2.print(F("INSTANT")); 72 u8g2.setCursor(75,52); u8g2.print(F("MAXIMUM")); 73 74 showUVCategory(); 75 u8g2.setCursor(88,64); u8g2.print(F("F.Marzocca")); 76 77 } while ( u8g2.nextPage() ); 78 delay(200); 79} 80 81// Reads maxUV and prints the UV category 82void showUVCategory() { 83 char strCat[12]; 84 85 byte categ = (byte)(maxUV+0.5); //round up 86 if ((categ >= 0) && (categ < 3)) { 87 strcpy(strCat, "LOW"); 88 } else if ((categ >= 3) && (categ < 6)) { 89 strcpy(strCat, "MODERATE"); 90 } else if ((categ >= 6) && (categ < 8)) { 91 strcpy(strCat, "HIGH !"); 92 } else if ((categ >= 8) && (categ < 10)) { 93 strcpy(strCat, "VERY HIGH!"); 94 } else if (categ >= 11) { 95 strcpy(strCat, "EXTREME!"); 96 } 97 98 u8g2.setCursor(0,64); 99 u8g2.print(strCat); 100 101} 102 103//Takes an average of readings on a given pin 104//Returns the average 105int averageAnalogRead(int pinToRead) 106{ 107 byte numberOfReadings = 16; 108 unsigned int runningValue = 0; 109 110 for(int x = 0 ; x < numberOfReadings ; x++) 111 runningValue += analogRead(pinToRead); 112 runningValue /= numberOfReadings; 113 114 return(runningValue); 115} 116 117//The Arduino Map function but for floats 118//From: http://forum.arduino.cc/index.php?topic=3922.0 119float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) 120{ 121 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 122} 123 124void readBattery() { 125 long battery = readBattVcc(); 126 long VccMin = 2300; //Battery minimum voltage read on Vcc 127 byte batteryBar; //Battery progress bar 128 int barStep = 140; //step for battery progress bar (235) 129 130 batteryBar = (battery - VccMin)/barStep; 131 132 //battery icon 133 u8g2.setFont(u8g2_font_open_iconic_embedded_2x_t); 134 u8g2.drawGlyph(1, FIRST_ROW_Y, 73 ); 135 136 // battery status cursor 137 u8g2.setFont(u8g2_font_open_iconic_play_1x_t); 138 for (byte i=1; i<=batteryBar; i++) { 139 u8g2.drawGlyph( 128-9*i,FIRST_ROW_Y-4,75); 140 } 141 142 // battery voltage 143 u8g2.setFont(u8g2_font_freedoomr10_tu); 144 u8g2.setCursor(25, FIRST_ROW_Y); 145 u8g2.print(float(battery)/1000, 3); 146 147} 148 149 150long readBattVcc() 151{ 152 int sum=0; 153 int sample_count=0; 154 long voltage= 0; 155 #define NUM_SAMPLES 10 156 // take a number of analog samples and add them up 157 while (sample_count < NUM_SAMPLES) { 158 sum += analogRead(VBATT); 159 sample_count++; 160 delay(2); 161 } 162 // calculate the voltage 163 // use 5000 for a 5.0V ADC reference voltage 164 // 5020V is the calibrated reference voltage (in millivolts) for my project 165 voltage = ((long)sum / (long)NUM_SAMPLES * 5020) / 1024.0; 166 return voltage; //Vbattery in millivolts 167} 168 169 170 171 172 173
Comments
Only logged in users can leave comments
fmarzocca
0 Followers
•0 Projects
Table of contents
Intro
12
0