Задать вопрос
@walhi

Как объявить глобальную переменную, принадлежащую классу?

Добрый день.

Решил создать для универа некий вахтершозаменитель, который будет давать вместо них звонки вовремя. Для удобства описал класс time.

Так как проверять буду прерываниями по таймеру, хорошо бы иметь текущее время и время следующего звонка в глобальных переменных. Или хотя бы следующий. Компилятор не ругается, но железка зависает.

Пробовал выкрутиться через указатели, но это не сильно помогло. За качество кода вынужден просить прощения.
#include <EEPROM.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h> // written by mattt on the Arduino forum and modified by D. Sjunnesson



int incomingByte;
int address = 1;


class time{
private:
  int minute;
  int hour;
  int week;
public:
  time () {
    hour = RTC.get(DS1307_HR,true);
    minute = RTC.get(DS1307_MIN,false);	
    if ((week = RTC.get(DS1307_DOW,false))==7) week = 0; 
    else week = 1;
  }
  time (int a, int b, int c){
    hour = a;
    minute = b;
    week = c;
  }
  void update () {
    hour = RTC.get(DS1307_HR,true);
    minute = RTC.get(DS1307_MIN,false);
    if ((week = RTC.get(DS1307_DOW,false))==7) week = 0;
  }
  void output_time (){
    Serial.print(hour);
    Serial.print(":");
    Serial.println(minute);
  }
  void output_date (){
    Serial.print(RTC.get(DS1307_DATE,false));
    Serial.print("/");
    Serial.print(RTC.get(DS1307_MTH,false));
    Serial.print("/");
    Serial.println(RTC.get(DS1307_YR,false));
  }
  friend void next_ring (time& a, time& b){
    if (a==b) {
      if (address == 47) address = -1;
      address++;
      b.hour = EEPROM.read(address);
      address++;
      b.minute = EEPROM.read(address);
    } 
    else {
      while(a>b){
        if (address == 47){
          address = -1;
          address++;
          b.hour = EEPROM.read(address);
          address++;
          b.minute = EEPROM.read(address); 
          break;
        }
        address++;
        b.hour = EEPROM.read(address);
        address++;
        b.minute = EEPROM.read(address);          

      }
    }
    Serial.print("Now - ");
    a.output_time();
    Serial.print("Next ring - ");
    b.output_time();
  }
  friend int operator== (time& a, time& b) {
    return ((a.minute == b.minute) && (a.hour == b.hour) && a.week && b.week);
  }
  friend int operator> (time& a, time& b) {
    if (a.hour>b.hour){
      return (1);
    } 
    else {
      if (a.hour==b.hour){
        return (a.minute>b.minute);
      } 
      else {
        return (0);
      }
    }
  }
  friend int operator< (time& a, time& b) {
    if (a.hour<b.hour){
      return (1);
    } 
    else {
      if (a.hour==b.hour){
        return (a.minute<b.minute);
      } 
      else {
        return (0);
      }
    }
  }
};

int led = 13;
int relay = 10;
int t=0;

void set(){
  int temp;
  Serial.print("Do you really want to change the time? (y/n)");
  while (!Serial.available()){
  };
  incomingByte = Serial.read();
  if (incomingByte == 'y'){
    RTC.stop();
    RTC.set(DS1307_SEC,0);

    Serial.print("\r\nEnter day - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = temp * 10 + incomingByte - 48;
    RTC.set(DS1307_DATE, temp);

    Serial.print("\r\nEnter mounth - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = temp * 10 + incomingByte - 48;
    RTC.set(DS1307_MTH, temp);

    Serial.print("\r\nEnter year - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = temp * 10 + incomingByte - 48;    
    RTC.set(DS1307_YR, temp);

    Serial.print("\r\nEnter day of week (1-monday, ..., 7-sunday) - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    RTC.set(DS1307_DOW, temp);

    Serial.print("\r\nEnter hour - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = temp * 10 + incomingByte - 48;
    RTC.set(DS1307_HR, temp);

    Serial.print("\r\nEnter minute - ");
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = incomingByte - 48;
    while (!Serial.available()){
    };
    incomingByte = Serial.read();
    Serial.print(incomingByte-48);
    temp = temp * 10 + incomingByte - 48;
    RTC.set(DS1307_MIN, temp);
    RTC.start();
  }
  Serial.println();
  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year
  Serial.println();
}

time* now_address;
time* next_address;
void ring (){
  Serial.print("Ring! ");
  Serial.print(RTC.get(DS1307_HR,false));
  Serial.print(":");
  Serial.println(RTC.get(DS1307_MIN,false));
  //now.output_time();
  digitalWrite(relay, HIGH);
  delay(1000);
  digitalWrite(relay, LOW);
}


ISR(TIMER2_OVF_vect)  
{ 
  if (t==50) {
    digitalWrite(led, !digitalRead(led));
    if (*now_address == *next_address) ring();
    now_address->output_time();
    t = 0;
  } 
  else {
    t++;
  }
} 




void setup()
{
  Serial.begin(9600);
  TCCR2A = 0x00;                      // нормальный режим таймера
  TCCR2B |= (1<<CS22) | (1<<CS21) | (1<<CS20);          //предделитель на 1024
  TIMSK2 |= 1<<TOIE2;               // прерывание по переполнению
  pinMode(led, OUTPUT);
}

void loop()
{
  time now;
  time next (EEPROM.read(0), EEPROM.read(1), 1);
  now_address = &now;
  next_address = &next;
  next_ring(now, next);
  while (true){
    while (!Serial.available()){
      delay (100);
    };
    switch ((incomingByte = Serial.read())) {
    case 'h':
      Serial.print("h - help\r\ns - set time\r\nt - time\r\nd - date\r\nr - ring!\r\nn - next ring\r\n");
      break;
    case 's':
      set();
      now.update();
      next_ring(now, next);
      break;
    case 't':
      now.update();
      now.output_time();
      break;
    case 'd':
      now.output_date();
      break;
    case 'r':
      ring();
      break;
    case 'n':
      next_ring(now, next);
      break;
    default: 
      Serial.print("error\r\nh - help\r\ns - set time\r\nt - time\r\nd - date\r\nr - ring!\r\nn - next ring\r\n");
    };
  }
}
  • Вопрос задан
  • 2883 просмотра
Подписаться 2 Оценить Комментировать
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
У вас охрененный delay внутри ring() который вы зовёте из ISR. Вообще делать работу в ISR -- дурной тон, устанавливайте флажки, ставьте задания в очередь и делайте работу в основном цикле.

И ещё: вы уверены, что now_address и next_address будут установлены до разрешения прерываний?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы