NittyGritty icon

HumFanControl_I2C_BME280.ino

NittyGritty | PRO | 03/01/22 08:18:48 PM UTC | 0 ⭐ | 1586 👁️ | Never ⏰ | []
C++ |

21.64 KB

|

None

|

0 👍

/

0 👎

#include <Time.h>
#include <Timezone.h>   
#include <string.h>
#include <Wire.h>
 
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 
#define I2C_ADDR    0x3f
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
 
LiquidCrystal_I2C    lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin, BACKLIGHT_PIN, POSITIVE);
 
int screenWidth = 20;
int screenHeight = 4;
 
int countMovement = 0;
int stringStart = 0;
int stringStop = 0;
int scrollCursor = 0;
 
#include <DS3232RTC.h>  // A  DS3231/DS3232 library
 
/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor
  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650
  These sensors supports either I2C or SPI to communicate, 2 or 4 pins are required
  to interface. However this sketch is using I2C for communications and only 
  needs 2 wires for communication
 ***************************************************************************/
 
#include "cactus_io_BME280_I2C.h"
 
// Create the BME280 object
// BME280_I2C bme;              // I2C using default 0x77 
BME280_I2C bme(0x76);  // I2C using address 0x76
 
double ALTITUDE = 423.0; // Altitude of sensor in meters
double Lw = 9;
double Ln = 49;
 
#include <dht.h>
dht DHT;
#define DHT22_PIN 5
 
const char compile_date[] =  __DATE__ "-" __TIME__;
const char compile_file[] =  __FILE__ ;
 
 
// ----------------------
int pwmPin   = 10;   // fan PWM -> connected to digital pin 9
int pwmVal   = 0;
int DEBUG    = 1; // DEBUG counter; if set to 1, will write values back via serial
 
// Definition of Arduino type
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define  IS_MEGA  (1)
#define  IS_UNO   (0)
#else
#define  IS_MEGA  (0)
#define  IS_UNO   (1)
#endif
 
// Analog output (i.e PWM) pins. These must be chosen so that we can change the PWM frequency without affecting the millis()
// function or the MsTimer2 library. So don't use timer/counter 1 or 2. See comment in setup() function.
// THESE PIN NUMBERS MUST NOT BE CHANGED UNLESS THE CODE IN setup(), setTransistorFanSpeed() AND setDiodeFanSpeed() IS CHANGED TO MATCH!
#if IS_UNO
// On the Uno we can only use the OC1B pin, so these pin numbers are both 10
const int transistorFanPin = 10;     // OC1B
const int diodeFanPin = 10;          // OC1B
#else
// On the Mega we use OC1B and OC1C
const int transistorFanPin = 12;     // OC1B
const int diodeFanPin = 13;          // OC1C
#endif
 
 
// Definitions for PWM fan control
const unsigned char maxFanSpeed = 80;   // this is calculated as 16MHz divided by 8 (prescaler), divided by 25KHz (target PWM frequency from Intel specification) 
 
char cb[100];
 
//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {
  "CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
