#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!
You must login before you can post a comment. .