Аквариумный контроллер. Пара вопросов.

ilprohorowi4
Offline
Зарегистрирован: 22.02.2014

Решил перенести тему, в другой прошу модераторов удалить сообщения.

Итак, нашел хороший проект. http://forum.arduino.cc/index.php?topic=63503.0 .

Суть: имитирует фазы луны, случайно накладывает изменения в погоде... В общем, штука классная.

Но, 1) На какой микросхеме реализуется? Автор написал просто Ардуино Мега, а какая именно? 2560? 1280? Или нет разницы?

2) Автор приводит полный код? Т.е. мне достаточно купить ардиуину, скопировать код и прошить?

3) Реализована ли схема рассвета-заката? Т.е. светодиоды плавно включаются?

Большое спасибо за внимание!!!!

ilprohorowi4
Offline
Зарегистрирован: 22.02.2014

Сразу приведу код

/*******************************************************************************
 *
 * Purpose: Aquarium Controller
 *
 * 
 * Arduino Version 022
 * 
 * 
 * 
 * Originally written by Martin, liquidartstattoos@gmail.com
 *
 * Initial version 1.0   5.21.2011
 *
 *  Changes      Date              Details
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *******************************************************************************/
#include "Wire.h" 
#define DS1307_I2C_ADDRESS 0x68 //set rtc
#include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 9 //Define the pin of the DS18B20



int moon = 2;              // moon light 
int fan = 49;            // Fan power relay connected to analog pin 0
int heater = 31;         // heater

int iBlueIntensity;	//declare the integer of blue intensity
float fBlueIntensity;	//declare the floating point version of blue intensity

// RTC variables 
byte second, rtcMins, oldMins, rtcHrs, oldHrs, dayOfWeek, dayOfMonth, month, year, psecond;  

LiquidCrystal lcd(22,23,24,25,26,27);
//LiquidCrystal lcd(12,13,4,5,6,7);   // typically 8, 9, 4, 5, 6, 7

 
//  Set up the custom fish icon
byte newChar[8] = {
	B00000,
	B00000,
	B10001,
	B11011,
	B11111,
	B11111,
	B11001,
	B10000
};

byte newChar1[8] = {
	B00001,
	B00010,
	B11101,
	B11010,
	B11111,
	B11110,
	B11100,
	B00000
};
byte newChar2[8] = {
	B00000,
	B00000,
	B10001,
	B11011,
	B11111,
	B11111,
	B10011,
	B00001
};
byte newChar3[8] = {
	B10000,
	B01000,
	B10111,
	B01011,
	B11111,
	B01111,
	B00111,
	B00000
};
byte newChar4[8] = {
	B00111,
	B01110,
	B11100,
	B11000,
	B11000,
	B11100,
	B01110,
	B00111
};
byte newChar5[8] = {
	B01010,
	B10000,
	B00010,
	B01001,
	B00100,
	B10000,
	B00100,
	B10001
};
byte newChar6[8] = {
	B01010,
	B00100,
	B00001,
	B11011,
	B00011,
	B00001,
	B01000,
	B10010
};
byte newChar7[8] = {
	B10010,
	B00100,
	B10000,
	B11011,
	B11000,
	B10000,
	B00010,
	B01001
};

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);


// LED variables (Change to match your needs) 
byte bluePins[]      =  {3,4};  // PWM pins for blues - if you plan to use the photo stagger, please place the pins in the order you would like them to start 
byte whitePins[]     =  {5,6};       // PWM pins for whites - if you plan to use the photo stagger, please place the pins in the order you would like them to start 

byte blueChannels    =        2;    // how many PWMs for blues (count from above) 
byte whiteChannels   =        2;    // how many PWMs for whites (count from above) 

int photoStagger     =        0;    //  offset for east - west delay on each channel in minutes 
int startOffset      =        0;    // offset for start times in minutes - used if you want to change the start and finish time of the cycle.  i.e move it to a later time in the day 
int colourOffset     =        30;   // offset for whites to start after blues start in minutes 

byte blueLevel[]       =      {255,255};  // max intensity for Blue LED's 
byte whiteLevel[]      =      {255,255};  // max intensity for White LED's 


// Month Data for Start, Stop, Photo Period and Fade (based off of actual times, best not to change) 

int daysInMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  //Days in each month 