TimeChangeRule CET = {
  "CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
Timezone CE(CEST, CET);
 
TimeChangeRule *tcr;        //pointer to the time change rule, use to get TZ abbrev
time_t utc, local;
 
  char* weekdays[] = {
    "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
  };
 
int osec = -1;
 
 
// phases of the moon (0 is new moon, p1-waxing crescent, p5-first quarter, p10-full moon, etc.)
 
#define d 0xFF                    // delimeter
 
const char phases[][11] PROGMEM = {
  {
    24,28,38,42,50,61,65,73,77,87,91  },     // p1
  {
    16,29,43,60,72,86,99,d  },               // p2
  {
    12,17,30,44,59,71,85,98,103,d  },        // p3
  {
    1,18,31,58,84,97,9,d  },                 // p4
  {
    2,3,4,6,7,8,d  },                        // p5 first / last quarter
  {
    96,83,57,32,19,d  },                     // p6
  {
    102,95,82,33,20,13,d  },                 // p7
  {
    70,56,45,20,d  },                        // p8
  {
    94,81,69,55,46,34,21,d  },               // p9
  {
    90,80,76,68,64,54,51,47,39,35,25  }      // p10
};
 
 
// Set the transistor fan speed, where 0 <= fanSpeed <= maxFanSpeed
void setTransistorFanSpeed(unsigned char fanSpeed)
{
  OCR1BH = 0;
  OCR1BL = fanSpeed;
}
 
// Set the diode fan speed, where 0 <= fanSpeed <= maxFanSpeed
void setDiodeFanSpeed(unsigned char fanSpeed)
{
#if IS_UNO
  OCR1BH = 0;
  OCR1BL = fanSpeed;
#else
  OCR1CH = 0;
  OCR1CL = fanSpeed;
#endif
}
 
void setup() {
 
  Serial.begin(9600);
  
  
    // Set up the PWM pins for a PWM frequency close to the recommended 25KHz for the Intel fan spec.
  // We can't get this frequency using the default TOP count of 255, so we have to use a custom TOP value.
  
#if IS_UNO
 
  // Only timer/counter 1 is free because TC0 is used for system timekeeping (i.e. millis() function),
  // and TC2 is used for our 1-millisecond tick. TC1 controls the PWM on Arduino pins 9 and 10.
  // However, we can only get PWM on pin 10 (controlled by OCR1B) because we are using OCR1A to define the TOP value.
  // Using a prescaler of 8 and a TOP value of 80 gives us a frequency of 16000/(8 * 80) = 25KHz exactly.
  TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) | (1 << WGM10);  // OC1A (pin 9) disconnected, OC1B (pin 10) = inverted fast PWM  
 #ifdef FAN_AUDIO_TEST
  // test code to get 440Hz output (= concert A) to test the logic 
  OCR1AH = 0;
  OCR1BL = 71;  // 50% duty cycle 
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12);  // TOP = OCRA, prescaler = 256
 
  OCR1AL = 141; // TOP = 141, 16000000 / (256 * 142) = 440.014
  OCR1BH = 0;
 #else
  OCR1AH = 0;
  OCR1AL = 79;  // TOP = 79
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR0A, prescaler = 8
 
  OCR1BH = 0;
  OCR1BL = maxFanSpeed;  // max fan speed (i.e. pin 5 initially low all the time)  
 #endif
 
  TCNT1H = 0;
  TCNT1L = 0; 
#else
 
  // On the Mega we use TC1 and OCR1B, OCR1C
  TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1) | (1 << COM1C1) | (1 << WGM11) | (1 << WGM10);  // OC1A disconnected, OC1B = OC1C inverted fast PWM  
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR1A, prescaler = 8
  TCCR1C = 0;
  OCR1AH = 0;
  OCR1AL = 79;  // TOP = 79
 
  OCR1BH = 0;
  OCR1BL = maxFanSpeed;
  OCR1CH = 0;
  OCR1CL = maxFanSpeed;
  
  TCNT1H = 0;
  TCNT1L = 0;
#endif
  
  // We have to enable the ports as outputs before PWM will work.
  pinMode(transistorFanPin, OUTPUT);
  pinMode(diodeFanPin, OUTPUT);
 
// ------------------------------
 
  lcd.begin(screenWidth, screenHeight);             // LCD Hintergrundbeleuchtung aktivieren
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.clear();
  lcd.setCursor(0, 0);
  
  // ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i< 3; i++)
  {
    lcd.backlight();
    delay(250);
 
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on  
 
  Serial.println(compile_date);
  roop(0, compile_date, 100);
 
  Serial.println(compile_file);
  roop(1, compile_file, 100);
  
  delay(1000);
 
  lcd.clear(); //Clear screen
  lcd.noCursor(); //disable cursor, enable cursore use: enableCursor();
  lcd.setCursor(0, 0);
 
  // Initialize the sensor (it is important to get calibration values stored on the device).
 
  if (bme.begin())
  {
    Serial.println(F("BME280 init success"));
    lcd.print(F("BME280 init success"));
  }
  else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.
 
    Serial.println(F("BME280 init fail\n\n"));
    lcd.print(F("BME280 init fail"));
    while(1); // Pause forever.
  }
  float temp = bme.getTemperature_C();
  
  delay(1000); 
  lcd.setCursor(0, 1);  
 
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
 
  if(timeStatus()!= timeSet)
  {
    lcd.println(F("RTC sync Error"));
  }   
  else
  {
    lcd.print(F("RTC sync OK"));
  }
 
  delay(1000);   
 
  lcd.clear(); //Clear screen
  lcd.setCursor(0, 0);
  delay(1000);   
 
  setTime(hour(),minute(),second(),day(),month(),(year()-2000) ); // set time to Saturday 8:29:00am Jan 1 2011
 
  digitalClockDisplay();
  
//   FanTest();
}
 
// =====================================================================================================
 
