Программные часы

hypersash
Offline
Зарегистрирован: 07.12.2011

 Всем доброго времени суток! В школе нужно писать научную работу и я как тему выбрал Ардуину =) Хочу написать звонок (на/с уроков), с дисплеем где будут отображаться разные плюшки. Смысл в том что-бы паять по минимум, только кодить. Сам осваивать начал недавно, добрался до ШИМа и прочих вкусностях со светодиодами =) Так вот, гугление на тему часов выдает только схемы с применением микры DS, которая по сути и являеться часами. Не могли-бы уважаемые форумчане подтолкнуть меня в направлении программных часов исключительно на Ардуине? Прерывания (сами звонки и вывод на дисплей надеюсь осилю) Только вот по часам инфы нет совсем =( Спасибо за помощь!

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011
hypersash
Offline
Зарегистрирован: 07.12.2011

Страница не найдена =(

-------------------

Ой, понял, надо было пробел в конце убрать.. Спасибо =)

Alexander
Offline
Зарегистрирован: 25.04.2010

Правильная ссылка
http://arduino.ru/forum/programmirovanie/chasy-i-arduino

Там в первой ссылке пробел вконце затисался, я там тоже поправлю

whoim
Offline
Зарегистрирован: 03.11.2011

 Снова привет! Для будушего проекта написал скетч. Работает с DS1307 (кто не знает - отдельная махонькая микросхема со своей батарейкой, 10 лет идут часы невзирая на питание атмеги).

Скетч позволяет из строки терминала получить время и установить его (через unixtime). Просто вводите команды: now, uset xxxxxxxxxx

Вот код. Помогите пожалуйста оптимизировать его.. так неохота менять камень, скетч уже 6кб занимает из 7.. А еще читать-писать в ееепром сцуко..

#include <Wire.h>
#include "RTClib.h"
 
RTC_DS1307 RTC;
#define RX_Data_size 16
byte RX_Data[RX_Data_size];

void setup () {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  //blink - a ready
  pinMode(13,OUTPUT);
  for (int x=0; x<=5; x++) {
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
 
  Serial.println("Starting.. ok");
  Serial.print("Now: ");
  print_now();
}

void loop () {
  //read command from terminal
  RX();
  if(RX_Data[0] != NULL) {
  //select command
  //command uset (unixtime set)
  if(RX_Data[0]=='u'&&RX_Data[1]=='s'&&RX_Data[2]=='e'&&RX_Data[3]=='t'&&RX_Data[4]==' ') {
    RTC.adjust(strtol((char*)RX_Data + 4, NULL, 10));
    Serial.print("DateTime set to ");
    print_now();
  }
  //command now, print the date
  else if(RX_Data[0]=='n'&&RX_Data[1]=='o'&&RX_Data[2]=='w') {
    Serial.print("Now: ");
    print_now();
  }
  //default
  else {
    Serial.println("unknown command or invalid use, read manual");
  }
  //clear buffer
  RX_Data_clear();
  }
   
  delay(200);
}

//Serial read func
void RX() {
    byte RX_i = 0;
    byte b;
    while (Serial.available()) {
      b = Serial.read();
      if(b == 13) break;
      RX_Data[RX_i] =  b;
      RX_i++;
      if(RX_i > RX_Data_size - 1) break;
    }

}

void RX_Data_clear(){
   for (int x = 0; x <= RX_Data_size - 1; x++) 
      RX_Data[x] = 0;
}

void print_now() {
    DateTime now = RTC.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.println(now.second(), DEC);
}

 

whoim
Offline
Зарегистрирован: 03.11.2011

  Смысл в том что-бы паять по минимум

А там и правда паять по минимум. Микросхема, кварц от старой материнки, два резистора. Микросхема копеечная. Зато не зависит от "внешних условий", и точная (если кварц качественный)

zhuki
Offline
Зарегистрирован: 12.10.2011

Whoim  вы хотите сократить код ?  Зачем вам связь ?  Для того что бы однажды в 10 лет установить часы и дату.

Первый раз при включении DS1307 установите время и дату ,заремте ненужные строки и загрузите в контроллер без возможности коррекции.

Для себя я оставил возможность коррекции из внешней программы это всего 12 строк текста.

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

ОЧень много кушать библиотека Serial 

Зачем в ком порт выдавать значения часов? Примеры библиотек - это понятно, подключите дисплей и всё станет на места)))

Плюс есть еще другие библиотеки по работе с DS1307