int minMinuteStart[12] = {310, 332, 348, 360, 372, 386, 394, 387, 364, 334, 307, 298}; //Minimum start times in each month 
int maxMinuteStart[12] = {331, 347, 360, 372, 386, 394, 388, 365, 335, 308, 298, 309}; //Max start time in each month 

int minMinuteFade[12] = {350, 342, 321, 291, 226, 173, 146, 110, 122, 139, 217, 282}; //Minimum fade time in each month 
int maxMinuteFade[12] = {342, 321, 291, 226, 173, 146, 110, 122, 139, 217, 282, 350}; //Max fade time in each month 

int minMinuteStop[12] = {1122, 1120, 1102, 1073, 1047, 1034, 1038, 1050, 1062, 1071, 1085, 1105}; //minimum stop times each month 
int maxMinuteStop[12] = {1121, 1103, 1074, 1048, 1034, 1038, 1050, 1061, 1071, 1084, 1104, 1121}; //maximum stop times each month 


// Weather variables 

int weather = 1;  // 0 off, 1 on 

int clearDays[12] = {15, 12, 20, 23, 28, 37, 43, 48, 51, 41, 29, 23}; 
int cloudyDays[12] = {60, 61, 62, 60, 64, 63, 68, 66, 63, 54, 52, 53};  

float clearDay = 0.25; // Max cloud value on clear day (percent of max string value) 
float cloudyDay = 0.75; // Max cloud value on cloudy day (percent of max string value) 
float normalDay = 0.5; // Max cloud value on normal day (percent of max string value) 

byte value; 
int day, fadeOn, fadeOff, time, pause, count, cloud; 
long start, finish; 


// Other variables - Do not need to be changed. 

int minCounter;  // counter that resets at midnight 
long secCounter;  // counter for seconds - needed for weather 
int fadeDuration;  // minutes to fade - calculated by map above 
int ledStartMins;  // minute to start led’s - calculated by map above 
int ledStopMins;  // minute to stop led’s - calculated by map above 
byte blueMax[] = {0};      // used for over temp protection 
byte whiteMax[] = {0};    // used for over temp protection 
byte valueBlue[] = {0};  // value for clouds 
byte valueWhite[] = {0};   // value for clouds 

/****** LED Functions ******/ 
/***************************/ 

//function to set LED brightness according to time of day 

byte setLed( 
int mins,    // current time in minutes 
byte ledPin,  // pin for this channel of LEDs 
int start,   // start time for this channel of LEDs 
int fade,    // fade duration for this channel of LEDs 
int stop,    // stop time for this channel of LEDs 
byte ledMax,  // max value for this channel of LEDs 
long begin,   // time cloud cycle begins in seconds 
long secs,    // current time in seconds 
int on,       // time for cloud to fade on in seconds 
int off,      // time for cloud to fade off in seconds 
long time,     // time of cloud 
byte value    // value for cloud 


// max value for this channel 
)  { 
  byte ledVal = 0;   
  if (mins <= start || mins >= stop)  //this is when the LEDs are off, thus ledVal is 255; 
  { 
    ledVal = 0; 
  } 
  if (mins > start && mins <= start + fade) //this is sunrise  
  { 
    ledVal =  map(mins, start, start + fade, 0, ledMax); 
  } 
  if (mins > start + fade && mins < stop - fade && weather == 1) 
  { 
    ledVal = ledMax; 
    if (count == 1){ 
      if (secs >= begin && secs < begin + fadeOn) 
      { 
        ledVal = map(secs, begin, begin + on, ledMax, value); 
      } 
      if (secs >= begin + on && secs < begin + on + time) 
      { 
        ledVal = value; 
      } 
      if (secs >= begin + on + time && secs < begin + on + time + off) 
      {  
        ledVal = map(secs, begin + on + time, begin + on + time + off, value, ledMax); 
      } 
      if (secs >= begin + on + time + off) 
      { 
        ledVal = ledMax; 
      } 
      if (secs >= finish) 
      { 
        count = 0; 
      } 
    }  
  } 
  if (mins > start + fade && mins < stop - fade && weather == 0) 
  { 
    ledVal = ledMax; 
  } 
  if (mins < stop && mins >= stop - fade)  //this is the sunset 
  { 
    ledVal = map(mins, stop - fade, stop, ledMax, 0); 
  } 
  
  analogWrite(ledPin, ledVal); 
  return ledVal;    
}
/***** RTC Functions *******/ 
/***************************/ 
// Convert normal decimal numbers to binary coded decimal 
byte decToBcd(byte val) 
{ 
  return ( (val/10*16) + (val%10) ); 
} 

// Convert binary coded decimal to normal decimal numbers 
byte bcdToDec(byte val) 
{ 
  return ( (val/16*10) + (val%16) ); 
} 

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));   // If you want 12 hour am/pm you need to set
  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second = bcdToDec(Wire.receive() & 0x7f);
  *minute = bcdToDec(Wire.receive());
  *hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
  *dayOfWeek = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month = bcdToDec(Wire.receive());
  *year = bcdToDec(Wire.receive());
}
int moonPhase(int moonYear, int moonMonth, int moonDay)
{
  int dayFromYear, dayFromMonth;
  double julianDay;
  int phase;

  if (moonMonth < 3)			//keep the month before march
  {
    moonYear--;			//take away a year
    moonMonth += 12;		//add an extra 12 months (the year taken away from before)
  }
  ++moonMonth;
  dayFromYear = 365.25 * moonYear; //get days from current year
  dayFromMonth = 30.6 * moonMonth; //get number of days from the current month
  julianDay = dayFromYear + dayFromMonth + moonDay - 694039.09; //add them all  
  julianDay /= 29.53;		//divide by the length of lunar cycle
  phase = julianDay;		//take integer part
  julianDay -= phase;		//get rid of the int part
  phase = julianDay*8 + 0.5;	//get it between 0-8 and round it by adding .5
  phase = phase & 7;		//get a number between 1-7
  return phase; 		//1 == new moon, 4 == full moon
}


/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  D E F I N E  :  O N E S E C O N D |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



void onesecond() //function that runs once per second while program is running
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  lcd.setCursor(0, 0);
  if(hour>0)
  {
    if(hour<=12)
    {
      lcd.print(hour, DEC);
    }
    else
    {
      lcd.print(hour-12, DEC);
    }
  }
  else
  {
    lcd.print("12");
  }
  lcd.print(":");
  if (minute < 10) {
    lcd.print("0");
  }
  lcd.print(minute, DEC);
  //lcd.print(":");
  //if (second < 10) {
  //  lcd.print("0");
  //}
  //lcd.print(second, DEC);
  if(hour<12)
  {
    lcd.print("am");
  }
  else
  {
    lcd.print("pm");
  }
  lcd.print(" ");
  delay(1000);
}



