Back to Parent

#include <math.h>


int clokfreq= 10; //Overall timer of the clock
float freq = 1/clokfreq;

int brightness = 255; // Full brightness for an CATHODE RGB LED is 0, OFF is 255

int redPin = D2;    // RED pin of the LED to PWM pin **d2**
int greenPin = D3;  // GREEN pin of the LED to PWM pin **d3**
int bluePin = D4;   // BLUE pin of the LED to PWM pin **D4**
int ePins[] = {redPin, greenPin, bluePin}; //RGB
int eColor[] = {250,250,250};
int eNull[] = {0,0,0};

//Create Light Sensor related variables
int lightPin = A1; //LIghtsensor
int lightLevel = 0;

// Create Temparature sensor related variables
int tempPin = A0; //Temparature sensor
double temperature = 0.0;
double temperatureF = 0.0;
int movAverage[] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};
int reading = 0;
int avetemp = 0;

bool tempNormal = false;

int last_published = -1;

bool demomode = true;
int ndemo = 0;


void setup() {

    //Initialise the pins
    pinMode(redPin, OUTPUT);
    pinMode(bluePin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(lightPin, INPUT);
    
    //Create output monitoring variables to Console - RGB
    Particle.variable("Red", eColor[0]);
    Particle.variable("Green", eColor[1]);
    Particle.variable("Blue", eColor[2]);
    
    Particle.function("vRed", changeLED);
    
    // Register a Particle variable here
    Particle.variable("temperature", &temperature, DOUBLE);
    Particle.variable("temperatureF", &temperatureF, DOUBLE);

    // Connect the temperature sensor to A0 and configure it
    // to be an input
    pinMode(tempPin, INPUT);
    
    testCycle();
    
}

int changeLED(String command){
//    int colorValue = command.toInt();;
//    outputt(colorValue, 0, 0);
//    return 1;
}

void testCycle(){
    eColor[0] = 0;
    eColor[1] = 255;
    eColor[2] = 0;
    for (int i = 0; i < 3; i++){
        outputt(eColor);
        delay(500);
        outputt(eNull);
        delay(500);    
    }
}

//Output the passed vector Value to the LED
void outputt(int outCol[3]){
    analogWrite(redPin, 255-outCol[0]);
    analogWrite(greenPin, 255-outCol[1]);
    analogWrite(bluePin, 255-outCol[2]);
}


//Pulse according to sine grap, nticks = number of clock cycles, tickval = distance in sine space
//amp = amplitude of sinegraph scalar; pticks = array of pause positions; pdurs = array of pause durations
void pulse(int outCol[3], int nticks, float tickval, float amp, int pticks[2], int pdurs[2]){
    int noPauses = 2;
    
    float scycle = 0; //track the x position of sine graph
    float scal = 0; //the scalar -> y position of sine graph
    int redvaltmp, bluevaltmp, greenvaltmp;
    int tmpCol[3];
    
    
    for (int lp = 0; lp < nticks; lp++){
        scycle = scycle + tickval;
        scal = (amp*sin(scycle)+1)/2; //convert to 0-1 space scalar for led out
    
        for (int i = 0; i < 3; i++){
            tmpCol[i] = round(outCol[i] * scal);
        }
    
        outputt(tmpCol);
        
        for (int lp2 = 0; lp2 < noPauses; lp2++){
            if (lp == pticks[lp2]){
                delay(pdurs[lp2]);
            }
        }
        delay(clokfreq);
    }
}

//Repeat pulse n times, accept parameters for cycle length and number of cycles
void pulse_durxn(int outCol[3], int ncycles, float cyclelen){
    int pticks[2] = {0,0};
    int pdurs[2] = {0,0};
    
    pulse(outCol, round(ncycles*cyclelen/clokfreq), 6.284*clokfreq/cyclelen, 1, pticks, pdurs);
}

//Use pulse and add pauses at top and bottom 
void breath(int outCol[3], int ncycles, float in_out, float outhold, float inhold, float depth){
    
    // set the breakpoints at the top and bottom of the sine graph 25% and 75% for sine graph that starts at 0
    int pticks[2] = {round(0.25*2*in_out/clokfreq),round(0.75*2*in_out/clokfreq)};
    
    //pass the hold delays through
    int pdurs[2] = {inhold,outhold};
    
    //in_out*2 is equal to one period of the grpah
    //in_out is equal to a breath in cycle or breath our cycle
    //2 x in_out/clokfreq = number of ticks for 1 period
    //6.284/above term is the length of one tick in sine unit space to cover (6.284 = 2 x pi)
    //0.95 to nto use the full range
    for (int lp = 0; lp < ncycles; lp++){
        pulse(outCol, round(2*in_out/clokfreq), 6.284*clokfreq/(2*in_out), depth, pticks, pdurs);
    }
}

//Flicker a colour; nscale is the scaling of the clock
void flicker(int outCol[3], int nscale){
    byte flicker[] = {180, 30, 89, 23, 255, 200, 90, 150, 60 , 230, 180, 45, 90};
    int tmpCol[3];
    
    for (int i = 0; i < 13; i++){
        for (int i2 = 0; i2 < 3; i2++){
            tmpCol[i2] = round(outCol[i2]*flicker[i]/255);   
        }
        outputt(tmpCol);
        delay(round(clokfreq*nscale));
    }
}

void shiver(int outCol[3], int nscale){
    byte flicker[] = {180, 180, 30, 180, 180, 30, 180, 180, 30, 30};
    int tmpCol[3];
    
    for (int i = 0; i < 10; i++){
        for (int i2 = 0; i2 < 3; i2++){
            tmpCol[i2] = round(outCol[i2]*flicker[i]/255);   
        }
        outputt(tmpCol);
        delay(round(clokfreq*nscale));
    }
}   

float updatetemp(float newtemp){
    float agg = 0;
    agg = newtemp;
    float updateval = 0.0;
    for (int i = 0; i < 49; i++){
        movAverage[i] = movAverage[i+1];
        agg = agg + movAverage[i+1];
    }
    movAverage[49] = newtemp;
    updateval = agg/50;
    return(updateval);
}

void to_spreadsheet( ){

    //check if 1 minute has elapsed
    if( last_published + 60000 < millis() ){
    	Particle.publish( "log_to_spreadsheet", String( lightLevel  ) );
    	Particle.publish( "log_to_spreadsheet", String( avetemp  ) );
    	last_published = millis();
    }
}
	

void loop() {
    
    //PROC: read in all sensors INPUT: Get from sensors OUTPUT: sensLightIn; senTempIn; sensSoilIn
    
    //Read light level
    lightLevel = analogRead(lightPin);
    //Particle.publish("light_reading", String(lightLevel));
    
    //Read temp
    reading = analogRead(tempPin);
    // The returned value from the device is going to be in the range from 0 to 4095
    // Calculate the voltage from the sensor reading
    double voltage = (reading * 3.3) / 4095.0;
    // Calculate the temperature and update our static variable
    temperature = (voltage - 0.5) * 100;
    avetemp = updatetemp(temperature);
    // Now convert to Farenheight
    temperatureF = ((temperature * 9.0) / 5.0) + 32.0;
    
    //Code for demo mode
    int ncyc = 1;
    if (demomode == true){
        if (ndemo < ncyc){
            //normal
            lightLevel = 1500;
            avetemp = 15;
        }else{
            if (ndemo < 2*ncyc){
                //bright
                lightLevel = 2500;
                avetemp = 15;
            }else{
                if (ndemo < 3*ncyc){
                    lightLevel = 500;
                    avetemp = 15;
                }else{
                    if (ndemo < 8*ncyc){
                        lightLevel = 1500;
                        avetemp = 30;
                    }else{
                        if (ndemo < 12*ncyc){
                            lightLevel = 1500;
                            avetemp = -2;
                        }
                    }
                }   
            }
        }
        ndemo ++;
    }
    if (ndemo > 12*ncyc){
        ndemo = 0;
    }
    
    //OUtput to console for monitoring
    Particle.publish("temperature", String(temperature));
    Particle.publish("avetemp", String(avetemp));
  
    //PROC: emote - NOTE only two sensors implemented
        //If both Agg < and Imm < - emote urgent; 
        //If Agg < and Imm > - emote gentle
        //If Agg > then emote well
        // Hierarchy - Temp, Light, Water
        //Well - Green stable - Pulse breath DONE
        //Too Hot - Flicker flame - Flicker flame DONE
        //Too Cold - Shiver cold - SOLVED
        //Too Dark - Green dim
        //Too Bright - Green bright
        //Thirsty -  Sick looking blue - May be too difficult
        //Swamped - Yellow blue - May be too difficult 
        
    if (avetemp < 10){
         //shiver
        eColor[0] = 0; eColor[1] = 0; eColor[2] = 255; //Red works better
        shiver(eColor, 3); //set to 100ms 10x 10ms clock
        tempNormal = false;
    }else{
        if (avetemp > 25){
            //falme
            //eColor[0] = 89; eColor[1] = 35; eColor[2] = 13; //Flame color - did not work
            eColor[0] = 255; eColor[1] = 0; eColor[2] = 0; //Red works better
            flicker(eColor, 10); //set to 100ms 10x 10ms clock
            tempNormal = false;
        }else{
            tempNormal = true;
        }
    }
    
    Particle.publish("TempNormal", String(tempNormal));
    if (tempNormal == true){
        if (lightLevel < 1000){
            //Sleep
            eColor[0] = 0; eColor[1] = 255; eColor[2] = 0;
            breath(eColor, 4, 2000, 1000, 400, 0.8);    
        }else{
            if (lightLevel > 2000){
                //Pant
                eColor[0] = 0; eColor[1] = 255; eColor[2] = 0;
                breath(eColor, 8, 120, 20, 0, 0.9);    
            }else{
                //Live
                eColor[0] = 0; eColor[1] = 255; eColor[2] = 0;
                breath(eColor, 6, 1000, 800, 200, 0.8);
            }
        }
    }

    //Output to IFFFT    
    to_spreadsheet();
    
    //tick the clock over
    delay(clokfreq);
}
Click to Expand

Content Rating

Is this a good/useful/informative piece of content to include in the project? Have your say!

0