void loop()
{
    if (second() != osec) {
 
    switch (second())
    {
    case 0:
      BME_DisplayTempHumDew();
      break;
 
    case 10:
      DHT_DisplayTempHumDew();    
      break;
 
    case 20:
      DisplayPressure();
      break;
 
    case 30:
      BME_DisplayTempHumDew();
      break;
 
    case 40:
      DHT_DisplayTempHumDew();    
      break;
 
    case 50:
      DisplayPressure();
      break;
    }
    osec = second();
    digitalClockDisplay();
    CheckClockSet();
    delay(500); // wait one second between clock display
  }
}
// ===========================================================
void DisplayPressure() {
 
  double bme_abs, rel_pres ;
 
  char string_rel_pressure[8];
  char string_abs_pressure[8];
  char string_elevation[8];
 
    bme_abs = bme.getPressure()/100;
    rel_pres = bme_abs / pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255);
 
  dtostrf(bme_abs,  4, 1, string_abs_pressure);
  dtostrf(rel_pres, 4, 1, string_rel_pressure);
  dtostrf(ALTITUDE, 3, 1, string_elevation);
 
  sprintf(cb, "Absoluter Luftdruck: %shPa\tLuftdruck auf Meereshoehe: %shPa\tHoehe: %sm",
               string_abs_pressure,
               string_rel_pressure,
               string_elevation
               );
  Serial.println(cb);
 
  lcd.clear();
  lcd.setCursor(0, 0);
  sprintf(cb, "Luftdruck  %shPa", string_rel_pressure);
  lcd.print(cb);
 
  lcd.setCursor(0, 1);
  sprintf(cb, "Luftdruck  %shPa", string_abs_pressure);
  lcd.print(cb);
 
  lcd.setCursor(0, 2);
  sprintf(cb, "H%che          %sm", char(0xef), string_elevation);
  lcd.print(cb);
 
  /* ------------------------------------------------------- */
  digitalClockDisplay();
}
 
// ===============================================================
// BME280 related
// Display Temp./Hum./Dew
// 
 
void BME_DisplayTempHumDew() {
 
  double bme_temp, bme_humidity, bme_dew;
 
  char string_bme_temp[10];
  char string_bme_humidity[10];
  char string_bme_dew[10];
  
  
    bme_temp = bme.getTemperature_C();
    bme_humidity = bme.getHumidity();
    bme_dew = dewPointFast(bme_temp, bme_humidity);
 
 
 
  dtostrf(bme_temp, 3, 1, string_bme_temp);
  dtostrf(bme_humidity, 3, 1, string_bme_humidity);
  dtostrf(bme_dew, 3, 1, string_bme_dew);
 
  sprintf(cb, "BME-Temperature: %s°C\tBME-Humidity: %s%%rH\tBME-Dewpoint: %s°C\t",
               string_bme_temp,
               string_bme_humidity,
               string_bme_dew
               );
  Serial.println(cb);
 
  lcd.clear(); //Clear screen
  lcd.setCursor(0, 0);
  sprintf(cb, "Luftfeuchte  %s%%rH", string_bme_humidity);
  lcd.print(cb);
 
  lcd.setCursor(0, 1);
  sprintf(cb, "Temperatur    %s%cC", string_bme_temp, char(0xdf) );
  lcd.print(cb);
 
  lcd.setCursor(0, 2);
  sprintf(cb, "Taupunkt      %s%cC", string_bme_dew, char(0xdf));
  lcd.print(cb);
 
  /* ------------------------------------------------------- */
  // 40 values from 60%rH to 100%rH
  
  int RPM[] = { 
    50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
    40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
    30, 28, 26, 24, 22, 20, 18, 16, 14, 12,
    10, 9, 8, 7, 6, 5, 4, 3, 2, 1
  };
 
  int hum, fan_speed;
 
  hum=bme_humidity;     // convert to integer
 
  if ((hum) > 60)
    {
      hum=hum-60;
      fan_speed=(RPM[hum]);
      setTransistorFanSpeed(fan_speed);
    }    
    else
    {
      fan_speed=0;
      setTransistorFanSpeed(70);
    }
    sprintf(cb, "Hum = %2d\tfan_speed = %2d", hum, fan_speed);
    Serial.println(cb);
  
//  lcd.setCursor(10, 1);
//  lcd.print("Fan ");
//  lcd.print(fan_speed);
 
  /* ------------------------------------------------------- */
  digitalClockDisplay();
}
 
// ===============================================================
// DHT related
// Display Temp./Hum./Dew
// 
 