void setup()  {  

  pinMode(heater, OUTPUT);      //Set Heater Relay
  pinMode(fan, OUTPUT);      // Set analog pin 0 as a output
  sensors.begin();             // Start up the DS18B20 Temp library
  
  // init I2C   
  Serial.begin(9600); 
  Wire.begin(); 
  randomSeed(analogRead(1));
  
    /*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  S E T U P - D I S P L A Y |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/



  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  second = 00;
  minute = 50;
  hour = 6;
  dayOfWeek = 0;  // Sunday is 0
  dayOfMonth = 22;
  month = 5;
  year = 11;
  
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

  lcd.createChar(0, newChar);
  lcd.createChar(1, newChar1);
  lcd.createChar(2, newChar2);
  lcd.createChar(3, newChar3);
  lcd.createChar(4, newChar4);
  lcd.createChar(5, newChar5);
  lcd.createChar(6, newChar6);
  lcd.createChar(7, newChar7);
  lcd.begin(20, 4); // set up the LCD's number of rows and columns:
   // Print a message to the LCD.
  lcd.setCursor(3, 0);
  lcd.write(0);
  lcd.write(1);
  lcd.setCursor(6, 0);// set the cursor to column 4, line 0
  lcd.print("SaltyDog's");
  lcd.setCursor(15, 0);
  lcd.write(3);
  lcd.write(2);
  lcd.setCursor(3, 2);
  lcd.print("ReefController");
  delay(5000);
  lcd.clear(); 
  lcd.setCursor(0, 0);
  lcd.write(0);
  lcd.write(1);
  lcd.setCursor(3, 0);// set the cursor to column 0, line 0
  lcd.print("My Marine Tank");
  lcd.setCursor(18, 0);
  lcd.write(3);
  lcd.write(2);
  lcd.setCursor(11, 1);
  lcd.print("L: ");
  lcd.setCursor(0, 1);
  lcd.print("W: ");
  lcd.setCursor(1, 2);
  lcd.print("Heater: ");
  lcd.setCursor(12, 2);
  lcd.print("Fans: ");

}
/***** Main Loop ***********/ 
/***************************/ 
void loop(){ 
    onesecond();

          
  float fSecond, fHour, fMinute;		//turn the times read from the RTC into float for math ops
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; //declare variables to hold the times

  getDateDs1307(&second, &rtcMins, &rtcHrs, &dayOfWeek, &dayOfMonth, &month, &year); 

  fSecond = (float) second;			//sets fSecond as the float version of the integer second from the RTC
  fMinute = (float) minute;			//same as above, but for the minute
  fHour = (float) hour;				//ditto, but for the hour
  int lunarCycle = moonPhase(year, month, dayOfMonth); //get a value for the lunar cycle
  //--------MOON LED SETUP----------//


  if ( ((hour == 7) && (minute < 00)) || (hour < 7))//Off at 730am.
  {
    fBlueIntensity = 255;		//...then we want the blue LED at the max brightness (255)
  }

  else if (hour > 17) //&& (hour < 19))             // On at 5pm
  {	
    fBlueIntensity = 255 * (((fHour - 19) + (fMinute / 59)) / 7);   //...set intensity out of 255 based on time since 17:00
  }
  else
  {
    fBlueIntensity = 0;
  }

 //---------account for the moon cycle with the blue LEDs---------//

  if (lunarCycle == 0)		//new moon
  {
    fBlueIntensity /= 2;
  }
  if ((lunarCycle == 1) || (lunarCycle == 7))	//cresent
  {
    fBlueIntensity /= 1.75 ;
  }
  if ((lunarCycle == 2) || (lunarCycle == 6))	//half moon
  {
   fBlueIntensity /= 1.5;
  }
  if ((lunarCycle == 3) || (lunarCycle == 5))	//gibbous
  {
    fBlueIntensity /= 1.25;
  }

  //full moon is full intensity 


  //----------FLOAT TO INT-------------//
  iBlueIntensity = (int) fBlueIntensity;



  //---prepare the intensities to be written to pin----//

  if (iBlueIntensity < 0) //if the blue intensity is less then 0, set it to 0
  {
    iBlueIntensity = 0;
  }



  //------------and finally, we write the values of the lights to the pins--------------//

  analogWrite(moon, iBlueIntensity);
  delay(1000);


  minCounter = rtcHrs * 60 + rtcMins; 
  secCounter = (long)minCounter * 60 + (long)second; 

  // Start and Stop Times, Fade Time Functions 

  ledStartMins = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteStart[month-1], maxMinuteStart[month-1]) + startOffset; //LED Start time 
  fadeDuration = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteFade[month-1], maxMinuteFade[month-1]); //LED Fade time 
  ledStopMins = map(dayOfMonth, 1, daysInMonth[month-1], minMinuteStop[month-1], maxMinuteStop[month-1]) + startOffset; // LED Stop time 

  // Weather Functions 

  if (minCounter == 0 && second == 0 || day == 0){ 
    { 
      day = random(1,101); 
    } 
  }   
  if (count == 0){ 
    if (day <= clearDays[month-1]) // Clear Day 
    { 
      int t; 
      for (t = 0; t < blueChannels; t++) 
      {   
        valueBlue[t] = random(blueLevel[t]*clearDay,blueLevel[t]); 
      } 
      for (t = 0; t < whiteChannels; t++) 
      { 
        valueWhite[t] = random(whiteLevel[t]*clearDay,whiteLevel[t]); 
      } 
    } 
    if (day > clearDays[month-1] && day <= cloudyDays[month-1]) // Cloudy Day  
    { 
      int t; 
      for (t = 0; t < blueChannels; t++) 
      {   
        valueBlue[t] = random(blueLevel[t]*normalDay,blueLevel[t]*cloudyDay); 
      } 
      for (t = 0; t < whiteChannels; t++) 
      { 
        valueWhite[t] = random(whiteLevel[t]*normalDay,whiteLevel[t]*cloudyDay); 
      } 
    }  
    if (day > cloudyDays[month-1]) // Normal Day  
    { 
      int t; 
      for (t = 0; t < blueChannels; t++) 
      {   
        valueBlue[t] = random(blueLevel[t]*normalDay,blueLevel[t]); 
      } 
      for (t = 0; t < whiteChannels; t++) 
      { 
        valueWhite[t] = random(whiteLevel[t]*normalDay,whiteLevel[t]); 
      } 
    }   

    fadeOn = random(5,8); // Fade on of cloud in seconds 
    fadeOff = random(5,8); // Fade off of cloud in seconds 
    time = random(30,300); // Length of cloud in seconds 
    pause = random(5,300); // Time between clouds in seconds 
    start = secCounter; // Sets cycle start time 
    finish = start + fadeOn + time + fadeOff + pause; // Sets cylce finish time in seconds 
    count = 1; 
  } 
  

   
   
  int t; 
      for (t = 0; t < blueChannels; t++) 
      {   
        blueMax[t] = blueLevel[t]; 
      } 
      for (t = 0; t < whiteChannels; t++) 
      { 
        whiteMax[t] = whiteLevel[t]; 
      } 
       

  // LED State and Serial Print 
  if (psecond != second){ 
    psecond = second; 
    update_leds(); 
  } 
  delay(50); 
} 