whoim
Offline
Зарегистрирован: 03.11.2011

zhuki пишет:

Whoim  вы хотите сократить код ?  Зачем вам связь ?  Для того что бы однажды в 10 лет установить часы и дату.

Первый раз при включении DS1307 установите время и дату ,заремте ненужные строки и загрузите в контроллер без возможности коррекции.

Для себя я оставил возможность коррекции из внешней программы это всего 12 строк текста.

Нужно с помощью программы на компьютере заливать данные о задачах - когда и что включать, насколько, как повторять. Думаете, с дисплеем меньше будет памяти кушаться?

 

whoim
Offline
Зарегистрирован: 03.11.2011

Adessit пишет:

ОЧень много кушать библиотека Serial 

Зачем в ком порт выдавать значения часов? Примеры библиотек - это понятно, подключите дисплей и всё станет на места)))

Плюс есть еще другие библиотеки по работе с DS1307

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

hypersash
Offline
Зарегистрирован: 07.12.2011

Каникулы прошли бурно и вот я взялся за дело =) Пока есть только часы с 2мя кнопками, одна для часов, другая для минут. Пока хочк некоторое время погонять, чтобы определить отставание и потом программно добавлять коэффицент отставания. Покачто за пол часа на 10 сек отстали.

Как вы считаете лучше реализовать звонки? Будет на некий пин повешана релюха, которая и будет коммутировать школьный звонок, соответственно на нее пару секунд должен идти HIGH. Это все понятно, а как оптимальнее будет сделать отсчет уроков и переменок, при том что переменки разные по длинне.

Вот что есть сейчас =)


 

youtu.be/MWSGCc1OqSk

hypersash
Offline
Зарегистрирован: 07.12.2011

Все потиху продвигаеться =) Только проблема в том, что я плохо знаю язык. Поэтому выходит индусский код. Есть парочка вопросов))

1. Мне надобно скроллить справа на лево только первую строку, при том что в нижней строке он неизменно показывал бы время. У меня получалось скроллить только весь дисплей, пробывал и lcd.autoscroll() и lcd.scrollDisplayLeft(). Спасибо! =)

2. Как ЭТО непотребство можно более оптимизировать?

#include <LiquidCrystal.h>//библиотека для работы с LCD
 long previousMicros = 0;//переменная для хранения значений таймера
 
 int sek=0;//значение секунд
 int min=0;//значение минут
 int chas=0;//значение часов
 int knopka=0;//значение кнопки
 int knopka2=0;//кнопка часов
 int knopka3=0;//кнопка звонка вручную

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//инициализация портов