void DHT_DisplayTempHumDew() {
 
  double dht_humidity, dht_temperature, dht_dew;
  char string_temp[10];
  char string_hum[10];
  char string_dew[10];
 
  // READ DHT DATA
  uint32_t start = micros();
  int chk = DHT.read22(DHT22_PIN);
  uint32_t stop = micros();
 
  Serial.println();
  Serial.print(F("Read sensor: "));
  switch (chk)
  {
  case 0: 
    Serial.println("OK"); 
    break;
  case -1: 
    Serial.println("Checksum error"); 
    break;
  case -2: 
    Serial.println("Time out error"); 
    break;
  default: 
    Serial.println("Unknown error"); 
    break;
  } 
 
  // DISPLAY DATA
 
  dht_humidity = DHT.humidity;
  dht_temperature = DHT.temperature;
  dht_dew = dewPointFast(dht_temperature, dht_humidity);
 
  dtostrf(dht_humidity, 3, 1, string_hum);
  dtostrf(dht_temperature, 3, 1, string_temp);
  dtostrf(dht_dew, 3, 1, string_dew);
 
  lcd.clear(); //Clear screen
  lcd.setCursor(0, 0);
 
  sprintf(cb, "Luftfeuchte  %s%%rH", string_hum);
  lcd.print(cb);
 
  lcd.setCursor(0, 1);
  sprintf(cb, "Temperatur   %s%cC", string_temp, char(0xdf));
  lcd.print(cb);
 
  lcd.setCursor(0, 2);
  sprintf(cb, "Taupunkt     %s%cC", string_dew, char(0xdf));
  lcd.print(cb);
 
  sprintf(cb, "Humidity: %s%%rH\tTemperatur: %s°C\r\nTaupunkt: %s°C\tConversion time: %4dµs", string_hum, string_temp, string_dew, (stop - start));
  Serial.println(cb);
  /* ------------------------------------------------------- */
  digitalClockDisplay();
}
 
// =================================================================
void digitalClockDisplay() {
 
  utc = now();
  local = CE.toLocal(utc, &tcr);
  printTimeLCD(local, tcr -> abbrev);
}
 
void printTimeLCD(time_t t, char *tz) {
 
  // Da in dem vierzeiligen Display noch eine Zeile Platz hatte
  // hier eine Art von Sekundenzeiger
  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)) ;
 
  lcd.setCursor(0, 3);
  lcd.print(cb);
 
  Serial.println();
  utc = now();
  printTime(utc, "UTC");
  local = CE.toLocal(utc, &tcr);
  printTime(local, tcr -> abbrev);
}
//Function to print time with time zone
void printTime(time_t t, char *tz)
{
  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 ) ;
  Serial.println(cb);
}
 
 // -----( Declare User-written Functions )-----
 //Celsius to Fahrenheit conversion
 double Fahrenheit(double celsius)
 {
 return 1.8 * celsius + 32;
 }
 
 
//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
  return celsius + 273.15;
}
 
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
  double A0= 373.15/(273.15 + celsius);
  double SUM = -7.90298 * (A0-1);
  SUM += 5.02808 * log10(A0);
  SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
  SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
  SUM += log10(1013.246);
  double VP = pow(10, SUM-3) * humidity;
  double T = log(VP/0.61078);   // temp var
  return (241.88 * T) / (17.558-T);
}
 
// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
  double a = 17.271;
  double b = 237.7;
  double temp = (a * celsius) / (b + celsius) + log(humidity/100);
  double Td = (b * temp) / (a - temp);
  return Td;
 
}
 
void CheckClockSet() {
  if (Serial.available()) {
    time_t t = processSyncMessage();
    if (t > 0)
    {
      RTC.set(t);   // set the RTC and the system time to the received value
      setTime(t);
 
      Serial.println("New Tiime has been set");
      utc = now();
      printTime(utc, "UTC");
      local = CE.toLocal(utc, &tcr);
      printTime(local, tcr -> abbrev);
    }
  } // if no input, just return
}
 
/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
 
time_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  while (Serial.available() >=  TIME_MSG_LEN ) { // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);
    if ( c == TIME_HEADER ) {
      time_t pctime = 0;
      for (int i = 0; i < TIME_MSG_LEN - 1; i++) {
        c = Serial.read();
        if ( c >= '0' && c <= '9') {
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
        }
      }
      return pctime;
    }
  }
  return 0;
}
// ===================================
 
// ===================================
void DisplayMoonPhase()
{
  local = CE.toLocal(utc, &tcr);
  Serial.println("MoonPhase:\t");
  Serial.println(MoonPhase(local, tcr -> abbrev));
 
  lcd.setCursor(0, 0);
  lcd.print("Mondphase:          ");
  lcd.setCursor(11, 0);
  lcd.print(MoonPhase(local, tcr -> abbrev));
 
  lcd.setCursor(0, 1);
  lcd.print("Aufgang:        ");
 
  lcd.setCursor(0, 2);
  lcd.print("Untergang:      ");
 
  lcd.setCursor(0, 3);
  lcd.println("                ");
 
 
}
 