void update_leds( void ){ 
  int i; 
  byte ledVal; 
  for (i = 0; i < blueChannels; i++){ 
    ledVal = setLed(minCounter, bluePins[i], ledStartMins + (photoStagger * (i+1)), fadeDuration, ledStopMins - (photoStagger * (i+1)), blueMax[i], start, secCounter, fadeOn, fadeOff, time, valueBlue[i]); 
  } 
  for (i = 0; i < whiteChannels; i++){ 
    ledVal = setLed(minCounter, whitePins[i], ledStartMins + colourOffset + (photoStagger * (i+1)), fadeDuration, ledStopMins - colourOffset - (photoStagger * (i+1)), whiteMax[i], start, secCounter, fadeOn, fadeOff, time, valueWhite[i]);    
  } 
// DS18B20 display
sensors.requestTemperatures(); // Send the command to get temperatures
delay(250);

  lcd.setCursor(13, 1);
  
float temp1=0, temp2=0;

  //lcd.print("Led Temp:");
  temp1=sensors.getTempFByIndex(1);
  lcd.print(sensors.getTempFByIndex(1)); 
  lcd.print((char)223);
  lcd.print("F");
 
  lcd.setCursor(2, 1);
  //lcd.print("Tank Temp: ");
  temp2=sensors.getTempFByIndex(0);
  lcd.print(sensors.getTempFByIndex(0)); 
  lcd.print((char)223);
  lcd.print("F");

if ( (temp1) > 98)
    {
    digitalWrite(fan, HIGH);
    lcd.setCursor(17,2);
    lcd.print("On");
    }
else if ( (temp1) < 92)
    {
    digitalWrite(fan, LOW);
    lcd.setCursor(17,2);
    lcd.print("Off");
    }

if ( (temp2) < 78 )
    {
    digitalWrite(heater, HIGH);
    lcd.setCursor(8,2);
    lcd.print("On");
    }
else if ( (temp2) > 82 )
    {
    digitalWrite(heater, LOW);
    lcd.setCursor(8,2);
    lcd.print("Off");
    }   
//  lcd.print(sensors.getTempCByIndex(0));
//  lcd.print((char)223); 
//  lcd.print("C");
  
  //delay(500);  
}  

 

MaksMS
Offline
Зарегистрирован: 11.03.2013

Скорее всего в 1280 влезет тоже,просто в 2560 в  2 раза памяти ,и например в китае 2560 стоит дешевле почему-то.

Для запуска схемы необходимо не только ардуина,но и лсд экран  и другие детали .Так же необходимо устананавливать дополнительные библиотеки..

ilprohorowi4
Offline
Зарегистрирован: 22.02.2014

ЛСД экран, часики, БП, драйверы - это понятно. А какие библиотеки? Где их взять?
ЗЫ спасибо за ответ

ilprohorowi4
Offline
Зарегистрирован: 22.02.2014
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
ilprohorowi4
Offline
Зарегистрирован: 22.02.2014

trembo, кредитки нет, PayPal'a тоже :( Проблемка :)

ilprohorowi4
Offline
Зарегистрирован: 22.02.2014

а подойдет такой дисплей? http://dx.com/ru/p/16-x-2-character-lcd-display-module-with-blue-backlig...

если в 441 строке поменять 20 и 4 на 16 и 2 соответственно. Я вообще не мойму, зачем там дисплей?