Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
UV Sense
void InitizlizeSerial()
{
Serial.begin(9600);
BTSerial.begin(9600);
delay (50);
BTSerial.println("OK!");
Serial.println("OK!");
while (SkinType <= 0 || SkinType >= 7) {
BTSerial.println("WAITING FOR SKIN TYPE");
Serial.println("WAITING FOR SKIN TYPE");
delay (5000);
if (BTSerial.available () > 0) {
SkinRead();
}
}
}
void initializeSetUp ()
{
//sleepSetUp();
pinMode(UVOUT, INPUT);
pinMode(REF_3V3, INPUT);
digitalWrite(resetPin, HIGH);
pinMode(13, OUTPUT);
pinMode(resetPin, OUTPUT);
SkinType = EEPROM.read (0); // apothikeusi tou tipou dermatos
SkinSwitch(); // dinei tin metavliti SkinTime apo EEPROM
ExposureTime = 1;
currentPersent = 0;
totalPersent = 0;
SPF = 1;
SetTimer(1, 30, 00); // HH,MM,SS set timer
if ((SkinType <= 0) || (SkinType >= 7)) {
SkinRead();
}
}
void setup()
{
// CLKPR = 0x80;
//CLKPR = 0x00; // 8 multiplyer on clock
initializeSetUp();
InitizlizeSerial();
}
void loop()
{
SerialIn();
Sample();
if ((SPFflag == 1) && (SPF > 1))
{
CountDownTimer();
}
else {
}
}
#include <Wire.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial BTSerial(10, 11);// RX Virtual ,TX Virtual
#define LED_PIN 13
#define Skin1 67
#define Skin2 100
#define Skin3 200
#define Skin4 300
#define Skin5 400
#define Skin6 500
#define noSPF 1
#define MillsMins 60000
#define intervalSample 5000
int UVOUT = A0; //Output from the sensor
int REF_3V3 = A1; //3.3V power on the Arduino board
float uvIntensity;
float outputVoltage;
int refLevel;
int uvLevel;
unsigned long Watch, _micro, time = micros();
unsigned int Clock = 0, R_clock;
boolean Reset = false, Stop = false, Paused = false;
volatile boolean timeFlag = false;
int SkinTime;
int SkinType;
float UVindex;
int SPF;
boolean SampleFlag;
int readSPF;
int readSkinType;
int currentSPF;
boolean SPFflag;
int resetPin = 9;
unsigned long previousMillis;
unsigned long currentMillis;
float currentPersent;
float totalPersent;
float lastPersent;
float ExposureSecsFloated;
unsigned int INTcastedBuzzzerPersent;
unsigned int ExposureTimeHours;
unsigned int ExposureTimeMin;
unsigned long ExposureTime;
unsigned long ExposureTimeSecs;
unsigned long ExposureTimeRemaining;
unsigned long ExTimeRemainingHours;
unsigned long ExTimeRemainingMins;
unsigned long SessionMillis;
unsigned int SessionMins;
int dLastPersent;
float Vout;
float Vin;
float volt;
float percent;
void Battery () {
#define Z1 150
#define Z2 510
Vout = analogRead(A2) * (3.3 / 1023.0);
Vin = (Z1 + Z2) / (Z2) * Vout;
volt = (float)readVcc() / 1000;
percent = ((Vin - 3) / 0.7) * 100;
}
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA, ADSC));
result = ADCL;
result |= ADCH << 8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
void Buzzer1 ()
{
Serial.print("BUZZER SENT: "); Serial.println(" REAPPLY SUNSREEN");
BTSerial.print("BUZZER SENT: "); BTSerial.println(" REAPPLY SUNSREEN");
BTSerial.print("*b1"); BTSerial.println("*");
Buzz();
}
void Buzzer2 ()
{
BTSerial.print("DANGEROUS LEVELS: "); BTSerial.println (totalPersent); BTSerial.println(" % OF DAILY EXPOSURE");
Serial.print("DANGEROUS LEVELS: "); Serial.println (totalPersent); Serial.println(" % OF DAILY EXPOSURE");
BTSerial.print("*b2"); BTSerial.println("*");
Buzz();
}
void Buzzer3 ()
{
BTSerial.print("LOW BATTERY LEVEL: "); BTSerial.println (totalPersent); BTSerial.println(" % OF DAILY EXPOSURE");
Serial.print("LOW BATTERY LEVEL: "); Serial.println (totalPersent); Serial.println(" % OF DAILY EXPOSURE");
BTSerial.print("*b3"); BTSerial.println("*");
Buzz();
}
void Buzz ()
{
for (int i = 0; i <= 20; i++) {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(250); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(250);
}
}
void Maths()
{
ExposureTimeRemaining = ((SkinTime - (SkinTime * (totalPersent / 100))) / uvIntensity) * SPF; // opou 12 uv index
ExTimeRemainingHours = ExposureTimeRemaining / 60;
ExTimeRemainingMins = ExposureTimeRemaining - (ExTimeRemainingHours * 60);
ExposureTime = (SkinTime / uvIntensity) * SPF; // opou 12 uv index
ExposureTimeSecs = ExposureTime * 60;
ExposureSecsFloated = (float) ExposureTimeSecs;
currentPersent = (100 * 5) / ExposureSecsFloated; // nomizo to 5 einai to 5 sec sample time
totalPersent = totalPersent + currentPersent;
ExposureTimeHours = ExposureTime / 60;
ExposureTimeMin = ExposureTime - (ExposureTimeHours * 60);
SessionMillis = millis();
SessionMins = SessionMillis / MillsMins;
}
void DangerPersent() {
int dCurentPersent = (int) totalPersent;
if ((dCurentPersent >= 90) && (dCurentPersent > dLastPersent)) {
Buzzer2();
}
dLastPersent = dCurentPersent;
}
void Sample()
{
currentMillis = millis();
if (currentMillis - previousMillis >= intervalSample) {
SampleFlag = 1;
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (SampleFlag == 1) {
UVread ();
Battery();
Maths();
DangerPersent();
SPFTimeCheck();
Print();
/* //BOD DISABLE - this must be called right before the __asm__ sleep instruction
MCUCR |= (3 << 5); //set both BODS and BODSE at the same time
MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); //then set the BODS bit and clear the BODSE bit at the same time
__asm__ __volatile__("sleep");//in line assembler to go to sleep*/
}
}
else {
SampleFlag == 0;
}
}
void SerialIn ()
{
if (BTSerial.available () > 0) {
if (BTSerial.peek() == 't') {
BTSerial.read () - 't';
Serial.read () - 't';
SkinRead();
}
else if (BTSerial.peek() == 's') {
BTSerial.read() - 's';
Serial.read() - 's';
SPFread();
ResetTimer();
}
else if (BTSerial.peek() == 'r') {
BTSerial.read() - 'r';
Serial.read() - 'r';
BTSerial.println("Command: RESET SPF TIMER");
Serial.println("Command: RESET SPF TIMER");
ResetTimer();
SPFflag = 1;
}
else if (BTSerial.peek() == 'n') {
BTSerial.read() - 'n';
Serial.read() - 'n';
BTSerial.println("Command: BUZZ");
Serial.println("Command: BUZZ");
Buzz();
}
else if (BTSerial.peek() == 'z') {
BTSerial.read() - 'z';
Serial.read() - 'z';
BTSerial.println("Command: DEVICE RESET");
Serial.println("Command: DEVICE RESET");
digitalWrite (resetPin, LOW);
}
while (BTSerial.available() > 0) {
BTSerial.read();
}
}
}
void Print()
{
BTSerial.print("*u"); BTSerial.print(uvIntensity); BTSerial.println("*");
BTSerial.print("*s"); BTSerial.print(SPF); BTSerial.println("*");
BTSerial.print("*r"); // remaining exposure time
BTSerial.print(ExTimeRemainingHours);
BTSerial.print(":");
BTSerial.print(ExTimeRemainingMins); BTSerial.println("*");
BTSerial.print("*p"); BTSerial.print (totalPersent); BTSerial.println("*");
BTSerial.print("*t"); // exposure time
BTSerial.print(ShowHours());
BTSerial.print(":");
BTSerial.print(ShowMinutes()); BTSerial.println("*");
BTSerial.flush ();
Serial.println("===================");
Serial.print("UV: "); Serial.println(uvIntensity);
Serial.print("Skin Type: "); Serial.println(SkinType);
Serial.print("Skin Time: "); Serial.println(SkinTime);
Serial.print("SPF: "); Serial.println(currentSPF);
Serial.print("SPF FLAG: "); Serial.println (SPFflag);
Serial.print("SPF Timer: ");
Serial.print(ShowHours());
Serial.print(":");
Serial.print(ShowMinutes());
Serial.print(":");
Serial.println(ShowSeconds());
Serial.print("Session Minutes: "); Serial.println(SessionMins);
Serial.print("Exposure Time Minutes: "); Serial.println(ExposureTime);
Serial.print("Exposure Time Seconds: "); Serial.println(ExposureTimeSecs);
Serial.print("Exposure Time: "); Serial.print(ExposureTimeHours); Serial.print(":"); Serial.println(ExposureTimeMin);
Serial.print("Exposure Time Remainning: "); Serial.print(ExTimeRemainingHours); Serial.print(":"); Serial.println(ExTimeRemainingMins);
Serial.print("Current Persent Done: "); Serial.print (currentPersent, 10); Serial.println(" %");
Serial.print("Casted Float Persent Done: "); Serial.print (totalPersent); Serial.println(" %");
Serial.print("Exposure Time Remaining: "); Serial.println (ExposureTimeRemaining);
Serial.print("Battery: "); Serial.print (percent); Serial.print (" % "); Serial.print(" / "); Serial.print (Vin); Serial.println(" V");
Serial.println("===================");
Serial.flush ();
BTSerial.print("UV: "); BTSerial.println(uvIntensity);
/* BTSerial.print("Skin Type: "); BTSerial.println(SkinType);
BTSerial.print("Skin Time: "); BTSerial.println(SkinTime);
BTSerial.print("SPF: "); BTSerial.println(SPF);
BTSerial.print("SPF FLAG: "); BTSerial.println (SPFflag); */
BTSerial.print("SPF Timer: ");
BTSerial.print(ShowHours());
BTSerial.print(":");
BTSerial.print(ShowMinutes());
BTSerial.print(":");
BTSerial.println(ShowSeconds());
BTSerial.print("Session Minuetes: "); BTSerial.println(SessionMins);
BTSerial.print("Exposure Time: "); BTSerial.print(ExposureTimeHours); BTSerial.print(":"); BTSerial.println(ExposureTimeMin);
BTSerial.print("Persent Done: "); BTSerial.print (totalPersent); BTSerial.println(" %");
//BTSerial.print("Expose Min Remaining: "); BTSerial.println (ExposureTimeRemaining);
BTSerial.print("Battery: "); BTSerial.print (percent); BTSerial.print (" % "); BTSerial.print(" / "); BTSerial.print (Vin); BTSerial.println (" V");
BTSerial.flush ();
}
void SkinRead()
{
BTSerial.println("ENTER SKIN TYPE");
Serial.println("ENTER SKIN TYPE");
while (BTSerial.available() == 0) {}
while (BTSerial.available() > 0) {
readSkinType = BTSerial.read () - '0';
delay(100);
if ((readSkinType > 0) && (readSkinType < 7)) {
if (SkinType != readSkinType) {
SkinType = readSkinType;
SkinSwitch();
EEPROM.write (0, SkinType);
digitalWrite (resetPin, LOW);
delay (5);
}
else {
}
}
else {
SkinRead();
}
}
}
void SkinSwitch()
{
switch (SkinType) {
case 1:
SkinTime = Skin1;
break;
case 2:
SkinTime = Skin2;
break;
case 3:
SkinTime = Skin3;
break;
case 4:
SkinTime = Skin4;
break;
case 5:
SkinTime = Skin5;
break;
case 6:
SkinTime = Skin6;
break;
}
}
void sleepSetUp() {
pinMode(LED_PIN, OUTPUT);
//Save Power by writing all Digital IO LOW - note that pins just need to be tied one way or another, do not damage devices!
for (int i = 0; i < 20; i++) {
if (i != 2) //just because the button is hooked up to digital pin 2
pinMode(i, OUTPUT);
}
attachInterrupt(0, digitalInterrupt, FALLING); //interrupt for waking up
//SETUP WATCHDOG TIMER
WDTCSR = (24);//change enable and WDE - also resets
WDTCSR = (33);//prescalers only - get rid of the WDE and WDCE bit
WDTCSR |= (1 << 6); //enable interrupt mode
//Disable ADC - don't forget to flip back after waking up if using ADC in your application ADCSRA |= (1 << 7);
ADCSRA &= ~(1 << 7);
//ENABLE SLEEP - this enables the sleep mode
SMCR |= (1 << 2); //power down mode
SMCR |= 1;//enable sleep
}
void digitalInterrupt() {
//needed for the digital input interrupt
}
ISR(WDT_vect) {
//DON'T FORGET THIS! Needed for the watch dog timer. This is called after a watch dog timer timeout - this is the interrupt function called after waking up
}// watchdog interrupt
void SPFread()
{
BTSerial.println("Command received: ENTER SPF LEVEL");
Serial.println("Command received: ENTER SPF LEVEL");
SPF = 0 ;
while (BTSerial.available() == 0) {}
while (BTSerial.available() > 0) {
byte incoming = BTSerial.read();
delay (50);
if (incoming >= '0' && incoming <= '9') {
SPF = (SPF * 10) + (incoming - '0');
delay (5);
}
}
currentSPF = SPF;
if (SPF > 1) {
SPFflag = 1;
}
else {
SPFflag = 0;
}
ResetTimer();
}
void SPFTimeCheck()
{
boolean flag;
int lastButtonState = 0;
int buttonState = SPFflag;
if ((ShowHours() == 0) && (ShowMinutes() == 0)) {
SPF = noSPF;
flag = 0;
}
else if ((ShowHours() > 0) || (ShowMinutes() > 0)) {
currentSPF = SPF;
flag = 1;
}
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
if (buttonState == flag) {
} else {
Buzzer1(); //BUZZER FUNCTION
SPFflag = 0;
}
}
lastButtonState = buttonState;
}
boolean CountDownTimer()
{
static unsigned long duration = 1000000; // 1 second
timeFlag = false;
if (!Stop && !Paused) // if not Stopped or Paused, run timer
{
// check the time difference and see if 1 second has elapsed
if ((_micro = micros()) - time > duration )
{
Clock--;
timeFlag = true;
if (Clock == 0) // check to see if the clock is 0
Stop = true; // If so, stop the timer
// check to see if micros() has rolled over, if not,
// then increment "time" by duration
_micro < time ? time = _micro : time += duration;
}
}
return !Stop; // return the state of the timer
}
void ResetTimer()
{
SetTimer(R_clock);
Stop = false;
}
void StartTimer()
{
Watch = micros(); // get the initial microseconds at the start of the timer
Stop = false;
Paused = false;
}
void StopTimer()
{
Stop = true;
}
void StopTimerAt(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
if (TimeCheck(hours, minutes, seconds) )
Stop = true;
}
void PauseTimer()
{
Paused = true;
}
void ResumeTimer() // You can resume the timer if you ever stop it.
{
Paused = false;
}
void SetTimer(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
// This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0
unsigned int _S = (seconds / 60), _M = (minutes / 60);
if (_S) minutes += _S;
if (_M) hours += _M;
Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
R_clock = Clock;
Stop = false;
}
void SetTimer(unsigned int seconds)
{
// StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60);
Clock = seconds;
R_clock = Clock;
Stop = false;
}
int ShowHours()
{
return Clock / 3600;
}
int ShowMinutes()
{
return (Clock / 60) % 60;
}
int ShowSeconds()
{
return Clock % 60;
}
unsigned long ShowMilliSeconds()
{
return (_micro - Watch) / 1000.0;
}
unsigned long ShowMicroSeconds()
{
return _micro - Watch;
}
boolean TimeHasChanged()
{
return timeFlag;
}
// output true if timer equals requested time
boolean TimeCheck(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
return (hours == ShowHours() && minutes == ShowMinutes() && seconds == ShowSeconds());
}
void UVread ()
{
uvLevel = averageAnalogRead(UVOUT);
refLevel = averageAnalogRead(REF_3V3);
outputVoltage = 3.3 / refLevel * uvLevel; //Use the 3.3V power pin as a reference to get a very accurate output value from sensor
uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0); //Convert the voltage to a UV intensity level
/*
Serial.print("output: ");
Serial.print(refLevel);
Serial.print("ML8511 output: ");
Serial.print(uvLevel);
Serial.print(" / ML8511 voltage: ");
Serial.print(outputVoltage);
Serial.print(" / UV Intensity (mW/cm^2): ");
Serial.print(uvIntensity);
Serial.println();
*/
}
int averageAnalogRead(int pinToRead) //Takes an average of readings on a given pin
{ //Returns the average
byte numberOfReadings = 8;
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) //The Arduino Map function but for floats
{ //From: http://forum.arduino.cc/index.php?topic=3922.0
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.