#include <DS3232RTC.h> //
http://github.com/JChristensen/DS3232RTC
#include <Time.h> //
http://www.arduino.cc/playground/Code/Time
#include <Wire.h>
/*
Name: AquariumLight.ino
Created: 6/1/2017 11:26:47 AM
Author: Federico Favotto
*/
/*
Possible commands:
----------------------------
Sync time:
1 byte: 's'
8 bytes: time in long (Epoch)
----------------------------
Load program: (overwrite existing)
1 byte: 'l'
1 byte: number of segment, N
N segment:
byte c_index: user index from 0 (0,1,2,3,4)
byte c_pin: arduino pin for channelindex (3, 5, 6, 9, 10, and 11 for arduino Nano)
byte hours: 0-24 hours
byte minutes: 0-59 minutes
byte value: 0-255 value desired of digitalWrite when event ends
byte length: time to go to desired in minutes
----------------------------
Read program:
1 byte: 'r'
*/
#define DS3231_I2C_ADDRESS 0x68
#define SERIAL_BUFFER_LENGTH 200
#define DELAY_DEF 50 //delay in millis
#define BOOST_ON_START 50
float DELAY_WEIGHT;
struct c_status {
bool isActive;
int channelAd; //questo non servirebbe
float actualValue;
float inc; //increment of float
byte valueTo;
};
struct c_light_ev {
byte c_index;//index of channel
byte c_pin; //arduino pin for c_index
byte hours; //hours when starts
byte minutes; //minutes when starts
byte value; //the value to go with sin
byte length; //length of effect
};
char serialBuffer[SERIAL_BUFFER_LENGTH];
/*Se a true il byte meno significativo è memorizzato per primo*/
bool isLE = false;
int readed = 0;
int bytesReady = 0;
//hardcoded todo: change it!
int numberOfChannels = 0;
tmElements_t actualTime;
struct c_status* channel;
int eventsNumber;
struct c_light_ev* events;
byte eventsP = 0;
byte rtcRes;
void setup()
{
DELAY_WEIGHT = 60000 / DELAY_DEF; //NUMERO DI SCATTI IN un minuto;
Serial.begin(115200);
Serial.println("Hi");
setSyncProvider(RTC.get);
createTanganikaLight();
initializeChannels();
initTanganikaLight();
rtcRes = RTC.read(actualTime);
digitalClockDisplay(actualTime);
//dovrei portarmi in uno stato coerente
while ((eventsP<eventsNumber) && (actualTime.Hour > events[eventsP].hours || (actualTime.Hour == events[eventsP].hours && actualTime.Minute >= events[eventsP].minutes))) {
//devo calcolare la roba per sto events
byte idx = events[eventsP].c_index;
channel[idx].channelAd = events[eventsP].c_pin;
channel[idx].valueTo = events[eventsP].value;
channel[idx].inc = ((channel[idx].valueTo - channel[idx].actualValue) / (events[eventsP].length*DELAY_WEIGHT))*BOOST_ON_START; //per ora niente sinusoide
printChannelStatus(channel + idx);
eventsP++;// = (eventsP + 1) % eventsNumber;
}
Serial.print("eventsP: ");
Serial.print(eventsP);
Serial.println();
if (eventsP >= eventsNumber) {
//inSecondDay = true;
eventsP %= eventsNumber;
}
Serial.println("Controllo stato canali");
for (byte i = 0; i < numberOfChannels; i++) {
Serial.print("Canale Index: ");
Serial.print(i);
Serial.print(" Address: ");
Serial.println(channel
.channelAd);
delay(1000);
printChannelStatus(channel + i);
pinMode(channel.channelAd, OUTPUT);
if ((byte)(round(channel.actualValue)) != channel.valueTo) {
//printChannelStatus(channel + i);
channel.isActive = true;
}
}
Serial.println("Fine Setup");
delay(10000);
}
void loop() {
rtcRes = RTC.read(actualTime);
while (actualTime.Hour == events[eventsP].hours && actualTime.Minute == events[eventsP].minutes) {
//devo calcolare la roba per sto events
byte idx = events[eventsP].c_index;
channel[idx].channelAd = events[eventsP].c_pin;
channel[idx].valueTo = events[eventsP].value;
channel[idx].inc = (channel[idx].valueTo - channel[idx].actualValue) / (events[eventsP].length*DELAY_WEIGHT); //per ora niente sinusoide
channel[idx].isActive = true;
printChannelStatus(channel + idx);
eventsP++;// = (eventsP + 1) % eventsNumber;
if (eventsP >= eventsNumber) {
//inSecondDay = true;
eventsP %= eventsNumber;
}
}
for (byte i = 0; i < numberOfChannels; i++) {
if (channel.isActive) {
channel.actualValue = channel.actualValue + channel.inc;
float newVal = (round(channel.actualValue));
if (newVal < 0) newVal = 0;
analogWrite(channel[i].channelAd, (byte)newVal);
Serial.print("channel: ");
Serial.print(channel[i].channelAd);
Serial.print(" byte sent: ");
Serial.print((byte)newVal);
Serial.print(" float: ");
Serial.println(newVal, 4);
if (channel[i].inc>0 && channel[i].actualValue >= channel[i].valueTo) {
channel[i].isActive = false;
printChannelStatus(channel + i);
}
else if(channel[i].inc<0 && (round(channel[i].actualValue)) <= channel[i].valueTo) {
channel[i].isActive = false;
printChannelStatus(channel + i);
}
}
}
readFromSerial();
if (bytesReady > 0) {
manageSerialCommand();
}
delay(DELAY_DEF);
}
void printChannelStatus(struct c_status *c) {
Serial.print("c->channelAd: ");
Serial.print(c->channelAd);
Serial.print(" c->actualValue: ");
Serial.print(c->actualValue, 4);
Serial.print(" c->valueTo: ");
Serial.print(c->valueTo);
Serial.print(" c->isActive: ");
Serial.print(c->isActive);
Serial.print(" c->inc: ");
Serial.print(c->inc, 4);
Serial.println();
}
void initTanganikaLight() {
channel[0].channelAd = 5;
channel[1].channelAd = 6;
}
void createTanganikaLight() {
eventsNumber = 5;
events= (struct c_light_ev*) malloc(sizeof(c_light_ev)*eventsNumber);
numberOfChannels = 2;
//accendo tutti i bianchi
events[0].c_index = 1;
events[0].c_pin = 6;
events[0].hours = 9;
events[0].minutes = 0;
events[0].length = 20;
events[0].value = 255;
//accendo i blu fino a 30
events[1].c_index = 0;
events[1].c_pin = 5;
events[1].hours = 9;
events[1].minutes = 0;
events[1].length = 20;
events[1].value = 30;
//spengo i bianchi
events[2].c_index = 1;
events[2].c_pin = 6;
events[2].hours = 20;
events[2].minutes = 40;
events[2].length = 35;
events[2].value = 0;
//attenuo i blu
events[3].c_index = 0;
events[3].c_pin = 5;
events[3].hours = 20;
events[3].minutes = 50;
events[3].length = 25;
events[3].value = 1;
events[4].c_index = 0;
events[4].c_pin = 5;
events[4].hours = 21;
events[4].minutes = 16;
events[4].length = 5;
events[4].value = 0;
}
void initializeChannels() {
channel = (struct c_status*) malloc(sizeof(c_status)*numberOfChannels);
for (int i = 0; i < numberOfChannels; i++) {
channel[i].actualValue = 0;
channel[i].inc = 0.0;
channel[i].isActive = false;
channel[i].valueTo = 0;
}
}
void manageSerialCommand() {
//check command and if it's complete
//now it will only show time
}
void readFromSerial() {
while (Serial.available()) {
Serial.println("Sto per leggere");
readed = Serial.readBytes(serialBuffer + bytesReady, SERIAL_BUFFER_LENGTH - bytesReady);
bytesReady += readed;
Serial.print(readed);
Serial.println(" bytes letti");
}
}
void digitalClockDisplay(tmElements_t &tm)
{
// digital clock display of the time
Serial.print(tm.Hour);
Serial.print(":");
Serial.print(tm.Minute);
Serial.print(":");
Serial.print(tm.Second);
Serial.print(' ');
Serial.print(tm.Day);
Serial.print(' ');
Serial.print(tm.Month);
Serial.print(' ');
Serial.print(tm.Year);
Serial.println();
}
//
//void checkLE() {
// unsigned long l = 1;
// char* c = (char*)&l;
// isLE = (*c == 1);
//}
Desktop version