float MoonPhase(time_t t, char *tz)
{
  return GetPhase(year(t), month(t), day(t) );
}
 
float GetPhase(int nYear, int nMonth, int nDay) // calculate the current phase of the moon
{ 
  float phase;
  double AG, IP; 
  long YY, MM, K1, K2, K3, JD; 
  YY = nYear - floor((12 - nMonth) / 10); 
  MM = nMonth + 9;
  if (MM >= 12)
  {
    MM = MM - 12;
  }
  K1 = floor(365.25 * (YY + 4712));
  K2 = floor(30.6 * MM + 0.5);
  K3 = floor(floor((YY / 100) + 49) * 0.75) - 38;
  JD = K1 + K2 + nDay + 59;
  if (JD > 2299160)
  {
    JD = JD - K3;
  }
  IP = MyNormalize((JD - 2451550.1) / 29.530588853);
  AG = IP*29.53;
  phase = 0; 
  if ((AG < 1.84566) && (phase == 0))
  {
    phase = 0;  //new; 0% illuminated
  }
  if ((AG < 5.53699) && (phase == 0))
  {
    phase = .25; //Waxing crescent; 25% illuminated
  }
  if ((AG < 9.922831) && (phase == 0))
  {
    phase = .50;    //First quarter; 50% illuminated
  }
  if ((AG < 12.91963) && (phase == 0))
  {
    phase = .75; //Waxing gibbous; 75% illuminated
  }
  if ((AG < 16.61096) && (phase == 0))
  {
    phase = 1; //Full; 100% illuminated
  }
  if ((AG < 20.30228) && (phase == 0))
  {
    phase = .75; //Waning gibbous; 75% illuminated
  }
  if ((AG < 23.99361) && (phase == 0))
  {
    phase = .50; //Last quarter; 50% illuminated
  }
  if ((AG < 27.68493) && (phase == 0))
  {
    phase = .25; //Waning crescent; 25% illuminated
  }
  if (phase == 0)
  {
    phase = 0;  //default to new; 0% illuminated
  }
  return phase; 
}
 
double MyNormalize(double v) 
{ 
  v = v - floor(v);
  if (v < 0)
    v = v + 1;
  return v;
} 
 
// ================ from:
// http://reefsanctuary.com/forum/index.php?threads/show-your-arduino-controller-sketch.71063/
// =============
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
}
 
void FanTest()
{
  setTransistorFanSpeed(0);
  delay(5000);   // run for 30 seconds at maximum fan speed
 
  setTransistorFanSpeed(10);
  delay(5000);   // run for 30 seconds at maximum fan speed
 
  setTransistorFanSpeed(20);
  delay(5000);   // run for 30 seconds at low fan speed
 
  setTransistorFanSpeed(30);
  delay(5000);   // run for 30 seconds at low fan speed
 
  setTransistorFanSpeed(40);
  delay(5000);   // run for 30 seconds at low fan speed
 
  setTransistorFanSpeed(50);
//  delay(5000);   // run for 30 seconds at low fan speed
 
}
 
// ==========================================
void roop(int Reihe, String line2, int speed) {
  countMovement = 0;
  stringStart = 0;
  stringStop = 0;
  scrollCursor = 0;
 
  // Serial.print(countMovement); Serial.print("-"); Serial.println(line2.length() + 1);
  while ( ( countMovement ) < (line2.length() + 2 )  )
  {
    lcd.setCursor(scrollCursor, Reihe);
    // Serial.print("Cursor: "); Serial.print(scrollCursor); Serial.print(" "); Serial.println(Reihe);
    lcd.print(line2.substring(stringStart, stringStop));
    // Serial.println( line2.substring(stringStart, stringStop) );
    delay(speed);
 
    if (stringStart == 0 && scrollCursor > 0) {
      // Serial.println(scrollCursor);
      scrollCursor--;
      stringStop++;
    } else if (stringStart == stringStop) {
      stringStart = stringStop = 0;
      scrollCursor = screenWidth;
    } else if (stringStop == line2.length() && scrollCursor == 0) {
      stringStart++;
    } else {
      stringStart++;
      stringStop++;
    }
    countMovement++;
  }
}
void ClearLine(int line)
{
}
 
 
 

Comments