Assitance getting started

Hey guys,

Here is a quick rundown of what I am trying to accomplish. It seems simple in my mind but yet I am lost. I want to make my arduino output a certain PWM value based on time of day. I want it to ramp up and down as well. Say at 8AM start rising till it hits max around noon and stay there for 2 or 3 hours and then ramp down to end around 10 or 11pm.

I have an RTC and have been going through a couple of the example sketches. I have dabbled in programming but never really got serious about it.

I have done stuff like making the arduino read a button press and turn on a led, I have made it read from a temp sensor and serial.print the value return. Just basic stuff.

I am totally overwhelmed currently and not sure where to start. I want to get this part completed and working and my next goal will to be able to set what PWM value at what time through a keypad shield.

I am not expecting anyone to write it for me.

I figure I am going to have to write a for loop for the ramp up and a seperate for the ramp down. and maybe a third for the amount of time where there is to be no PWM value. Or maybe seperate functions for each of the periods. Ramp up, Ramp down, and idle.

Thanks for any guidance you guys can give

No for loops needed. Let loop() fun freely

Instead of the absolute time of day use the number of minutes since midnight
08:00 is 480
12:00 is 720
15:00 is 900
23:00 is 1380

When the minutes value is between 480 and 720 map() the difference to a rising PWM value
When the minute value is between 720 and 900 turn the PWM fully on
When the minutes value is between 900 and 1380 map() the difference to a falling PWM value

Thank you for replying. Right now I am focusing on being able to get the data I need from the DS1307. Do I need to use Wire for communication over I2C or do I need to use the RTC library? I cannot find anything showing how to get just the number of minutes since midnight.

I like your solution for dealing with the PWM value. I believe I can write the code for that. But first I need to understand how to get what I am needing from the DS1307. Thanks for the help again.

For single value for the day i think I have figured it out.

int day = ((hour * 60) + minute);

that should get it.

I am fairly sure this has been done before. I am still looking for some code that someone wrote that is similar to what I am wanting to do. But until I do I am gonna keep plugging along.

There are examples that come with libraries.
If you haven’t studied them, you should study them to see how things are done.

Also, see:

I have been reading and playing around. I am not totally lost…lol… almost but still.

So here is what I have so far. A lot of it was copied and pasted from examples, but there are a few things I have typed in.

#define DS1307_I2C_ADDRESS 0x68   
#include "Wire.h"                 
#include <LiquidCrystal.h>        


int blue = 3;
int white = 11; 
int bluemin = 0;
int whitemin = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


byte decToBcd(byte val)           
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)           
{
  return ( (val/16*10) + (val%16) );
}
                               
void setDateDs1307(byte second,   
byte minute,                      
byte hour,                        
byte dayOfWeek,                   
byte dayOfMonth,                 
byte month,                       
byte year)                       
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));    
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));      
                                  
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

                                 
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  second = 56;
  minute = 16;
  hour = 18;
  dayOfWeek = 6;
  dayOfMonth = 12;
  month = 5;
  year = 18;

  analogWrite(blue,bluemin);
  analogWrite(white,whitemin);
  lcd.begin(16,2);
  lcd.setCursor(0,1);
  lcd.print("blue:");
  lcd.print(bluemin);
  lcd.setCursor(8,1);
  lcd.print("white:");
  lcd.print(whitemin);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  int time = ((hour * 60) + minute);
  map(time, 0, 1440, 0, 255);

}

So now I am trying to figure out how to get the PWM output accomplished. In the end the pwm output of the Arduino is going to be bumped up to 0-10v pwm. I am wanting to control two separate channels. The other thing I am going to have to figure out is the fact that I don’t want either channel running at 100%. for instance channel one I want to ramp from 0 to 40% and channel 2 0 to 10%.

here is how I am thinking of doing the next part. There is something wrong with the formatting of my nested statements. and my brain is hurting. But before I go any further I would love some opinions. Thanks!

 map(time, 0, 1440, 0, 255);

  if (time >= 480 && time <720);
  {
    for (int i=0; i<=255; i++)
    {
      analogWrite(bluemin, i);
    } 
    else if (time >=720 && time <900);
    {
      analogWrite(bluemin, 255);
    }
    else if (time >=900 && time <1320);
    
      for (int i=0; i>=255; i--)
      {
      analogWrite(bluemin, i);
      }
     else (time >=1320 || time <480);
    {
      analogWrite(bluemin, 0);
    }
  }

Dang semi-colons in the wrong places.

Yes, you will do this a few times then eventually learn that they shouldn’t be there :wink:

;

if (time >= 480 && time <720); <———<<<<

Jtroutt19:
Dang semi-colons in the wrong places.

Yes, we all do it.
I have a general rule.
There is never a ; before a { (even on a previous line).

Tom.... :slight_smile:

Does the code look correct so far. As in will it do what i am wanting it to do?

  if (time >= 480 && time <720);
  {
    for (int i=0; i<=255; i++)
    {
      analogWrite(bluemin, i);
    }

You don’t need the for loop unless you want the output to ramp from 0 to 255 in less than a millisecond. If you want the output to be proportional to the time that has passed in the current period then use the difference between 480 and the time now to derive the PWM value for the current time.