Advertisement
NittyGritty

HumFanControl_I2C_BME280.ino

Mar 1st, 2022
1,286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.64 KB | None | 0 0
  1. #include <Time.h>
  2. #include <Timezone.h>  
  3. #include <string.h>
  4. #include <Wire.h>
  5.  
  6. #include <LCD.h>
  7. #include <LiquidCrystal_I2C.h>
  8.  
  9. #define I2C_ADDR    0x3f
  10. #define BACKLIGHT_PIN     3
  11. #define En_pin  2
  12. #define Rw_pin  1
  13. #define Rs_pin  0
  14. #define D4_pin  4
  15. #define D5_pin  5
  16. #define D6_pin  6
  17. #define D7_pin  7
  18.  
  19. LiquidCrystal_I2C    lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin, BACKLIGHT_PIN, POSITIVE);
  20.  
  21. int screenWidth = 20;
  22. int screenHeight = 4;
  23.  
  24. int countMovement = 0;
  25. int stringStart = 0;
  26. int stringStop = 0;
  27. int scrollCursor = 0;
  28.  
  29. #include <DS3232RTC.h>  // A  DS3231/DS3232 library
  30.  
  31. /***************************************************************************
  32.   This is a library for the BME280 humidity, temperature & pressure sensor
  33.   Designed specifically to work with the Adafruit BME280 Breakout
  34.   ----> http://www.adafruit.com/products/2650
  35.   These sensors supports either I2C or SPI to communicate, 2 or 4 pins are required
  36.   to interface. However this sketch is using I2C for communications and only
  37.   needs 2 wires for communication
  38.  ***************************************************************************/
  39.  
  40. #include "cactus_io_BME280_I2C.h"
  41.  
  42. // Create the BME280 object
  43. // BME280_I2C bme;              // I2C using default 0x77
  44. BME280_I2C bme(0x76);  // I2C using address 0x76
  45.  
  46. double ALTITUDE = 423.0; // Altitude of sensor in meters
  47. double Lw = 9;
  48. double Ln = 49;
  49.  
  50. #include <dht.h>
  51. dht DHT;
  52. #define DHT22_PIN 5
  53.  
  54. const char compile_date[] =  __DATE__ "-" __TIME__;
  55. const char compile_file[] =  __FILE__ ;
  56.  
  57.  
  58. // ----------------------
  59. int pwmPin   = 10;   // fan PWM -> connected to digital pin 9
  60. int pwmVal   = 0;
  61. int DEBUG    = 1; // DEBUG counter; if set to 1, will write values back via serial
  62.  
  63. // Definition of Arduino type
  64. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  65. #define  IS_MEGA  (1)
  66. #define  IS_UNO   (0)
  67. #else
  68. #define  IS_MEGA  (0)
  69. #define  IS_UNO   (1)
  70. #endif
  71.  
  72. // Analog output (i.e PWM) pins. These must be chosen so that we can change the PWM frequency without affecting the millis()
  73. // function or the MsTimer2 library. So don't use timer/counter 1 or 2. See comment in setup() function.
  74. // THESE PIN NUMBERS MUST NOT BE CHANGED UNLESS THE CODE IN setup(), setTransistorFanSpeed() AND setDiodeFanSpeed() IS CHANGED TO MATCH!
  75. #if IS_UNO
  76. // On the Uno we can only use the OC1B pin, so these pin numbers are both 10
  77. const int transistorFanPin = 10;     // OC1B
  78. const int diodeFanPin = 10;          // OC1B
  79. #else
  80. // On the Mega we use OC1B and OC1C
  81. const int transistorFanPin = 12;     // OC1B
  82. const int diodeFanPin = 13;          // OC1C
  83. #endif
  84.  
  85.  
  86. // Definitions for PWM fan control
  87. const unsigned char maxFanSpeed = 80;   // this is calculated as 16MHz divided by 8 (prescaler), divided by 25KHz (target PWM frequency from Intel specification)
  88.  
  89. char cb[100];
  90.  
  91. //Central European Time (Frankfurt, Paris)
  92. TimeChangeRule CEST = {
  93.   "CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
  94. TimeChangeRule CET = {
  95.   "CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
  96. Timezone CE(CEST, CET);
  97.  
  98. TimeChangeRule *tcr;        //pointer to the time change rule, use to get TZ abbrev
  99. time_t utc, local;
  100.  
  101.   char* weekdays[] = {
  102.     "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
  103.   };
  104.  
  105. int osec = -1;
  106.  
  107.  
  108. // phases of the moon (0 is new moon, p1-waxing crescent, p5-first quarter, p10-full moon, etc.)
  109.  
  110. #define d 0xFF                    // delimeter
  111.  
  112. const char phases[][11] PROGMEM = {
  113.   {
  114.     24,28,38,42,50,61,65,73,77,87,91  },     // p1
  115.   {
  116.     16,29,43,60,72,86,99,d  },               // p2
  117.   {
  118.     12,17,30,44,59,71,85,98,103,d  },        // p3
  119.   {
  120.     1,18,31,58,84,97,9,d  },                 // p4
  121.   {
  122.     2,3,4,6,7,8,d  },                        // p5 first / last quarter
  123.   {
  124.     96,83,57,32,19,d  },                     // p6
  125.   {
  126.     102,95,82,33,20,13,d  },                 // p7
  127.   {
  128.     70,56,45,20,d  },                        // p8
  129.   {
  130.     94,81,69,55,46,34,21,d  },               // p9
  131.   {
  132.     90,80,76,68,64,54,51,47,39,35,25  }      // p10
  133. };
  134.  
  135.  
  136. // Set the transistor fan speed, where 0 <= fanSpeed <= maxFanSpeed
  137. void setTransistorFanSpeed(unsigned char fanSpeed)
  138. {
  139.   OCR1BH = 0;
  140.   OCR1BL = fanSpeed;
  141. }
  142.  
  143. // Set the diode fan speed, where 0 <= fanSpeed <= maxFanSpeed
  144. void setDiodeFanSpeed(unsigned char fanSpeed)
  145. {
  146. #if IS_UNO
  147.   OCR1BH = 0;
  148.   OCR1BL = fanSpeed;
  149. #else
  150.   OCR1CH = 0;
  151.   OCR1CL = fanSpeed;
  152. #endif
  153. }
  154.  
  155. void setup() {
  156.  
  157.   Serial.begin(9600);
  158.  
  159.  
  160.     // Set up the PWM pins for a PWM frequency close to the recommended 25KHz for the Intel fan spec.
  161.   // We can't get this frequency using the default TOP count of 255, so we have to use a custom TOP value.
  162.  
  163. #if IS_UNO
  164.  
  165.   // Only timer/counter 1 is free because TC0 is used for system timekeeping (i.e. millis() function),
  166.   // and TC2 is used for our 1-millisecond tick. TC1 controls the PWM on Arduino pins 9 and 10.
  167.   // However, we can only get PWM on pin 10 (controlled by OCR1B) because we are using OCR1A to define the TOP value.
  168.   // Using a prescaler of 8 and a TOP value of 80 gives us a frequency of 16000/(8 * 80) = 25KHz exactly.
  169.   TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) | (1 << WGM10);  // OC1A (pin 9) disconnected, OC1B (pin 10) = inverted fast PWM  
  170.  #ifdef FAN_AUDIO_TEST
  171.   // test code to get 440Hz output (= concert A) to test the logic
  172.   OCR1AH = 0;
  173.   OCR1BL = 71;  // 50% duty cycle
  174.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12);  // TOP = OCRA, prescaler = 256
  175.  
  176.   OCR1AL = 141; // TOP = 141, 16000000 / (256 * 142) = 440.014
  177.   OCR1BH = 0;
  178.  #else
  179.   OCR1AH = 0;
  180.   OCR1AL = 79;  // TOP = 79
  181.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR0A, prescaler = 8
  182.  
  183.   OCR1BH = 0;
  184.   OCR1BL = maxFanSpeed;  // max fan speed (i.e. pin 5 initially low all the time)  
  185.  #endif
  186.  
  187.   TCNT1H = 0;
  188.   TCNT1L = 0;
  189. #else
  190.  
  191.   // On the Mega we use TC1 and OCR1B, OCR1C
  192.   TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1) | (1 << COM1C1) | (1 << WGM11) | (1 << WGM10);  // OC1A disconnected, OC1B = OC1C inverted fast PWM  
  193.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR1A, prescaler = 8
  194.   TCCR1C = 0;
  195.   OCR1AH = 0;
  196.   OCR1AL = 79;  // TOP = 79
  197.  
  198.   OCR1BH = 0;
  199.   OCR1BL = maxFanSpeed;
  200.   OCR1CH = 0;
  201.   OCR1CL = maxFanSpeed;
  202.  
  203.   TCNT1H = 0;
  204.   TCNT1L = 0;
  205. #endif
  206.  
  207.   // We have to enable the ports as outputs before PWM will work.
  208.   pinMode(transistorFanPin, OUTPUT);
  209.   pinMode(diodeFanPin, OUTPUT);
  210.  
  211. // ------------------------------
  212.  
  213.   lcd.begin(screenWidth, screenHeight);             // LCD Hintergrundbeleuchtung aktivieren
  214.   lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  215.   lcd.clear();
  216.   lcd.setCursor(0, 0);
  217.  
  218.   // ------- Quick 3 blinks of backlight  -------------
  219.   for(int i = 0; i< 3; i++)
  220.   {
  221.     lcd.backlight();
  222.     delay(250);
  223.  
  224.     lcd.noBacklight();
  225.     delay(250);
  226.   }
  227.   lcd.backlight(); // finish with backlight on  
  228.  
  229.   Serial.println(compile_date);
  230.   roop(0, compile_date, 100);
  231.  
  232.   Serial.println(compile_file);
  233.   roop(1, compile_file, 100);
  234.  
  235.   delay(1000);
  236.  
  237.   lcd.clear(); //Clear screen
  238.   lcd.noCursor(); //disable cursor, enable cursore use: enableCursor();
  239.   lcd.setCursor(0, 0);
  240.  
  241.   // Initialize the sensor (it is important to get calibration values stored on the device).
  242.  
  243.   if (bme.begin())
  244.   {
  245.     Serial.println(F("BME280 init success"));
  246.     lcd.print(F("BME280 init success"));
  247.   }
  248.   else
  249.   {
  250.     // Oops, something went wrong, this is usually a connection problem,
  251.     // see the comments at the top of this sketch for the proper connections.
  252.  
  253.     Serial.println(F("BME280 init fail\n\n"));
  254.     lcd.print(F("BME280 init fail"));
  255.     while(1); // Pause forever.
  256.   }
  257.   float temp = bme.getTemperature_C();
  258.  
  259.   delay(1000);
  260.   lcd.setCursor(0, 1);  
  261.  
  262.   setSyncProvider(RTC.get);   // the function to get the time from the RTC
  263.  
  264.   if(timeStatus()!= timeSet)
  265.   {
  266.     lcd.println(F("RTC sync Error"));
  267.   }  
  268.   else
  269.   {
  270.     lcd.print(F("RTC sync OK"));
  271.   }
  272.  
  273.   delay(1000);  
  274.  
  275.   lcd.clear(); //Clear screen
  276.   lcd.setCursor(0, 0);
  277.   delay(1000);  
  278.  
  279.   setTime(hour(),minute(),second(),day(),month(),(year()-2000) ); // set time to Saturday 8:29:00am Jan 1 2011
  280.  
  281.   digitalClockDisplay();
  282.  
  283. //   FanTest();
  284. }
  285.  
  286. // =====================================================================================================
  287.  
  288. void loop()
  289. {
  290.     if (second() != osec) {
  291.  
  292.     switch (second())
  293.     {
  294.     case 0:
  295.       BME_DisplayTempHumDew();
  296.       break;
  297.  
  298.     case 10:
  299.       DHT_DisplayTempHumDew();    
  300.       break;
  301.  
  302.     case 20:
  303.       DisplayPressure();
  304.       break;
  305.  
  306.     case 30:
  307.       BME_DisplayTempHumDew();
  308.       break;
  309.  
  310.     case 40:
  311.       DHT_DisplayTempHumDew();    
  312.       break;
  313.  
  314.     case 50:
  315.       DisplayPressure();
  316.       break;
  317.     }
  318.     osec = second();
  319.     digitalClockDisplay();
  320.     CheckClockSet();
  321.     delay(500); // wait one second between clock display
  322.   }
  323. }
  324. // ===========================================================
  325. void DisplayPressure() {
  326.  
  327.   double bme_abs, rel_pres ;
  328.  
  329.   char string_rel_pressure[8];
  330.   char string_abs_pressure[8];
  331.   char string_elevation[8];
  332.  
  333.     bme_abs = bme.getPressure()/100;
  334.     rel_pres = bme_abs / pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255);
  335.  
  336.   dtostrf(bme_abs,  4, 1, string_abs_pressure);
  337.   dtostrf(rel_pres, 4, 1, string_rel_pressure);
  338.   dtostrf(ALTITUDE, 3, 1, string_elevation);
  339.  
  340.   sprintf(cb, "Absoluter Luftdruck: %shPa\tLuftdruck auf Meereshoehe: %shPa\tHoehe: %sm",
  341.                string_abs_pressure,
  342.                string_rel_pressure,
  343.                string_elevation
  344.                );
  345.   Serial.println(cb);
  346.  
  347.   lcd.clear();
  348.   lcd.setCursor(0, 0);
  349.   sprintf(cb, "Luftdruck  %shPa", string_rel_pressure);
  350.   lcd.print(cb);
  351.  
  352.   lcd.setCursor(0, 1);
  353.   sprintf(cb, "Luftdruck  %shPa", string_abs_pressure);
  354.   lcd.print(cb);
  355.  
  356.   lcd.setCursor(0, 2);
  357.   sprintf(cb, "H%che          %sm", char(0xef), string_elevation);
  358.   lcd.print(cb);
  359.  
  360.   /* ------------------------------------------------------- */
  361.   digitalClockDisplay();
  362. }
  363.  
  364. // ===============================================================
  365. // BME280 related
  366. // Display Temp./Hum./Dew
  367. //
  368.  
  369. void BME_DisplayTempHumDew() {
  370.  
  371.   double bme_temp, bme_humidity, bme_dew;
  372.  
  373.   char string_bme_temp[10];
  374.   char string_bme_humidity[10];
  375.   char string_bme_dew[10];
  376.  
  377.  
  378.     bme_temp = bme.getTemperature_C();
  379.     bme_humidity = bme.getHumidity();
  380.     bme_dew = dewPointFast(bme_temp, bme_humidity);
  381.  
  382.  
  383.  
  384.   dtostrf(bme_temp, 3, 1, string_bme_temp);
  385.   dtostrf(bme_humidity, 3, 1, string_bme_humidity);
  386.   dtostrf(bme_dew, 3, 1, string_bme_dew);
  387.  
  388.   sprintf(cb, "BME-Temperature: %s°C\tBME-Humidity: %s%%rH\tBME-Dewpoint: %s°C\t",
  389.                string_bme_temp,
  390.                string_bme_humidity,
  391.                string_bme_dew
  392.                );
  393.   Serial.println(cb);
  394.  
  395.   lcd.clear(); //Clear screen
  396.   lcd.setCursor(0, 0);
  397.   sprintf(cb, "Luftfeuchte  %s%%rH", string_bme_humidity);
  398.   lcd.print(cb);
  399.  
  400.   lcd.setCursor(0, 1);
  401.   sprintf(cb, "Temperatur    %s%cC", string_bme_temp, char(0xdf) );
  402.   lcd.print(cb);
  403.  
  404.   lcd.setCursor(0, 2);
  405.   sprintf(cb, "Taupunkt      %s%cC", string_bme_dew, char(0xdf));
  406.   lcd.print(cb);
  407.  
  408.   /* ------------------------------------------------------- */
  409.   // 40 values from 60%rH to 100%rH
  410.  
  411.   int RPM[] = {
  412.     50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
  413.     40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
  414.     30, 28, 26, 24, 22, 20, 18, 16, 14, 12,
  415.     10, 9, 8, 7, 6, 5, 4, 3, 2, 1
  416.   };
  417.  
  418.   int hum, fan_speed;
  419.  
  420.   hum=bme_humidity;     // convert to integer
  421.  
  422.   if ((hum) > 60)
  423.     {
  424.       hum=hum-60;
  425.       fan_speed=(RPM[hum]);
  426.       setTransistorFanSpeed(fan_speed);
  427.     }    
  428.     else
  429.     {
  430.       fan_speed=0;
  431.       setTransistorFanSpeed(70);
  432.     }
  433.     sprintf(cb, "Hum = %2d\tfan_speed = %2d", hum, fan_speed);
  434.     Serial.println(cb);
  435.  
  436. //  lcd.setCursor(10, 1);
  437. //  lcd.print("Fan ");
  438. //  lcd.print(fan_speed);
  439.  
  440.   /* ------------------------------------------------------- */
  441.   digitalClockDisplay();
  442. }
  443.  
  444. // ===============================================================
  445. // DHT related
  446. // Display Temp./Hum./Dew
  447. //
  448.  
  449. void DHT_DisplayTempHumDew() {
  450.  
  451.   double dht_humidity, dht_temperature, dht_dew;
  452.   char string_temp[10];
  453.   char string_hum[10];
  454.   char string_dew[10];
  455.  
  456.   // READ DHT DATA
  457.   uint32_t start = micros();
  458.   int chk = DHT.read22(DHT22_PIN);
  459.   uint32_t stop = micros();
  460.  
  461.   Serial.println();
  462.   Serial.print(F("Read sensor: "));
  463.   switch (chk)
  464.   {
  465.   case 0:
  466.     Serial.println("OK");
  467.     break;
  468.   case -1:
  469.     Serial.println("Checksum error");
  470.     break;
  471.   case -2:
  472.     Serial.println("Time out error");
  473.     break;
  474.   default:
  475.     Serial.println("Unknown error");
  476.     break;
  477.   }
  478.  
  479.   // DISPLAY DATA
  480.  
  481.   dht_humidity = DHT.humidity;
  482.   dht_temperature = DHT.temperature;
  483.   dht_dew = dewPointFast(dht_temperature, dht_humidity);
  484.  
  485.   dtostrf(dht_humidity, 3, 1, string_hum);
  486.   dtostrf(dht_temperature, 3, 1, string_temp);
  487.   dtostrf(dht_dew, 3, 1, string_dew);
  488.  
  489.   lcd.clear(); //Clear screen
  490.   lcd.setCursor(0, 0);
  491.  
  492.   sprintf(cb, "Luftfeuchte  %s%%rH", string_hum);
  493.   lcd.print(cb);
  494.  
  495.   lcd.setCursor(0, 1);
  496.   sprintf(cb, "Temperatur   %s%cC", string_temp, char(0xdf));
  497.   lcd.print(cb);
  498.  
  499.   lcd.setCursor(0, 2);
  500.   sprintf(cb, "Taupunkt     %s%cC", string_dew, char(0xdf));
  501.   lcd.print(cb);
  502.  
  503.   sprintf(cb, "Humidity: %s%%rH\tTemperatur: %s°C\r\nTaupunkt: %s°C\tConversion time: %4dµs", string_hum, string_temp, string_dew, (stop - start));
  504.   Serial.println(cb);
  505.   /* ------------------------------------------------------- */
  506.   digitalClockDisplay();
  507. }
  508.  
  509. // =================================================================
  510. void digitalClockDisplay() {
  511.  
  512.   utc = now();
  513.   local = CE.toLocal(utc, &tcr);
  514.   printTimeLCD(local, tcr -> abbrev);
  515. }
  516.  
  517. void printTimeLCD(time_t t, char *tz) {
  518.  
  519.   // Da in dem vierzeiligen Display noch eine Zeile Platz hatte
  520.   // hier eine Art von Sekundenzeiger
  521.   sprintf(cb, "%s %02d.%02d.%02d %02d:%02d:%02d", (weekdays[weekday(t) - 1]), day(t), month(t),year(t)-2000, hour(t), minute(t), second(t)) ;
  522.  
  523.   lcd.setCursor(0, 3);
  524.   lcd.print(cb);
  525.  
  526.   Serial.println();
  527.   utc = now();
  528.   printTime(utc, "UTC");
  529.   local = CE.toLocal(utc, &tcr);
  530.   printTime(local, tcr -> abbrev);
  531. }
  532. //Function to print time with time zone
  533. void printTime(time_t t, char *tz)
  534. {
  535.   sprintf(cb, "%s, %02d.%02d.%04d %02d:%02d:%02d %s", (weekdays[weekday(t) - 1]), day(t), month(t),year(t), hour(t), minute(t), second(t), tz ) ;
  536.   Serial.println(cb);
  537. }
  538.  
  539.  // -----( Declare User-written Functions )-----
  540.  //Celsius to Fahrenheit conversion
  541.  double Fahrenheit(double celsius)
  542.  {
  543.  return 1.8 * celsius + 32;
  544.  }
  545.  
  546.  
  547. //Celsius to Kelvin conversion
  548. double Kelvin(double celsius)
  549. {
  550.   return celsius + 273.15;
  551. }
  552.  
  553. // dewPoint function NOAA
  554. // reference: http://wahiduddin.net/calc/density_algorithms.htm
  555. double dewPoint(double celsius, double humidity)
  556. {
  557.   double A0= 373.15/(273.15 + celsius);
  558.   double SUM = -7.90298 * (A0-1);
  559.   SUM += 5.02808 * log10(A0);
  560.   SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
  561.   SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
  562.   SUM += log10(1013.246);
  563.   double VP = pow(10, SUM-3) * humidity;
  564.   double T = log(VP/0.61078);   // temp var
  565.   return (241.88 * T) / (17.558-T);
  566. }
  567.  
  568. // delta max = 0.6544 wrt dewPoint()
  569. // 5x faster than dewPoint()
  570. // reference: http://en.wikipedia.org/wiki/Dew_point
  571. double dewPointFast(double celsius, double humidity)
  572. {
  573.   double a = 17.271;
  574.   double b = 237.7;
  575.   double temp = (a * celsius) / (b + celsius) + log(humidity/100);
  576.   double Td = (b * temp) / (a - temp);
  577.   return Td;
  578.  
  579. }
  580.  
  581. void CheckClockSet() {
  582.   if (Serial.available()) {
  583.     time_t t = processSyncMessage();
  584.     if (t > 0)
  585.     {
  586.       RTC.set(t);   // set the RTC and the system time to the received value
  587.       setTime(t);
  588.  
  589.       Serial.println("New Tiime has been set");
  590.       utc = now();
  591.       printTime(utc, "UTC");
  592.       local = CE.toLocal(utc, &tcr);
  593.       printTime(local, tcr -> abbrev);
  594.     }
  595.   } // if no input, just return
  596. }
  597.  
  598. /*  code to process time sync messages from the serial port   */
  599. #define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
  600. #define TIME_HEADER  'T'   // Header tag for serial time sync message
  601.  
  602. time_t processSyncMessage() {
  603.   // return the time if a valid sync message is received on the serial port.
  604.   while (Serial.available() >=  TIME_MSG_LEN ) { // time message consists of a header and ten ascii digits
  605.     char c = Serial.read() ;
  606.     Serial.print(c);
  607.     if ( c == TIME_HEADER ) {
  608.       time_t pctime = 0;
  609.       for (int i = 0; i < TIME_MSG_LEN - 1; i++) {
  610.         c = Serial.read();
  611.         if ( c >= '0' && c <= '9') {
  612.           pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
  613.         }
  614.       }
  615.       return pctime;
  616.     }
  617.   }
  618.   return 0;
  619. }
  620. // ===================================
  621.  
  622. // ===================================
  623. void DisplayMoonPhase()
  624. {
  625.   local = CE.toLocal(utc, &tcr);
  626.   Serial.println("MoonPhase:\t");
  627.   Serial.println(MoonPhase(local, tcr -> abbrev));
  628.  
  629.   lcd.setCursor(0, 0);
  630.   lcd.print("Mondphase:          ");
  631.   lcd.setCursor(11, 0);
  632.   lcd.print(MoonPhase(local, tcr -> abbrev));
  633.  
  634.   lcd.setCursor(0, 1);
  635.   lcd.print("Aufgang:        ");
  636.  
  637.   lcd.setCursor(0, 2);
  638.   lcd.print("Untergang:      ");
  639.  
  640.   lcd.setCursor(0, 3);
  641.   lcd.println("                ");
  642.  
  643.  
  644. }
  645.  
  646. float MoonPhase(time_t t, char *tz)
  647. {
  648.   return GetPhase(year(t), month(t), day(t) );
  649. }
  650.  
  651. float GetPhase(int nYear, int nMonth, int nDay) // calculate the current phase of the moon
  652. {
  653.   float phase;
  654.   double AG, IP;
  655.   long YY, MM, K1, K2, K3, JD;
  656.   YY = nYear - floor((12 - nMonth) / 10);
  657.   MM = nMonth + 9;
  658.   if (MM >= 12)
  659.   {
  660.     MM = MM - 12;
  661.   }
  662.   K1 = floor(365.25 * (YY + 4712));
  663.   K2 = floor(30.6 * MM + 0.5);
  664.   K3 = floor(floor((YY / 100) + 49) * 0.75) - 38;
  665.   JD = K1 + K2 + nDay + 59;
  666.   if (JD > 2299160)
  667.   {
  668.     JD = JD - K3;
  669.   }
  670.   IP = MyNormalize((JD - 2451550.1) / 29.530588853);
  671.   AG = IP*29.53;
  672.   phase = 0;
  673.   if ((AG < 1.84566) && (phase == 0))
  674.   {
  675.     phase = 0;  //new; 0% illuminated
  676.   }
  677.   if ((AG < 5.53699) && (phase == 0))
  678.   {
  679.     phase = .25; //Waxing crescent; 25% illuminated
  680.   }
  681.   if ((AG < 9.922831) && (phase == 0))
  682.   {
  683.     phase = .50;    //First quarter; 50% illuminated
  684.   }
  685.   if ((AG < 12.91963) && (phase == 0))
  686.   {
  687.     phase = .75; //Waxing gibbous; 75% illuminated
  688.   }
  689.   if ((AG < 16.61096) && (phase == 0))
  690.   {
  691.     phase = 1; //Full; 100% illuminated
  692.   }
  693.   if ((AG < 20.30228) && (phase == 0))
  694.   {
  695.     phase = .75; //Waning gibbous; 75% illuminated
  696.   }
  697.   if ((AG < 23.99361) && (phase == 0))
  698.   {
  699.     phase = .50; //Last quarter; 50% illuminated
  700.   }
  701.   if ((AG < 27.68493) && (phase == 0))
  702.   {
  703.     phase = .25; //Waning crescent; 25% illuminated
  704.   }
  705.   if (phase == 0)
  706.   {
  707.     phase = 0;  //default to new; 0% illuminated
  708.   }
  709.   return phase;
  710. }
  711.  
  712. double MyNormalize(double v)
  713. {
  714.   v = v - floor(v);
  715.   if (v < 0)
  716.     v = v + 1;
  717.   return v;
  718. }
  719.  
  720. // ================ from:
  721. // http://reefsanctuary.com/forum/index.php?threads/show-your-arduino-controller-sketch.71063/
  722. // =============
  723. int moonPhase(int moonYear, int moonMonth, int moonDay)
  724. {
  725.   int dayFromYear, dayFromMonth;
  726.   double julianDay;
  727.   int phase;
  728.  
  729.   if (moonMonth < 3)            //keep the month before march
  730.   {
  731.     moonYear--;         //take away a year
  732.     moonMonth += 12;        //add an extra 12 months (the year taken away from before)
  733.   }
  734.   ++moonMonth;
  735.   dayFromYear = 365.25 * moonYear; //get days from current year
  736.   dayFromMonth = 30.6 * moonMonth; //get number of days from the current month
  737.   julianDay = dayFromYear + dayFromMonth + moonDay - 694039.09; //add them all  
  738.   julianDay /= 29.53;       //divide by the length of lunar cycle
  739.   phase = julianDay;        //take integer part
  740.   julianDay -= phase;       //get rid of the int part
  741.   phase = julianDay*8 + 0.5;    //get it between 0-8 and round it by adding .5
  742.   phase = phase & 7;        //get a number between 1-7
  743.   return phase;         //1 == new moon, 4 == full moon
  744. }
  745.  
  746. void FanTest()
  747. {
  748.   setTransistorFanSpeed(0);
  749.   delay(5000);   // run for 30 seconds at maximum fan speed
  750.  
  751.   setTransistorFanSpeed(10);
  752.   delay(5000);   // run for 30 seconds at maximum fan speed
  753.  
  754.   setTransistorFanSpeed(20);
  755.   delay(5000);   // run for 30 seconds at low fan speed
  756.  
  757.   setTransistorFanSpeed(30);
  758.   delay(5000);   // run for 30 seconds at low fan speed
  759.  
  760.   setTransistorFanSpeed(40);
  761.   delay(5000);   // run for 30 seconds at low fan speed
  762.  
  763.   setTransistorFanSpeed(50);
  764. //  delay(5000);   // run for 30 seconds at low fan speed
  765.  
  766. }
  767.  
  768. // ==========================================
  769. void roop(int Reihe, String line2, int speed) {
  770.   countMovement = 0;
  771.   stringStart = 0;
  772.   stringStop = 0;
  773.   scrollCursor = 0;
  774.  
  775.   // Serial.print(countMovement); Serial.print("-"); Serial.println(line2.length() + 1);
  776.   while ( ( countMovement ) < (line2.length() + 2 )  )
  777.   {
  778.     lcd.setCursor(scrollCursor, Reihe);
  779.     // Serial.print("Cursor: "); Serial.print(scrollCursor); Serial.print(" "); Serial.println(Reihe);
  780.     lcd.print(line2.substring(stringStart, stringStop));
  781.     // Serial.println( line2.substring(stringStart, stringStop) );
  782.     delay(speed);
  783.  
  784.     if (stringStart == 0 && scrollCursor > 0) {
  785.       // Serial.println(scrollCursor);
  786.       scrollCursor--;
  787.       stringStop++;
  788.     } else if (stringStart == stringStop) {
  789.       stringStart = stringStop = 0;
  790.       scrollCursor = screenWidth;
  791.     } else if (stringStop == line2.length() && scrollCursor == 0) {
  792.       stringStart++;
  793.     } else {
  794.       stringStart++;
  795.       stringStop++;
  796.     }
  797.     countMovement++;
  798.   }
  799. }
  800. void ClearLine(int line)
  801. {
  802. }
  803.  
  804.  
  805.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement