Управление рассадным боксом платами ардуино

Тема в разделе "Arduino & Shields", создана пользователем MESS, 2 мар 2015.

  1. X-Dron

    X-Dron Гик

    Дело не в часах, а в индикации на панели.
    тип uint8_t переменной minute не может вместить значение 5678.
    При включении питания наводки могут вывести на дисплей что угодно, а в программе нет его очистки.
    либо перед lcd.setCursor(0, 1); поставить lcd.clear();
    тогда дисплей будет чистится каждый раз перед выводом времени,
    либо после lcd.begin(20, 4); так же поставить lcd.clear();
    в этом случае дисплей очистится полностью только при инициализации.
    Я уже давал совет в личке перевести прогу под имеющийся у Вас OLIMEX SHIELD-LCD16x2.
    Со скетчем помогу.
    Посмотрел внимательно доку по этому шилду - помимо дисплея и кнопок у него есть еще и пины, которые можно использовать как дополнительные входы-выходы (GPIO). Их 9 штук, но они по, умолчанию, не распаяны. Если дисплей не на разъеме, а припаян к красной плате, то с установкой разъема GPIO могут быть проблемы.
    Функции для работы с GPIO:
    LCD16x2::pinMode(uint8_t pin, uint8_t direction)
    LCD16x2::digitalWrite(uint8_t pin, uint8_t level)
    uint8_t LCD16x2::digitalRead(uint8_t pin)
    Небольшой минус только в том, что в заводской библиотеке используется для вывода только тип String.
    Для вывода целочисленных значений нужно использовать lcdWrite(string(Int_Value));
     
  2. MESS

    MESS Гик

    Наконец то дисплей OLIMEX LCD16х2 заработал, благодаря большой работе
    X-Dron , за что ему огромное спасибо и респект!
    Теперь появились дополнительные пины на НАНО и на LCD есть входы GPIO и кнопки. Есть стимул дальше продолжить, но появились другие проблемы, которые более важны.
    При отключении от порта компа и переходе на стороннее питание (стаб), время на дисплее не отображается. Увеличение интервала запроса времени от часов, не помогает.
    Получилось только так: если подключить внешний источник после загрузки скетча а затем отключить комп. Если же внешний источник (12В стаб) включен во время загрузки- она не происходит.
    Оставил эти часы на ночь включенными и утром увидел совсем не те цифры. очистка дисплея в программе есть. Следующая проблема -
    внешние воздействия на ардуино.
    Я понимаю что макет с длинными проводами, хорошо "ловит" помехи, и я буду принимать аппаратные меры при будущей сборке девайса. Но поскольку хочется сварганить " работящий девайс, а не игрушку на час", сейчас возникают вопросы:
    1. Можно ли программно уменьшить влияние помех
    2. можно ли осуществить внешний контроль и коррекцию работы. готов на увеличение числа ардуин.
    3. Есть ли для 3107 решения по доработке для улучшения точности и надежности? Или искать другие часы?
    4.Как использовать кнопки дисплея для коррекции времени?
     

    Вложения:

  3. X-Dron

    X-Dron Гик

    Родилась идея, а что если при старте от внешнего питания экран и PIC16F722A не успевают инициализироваться.
    Поставьте перед Wire.begin() с сетапе delay(500).
    По п.4. Можно, но это приличный труд. Без дисплея удаленно делать крайне тяжело.
    У меня для обычного 4-х разрядного индикатора на I2C получился такой код. (Только чтобы имели представление, Вам не подойдет)
    Код (Text):
    #include <DI.h>
    #include <Meander.h>
    #include <Timer_P.h>
    #include <DS3231.h>
    #include <Wire.h>
    #include <EEPROM.h>
    #include "TM1637.h"

    //Массив, содержащий время компиляции
    char compileTime[] = __TIME__;
    char compileDate[] = __DATE__;

    #define DISPLAY_CLK_PIN 11
    #define DISPLAY_DIO_PIN 12
    #define MODE_KEY_PIN 5
    #define PLUS_KEY_PIN 6
    #define MINUS_KEY_PIN 7

    TM1637 display(DISPLAY_CLK_PIN, DISPLAY_DIO_PIN);
    DS3231 Clock;
    DI ModeKey(MODE_KEY_PIN, 10), PlusKey(PLUS_KEY_PIN, 10), MinusKey(MINUS_KEY_PIN, 10);
    Timer_P DisplayPeriod, AutoID_Timer, SecsSetted;
    Meander P_s;
    int Mode=0, Hour, Minute, HourToSet, MinuteToSet, OutPeriod=200;
    boolean ModeKey_old, PlusKey_old, MinusKey_old, Mode2_old, Mode3_old, SecsSetted_old;

    void setup()
    {
      // Start the I2C interface
      Wire.begin();
      //Включаем и настраиваем индикатор
      display.set();
      display.init();

      //Получаем число из строки, зная номер первого символа
      byte hour = getInt(compileTime, 0);
      byte minute = getInt(compileTime, 3);
      byte second = getInt(compileTime, 6);
     
      unsigned int hash =  hour * 60 * 60 + minute  * 60 + second;
      if (EEPROMReadInt(0) != hash) {
        //Сохраняем новый хэш
        EEPROMWriteInt(0, hash);
        Clock.setSecond(second);
        Clock.setMinute(minute);
        Clock.setHour(hour);
      }
      pinMode(13, OUTPUT);
    }

    void loop()
    {
      //Запускаем меандр
      P_s.MeanderV(OutPeriod*2, OutPeriod);
      ModeKey.DI_Refresh();
      PlusKey.DI_Refresh();
      MinusKey.DI_Refresh();

      DisplayPeriod.TimerV(!DisplayPeriod.Q0(), 0, 2, OutPeriod); // Самосбрасывающийся таймер периода
      AutoID_Timer.TimerV(!AutoID_Timer.Q0() && (PlusKey.DI_Read() || MinusKey.DI_Read()) && !(PlusKey.DI_Read() && MinusKey.DI_Read()) , 0, 2, OutPeriod*2);
      SecsSetted.TimerV((Mode==1 && ((PlusKey.DI_Read() &&!PlusKey_old) || (MinusKey.DI_Read() && !MinusKey_old))),0,1,1500);

      if (ModeKey.DI_Read() && !ModeKey_old) Mode = (++Mode)%4; //Перебор режимов
      if (!SecsSetted.Q0() && SecsSetted_old) Mode = 2;
      if (Mode ==2  && !Mode2_old) MinuteToSet = Minute;
      if (Mode ==3  && !Mode3_old) HourToSet = Hour;

      if (Mode==1 && ((PlusKey.DI_Read() &&!PlusKey_old) || (MinusKey.DI_Read() && !MinusKey_old))) Clock.setSecond(0);
      if (Mode!=2 && Mode2_old) Clock.setMinute(MinuteToSet);
      if (Mode!=3 && Mode3_old) Clock.setHour(HourToSet);
      if ((PlusKey.DI_Read() || MinusKey.DI_Read()) && !(PlusKey.DI_Read() && MinusKey.DI_Read()) && Mode == 2){
        if (PlusKey.DI_Read() && (!PlusKey_old || AutoID_Timer.Q0())) MinuteToSet=(++MinuteToSet)%60;
        if (MinusKey.DI_Read() && (!MinusKey_old || AutoID_Timer.Q0())) MinuteToSet=--MinuteToSet;
        if (MinuteToSet < 0) MinuteToSet = 59;
      }

      if ((PlusKey.DI_Read() || MinusKey.DI_Read()) && !(PlusKey.DI_Read() && MinusKey.DI_Read()) && Mode == 3){
        if (PlusKey.DI_Read() && (!PlusKey_old || AutoID_Timer.Q0())) HourToSet=(++HourToSet)%24;
        if (MinusKey.DI_Read() && (!MinusKey_old || AutoID_Timer.Q0())) HourToSet=--HourToSet;
        if (HourToSet < 0) HourToSet = 24;
      }

      if (DisplayPeriod.Q0()){
          // Get data from the DS3231
          int8_t timeDisp[4];
          bool h12=false;
          bool PM=false;

          //Запрашиваем время
          Minute = Clock.getMinute();    
          Hour = Clock.getHour(h12, PM);
       
          //Получаем десятки часов с помощью целочисленного деления
          timeDisp[0] = Hour / 10;
          timeDisp[1] = Hour % 10;
          timeDisp[2] = Minute / 10;
          timeDisp[3] = Minute % 10;
       
          switch (Mode) {
            case 1:
              //if (P_s.Q0()){
                  timeDisp[0] = 16;
                  timeDisp[1] = 16;
                  timeDisp[2] = 16;
                  timeDisp[3] = 16;
              //}
              break;
            case 2:
              if (P_s.Q0()){
                  timeDisp[2] = MinuteToSet / 10;
                  timeDisp[3] = MinuteToSet % 10;
              }else{
                  timeDisp[2] = 16;
                  timeDisp[3] = 16;
              }
              break;
            case 3:
              if (P_s.Q0()){
                  timeDisp[0] = HourToSet / 10;
                  timeDisp[1] = HourToSet % 10;
              }else{
                  timeDisp[0] = 16;
                  timeDisp[1] = 16;
              }      
              break;
          }
          display.display(timeDisp);
          display.point(((Clock.getSecond() % 2 ? POINT_ON : POINT_OFF) && !SecsSetted.Q0()) || (!P_s.Q0() && SecsSetted.Q0()));
      }
      ModeKey_old = ModeKey.DI_Read();
      PlusKey_old = PlusKey.DI_Read();
      MinusKey_old = MinusKey.DI_Read();
      SecsSetted_old = SecsSetted.Q0();
      Mode2_old = (Mode==2);
      Mode3_old = (Mode==3);
      digitalWrite(13, P_s.Q0());
    }

    //Содержимое функции объяснено ниже
    char getInt(const char* string, int startIndex) {
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    }

    //Запись двухбайтового числа в память
    void EEPROMWriteInt(int address, int value)
    {
      EEPROM.write(address, lowByte(value));
      EEPROM.write(address + 1, highByte(value));
    }
    //Чтение числа из памяти
    unsigned int EEPROMReadInt(int address)
    {
      byte lowByte = EEPROM.read(address);
      byte highByte = EEPROM.read(address + 1);
      return (highByte << 8) | lowByte;
    }
     
    Последнее редактирование: 14 мар 2015
  4. MESS

    MESS Гик

    пока не вышло.
    Выходит, что этот LCD не совместим с ардуино, поскольку возникают многочисленные проблемы?
    Попробую запитать от аккумулятора- хотя бы бросков по питанию не будет
     
  5. X-Dron

    X-Dron Гик

    Нет, как раз наоборот. Она именно заточено под ардуино. Но есть подозрения, что заточен под "монопольное" использование. На плате даже толком не разведены неиспользуемые платой пины ардуины. И развести их проблематично. Вывод I2C шины и сериал для подключения других устройств только в опциональном заказе (разводка UEXT).
    Так же устройств и производителей куча разных. В простых вариантах все достаточно просто работает. Начинаешь углубляться, стыковать разные датчики и модули и начинаются танцы с бубном.
    У меня есть часы с коррекцией времени от кнопок, дак они совершенно прекрасно работают на оригинальной итальянской ардуино уно. Переношу скетч на китайскую мегу и начинается. Может проработать сутки без сбоя. Может через пару секунд встать в полный стопор. Перезапуск не всегда помогает.
    При этом другой скетч, с самодельным шилдом на этой же меге работает без проблем сколько б его ни тестировал.
    Может связано с качеством питания, оно как-то влияет на I2C, может с тем, что у китайца стоит резонатор на 12МГц вместо 16. Может китайцы кондеры не те вставили, в итоге фронты заваливаются.

    На соседнем форуме натолкнули на мысль отредактировать boards.txt, протисать там 12МГц.
    Я уже пару раз спрашивал "А какой у Вас резонатор?" Может в нем дело.
    UPD:
    Изменения в boards.txt ни к чему не привели. Китайская мега так же уходит в стоп.
     
    Последнее редактирование: 14 мар 2015
  6. 9xA59kK

    9xA59kK Гик

    Было у меня подобное при отключении comPorta. При отключении компорта ардуина перезагружается, этоже должен сделать и дисплей. Если дисплей подключен по I2c тот так и происходит. Причем надо чтобы дисплей включался после загрузки ардуино. Есле дисплей включить первым, а потом ардуину, то может ничего не отображаться, хотя время будет тикать как надо. Тоже самое при переходе на другое питание.
     
    MESS нравится это.
  7. X-Dron

    X-Dron Гик

    9xA59kK

    прав. Киньте еще перемычку между ресетами. На шилде это рядом с пином 3.3V, крайняя. На nano 3-я нога со сторона ICSP-разъема по любую сторону платы.
     
  8. MESS

    MESS Гик

    установил перемычку
    - С перемычкой нажатие кнопки ресет сразу очищает дисплей , без перемычки - с задержкой в 6 секунд.
    если без разрыва питании от компа то через 10 секунд после ресета счет восстанавливается.

    -если на мгновение переподключить разьем компа, то счет не восстанавливается, выполняет только
    lcd.lcdWrite("Time:");
    попробую реализовать - ".. надо чтобы дисплей включался после загрузки ардуино."
    результат сообщу.
    А если "попросить" ардуино выдать на свой пин команду включения LCD? для попробовать:)
     
  9. MESS

    MESS Гик

    Попрбовал ресетить дисплей без кнопки , автономно -коснувшись массы. при этом дисплей очистился и через нес секунд счет появился, НО без Time:
    выходит void setup() уже не будет выполняется до ресета самой ардуино?

     
  10. geher

    geher Гуру

    Естественно. Так и было задумано. setup выполняется один раз при старте ардуины (после ресета или подачи питания), а дальше по кругу гоняется loop.
     
    MESS нравится это.
  11. X-Dron

    X-Dron Гик

    на OLIMEX LCD16х2 есть кнопка Reset. Она перезапускает и дисплей и arduino, если есть перемычка между ресетами
     
  12. MESS

    MESS Гик

    на схеме она есть, а на плате сразу не нашел. объявил в розыск
     
  13. MESS

    MESS Гик

    розыск обнаружил контактные площадки RST, которые ни с чем не "звонятся"
    придется из имеющухся кнопок приспособить одну. если доберусь к ним
     

    Вложения:

    • RST.png
      RST.png
      Размер файла:
      437,1 КБ
      Просмотров:
      898
    Последнее редактирование: 15 мар 2015
  14. MESS

    MESS Гик

    наконец-то!
     

    Вложения:

  15. MESS

    MESS Гик

    Однако попытки добавить в скетч работающего таймера, контроль и отображение температуры приводят к ошибкам. где они?
    не ругаются ли библиотеки ?
    OneWire.h> и <Wire.h> хотя разницу понимаю.
    Код (Text):


    #include <OneWire.h>
    #include <EEPROM.h>
    #include <LCD16x2.h>
    #include <DS1307.h>
    #include <Wire.h>
    #include <Timer_P.h>

    LCD16x2 lcd;

    // Назначаем пины для светодиодов
    #define RED 3                                        // красные светодиоды
    #define BLUE 12                                        // синие светодиоды
    #define ONEWIRE_PIN  2 // для DC18B20
    #define TEMPERATURE_UPDATE_TIME 10000  // частота чтения датчиков температуры (мсек)




    // для простоты отладки можно hour заменить на second или minute
    #define MORNING  clock.hour >=7 && clock.hour < 11    // период, который считаем как "утро"
    #define DAY      clock.hour >=11 && clock.hour < 17  // период, который считаем как "день"
    #define EVENING  clock.hour >=17 && clock.hour < 22  // период, который считаем как "вечер"
    #define NIGHT    clock.hour >=21 && clock.hour < 7    // период, который считаем как "ночь"


    //Массив, содержащий время компиляции
    char compileTime[] = __TIME__;

    OneWire ds(ONEWIRE_PIN);
    //Для работы с микросхемой часов используем библиотеки
    DS1307 clock;
    Timer_P ClockUpdateTimer;
    byte Sec_Old, Min_Old;
    byte setState;  // состояние, которое надо выполнить в зависимости от времени суток
    boolean P_First_Run;
    int tempSensor1;        // переменная, где храним текущую температуру с датчика 1
    unsigned long temp1LastUpdateTime; // переменная для расчета периода опроса датчика температуры

    void setup()
    {
        // конфигурируем пины на выход
      pinMode(RED, OUTPUT);
      pinMode(BLUE, OUTPUT);

      //Запускаем часы реального времени
      delay(5000 );
      Wire.begin();
      lcd.lcdClear();
      lcd.lcdGoToXY(2,1);
      lcd.lcdWrite("Time:");
    lcd.lcdGoToXY(2,2);
      lcd.lcdWrite("Temper-ra:");

      //Получаем число из строки, зная номер первого символа
      byte hour = getInt(compileTime, 0);
      byte minute = getInt(compileTime, 3);
      byte second = getInt(compileTime, 6);

      //Импровизированный хэш времени
      //Содержит в себе количество секунд с начала дня
      unsigned int hash = hour * 60 * 60 + minute * 60 + second;

      //Проверяем несовпадение нового хэша с хэшем в EEPROM
      if (EEPROMReadInt(0) != hash) {

        //Сохраняем новый хэш
        EEPROMWriteInt(0, hash);

        //Готовим для записи в RTC часы, минуты, секунды
        clock.fillByHMS(hour, minute, second);

        //Записываем эти данные во внутреннюю память часов.
        //С этого момента они начинают считать нужное для нас время
        clock.setTime();
        delay(100);
      }
      P_First_Run = true;

    }

    void loop()
    {
      //Запрашиваем время с часов
      ClockUpdateTimer.TimerV(!ClockUpdateTimer.Q0(), 0, 2, 500);
      if (ClockUpdateTimer.Q0() ||  P_First_Run) {clock.getTime(); delay(20);}//запрос времени раз в 500мс
      if ((clock.minute != Min_Old) || P_First_Run){
        lcd.lcdGoToXY(7,1);
        lcd.lcdWrite(clock.hour/10);
        lcd.lcdGoToXY(8,1);
        lcd.lcdWrite(clock.hour%10);

        lcd.lcdGoToXY(10,1);
        lcd.lcdWrite(clock.minute/10);
        lcd.lcdGoToXY(11,1);
        lcd.lcdWrite(clock.minute%10);

        //lcd.lcdGoToXY(12,1);
        //lcd.lcdWrite("*");
      }
      if ((clock.second != Sec_Old) || P_First_Run){
        //lcd.lcdGoToXY(9,2);
        //lcd.lcdWrite(clock.second); // контроль секунд под двоеточием
        lcd.lcdGoToXY(9,1);
        if (clock.second % 2 == 0) lcd.lcdWrite(" ");
        else lcd.lcdWrite(":");
      }
      Sec_Old = clock.second;// запоминаем текущие показания секунд
      Min_Old = clock.minute;
      P_First_Run = false;
    }
    // обращаемся к шине OneWire
      byte data[2];
      ds.reset();  
                                   //error: expected constructor, destructor, or type conversion before '.' token.    Что он хочет?
      ds.write(0xCC);
      ds.write(0x44);




      // читаем датчики температуры
      if (millis() - temp1LastUpdateTime > TEMPERATURE_UPDATE_TIME)
      {
        temp1LastUpdateTime = millis();
        ds.reset();
        ds.write(0xCC);
        ds.write(0xBE);
        data[0] = ds.read();
        data[1] = ds.read();
        tempSensor1 = (data[1] << 8) + data[0];
        tempSensor1 = tempSensor1 >> 4;
      }

    // выводим показания на дисплей
      lcd.lcdGoToXY(14,2);
      lcd.lcdWrite("    ");
      lcd.lcdGoToXY(14,2);
      if (tempSensor1 > 0) lcd.lcdWrite("+");
      if (tempSensor1 == 0) lcd.lcdWrite(" ");
      lcd.lcdWrite(tempSensor1);            // отображаем температуру
    }  // конец displayTemp


    char getInt(const char* string, int startIndex) {
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    }

    // трансформируем процентное значение в значение 0...255
    byte brightness(byte value)
    {
      return map(value, 0, 100, 0, 255);
    }


    //Запись двухбайтового числа в память
    void EEPROMWriteInt(int address, int value)
    {
      EEPROM.write(address, lowByte(value));
      EEPROM.write(address + 1, highByte(value));
    }

    //Чтение числа из памяти
    unsigned int EEPROMReadInt(int address)
    {
      byte lowByte = EEPROM.read(address);
      byte highByte = EEPROM.read(address + 1);

      return (highByte << 8) | lowByte;
    }
     
  16. X-Dron

    X-Dron Гик

    после
    Код (Text):
    P_First_Run = false;
    фигурная скобка лишняя она loop закрывает.
     
  17. MESS

    MESS Гик

    Несколько днй пытался вылечить НАНО, которые побывали в WIN7 и стали "инвалидами" по загрузке.
    Теперь пытаюсь сложный для меня скетч доводить по отдельным частям: таймер и регулятор параметров по отдельным платам. А потом буду пробовать их вместе "соединить".
    Прошу помочь вставить в работающий скетч отсчета и индикации времени, функции управления двумя каналами светодиодов досветки в зависимости от времени суток.
    Этот скетч считает время хорошо:
    Код (Text):
    #include <EEPROM.h>
    #include <LCD16x2.h>
    #include <DS1307.h>
    #include <Wire.h>
    #include <Timer_P.h>
    LCD16x2 lcd;

    // Назначаем пины для  светодиодов
    #define RED 3                                        // красные светодиоды
    #define BLUE 4                                        // синие светодиоды


    #define MORNING  clock.hour >=7 && clock.hour < 11               // период, который считаем как "утро"
    #define DAY      clock.hour >=11 && clock.hour < 17                     // период   "день"
    #define EVENING  clock.hour >=17 && clock.hour < 22             // период  "вечер"
    #define NIGHT    clock.hour >=21 && clock.hour < 7                   // период "ночь"


    //Массив, содержащий время компиляции
    char compileTime[] = __TIME__;
    //Для работы с микросхемой часов используем библиотеки
    DS1307 clock;
    Timer_P ClockUpdateTimer;
    byte Sec_Old, Min_Old;
    byte setState;  // состояние, которое надо выполнить в зависимости от времени суток
    boolean P_First_Run;

    void setup()
    {
        // конфигурируем пины на выход
      pinMode(RED, OUTPUT);
      pinMode(BLUE, OUTPUT);

      //Запускаем часы реального времени
      delay(5000 );
      Wire.begin();
      lcd.lcdClear();
      lcd.lcdGoToXY(2,1);
      lcd.lcdWrite("Time-");


      //Получаем число из строки, зная номер первого символа
      byte hour = getInt(compileTime, 0);
      byte minute = getInt(compileTime, 3);
      byte second = getInt(compileTime, 6);

      //Импровизированный хэш времени
      //Содержит в себе количество секунд с начала дня
      unsigned int hash = hour * 60 * 60 + minute * 60 + second;

      //Проверяем несовпадение нового хэша с хэшем в EEPROM
      if (EEPROMReadInt(0) != hash) {

        //Сохраняем новый хэш
        EEPROMWriteInt(0, hash);

        //Готовим для записи в RTC часы, минуты, секунды
        clock.fillByHMS(hour, minute, second);

        //Записываем эти данные во внутреннюю память часов.
        //С этого момента они начинают считать нужное для нас время
        clock.setTime();
        delay(100);
      }
      P_First_Run = true;
    }
    void loop()
    {
      //Запрашиваем время с часов
      ClockUpdateTimer.TimerV(!ClockUpdateTimer.Q0(), 0, 2, 500);
      if (ClockUpdateTimer.Q0() ||  P_First_Run) {clock.getTime(); delay(20);}//запрос времени раз в 500мс
      if ((clock.minute != Min_Old) || P_First_Run){
        lcd.lcdGoToXY(7,1);
        lcd.lcdWrite(clock.hour/10);
        lcd.lcdGoToXY(8,1);
        lcd.lcdWrite(clock.hour%10);

        lcd.lcdGoToXY(10,1);
        lcd.lcdWrite(clock.minute/10);
        lcd.lcdGoToXY(11,1);
        lcd.lcdWrite(clock.minute%10);

        //lcd.lcdGoToXY(12,1);
        //lcd.lcdWrite("*");
      }
      if ((clock.second != Sec_Old) || P_First_Run){
        //lcd.lcdGoToXY(9,2);
        //lcd.lcdWrite(clock.second); // контроль секунд под двоеточием
        lcd.lcdGoToXY(9,1);
        if (clock.second % 2 == 0) lcd.lcdWrite(" ");
        else lcd.lcdWrite(":");
      }
      Sec_Old = clock.second;// запоминаем текущие показания секунд
      Min_Old = clock.minute;
      P_First_Run = false;
    }
    char getInt(const char* string, int startIndex) {
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    }
    // трансформируем процентное значение в значение 0...255
    byte brightness(byte value)
    {
      return map(value, 0, 100, 0, 255);
    }
    //Запись двухбайтового числа в память
    void EEPROMWriteInt(int address, int value)
    {
      EEPROM.write(address, lowByte(value));
      EEPROM.write(address + 1, highByte(value));
    }
    //Чтение числа из памяти
    unsigned int EEPROMReadInt(int address)
    {
      byte lowByte = EEPROM.read(address);
      byte highByte = EEPROM.read(address + 1);

      return (highByte << 8) | lowByte;
    }
    А этот кусок, уже случайно заработавший, теперь перестал,не компилируется ( куда воткнуть?)

    Код (Text):

    // если  время ссответствует режиму утро, то включить красные на 100% а синие- на 50%
    if (MORNING)
      {
        analogWrite(RED, brightness(100));                  // включаем красные LED на 100% яркости
        analogWrite(BLUE, brightness(50));
        setLedBright();      // включаем светодиоды на заданную яркость
      displayState();   //
     
     
  18. MESS

    MESS Гик

    Удалось восстановить работу скетча только после того, как увеличил задержку в строке 78. Отчего это?
    Код (Text):
    001
    #include <EEPROM.h>
    002
    #include <LCD16x2.h>
    003
    #include <DS1307.h>
    004
    #include <Wire.h>
    005
    #include <Timer_P.h>
    006
    007
    LCD16x2 lcd;
    008
    // Назначаем пины для управления
    009
    #define RED 3                      // красные светодиоды
    010
    #define BLUE 4                    // синие светодиоды
    011
    012
    013
    // для простоты отладки можно hour заменить на second или minute
    014
    #define MORNING  clock.hour >=7 && clock.hour < 11    //  "утро"
    015
    #define DAY      clock.hour >=11 && clock.hour < 17  //  "день"
    016
    #define EVENING  clock.hour >=17 && clock.hour < 22  //  к "вечер"
    017
    #define NIGHT    clock.hour >=21 && clock.hour < 7
    018
    019
    020
    //Массив, содержащий время компиляции
    021
    char compileTime[] = __TIME__;
    022
    //Для работы с микросхемой часов используем библиотеки
    023
    DS1307 clock;
    024
    Timer_P ClockUpdateTimer;
    025
    byte Sec_Old, Min_Old;
    026
    027
    byte setState;  // состояние, которое надо выполнить в зависимости от времени суток
    028
    boolean P_First_Run;
    029
    030
    031
    032
    void setup()
    033
    {
    034
    // конфигурируем пины на выход
    035
      pinMode(RED, OUTPUT);
    036
      pinMode(BLUE, OUTPUT);
    037
    038
    039
    040
    //Запускаем часы реального времени
    041
      Wire.begin();
    042
      lcd.lcdClear();
    043
      lcd.lcdGoToXY(2,1);
    044
      lcd.lcdWrite("Time:");
    045
      lcd.lcdGoToXY  (1, 2);
    046
      lcd.lcdWrite("Mode: ");
    047
    048
    049
      //Получаем число из строки, зная номер первого символа
    050
      byte hour = getInt(compileTime, 0);
    051
      byte minute = getInt(compileTime, 3);
    052
      byte second = getInt(compileTime, 6);
    053
    054
      //Импровизированный хэш времени
    055
      //Содержит в себе количество секунд с начала дня
    056
      unsigned int hash = hour * 60 * 60 + minute * 60 + second;
    057
    058
      //Проверяем несовпадение нового хэша с хэшем в EEPROM
    059
      if (EEPROMReadInt(0) != hash) {
    060
    061
        //Сохраняем новый хэш
    062
        EEPROMWriteInt(0, hash);
    063
    064
        //Готовим для записи в RTC часы, минуты, секунды
    065
        clock.fillByHMS(hour, minute, second);
    066
    067
        //Записываем эти данные во внутреннюю память часов.
    068
    069
        clock.setTime();
    070
        delay(100 );
    071
      }
    072
      //P_First_Run = true;
    073
    }
    074
    void loop()  //строка73
    075
    {
    076
      //Запрашиваем время с часов
    077
    ClockUpdateTimer.TimerV(!ClockUpdateTimer.Q0(), 0, 2, 500);
    078
    if (ClockUpdateTimer.Q0()) {clock.getTime(); delay(28);}  //запрос времени раз в 500мс при задержке в 20 -НЕ МИГАЮТ СЕКУНДЫ!
    079
    if (clock.second != Sec_Old){
    080

    081
    082
    lcd.lcdGoToXY(7,1);
    083
        lcd.lcdWrite(clock.hour/10);
    084
        lcd.lcdGoToXY(8,1);
    085
        lcd.lcdWrite(clock.hour%10);
    086
     
    087
        lcd.lcdGoToXY(10,1);
    088
        lcd.lcdWrite(clock.minute/10);
    089
        lcd.lcdGoToXY(11,1);
    090
        lcd.lcdWrite(clock.minute%10);
    091
     
    092
     
    093
    if ((clock.second != Sec_Old) || P_First_Run){
    094
       
    095
        lcd.lcdGoToXY(9,1);
    096
        if (clock.second % 2 == 0) lcd.lcdWrite(" "); //if (clock.second % 2 == 0) lcd.lcdWrite(" ");
    097

    098
    099
    100
    101
    102
    103
               
    104
      else lcd.lcdWrite(":");
    105
      }
    106
      Sec_Old = clock.second;  //
    107
    Min_Old = clock.minute;
    108
      P_First_Run = false;
    109
    }
    110
    111
    // действия по наступлении утра
    112
      if (MORNING)
    113
      {
    114
        analogWrite(RED, brightness(100));                
    115
        analogWrite(BLUE, brightness(50));              
    116
     
    117
        displayState();                                  
    118
      }
    119
    120
      // действия по наступлении дня
    121
      if (DAY)
    122
      {
    123
        analogWrite(RED, brightness(100));                // включаем красные LED на 100% яркости
    124
        analogWrite(BLUE, brightness(100));                // включаем синие LED на 100% яркости
    125
     
    126
        displayState();                                    // выводим на дисплей сообщение о режиме работы
    127
      }
    128
    129
      // действия по наступлении вечера
    130
      if (EVENING)
    131
      {
    132
        analogWrite(RED, brightness(60));                
    133
        analogWrite(BLUE, brightness(40));              
    134
     
    135
        displayState();                                    // выводим на дисплей сообщение о режиме работы
    136
      }
    137
    138
      // действия по наступлении ночи
    139
      if (NIGHT)
    140
      {
    141
        analogWrite(RED, brightness(0));                  // выключаем красные LED
    142
        analogWrite(BLUE, brightness(0));                  // выключаем синие LED
    143
     
    144
        displayState();                                    // выводим на дисплей сообщение о режиме работы
    145
      }
    146
    }  // конец loop
    147
    148
    149
    void displayState()
    150
    {
    151

    152

    153
      lcd.lcdGoToXY  (7, 2);
    154
      if (MORNING) lcd.lcdWrite("Morning");                  // если утро
    155
      if (DAY) lcd.lcdWrite("Day "  );
    156
      if (EVENING) lcd.lcdWrite("EVENING "  );
    157
    }
    158
      char getInt(const char* string, int startIndex) {
    159
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    160
    }
    161
    // трансформируем процентное значение в значение 0...255
    162
    byte brightness(byte value)
    163
    {
    164
      return map(value, 0, 100, 0, 255);
    165
    }
    166
    167
    //Запись двухбайтового числа в память
    168
    void EEPROMWriteInt(int address, int value)
    169
    {
    170
      EEPROM.write(address, lowByte(value));
    171
      EEPROM.write(address + 1, highByte(value));
    172
    }
    173
    174
    //Чтение числа из памяти
    175
    unsigned int EEPROMReadInt(int address)
    176
    {
    177
      byte lowByte = EEPROM.read(address);
    178
      byte highByte = EEPROM.read(address + 1);
    179
    180
      return (highByte << 8) | lowByte;
    181
    }
     
     
    Последнее редактирование: 26 мар 2015
  19. shamzelia

    shamzelia Нерд

    А есть проект с конеретикой? хочу аналогичный свет) Но применять для выращивания круглогодичного своей зелени...
    Интересно: Схема, компоненты... логика работы