Coding Pwm module.
Re: Coding Pwm module.
Well, since you don't show anything on a custom screen, you really don't need anything on your main code.
You could just load the PWM code on your PWM module.
You could just load the PWM code on your PWM module.
Roberto.
Re: Coding Pwm module.
Open the enclosure.
You will see a 6 pin header.
Connect the USB-TTL cable and upload the code the same way you do on the controller.
Black wire is GND
You will see a 6 pin header.
Connect the USB-TTL cable and upload the code the same way you do on the controller.
Black wire is GND
Roberto.
Re: Coding Pwm module.
Alright.Should I enter the complete code or only pwm expansion custom code in it?
Re: Coding Pwm module.
this one.ReefAngel.PWM.SetChannel(0,PWMParabola(9,0,17,0,10,90,0));
ReefAngel.PWM.SetChannel(1,PWMParabola(9,0,16,30,20,95,0));
ReefAngel.PWM.SetChannel(2,PWMParabola(9,0,20,0,0,100,0));
ReefAngel.PWM.SetChannel(3,PWMParabola(9,0,12,0,25,100,0));
byte Fan1Speed;
Fan1Speed=map(ReefAngel.Params.Temp[1],772,800,30,100); // Calculate Fan 1 speed
Fan1Speed=constrain(Fan1Speed,0,100);
ReefAngel.PWM.SetChannel(4,Fan1Speed);
byte Fan2Speed;
Fan2Speed=map(ReefAngel.Params.Temp[2],772,800,30,100); // Calculate Fan 2 speed
Fan2Speed=constrain(Fan2Speed,0,100);
ReefAngel.PWM.SetChannel(5,Fan2Speed);
Re: Coding Pwm module.
ok i am trying to upload the above code getting an error "expected constructor,destructor, or type conversion before'.' token "
Re: Coding Pwm module.
No. No that code.
You have to copy one of the codes that someone else created on the threads I posted earlier.
Complete pwm code that they posted, but change and adapt to your own setup.
Sent from my SPH-D700 using Tapatalk 2
You have to copy one of the codes that someone else created on the threads I posted earlier.
Complete pwm code that they posted, but change and adapt to your own setup.
Sent from my SPH-D700 using Tapatalk 2
Roberto.
Re: Coding Pwm module.
You could also try helping rufessor test his code.
http://forum.reefangel.com/viewtopic.ph ... 9480#p9480
http://forum.reefangel.com/viewtopic.ph ... 9480#p9480
Roberto.
Re: Coding Pwm module.
i am planning to use this code
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include "ReefAngel_Globals.h"
#include "ReefAngel_Features.h"
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
#include <Wire.h>
#include <avr/wdt.h>
#define LEDPWM0 0
#define LEDPWM1 1
#define LEDPWM2 2
#define LEDPWM3 3
#define LEDPWM4 4
#define LEDPWM5 5
//*********************************************************************************************************************************
//Globals integers
long calcSec(long,long);
long calcTime(long,long);
short Ndays; //Returns the number of day in the year
//*********************************************************************************************************************************
byte cloudduration=0;
int cloudstart=0;
int rhour = 0, rmin = 0, shour = 0, smin = 0;
byte PWMports[] ={
3,5,6,9,10,11};
byte ChannelValue[] = {
0,0,0,0,0,0};
// PWM, sunrisehour, sunriseminute, sunsethour, sunsetminute, cloudstarthout, cloudstartminute, cloudduration
byte SeasonsVar[]={
0,0,0,0,0,0,0,0};
byte cmdnum=255;
byte datanum=255;
void setup()
{
Serial.begin(57600);
Wire.begin(8);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
randomSeed(analogRead(0));
pinMode(3,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
//wdt_enable(WDTO_1S);
setSyncProvider(RTC.get); // the function to get the time from the RTC
setSyncInterval(SECS_PER_HOUR); // Changed to sync every hour.
now();
}
void loop()
{
wdt_reset();
//Serial.println(ChannelValue[0],DEC);
if (cmdnum!=255)
{
ProcessCMD(cmdnum,datanum);
cmdnum=255;
datanum=255;
}
Seasons();
CheckCloud();
//Serial.println("Start");
//Serial.println(ChannelValue[0],DEC);
//Serial.println(rhour,DEC);
//Serial.println(rmin,DEC);
//Serial.println(shour,DEC);
//Serial.println(smin,DEC);
//Serial.println(cloudstart/60,DEC);
//Serial.println(cloudstart%60,DEC);
//Serial.println(cloudduration,DEC);
for (int a=0;a<6;a++)
{
analogWrite(PWMports[a],ChannelValue[a]);
}
}
void receiveEvent(int howMany) {
wdt_reset();
if (howMany==5)
{
byte cmd1, cmd2, cmd3, cmd4, cmd5;
cmd1=Wire.receive();
cmd2=Wire.receive();
cmd3=Wire.receive();
cmd4=Wire.receive();
cmd5=Wire.receive();
if (cmd1=='$' && cmd2=='$' && cmd3=='$')
{
cmdnum=cmd4;
datanum=cmd5;
//Serial.println(cmd4,DEC);
//Serial.println(cmd5,DEC);
}
}
else
{
for (int a=0;a<howMany;a++)
{
Wire.receive();
}
}
}
void ProcessCMD(byte cmd, byte data)
{
wdt_reset();
// Individual Channel
if (cmd>=0 && cmd<=5)
{
ChannelValue[cmd]=data;
analogWrite(PWMports[cmd],data);
}
}
void requestEvent() {
SeasonsVar[0]=ChannelValue[0];
SeasonsVar[1]=rhour;
SeasonsVar[2]=rmin;
SeasonsVar[3]=shour;
SeasonsVar[4]=smin;
SeasonsVar[5]=cloudstart/60;
SeasonsVar[6]=cloudstart%60;
SeasonsVar[7]=cloudduration;
Wire.send(SeasonsVar,8);
}
//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
void CheckCloud()
{
// ------------------------------------------------------------
// Change the values below to customize your cloud/storm effect
// Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
// For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 1
// Percentage chance of a cloud happening today
// For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100
// Minimum number of minutes for cloud duration. Don't use max duration of less than 6
#define Min_Cloud_Duration 6
// Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 20
// Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 2
// Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 5
// Only start the cloud effect after this setting
// In this example, start could after 11:30am
#define Start_Cloud_After NumMins(11,00)
// Always end the cloud effect before this setting
// In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(17,00)
// Percentage chance of a lightning happen for every cloud
// For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100
// Channels used by the actinic LEDs on the PWM Expansion module
// These channels will not be dimmed when the cloud effect is triggered
// Number is a binary form. B001100 means channel 2 and 3 are used for actinics
#define Actinic_Channels B001110
// Channels used by the daylight LEDs on the PWM Expansion module
// These channels will be used for the spike when lightning effect is triggered
// Number is a binary form. B000011 means channel 0 and 1 are used for daylights
#define Daylight_Channels B000001
// Note: Make sure to choose correct values that will work within your PWMSLope settings.
// For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
// Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen
// results could happen.
// Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
// In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can
//fit in that 510 minutes window.
// It's a tight fit, but it did.
//#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process.
// Change the values above to customize your cloud/storm effect
// ------------------------------------------------------------
// Do not change anything below here
static byte cloudchance=255;
static byte numclouds=0;
static byte lightningchance=0;
static byte cloudindex=0;
static byte lightningstatus=0;
static int LastNumMins=0;
// Every day at midnight, we check for chance of cloud happening today
if (hour()==0 && minute()==0 && second()==0) cloudchance=255;
#ifdef forcecloudcalculation
if (cloudchance==255)
#else
if (hour()==0 && minute()==0 && second()==1 && cloudchance==255)
#endif
{
//Pick a random number between 0 and 99
cloudchance=random(100);
// if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
// Check if today is day for clouds.
if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0;
// If we have cloud today
if (cloudchance)
{
// pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
// pick the time that the first cloud will start
// the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day.
cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
// Now that we have all the parameters for the cloud, let's create the effect
if (cloudchance)
{
//is it time for cloud yet?
if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
{
// let's go through all channels to pick which ones will be dimmed
for (int a=0;a<6;a++)
{
if (bitRead(Actinic_Channels,a)==0)
{
// this will slope down the channel from the current PWM to 0 within 3minutes.
// then it will stay at 0 for the duration of the cycle
// and finally slope up from 0 to PWM value within 3 minutes
// it is basically an inversed slope
ChannelValue[a]=ReversePWMSlope(cloudstart,cloudstart+cloudduration,ChannelValue[a],0,180);
}
}
if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5)
{
for (int b=0;b<6;b++)
{
if (bitRead(Daylight_Channels,b)==1)
{
if (random(100)<20) lightningstatus=1;
else lightningstatus=0;
if (lightningstatus) ChannelValue=100;
else ChannelValue=0;
//delay(10);
}
else
{
ChannelValue=20;
}
}
}
}
if (NumMins(hour(),minute())>(cloudstart+cloudduration))
{
cloudindex++;
if (cloudindex < numclouds)
{
cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
}
}
//End Cloud Function
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Reverse PWM slope from cloud function
byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
long n=elapsedSecsToday(now());
cstart*=60;
cend*=60;
if (n<cstart) return PWMStart;
if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
if (n>cend) return PWMStart;
}
//End Reverse PWM function
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Calculate Sunrise/set by date & predefined season & rise/set times
void Seasons()
{
#define forceseasoncalculation
static byte ssn , ssnp , ssnpt ;
long stime, wstime, vstime, wrtime, rtime, vrtime;
int wrhour,wrmin,wrsec,wshour,wsmin,wssec,rsec,ssec,vrhour,vrmin,vrsec,vshour,vsmin,vssec;
int iDiffrise = 0;
int iDiffset = 0;
int risediffperday = 0;
int setdiffperday = 0;
int totalrise = 0;
int totalset = 0;
byte s=0;
int DaysPerYear;
//rise and set times set by hour and minute. there are 4 seasons however there are 8 highs & lows in rise and set throughout the year
//first spot is second half of winter starting jan 1st
int risehour[8]= {
7,7,7,6,6,5,6,6 };
int riseminute[8]={
00,30,00,30,00,30,00,30 };
int sethour[8] = {
17,18,18,19,19,19,19,18 };
int setminute[8] = {
30,00,30,00,00,30,00,00 };
//
if (hour()==0 && minute()==0 && second()==0) ssnp=0;
#ifdef forceseasoncalculation
if (ssnp==0)
#else
if (hour()==0 && minute()==0 && second()==1 && ssnp==0)
#endif
{
//leapyear or not - Define days per year
if (year()%4 == 0 && !(year()%100 == 0 && year()%400 != 0)) {
DaysPerYear=366;
}
//every other year
else {
DaysPerYear = 365;
}
//Call Day Number Calc
DayNumber(year(),month(),day());
//define days between begin and middle season
int seasons[9] ={
0,45,96,135,187,238,283,328,DaysPerYear };
//define season and array pulling variable
for (s=0; seasons[s] < Ndays; s++) ssn = s+1, ssnpt = s+1, ssnp = s;
//set loop on array time pulling variable to go back to beginning instead of increasing array size
if (ssn >= 7) ssn = 0;
//differece in seconds between season array times
long rise1 = calcSec(risehour[ssn],riseminute[ssn]);
long rise2 = calcSec(risehour[ssnp],riseminute[ssnp]);
iDiffrise = calcTime(rise1, rise2);
long set1 = calcSec(sethour[ssn],setminute[ssn]);
long set2 = calcSec(sethour[ssnp],setminute[ssnp]);
iDiffset = calcTime(set1,set2);
//calculate new sunrise/set difference from array value
//here we take the difference in day and get a difference in seconds per day. So if the time difference is 30 minutes from the last e
//uation we divide that by the start day of season subtracted by the end day of season to get the number of days in the season
//example: 30 minutes/(day 45 – day 0) = 30/45 = 0.66666
//0.66666 is the difference of minutes each day throughout the season for sunrise
risediffperday = iDiffrise/(seasons[ssnpt]-seasons[ssnp]);
totalrise = risediffperday*(Ndays - seasons[ssnp]);
setdiffperday = iDiffset/(seasons[ssnpt]-seasons[ssnp]);
totalset = setdiffperday*(Ndays - seasons[ssnp]);
//creating time in seconds
rtime=calcSec(risehour[ssnp],riseminute[ssnp]);
if (ssnp == 0 || ssnp == 2 || ssnp == 4 || ssnp == 6){
rtime -= totalrise;
}
else {
rtime += totalrise;
}
stime=calcSec(sethour[ssnp],setminute[ssnp]);
if (ssnp == 1 || ssnp == 3 || ssnp == 5 || ssnp == 7){
stime -= totalset;
}
else {
stime += totalset;
}
wrtime = rtime + 1200;
wstime = stime - 1200;
vrtime = rtime - 1200;
vstime = stime + 1200;
//turning seconds back to h m s
//here are three different times offset by half hour to have different colors rise and set at different times
//standard times
rhour=rtime/3600;
rtime=rtime%3600;
rmin=rtime/60;
rtime=rtime%60;
rsec=rtime;
if(rsec > 30) rmin++;
shour=stime/3600;
stime=stime%3600;
smin=stime/60;
stime=stime%60;
ssec=stime;
if(ssec > 30) smin++;
//to change the offset change the number 1200 in seconds added or subtracted to rtime
//half hour shorter
wrhour = wrtime/3600;
wrtime=wrtime%3600;
wrmin=wrtime/60;
wrtime=wrtime%60;
wrsec=wrtime;
if(wrsec>30) wrmin++;
wshour = wstime/3600;
wstime=wstime%3600;
wsmin=wstime/60;
wstime=wstime%60;
wssec=wstime;
if(wssec>30) wsmin++;
//half hour longer
vrhour = vrtime/3600;
vrtime=vrtime%3600;
vrmin=vrtime/60;
vrtime=vrtime%60;
vrsec=vrtime;
if(vrsec>30) vrmin++;
vshour = vstime/3600;
vstime=vstime%3600;
vsmin=vstime/60;
vstime=vstime%60;
vssec=vstime;
if(vssec>30) vsmin++;
//time for each active led channel to pull for sunrise
int Sunrise[2]={
rhour,rmin };
int Sunset[2]={
shour,smin };
int whSunrise[2]={
wrhour,wrmin };
int whSunset [2]={
wshour,wsmin };
int vSunrise[2]={
vrhour,vrmin };
int vSunset [2]={
vshour,vsmin };
ChannelValue[LEDPWM0]=PWMSlope(whSunrise[1],whSunrise[2],whSunset[1],whSunset[2],0,100,180,ChannelValue[LEDPWM0]);
ChannelValue[LEDPWM1]=PWMSlope(vSunrise[1],vSunrise[2],vSunset[1],vSunset[2],0,100,180,ChannelValue[LEDPWM1]);
ChannelValue[LEDPWM2]=PWMSlope(Sunrise[1],Sunrise[2],Sunset[1],Sunset[2],0,100,180,ChannelValue[LEDPWM2]);
ChannelValue[LEDPWM3]=PWMSlope(Sunrise[1],Sunrise[2],whSunset[1],whSunset[2],0,100,180,ChannelValue[LEDPWM3]);
//return Sunrise, Sunset, whSunrise,whSunset,vSunrise,vSunset;
}
}
//End Seasons Calculation
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Calculators for Seasons function
long calcSec(long hr, long minu)
{
long totalseconds;
totalseconds=(hr*3600)+(minu*60);
return totalseconds;
}
long calcTime(long seconds1, long seconds2)
{
long timediff=abs(seconds1-seconds2);
return timediff;
}
void DayNumber(unsigned int y, unsigned int m, unsigned int d)
{
int days[]={
0,31,59,90,120,151,181,212,243,273,304,334 }; // Number of days at the beginning of the month in a not leap year.
//Start to calculate the number of day
if (m==1 || m==2){
Ndays = days[(m-1)]+d; //for any type of year, it calculate the number of days for January or february
} // Now, try to calculate for the other months
else if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0){ //those are the conditions to have a leap year
Ndays = days[(m-1)]+d+1; // if leap year, calculate in the same way but increasing one day
}
else { //if not a leap year, calculate in the normal way, such as January or February
Ndays = days[(m-1)]+d;
}
}
//End calculators
//*********************************************************************************************************************************
my 5 & 6 channels are assigned to fans so what modification i need to do in the code?
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include "ReefAngel_Globals.h"
#include "ReefAngel_Features.h"
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
#include <Wire.h>
#include <avr/wdt.h>
#define LEDPWM0 0
#define LEDPWM1 1
#define LEDPWM2 2
#define LEDPWM3 3
#define LEDPWM4 4
#define LEDPWM5 5
//*********************************************************************************************************************************
//Globals integers
long calcSec(long,long);
long calcTime(long,long);
short Ndays; //Returns the number of day in the year
//*********************************************************************************************************************************
byte cloudduration=0;
int cloudstart=0;
int rhour = 0, rmin = 0, shour = 0, smin = 0;
byte PWMports[] ={
3,5,6,9,10,11};
byte ChannelValue[] = {
0,0,0,0,0,0};
// PWM, sunrisehour, sunriseminute, sunsethour, sunsetminute, cloudstarthout, cloudstartminute, cloudduration
byte SeasonsVar[]={
0,0,0,0,0,0,0,0};
byte cmdnum=255;
byte datanum=255;
void setup()
{
Serial.begin(57600);
Wire.begin(8);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
randomSeed(analogRead(0));
pinMode(3,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
//wdt_enable(WDTO_1S);
setSyncProvider(RTC.get); // the function to get the time from the RTC
setSyncInterval(SECS_PER_HOUR); // Changed to sync every hour.
now();
}
void loop()
{
wdt_reset();
//Serial.println(ChannelValue[0],DEC);
if (cmdnum!=255)
{
ProcessCMD(cmdnum,datanum);
cmdnum=255;
datanum=255;
}
Seasons();
CheckCloud();
//Serial.println("Start");
//Serial.println(ChannelValue[0],DEC);
//Serial.println(rhour,DEC);
//Serial.println(rmin,DEC);
//Serial.println(shour,DEC);
//Serial.println(smin,DEC);
//Serial.println(cloudstart/60,DEC);
//Serial.println(cloudstart%60,DEC);
//Serial.println(cloudduration,DEC);
for (int a=0;a<6;a++)
{
analogWrite(PWMports[a],ChannelValue[a]);
}
}
void receiveEvent(int howMany) {
wdt_reset();
if (howMany==5)
{
byte cmd1, cmd2, cmd3, cmd4, cmd5;
cmd1=Wire.receive();
cmd2=Wire.receive();
cmd3=Wire.receive();
cmd4=Wire.receive();
cmd5=Wire.receive();
if (cmd1=='$' && cmd2=='$' && cmd3=='$')
{
cmdnum=cmd4;
datanum=cmd5;
//Serial.println(cmd4,DEC);
//Serial.println(cmd5,DEC);
}
}
else
{
for (int a=0;a<howMany;a++)
{
Wire.receive();
}
}
}
void ProcessCMD(byte cmd, byte data)
{
wdt_reset();
// Individual Channel
if (cmd>=0 && cmd<=5)
{
ChannelValue[cmd]=data;
analogWrite(PWMports[cmd],data);
}
}
void requestEvent() {
SeasonsVar[0]=ChannelValue[0];
SeasonsVar[1]=rhour;
SeasonsVar[2]=rmin;
SeasonsVar[3]=shour;
SeasonsVar[4]=smin;
SeasonsVar[5]=cloudstart/60;
SeasonsVar[6]=cloudstart%60;
SeasonsVar[7]=cloudduration;
Wire.send(SeasonsVar,8);
}
//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
void CheckCloud()
{
// ------------------------------------------------------------
// Change the values below to customize your cloud/storm effect
// Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
// For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 1
// Percentage chance of a cloud happening today
// For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100
// Minimum number of minutes for cloud duration. Don't use max duration of less than 6
#define Min_Cloud_Duration 6
// Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 20
// Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 2
// Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 5
// Only start the cloud effect after this setting
// In this example, start could after 11:30am
#define Start_Cloud_After NumMins(11,00)
// Always end the cloud effect before this setting
// In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(17,00)
// Percentage chance of a lightning happen for every cloud
// For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100
// Channels used by the actinic LEDs on the PWM Expansion module
// These channels will not be dimmed when the cloud effect is triggered
// Number is a binary form. B001100 means channel 2 and 3 are used for actinics
#define Actinic_Channels B001110
// Channels used by the daylight LEDs on the PWM Expansion module
// These channels will be used for the spike when lightning effect is triggered
// Number is a binary form. B000011 means channel 0 and 1 are used for daylights
#define Daylight_Channels B000001
// Note: Make sure to choose correct values that will work within your PWMSLope settings.
// For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
// Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen
// results could happen.
// Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
// In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can
//fit in that 510 minutes window.
// It's a tight fit, but it did.
//#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process.
// Change the values above to customize your cloud/storm effect
// ------------------------------------------------------------
// Do not change anything below here
static byte cloudchance=255;
static byte numclouds=0;
static byte lightningchance=0;
static byte cloudindex=0;
static byte lightningstatus=0;
static int LastNumMins=0;
// Every day at midnight, we check for chance of cloud happening today
if (hour()==0 && minute()==0 && second()==0) cloudchance=255;
#ifdef forcecloudcalculation
if (cloudchance==255)
#else
if (hour()==0 && minute()==0 && second()==1 && cloudchance==255)
#endif
{
//Pick a random number between 0 and 99
cloudchance=random(100);
// if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
// Check if today is day for clouds.
if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0;
// If we have cloud today
if (cloudchance)
{
// pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
// pick the time that the first cloud will start
// the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day.
cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
// Now that we have all the parameters for the cloud, let's create the effect
if (cloudchance)
{
//is it time for cloud yet?
if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
{
// let's go through all channels to pick which ones will be dimmed
for (int a=0;a<6;a++)
{
if (bitRead(Actinic_Channels,a)==0)
{
// this will slope down the channel from the current PWM to 0 within 3minutes.
// then it will stay at 0 for the duration of the cycle
// and finally slope up from 0 to PWM value within 3 minutes
// it is basically an inversed slope
ChannelValue[a]=ReversePWMSlope(cloudstart,cloudstart+cloudduration,ChannelValue[a],0,180);
}
}
if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5)
{
for (int b=0;b<6;b++)
{
if (bitRead(Daylight_Channels,b)==1)
{
if (random(100)<20) lightningstatus=1;
else lightningstatus=0;
if (lightningstatus) ChannelValue=100;
else ChannelValue=0;
//delay(10);
}
else
{
ChannelValue=20;
}
}
}
}
if (NumMins(hour(),minute())>(cloudstart+cloudduration))
{
cloudindex++;
if (cloudindex < numclouds)
{
cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
}
}
//End Cloud Function
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Reverse PWM slope from cloud function
byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
long n=elapsedSecsToday(now());
cstart*=60;
cend*=60;
if (n<cstart) return PWMStart;
if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
if (n>cend) return PWMStart;
}
//End Reverse PWM function
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Calculate Sunrise/set by date & predefined season & rise/set times
void Seasons()
{
#define forceseasoncalculation
static byte ssn , ssnp , ssnpt ;
long stime, wstime, vstime, wrtime, rtime, vrtime;
int wrhour,wrmin,wrsec,wshour,wsmin,wssec,rsec,ssec,vrhour,vrmin,vrsec,vshour,vsmin,vssec;
int iDiffrise = 0;
int iDiffset = 0;
int risediffperday = 0;
int setdiffperday = 0;
int totalrise = 0;
int totalset = 0;
byte s=0;
int DaysPerYear;
//rise and set times set by hour and minute. there are 4 seasons however there are 8 highs & lows in rise and set throughout the year
//first spot is second half of winter starting jan 1st
int risehour[8]= {
7,7,7,6,6,5,6,6 };
int riseminute[8]={
00,30,00,30,00,30,00,30 };
int sethour[8] = {
17,18,18,19,19,19,19,18 };
int setminute[8] = {
30,00,30,00,00,30,00,00 };
//
if (hour()==0 && minute()==0 && second()==0) ssnp=0;
#ifdef forceseasoncalculation
if (ssnp==0)
#else
if (hour()==0 && minute()==0 && second()==1 && ssnp==0)
#endif
{
//leapyear or not - Define days per year
if (year()%4 == 0 && !(year()%100 == 0 && year()%400 != 0)) {
DaysPerYear=366;
}
//every other year
else {
DaysPerYear = 365;
}
//Call Day Number Calc
DayNumber(year(),month(),day());
//define days between begin and middle season
int seasons[9] ={
0,45,96,135,187,238,283,328,DaysPerYear };
//define season and array pulling variable
for (s=0; seasons[s] < Ndays; s++) ssn = s+1, ssnpt = s+1, ssnp = s;
//set loop on array time pulling variable to go back to beginning instead of increasing array size
if (ssn >= 7) ssn = 0;
//differece in seconds between season array times
long rise1 = calcSec(risehour[ssn],riseminute[ssn]);
long rise2 = calcSec(risehour[ssnp],riseminute[ssnp]);
iDiffrise = calcTime(rise1, rise2);
long set1 = calcSec(sethour[ssn],setminute[ssn]);
long set2 = calcSec(sethour[ssnp],setminute[ssnp]);
iDiffset = calcTime(set1,set2);
//calculate new sunrise/set difference from array value
//here we take the difference in day and get a difference in seconds per day. So if the time difference is 30 minutes from the last e
//uation we divide that by the start day of season subtracted by the end day of season to get the number of days in the season
//example: 30 minutes/(day 45 – day 0) = 30/45 = 0.66666
//0.66666 is the difference of minutes each day throughout the season for sunrise
risediffperday = iDiffrise/(seasons[ssnpt]-seasons[ssnp]);
totalrise = risediffperday*(Ndays - seasons[ssnp]);
setdiffperday = iDiffset/(seasons[ssnpt]-seasons[ssnp]);
totalset = setdiffperday*(Ndays - seasons[ssnp]);
//creating time in seconds
rtime=calcSec(risehour[ssnp],riseminute[ssnp]);
if (ssnp == 0 || ssnp == 2 || ssnp == 4 || ssnp == 6){
rtime -= totalrise;
}
else {
rtime += totalrise;
}
stime=calcSec(sethour[ssnp],setminute[ssnp]);
if (ssnp == 1 || ssnp == 3 || ssnp == 5 || ssnp == 7){
stime -= totalset;
}
else {
stime += totalset;
}
wrtime = rtime + 1200;
wstime = stime - 1200;
vrtime = rtime - 1200;
vstime = stime + 1200;
//turning seconds back to h m s
//here are three different times offset by half hour to have different colors rise and set at different times
//standard times
rhour=rtime/3600;
rtime=rtime%3600;
rmin=rtime/60;
rtime=rtime%60;
rsec=rtime;
if(rsec > 30) rmin++;
shour=stime/3600;
stime=stime%3600;
smin=stime/60;
stime=stime%60;
ssec=stime;
if(ssec > 30) smin++;
//to change the offset change the number 1200 in seconds added or subtracted to rtime
//half hour shorter
wrhour = wrtime/3600;
wrtime=wrtime%3600;
wrmin=wrtime/60;
wrtime=wrtime%60;
wrsec=wrtime;
if(wrsec>30) wrmin++;
wshour = wstime/3600;
wstime=wstime%3600;
wsmin=wstime/60;
wstime=wstime%60;
wssec=wstime;
if(wssec>30) wsmin++;
//half hour longer
vrhour = vrtime/3600;
vrtime=vrtime%3600;
vrmin=vrtime/60;
vrtime=vrtime%60;
vrsec=vrtime;
if(vrsec>30) vrmin++;
vshour = vstime/3600;
vstime=vstime%3600;
vsmin=vstime/60;
vstime=vstime%60;
vssec=vstime;
if(vssec>30) vsmin++;
//time for each active led channel to pull for sunrise
int Sunrise[2]={
rhour,rmin };
int Sunset[2]={
shour,smin };
int whSunrise[2]={
wrhour,wrmin };
int whSunset [2]={
wshour,wsmin };
int vSunrise[2]={
vrhour,vrmin };
int vSunset [2]={
vshour,vsmin };
ChannelValue[LEDPWM0]=PWMSlope(whSunrise[1],whSunrise[2],whSunset[1],whSunset[2],0,100,180,ChannelValue[LEDPWM0]);
ChannelValue[LEDPWM1]=PWMSlope(vSunrise[1],vSunrise[2],vSunset[1],vSunset[2],0,100,180,ChannelValue[LEDPWM1]);
ChannelValue[LEDPWM2]=PWMSlope(Sunrise[1],Sunrise[2],Sunset[1],Sunset[2],0,100,180,ChannelValue[LEDPWM2]);
ChannelValue[LEDPWM3]=PWMSlope(Sunrise[1],Sunrise[2],whSunset[1],whSunset[2],0,100,180,ChannelValue[LEDPWM3]);
//return Sunrise, Sunset, whSunrise,whSunset,vSunrise,vSunset;
}
}
//End Seasons Calculation
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//Calculators for Seasons function
long calcSec(long hr, long minu)
{
long totalseconds;
totalseconds=(hr*3600)+(minu*60);
return totalseconds;
}
long calcTime(long seconds1, long seconds2)
{
long timediff=abs(seconds1-seconds2);
return timediff;
}
void DayNumber(unsigned int y, unsigned int m, unsigned int d)
{
int days[]={
0,31,59,90,120,151,181,212,243,273,304,334 }; // Number of days at the beginning of the month in a not leap year.
//Start to calculate the number of day
if (m==1 || m==2){
Ndays = days[(m-1)]+d; //for any type of year, it calculate the number of days for January or february
} // Now, try to calculate for the other months
else if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0){ //those are the conditions to have a leap year
Ndays = days[(m-1)]+d+1; // if leap year, calculate in the same way but increasing one day
}
else { //if not a leap year, calculate in the normal way, such as January or February
Ndays = days[(m-1)]+d;
}
}
//End calculators
//*********************************************************************************************************************************
my 5 & 6 channels are assigned to fans so what modification i need to do in the code?
Re: Coding Pwm module.
I think the code you have above is already all set for channels 0-3.
You can leave the code for your fan (channels 4 and 5) in the main code. Just remove the stuff in your main code that references the channels 0-3.
I think it should work this way like you wanted.
You can leave the code for your fan (channels 4 and 5) in the main code. Just remove the stuff in your main code that references the channels 0-3.
I think it should work this way like you wanted.
Roberto.
Re: Coding Pwm module.
Hi Roberto,
the code is giving following error "wire.receive() has been renamed Wire.read().
the code is giving following error "wire.receive() has been renamed Wire.read().
Re: Coding Pwm module.
That code was probably developed prior to the release of Arduino 1.0
Just change wire.receive() to wire.read() and it should work.
Just change wire.receive() to wire.read() and it should work.
Roberto.
Re: Coding Pwm module.
I just tried the code you posted.
It was definitely coded for earlier version of Arduino.
You will also need to replace the header section to this:
It was definitely coded for earlier version of Arduino.
You will also need to replace the header section to this:
Code: Select all
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include "Globals.h"
#include "ReefAngel_Features.h"
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Wire.h>
#include <avr/wdt.h>
Roberto.
Re: Coding Pwm module.
Bingo. got the code done. now should i remove pwm expansion code from my head unit code
Re: Coding Pwm module.
yes. Just leave the channels 4 and 5, which are for fan speed control.
Roberto.
Re: Coding Pwm module.
If you ever want to go back to original PWM code.
- Attachments
-
- PWMExpansionCommands.ino
- (3.04 KiB) Downloaded 448 times
Roberto.
Re: Coding Pwm module.
my original code is working fine. i want to program my pwm module for sunrise & sunset effect with random cloud & lightning.
Re: Coding Pwm module.
Great.
Now that we have established that everything works, we can move on to next step.
Remove the lines in your code that reference the PWM channels 0-3 and load the pwm code into your PWM module.
Now that we have established that everything works, we can move on to next step.
Remove the lines in your code that reference the PWM channels 0-3 and load the pwm code into your PWM module.
Roberto.
Re: Coding Pwm module.
You posted one earlier:
http://forum.reefangel.com/viewtopic.php?p=9591#p9591
http://forum.reefangel.com/viewtopic.php?p=9591#p9591
Roberto.
Re: Coding Pwm module.
You may want to ask or send a pm to the author of that code.
Or, we can go with standard Parabola and forget about the seasonal sunrise/sunset calculation.
Or, we can go with standard Parabola and forget about the seasonal sunrise/sunset calculation.
Roberto.
Re: Coding Pwm module.
Alright.I want to change that code to work with 2 drivers instead of 4. what changes should i make?
The Author seems to be away from the forum as i tried to contact him by pm without any response.
The Author seems to be away from the forum as i tried to contact him by pm without any response.
Re: Coding Pwm module.
Well, let's try another code then.
Let's start simple again. This code is simply doing the Parabola.
Test it out and let me know if it works.
Let's start simple again. This code is simply doing the Parabola.
Test it out and let me know if it works.
Code: Select all
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include "Globals.h"
#include "ReefAngel_Features.h"
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Wire.h>
#include <avr/wdt.h>
byte PWMports[] ={
3,5,6,9,10,11};
byte ChannelValue[] = {
0,0,0,0,0,0};
byte cmdnum=255;
byte datanum=255;
void setup()
{
Serial.begin(57600);
Wire.begin(8);
Wire.onReceive(receiveEvent);
randomSeed(analogRead(0));
pinMode(3,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
wdt_enable(WDTO_1S);
setSyncProvider(RTC.get); // the function to get the time from the RTC
setSyncInterval(SECS_PER_HOUR); // Changed to sync every hour.
now();
}
void loop()
{
wdt_reset();
//Serial.println(ChannelValue[0],DEC);
if (cmdnum!=255)
{
ProcessCMD(cmdnum,datanum);
cmdnum=255;
datanum=255;
}
ChannelValue[0]=PWMParabola(9,0,20,0,0,100,0);
ChannelValue[1]=PWMParabola(9,0,20,0,0,100,0);
ChannelValue[2]=PWMParabola(9,0,20,0,0,100,0);
ChannelValue[3]=PWMParabola(9,0,20,0,0,100,0);
for (int a=0;a<6;a++)
{
analogWrite(PWMports[a],ChannelValue[a]);
}
}
void receiveEvent(int howMany) {
wdt_reset();
if (howMany==5)
{
byte cmd1, cmd2, cmd3, cmd4, cmd5;
cmd1=Wire.read();
cmd2=Wire.read();
cmd3=Wire.read();
cmd4=Wire.read();
cmd5=Wire.read();
if (cmd1=='$' && cmd2=='$' && cmd3=='$')
{
cmdnum=cmd4;
datanum=cmd5;
//Serial.println(cmd4,DEC);
//Serial.println(cmd5,DEC);
}
}
else
{
for (int a=0;a<howMany;a++)
{
Wire.read();
}
}
}
void ProcessCMD(byte cmd, byte data)
{
wdt_reset();
// Individual Channel
if (cmd>=0 && cmd<=5)
{
ChannelValue[cmd]=data;
}
}
Roberto.
Re: Coding Pwm module.
Roberto.
The Code is not working. I uploaded it on my pwm module & changed my basic code by removing pwm parabola function from it.
The Code is not working. I uploaded it on my pwm module & changed my basic code by removing pwm parabola function from it.
Re: Coding Pwm module.
How are you making sure it is not working?
Did you measure voltages?
Right now, the PWM module is not communicating with the controller and data won't show up on the Portal.
Did you measure voltages?
Right now, the PWM module is not communicating with the controller and data won't show up on the Portal.
Roberto.