void setup()
{
 
 lcd.begin(16, 2);//иницифлизация дисплея
 pinMode(8,INPUT);//инициализация портов секунды
 pinMode(7,INPUT);//        -=-          минуты
 pinMode(9,INPUT);//инициализация портов сдвиг
 pinMode(13,OUTPUT);//инициализация портов
 pinMode(6, OUTPUT);// пин звонка
 pinMode(10, OUTPUT);// ШИМ звонка
 
  analogWrite(10, 25);
 delay(200);
 analogWrite(10, 0);
 delay(100);
  analogWrite(10, 100);
  delay(200);
  analogWrite(10, 0);
  delay(100);
   analogWrite(10, 25);
   delay(200);
    analogWrite(10, 0);
}



    
void loop()
{
   if (micros() - previousMicros >500000) 
 {  
   previousMicros = micros();  //запускаем таймер
   digitalWrite(13, !digitalRead(13));//меняем значение порта каждые 0.5секунд
   
   
   
   
   if(digitalRead(13)==HIGH)//если 13 нога лог1 то...
   {
     sek++;//переменная секунда + 1
     lcd.clear(); //обновление дисплея
     
     
     
     
     //вывод символов на дисплей//
     lcd.setCursor(2, 1);
     lcd.print(":");//выводим символ ":"между часами и минутами
     lcd.setCursor(5, 1);
     lcd.print(":");//выводим символ ":"между  минутами и секундами
   }
   
   if(digitalRead(13)==LOW)
   {
     //через каждые 0.5 секунд меняем символ ":" на " "
     lcd.setCursor(2, 1);
     lcd.print(" ");
     lcd.setCursor(5, 1);
     lcd.print(" ");
   }
   
          // СИСТЕМА ЗВОНКОВ!
          
          // первый
   
   if (chas==8&&min==15&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==8&&min==15&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==8&&min==55&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
          //второй
          
       if (chas==9&&min==00&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==9&&min==00&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }      
    if (chas==8&&min==40&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }       
   
         ///     третий
         
          if (chas==9&&min==50&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==9&&min==50&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==10&&min==30&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //       четвертый
   
    if (chas==10&&min==40&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==10&&min==40&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==11&&min==20&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //      пятый
   
    if (chas==12&&min==00&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==12&&min==00&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==12&&min==40&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //     шестой
   
    if (chas==12&&min==50&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==12&&min==50&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==13&&min==30&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //      седьмой
   
    if (chas==13&&min==40&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==13&&min==40&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==14&&min==20&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //    восьмой
   
    if (chas==14&&min==30&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==14&&min==30&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==15&&min==10&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   //     девятый
   
    if (chas==15&&min==20&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   if (chas==15&&min==20&&sek==59)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==2)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
    if (chas==16&&min==00&&sek==0)
  {
   digitalWrite(6, HIGH);
   analogWrite(10, 15);
  }
   if (sek==3)
   {
     digitalWrite(6, LOW);
     analogWrite(10, 0);
   }
   
   
          //поправка отставания часов
   
      if(min==59)//отставание на час примерно 1 секундa
  {
     sek=sek+1;//плюсуем коэффицент отставания
   }
   
                       //
   
   if(sek>59)//если переменная секунда больше 59 ...
   {
     sek=0;//сбрасываем ее на 0
     min++;//пишем +1 в переменную минута
   }
   

   
   if(min>59)//если переменная минута больше 59 ...
   {
     min=0;//сбрасываем ее на 0
     chas++;//пишем +1 в переменную час
   }
   
   
   
   
   if(chas>23)//если переменная час больше 23 ...
   {
     chas=0;//сбрасываем ее на 0
    
   }
   
    } 

   
   //вывод символов на дисплей//
   
   lcd.setCursor(0, 1);//выводим значение часов в строку - 1
   //столбец -4 
   lcd.print(chas);//количество часов
   
   lcd.setCursor(3, 1);//выводим значение часов в строку - 1
   //столбец -7 
   lcd.print(min);//количество минут
   
   lcd.setCursor(6, 1);//выводим значение часов в строку - 1
   //столбец -10 
   lcd.print(sek);//количество секунд
   
//   lcd.setCursor(13, 1);
 //  lcd.print(timer);//выводим таймер
   
//   lcd.setCursor(10,1);
//   lcd.print(timercount);//выводим счетчик таймера
   

 
      //установка времени//
          //кнопка//
 
 
   
   if(digitalRead(8)==HIGH&&knopka==0)//если кнопка нажата 
   // и перемення "knopka" равна 0 , то ...
   {
      min++;//пишем + 1 в переменную минута
      sek=0;//пишем 0 в переменную секунда
      knopka++;//пишем 1 в переменную кнопка
      //это нужно для того что бы с каждым нажатием кнопки
      //происходило только одно действие
      // плюс защита от "дребезга"
      
      
      
      //с каждым нажатием кнопки обновляем значения на дисплее//
      lcd.setCursor(0, 1);
   lcd.print(chas);
   
   lcd.setCursor(3, 1);
   lcd.print(min);
   
   lcd.setCursor(6, 1);
   lcd.print(sek);
   }
   {
     if(digitalRead(7)==HIGH&&knopka2==0)//если кнопка часов нажата, то
     {
     chas++;
     knopka2++;
     }
     if(digitalRead(7)==LOW&&knopka2==1)//если не нажата
      {
      
      knopka2=0;//обнуляем переменную "knopka"
   }
    {
     if(digitalRead(9)==HIGH&&knopka3==0)//если кнопка часов нажата, то
     {
     digitalWrite(6, HIGH);
     analogWrite(10, 15);
     knopka3++;
     }
     if(digitalRead(9)==LOW&&knopka3==1)//если не нажата
      {
      digitalWrite(6, LOW);
      analogWrite(10, 0);
      knopka3=0;//обнуляем переменную "knopka"
   }
   }
    if(digitalRead(8)==LOW&&knopka==1)//если кнопка НЕ нажата
   //и переменная knopka равна - 1 ,то ...
   {
      
      knopka=0;//обнуляем переменную "knopka"
   }
   
 
             //выводим надпись в строку - 0 
             
 lcd.setCursor(0, 0);
 lcd.print("Bell ver 3.4a");
  
  
}