#1 2016-03-12 19:33:51

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Проблема с работой программы. Нужен совет програмиста.

Доброго всем времени суток!
Итак нужна помощь знающих людей. Буду весьма благодарен за советы!

Апаратная часть:
Arduino Mega 2560
LCD-display 16*2
Real time clock
звуковой модуль Wtv020sd16p
матричная клавиатура 3*4
Реле 5V (реле только запланировано, еще не  купил).

Написал свою первую программу.
Техзадание:
На дисплее после включения отображаются дата и время. По таймеру включается музыка (посредством звукового модуля). За несколько секунд до сработки таймера должно сработать реле - это реле подаст напряжение на усилитель (чтобы усилитель работал лиш в то время когда надо).
Кроме того, пользователь должен иметь возможность самостоятельно запускать 9 музыкальных треков.

Алгоритм выбора трека пользователем
1. пользователь нажимает кнопку на клавиатуре от 1 до 9
2. на диспей выводится вопрос:
Play track#(номер трека)?
*-Yes #-No
3. если ошиблись с треком нажимаем #. На дисплей возвращается дата/время
4. если нажали * ардуино исполняет следующие действия:
а) включается реле
б) на дисплей на 10 секунд выводится надпись "Playing melody №"
в) подается команда на звуковой модуль играть трек №ХХ
г) очищается дисплей
д) выводит на дисплей дату/время

Проблема:
Описаные действия не всегда срабатывают как надо. При первом выборе трека (после включения/перезагрузки ардуино) музыка не воспроизводится. При последующих включениях музыка воспроизводится всегда но вывод надписей на дисплей срабатывает через раз - иногда корректно а иногда надпись "Play track#(номер трека)?" зависает на дисплее до окончания трека.
Никак не могу понять в чем дело, так как опыта в програмировании ноль. Помогите пожалуйста советом. Заранее спасибо.

Скетч:
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <Wtv020sd16p.h>
#include <Keypad.h>

RTC_DS1307 rtc;
LiquidCrystal  lcd (8, 9, 4, 5, 6, 7); // set the LCD address to 0x27 for a 16 chars and 2 line display

//Звуковий модуль: вказано піни
int resetPin = 19;  // The pin number of the reset pin.
int clockPin = 18;  // The pin number of the clock pin.
int dataPin = 17;  // The pin number of the data pin.
int busyPin = 16;  // The pin number of the busy pin.
Wtv020sd16p wtv020sd16p(resetPin, clockPin, dataPin, busyPin);
//кінець опису звукового модуля

DateTime now;

const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  rtc.begin();
  lcd.begin(16 , 2);
  lcd.home();
  lcd.clear();
}

void loop()
{
  now = rtc.now();
  time_on_lcd();
  delay(200);
  timer_bell();
  bell_menu();
}
//---------------------------------------------

void printDigits(int digits)
{
  // додає нуль якщо година, хвилина або секунда менша 10 (для гарного відображення часу).
  if (digits < 10) {
    lcd.print('0');
  }
  lcd.print(digits);
}

void time_on_lcd()
{
  //рисуем часы
  lcd.setCursor(0, 0);
  printDigits (now.hour());

  //рисуем минуты
  lcd.setCursor(3, 0);
  printDigits(now.minute());

  //рисуем статическое двоеточие между часами и минутами
  lcd.setCursor(2, 0);
  lcd.print(":");

  //рисуем секунды

  lcd.setCursor(6, 0);
  printDigits(now.second());


  //рисуем моргающее двоеточие, привязано к секундам, вывод слева или справа двоеточие зависит от четности секунд

  lcd.setCursor(5, 0);
  if (now.second() % 10 % 2 == 0) {
    lcd.print(":");
  }
  else
  {
    lcd.print(" ");
  }

  // Дата-месяц-день в нижней строке
  lcd.setCursor(0, 1);
  printDigits(now.year());

  lcd.setCursor(4, 1);
  lcd.print("-");

  lcd.setCursor(5, 1);
  printDigits(now.month());

  lcd.setCursor(7, 1);
  lcd.print("-");

  lcd.setCursor(8, 1);
  printDigits(now.day());

}

//----------------------------------------------------------------

void timer_bell()
{

  // Включение выхода на усилитель
  if (now.minute() == 59 && now.second() == 50)
  {
    digitalWrite (51, LOW);
  };
  if (now.minute() == 1 && now.second() == 15)
  {
    digitalWrite (51, HIGH);
  };
  //кінець спрацювання виходу 51


  //Сработка на заданое время - каждый час звучит мелодия
  if (now.hour() == 0 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(1);
  }

  if (now.hour() == 1 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(2);
  }

  if (now.hour() == 2 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(3);
  }

  if (now.hour() == 3 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(4);
  }

  if (now.hour() == 4 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(5);
  }

  if (now.hour() == 5 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(6);
  }

  if (now.hour() == 6 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(7);
  }

  if (now.hour() == 7 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(8);
  }

  if (now.hour() == 8 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(9);
  }

  if (now.hour() == 9 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(10);
  }

  if (now.hour() == 10 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(11);
  }

  if (now.hour() == 11 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(12);
  }

  if (now.hour() == 12 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(1);
  }

  if (now.hour() == 13 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(2);
  }

  if (now.hour() == 14 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(3);
  }

  if (now.hour() == 15 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(4);
  }

  if (now.hour() == 16 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(5);
  }

  if (now.hour() == 17 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(6);
  }

  if (now.hour() == 18 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(7);
  }

  if (now.hour() == 19 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(8);
  }

  if (now.hour() == 20 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(9);
  }

  if (now.hour() == 21 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(10);
  }

  if (now.hour() == 22 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(11);
  }

  if (now.hour() == 23 && now.minute() == 59 && now.second() == 59)
  {
    wtv020sd16p.playVoice(12);
  }
}

//----------------------------------------------------------------
//Выбор мелодии пользователем
void bell_menu()
{
  char key = customKeypad.getKey();
  if (key); // Check for a valid key.
  //------------------------------------------------------ Кнопка 1
  {
    switch (key)
    case '1':
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Play track №1?");
      lcd.setCursor(0, 1);
      lcd.print("*-YES    #-N0");
      do
      {
        key = customKeypad.getKey();
        switch (key)
        case '*':
        {
          digitalWrite (51, LOW);
          wtv020sd16p.playVoice(1);
          wtv020sd16p.stopVoice();
          wtv020sd16p.playVoice(1);
          lcd.clear();
          lcd.print("Playing melody 1");
          delay (10000);
          digitalWrite (51, HIGH);
          lcd.clear();
          return;
        }
        switch (key)
        case '#':
        {
          lcd.clear();
          return;
        }
      } while ( key != '*' || key != '#' );

      //------------------------------------------------------ Кнопка 2
    case '2':
      {
        lcd.clear();
        lcd.setCursor(0 , 0);
        lcd.print("Play track №1?");
        lcd.setCursor(0 , 1);
        lcd.print("*-YES    #-N0");
        do
        {
          key = customKeypad.getKey();
          switch (key)
          case '*':
          {
            digitalWrite (51, LOW);
            wtv020sd16p.playVoice(1);
            wtv020sd16p.stopVoice();
            wtv020sd16p.playVoice(1);
            lcd.clear();
            lcd.print("Playing melody 2");
            delay (5000);
            digitalWrite (51, HIGH);
            lcd.clear();
            return;
          }
          switch (key)
          case '#':
          {
            lcd.clear();
            return;
          }
        } while ( key != '*' || key != '#' );
        //------------------------------------------------------ Кнопка 3

      case '3':
        {
          lcd.clear();
          lcd.setCursor(0 , 0);
          lcd.print("Play track №3?");
          lcd.setCursor(0 , 1);
          lcd.print("*-YES    #-N0");
          do
          {
            key = customKeypad.getKey();
            switch (key)
            case '*':
            {
              digitalWrite (51, LOW);
              wtv020sd16p.playVoice(1);
              wtv020sd16p.stopVoice();
              wtv020sd16p.playVoice(1);
              lcd.clear();
              lcd.print("Playing melody 3");
              delay (5000);
              digitalWrite (51, HIGH);
              lcd.clear();
              return;
            }
            switch (key)
            case '#':
            {
              lcd.clear();
              return;
            }
          } while ( key != '*' || key != '#' );
          //------------------------------------------------------ Кнопка 4

        case '4':
          {
            lcd.clear();
            lcd.setCursor(0 , 0);
            lcd.print("Play track №4?");
            lcd.setCursor(0 , 1);
            lcd.print("*-YES    #-N0");
            do
            {
              key = customKeypad.getKey();
              switch (key)
              case '*':
              {
                digitalWrite (51, LOW);
                wtv020sd16p.playVoice(1);
                wtv020sd16p.stopVoice();
                wtv020sd16p.playVoice(1);
                lcd.clear();
                lcd.print("Playing melody 4");
                delay (5000);
                digitalWrite (51, HIGH);
                lcd.clear();
                return;
              }
              switch (key)
              case '#':
              {
                lcd.clear();
                return;
              }
            } while ( key != '*' || key != '#' );
            //------------------------------------------------------ Кнопка 5

          case '5':
            {
              lcd.clear();
              lcd.setCursor(0 , 0);
              lcd.print("Play track №5?");
              lcd.setCursor(0 , 1);
              lcd.print("*-YES    #-N0");
              do
              {
                key = customKeypad.getKey();
                switch (key)
                case '*':
                {
                  digitalWrite (51, LOW);
                  wtv020sd16p.playVoice(1);
                  lcd.clear();
                  lcd.print("Playing melody 5");
                  delay (5000);
                  digitalWrite (51, HIGH);
                  lcd.clear();
                  return;
                }
                switch (key)
                case '#':
                {
                  lcd.clear();
                  return;
                }
              } while ( key != '*' || key != '#' );
              //------------------------------------------------------ Кнопка 6

            case '6':
              {
                lcd.clear();
                lcd.setCursor(0 , 0);
                lcd.print("Play track №6?");
                lcd.setCursor(0 , 1);
                lcd.print("*-YES    #-N0");
                do
                {
                  key = customKeypad.getKey();
                  switch (key)
                  case '*':
                  {
                    digitalWrite (51, LOW);
                    wtv020sd16p.playVoice(1);
                    lcd.clear();
                    lcd.print("Playing melody 6");
                    delay (5000);
                    digitalWrite (51, HIGH);
                    lcd.clear();
                    return;
                  }
                  switch (key)
                  case '#':
                  {
                    lcd.clear();
                    return;
                  }
                } while ( key != '*' || key != '#' );
                //------------------------------------------------------ Кнопка 7

              case '7':
                {
                  lcd.clear();
                  lcd.setCursor(0 , 0);
                  lcd.print("Play track №7?");
                  lcd.setCursor(0 , 1);
                  lcd.print("*-YES    #-N0");
                  do
                  {
                    key = customKeypad.getKey();
                    switch (key)
                    case '*':
                    {
                      digitalWrite (51, LOW);
                      wtv020sd16p.playVoice(1);
                      lcd.clear();
                      lcd.print("Playing melody 7");
                      delay (5000);
                      digitalWrite (51, HIGH);
                      lcd.clear();
                      return;
                    }
                    switch (key)
                    case '#':
                    {
                      lcd.clear();
                      return;
                    }
                  } while ( key != '*' || key != '#' );
                  //------------------------------------------------------ Кнопка 8

                case '8':
                  {
                    lcd.clear();
                    lcd.setCursor(0 , 0);
                    lcd.print("Play track №8?");
                    lcd.setCursor(0 , 1);
                    lcd.print("*-YES    #-N0");
                    do
                    {
                      key = customKeypad.getKey();
                      switch (key)
                      case '*':
                      {
                        digitalWrite (51, LOW);
                        wtv020sd16p.playVoice(1);
                        lcd.clear();
                        lcd.print("Playing melody 8");
                        delay (5000);
                        digitalWrite (51, HIGH);
                        lcd.clear();
                        return;
                      }
                      switch (key)
                      case '#':
                      {
                        lcd.clear();
                        return;
                      }
                    } while ( key != '*' || key != '#' );
                    //------------------------------------------------------ Кнопка 9

                  case '9':
                    {
                      lcd.clear();
                      lcd.setCursor(0 , 0);
                      lcd.print("Play track №9?");
                      lcd.setCursor(0 , 1);
                      lcd.print("*-YES    #-N0");
                      do
                      {
                        key = customKeypad.getKey();
                        switch (key)
                        case '*':
                        {
                          digitalWrite (51, LOW);
                          wtv020sd16p.playVoice(1);
                          lcd.clear();
                          lcd.print("Playing melody 9");
                          delay (5000);
                          digitalWrite (51, HIGH);
                          lcd.clear();
                          return;
                        }
                        switch (key)
                        case '#':
                        {
                          lcd.clear();
                          return;
                        }
                      } while ( key != '*' || key != '#' );
                      //------------------------------------------------------
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Неактивний

#2 2016-03-12 21:09:45

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

const unsigned char table_music [24]
= {
	1,2,3,4,5,6,7,8,9,10,11,12,
	1,2,3,4,5,6,7,8,9,10,11,12
}  

void timer_bell()
{
  static int old_current_hour = 0xFF; 

   int new_hour = now.hour(); 
   int number_sound;

  if ( old_current_hour == 0xFF )
  { // no music on  start 
   old_current_hour = new_hour;
 }

 // Включение выхода на усилитель
  if (now.minute() == 59 )
  {
    if  ( now.second() == 50 )
    digitalWrite (51, LOW);
  }

  if (now.minute() == 1 )
  {
   if ( now.second() == 15 )
    digitalWrite (51, HIGH);
  }
  //кінець спрацювання виходу 51

  // Сработка на заданое время - каждый час звучит мелодия
   // - 1 sec ??????
   if ( old_current_hour !=  new_hour )
   {
	wtv020sd16p.playVoice( (new_hour%13) + 1);
     //  or  
    // wtv020sd16p.playVoice( table_music[new_hour%24]);
   }
}

много кода (((
но задача отлично прописана, молодцы!
по частям давайте оптимизировать
- 1 sec  от нового часа это важно?

Неактивний

#3 2016-03-12 21:16:23

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

void setup() {
  Wire.begin();
  Serial.begin(9600);
  rtc.begin();
  lcd.begin(16 , 2);
  lcd.home();
  lcd.clear();

 // add Initializes the module.
 wtv020sd16p.reset();

}

я новичек в arduino
попробуйте такой вариант

Неактивний

#4 2016-03-12 21:20:52

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

pls add break
switch ( )
{
case xxx:
break;
}

Неактивний

#5 2016-03-12 21:28:57

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

  void play_selected_music (int number_music)
 {
					lcd.clear();
                    lcd.setCursor(0 , 0);
                    lcd.print("Play track №X?"); // pls add number_music
                    lcd.setCursor(0 , 1);
                    lcd.print("*-YES    #-N0");
                    do
                    {
                      key = customKeypad.getKey();
                      switch (key)
                      case '*':
                      {
                        digitalWrite (51, LOW);
                        wtv020sd16p.playVoice(1);
                        lcd.clear();
                        lcd.print("Playing melody X"); // pls add number_music
                        delay (5000);
                        digitalWrite (51, HIGH);
                        lcd.clear();
                        return;
                      }
                      switch (key)
                      case '#':
                      {
                        lcd.clear();
                        return;
                      }
                    } while ( key != '*' || key != '#' );
}


//----------------------------------------------------------------
//Выбор мелодии пользователем
void bell_menu()
{
  char key = customKeypad.getKey();
  if (key); // Check for a valid key.
  //------------------------------------------------------ Кнопка 1
  if ( key >= '0' ) && ( key <= '9' )
	  play_selected_music (key - 0x20);
  }

не проверял, попробуйте от этого кода  начать
зависало, из за повторного ожидания кнопок

наверное )

Неактивний

#6 2016-03-13 00:11:59

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

Спасибо всем за то, что уделили мне свое время. Мне очень приятно.

Так как опыта в программировании у меня нет, я практически не понимаю кода. Поэтому разбирать Ваши рекомендации буду долго))
Начал с коментария #2.
Не понимаю Вашего кода вообще. Это волшебство - Вы уменьшили код в разы! И он работает! Правда, первый вариант "wtv020sd16p.playVoice( (new_hour%13) + 1);" после первого срабатывания в 23:00 спрабатывает каждый раз как только заканчивается мелодия и часы снова начинают идти. Расскоментил второй вариант. Жду 24:00

Неактивний

#7 2016-03-13 00:33:41

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

Извините, NoName, Ваш ник ввел меня в заблуждение - я подумал, что коменты оставлены несколькими участниками.

Неактивний

#8 2016-03-13 01:09:05

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

NoName, пожалуйста, попробуйте обьяснить мне как работает этот код. Самое интересное для меня что это - (new_hour%13) + 1)? Почему именно 13?

NoName пише:
const unsigned char table_music [24]
= {
	1,2,3,4,5,6,7,8,9,10,11,12,
	1,2,3,4,5,6,7,8,9,10,11,12
}  

void timer_bell()
{
  static int old_current_hour = 0xFF; 

   int new_hour = now.hour(); 
   int number_sound;

  if ( old_current_hour == 0xFF )
  { // no music on  start 
   old_current_hour = new_hour;
 }

 // Включение выхода на усилитель
  if (now.minute() == 59 )
  {
    if  ( now.second() == 50 )
    digitalWrite (51, LOW);
  }

  if (now.minute() == 1 )
  {
   if ( now.second() == 15 )
    digitalWrite (51, HIGH);
  }
  //кінець спрацювання виходу 51

  // Сработка на заданое время - каждый час звучит мелодия
   // - 1 sec ??????
   if ( old_current_hour !=  new_hour )
   {
	wtv020sd16p.playVoice( (new_hour%13) + 1);
     //  or  
    // wtv020sd16p.playVoice( table_music[new_hour%24]);
   }
}

много кода (((
но задача отлично прописана, молодцы!
по частям давайте оптимизировать
- 1 sec  от нового часа это важно?

Неактивний

#9 2016-03-13 11:16:40

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

немного промиле помешало правильно прочитать код )
в час ночи мелодия 1 а не 2

   if ( old_current_hour !=  new_hour )
   {
    old_current_hour =  new_hour; // зыбыл (((
    wtv020sd16p.playVoice( table_music[new_hour%24]);
   }

таблицы удобнее, можете сами выбрать   номер на каждый час
точно, %12 + 1   нужно, но тогда будет не правильно )

все не так )
0 - 12 мелодия
1 - 1
2 - 2
3 - 3
12 -

... используйте таблицу,   первый номер 12 )

const unsigned char table_music [24]
= {
    12,1,2,3,4,5,6,7,8,9,10,11,
    12,1,2,3,4,5,6,7,8,9,10,11,
}

Остання редакція NoName (2016-03-13 11:27:03)

Неактивний

#10 2016-03-13 23:32:53

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

Мелодию отрабатывает верно, но и запускает постоянно(((
Мелодия играет практически не останавливаясь (остановка только на время "зависания часов" - секунды на 2-3.

Остання редакція Jugun (2016-03-13 23:33:12)

Неактивний

#11 2016-03-14 00:03:59

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

последнюю редакцию покажите

Неактивний

#12 2016-03-14 00:16:55

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <Wtv020sd16p.h>
#include <Keypad.h>

RTC_DS1307 rtc;
LiquidCrystal  lcd (8, 9, 4, 5, 6, 7); // set the LCD address to 0x27 for a 16 chars and 2 line display

//Звуковий модуль: вказано піни
int resetPin = 19;  // The pin number of the reset pin.
int clockPin = 18;  // The pin number of the clock pin.
int dataPin = 17;  // The pin number of the data pin.
int busyPin = 16;  // The pin number of the busy pin.
Wtv020sd16p wtv020sd16p(resetPin, clockPin, dataPin, busyPin);
//кінець опису звукового модуля

DateTime now;

const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

const unsigned char table_music [24]
= {
  12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
};

void setup() {
  Wire.begin();
  Serial.begin(9600);
  rtc.begin();
  lcd.begin(16 , 2);
  lcd.home();
  lcd.clear();
  wtv020sd16p.reset();
}

void loop()
{
  now = rtc.now();
  time_on_lcd();
  delay(200);
  timer_bell();
  bell_menu();
}
//---------------------------------------------
void printDigits(int digits)
{
  // додає нуль якщо година, хвилина або секунда менша 10 (для гарного відображення часу).
  if (digits < 10) {
    lcd.print('0');
  }
  lcd.print(digits);
}
//---------------------------------------------
void time_on_lcd()
{
  //рисуем часы
  lcd.setCursor(0, 0);
  printDigits (now.hour());

  //рисуем минуты
  lcd.setCursor(3, 0);
  printDigits(now.minute());

  //рисуем статическое двоеточие между часами и минутами
  lcd.setCursor(2, 0);
  lcd.print(":");

  //рисуем секунды

  lcd.setCursor(6, 0);
  printDigits(now.second());

  //рисуем моргающее двоеточие, привязано к секундам, вывод слева или справа двоеточие зависит от четности секунд

  lcd.setCursor(5, 0);
  if (now.second() % 10 % 2 == 0) {
    lcd.print(":");
  }
  else
  {
    lcd.print(" ");
  }

  // Дата-месяц-день в нижней строке
  lcd.setCursor(0, 1);
  printDigits(now.year());

  lcd.setCursor(4, 1);
  lcd.print("-");

  lcd.setCursor(5, 1);
  printDigits(now.month());

  lcd.setCursor(7, 1);
  lcd.print("-");

  lcd.setCursor(8, 1);
  printDigits(now.day());
}

//---------------------------------------------
void timer_bell()
{
  static int old_current_hour = 0xFF;

  int new_hour = now.hour();
  int number_sound;

  if ( old_current_hour == new_hour )
  { // no music on  start
    old_current_hour = new_hour;
  }

  // Включение выхода на усилитель
  if (now.minute() == 59 )
  {
    if  ( now.second() == 50 )
      digitalWrite (51, LOW);
  }

  if (now.minute() == 1 )
  {
    if ( now.second() == 15 )
      digitalWrite (51, HIGH);
  }
  //кінець спрацювання виходу 51

  // Сработка на заданое время - каждый час звучит мелодия
  // - 1 sec ??????
  if ( old_current_hour !=  new_hour )
  {
    //wtv020sd16p.playVoice( table_music[new_hour%24]);
    wtv020sd16p.playVoice( (new_hour % 12) + 1);
    return;
  };
}
//---------------------------------------------
void play_selected_music (int number_music)
{
  char key = customKeypad.getKey();
  lcd.clear();
  lcd.setCursor(0 , 0);
  lcd.print("Play track №1?"); // pls add number_music
  lcd.setCursor(0 , 1);
  lcd.print("*-YES    #-N0");
  do
  {
    key = customKeypad.getKey();
    switch (key)
    case '*':
    {
      lcd.clear();
      lcd.print("Playing melody 1"); // pls add number_music
      digitalWrite (51, LOW);
      wtv020sd16p.playVoice(1);
      //      delay (5000);
      digitalWrite (51, HIGH);
      lcd.clear();
      return;
    }
    switch (key)
    case '#':
    {
      lcd.clear();
      return;
    }
  } while ( key != '*' || key != '#' );
}


//----------------------------------------------------------------
//Выбор мелодии пользователем
void bell_menu()
{
  char key = customKeypad.getKey();
  if (key); // Check for a valid key.
  {
    switch (key)
    case '1':
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Play track №1?");
      lcd.setCursor(0, 1);
      lcd.print("*-YES    #-N0");
      do
      {
        key = customKeypad.getKey();
        switch (key)
        case '*':
        {

          digitalWrite (51, LOW);
          lcd.clear();
          lcd.print("Playing melody 1");
          wtv020sd16p.playVoice(1);
          //wtv020sd16p.stopVoice();
          //wtv020sd16p.playVoice(1);
          delay (10000);
          digitalWrite (51, HIGH);
          lcd.clear();
          return;
        }
        switch (key)
        case '#':
        {
          lcd.clear();
          return;
        }
      } while ( key != '*' || key != '#' );

      if (( key >= '0' ) && ( key <= '9' ));
      play_selected_music (key - 0x20);

    }
  }
}

Неактивний

#13 2016-03-14 00:32:39

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

void timer_bell()
{
  static int old_current_hour = 0xFF;
  int new_hour = now.hour();
  int number_sound;
  if ( old_current_hour == 0xFF )
  { // no music on  start
    old_current_hour = new_hour;
  }
  // Включение выхода на усилитель
  if (now.minute() == 59 )
  {
    if  ( now.second() == 50 )
      digitalWrite (51, LOW);
  }
  if (now.minute() == 1 )
  {
    if ( now.second() == 15 )
      digitalWrite (51, HIGH);
  }
  //кінець спрацювання виходу 51
  // Сработка на заданое время - каждый час звучит мелодия
  // - 1 sec ??????
  if ( old_current_hour !=  new_hour )
  {
    //wtv020sd16p.playVoice( table_music[new_hour%24]);
    wtv020sd16p.playVoice( (new_hour % 12) + 1);
   old_current_hour = new_hour; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  };

}

Неактивний

#14 2016-03-14 20:59:49

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

Спасибо большое, NoName!

Если позволите, еще один вопрос - очень сильно моргает дисплей при воспроизведении даты/времени. Когда просто выводим текст - картинка стабильная. Для уменшения ефекта мерцания я написал команду "delay (200)":
void loop()
{
  now = rtc.now();
  time_on_lcd();
  delay(200);
  timer_bell();
  bell_menu();
}

Но теперь случилось что-то, чего я не могу об'яснить. Дата/время пропали с дисплея вообще. Проверил все соединения. Заново синхронизировал RTC с комп'ютерными часами. Не помогло.
Дата/время вернулись на экран как только я закоментировал "delay (200)". Но отображаются с тем же мерцанием. Уменьшение времени паузы проблему не решило.
Чем это можно об'яснить?

Неактивний

#15 2016-03-14 21:10:32

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

контроллер у Вас все время в работе,
ему бы спать побольше как порядному человеку
либо ожидать новой команды

void time_on_lcd()  перепишем через 2-3 часа )
потом скажете что и как.

Неактивний

#16 2016-03-14 21:30:41

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

void time_on_lcd()
{

char str[32] = {0};
// "--:--:--        "
// "----/--/--      "
static unsigned char old_sec = 0xFF ;


if  ( old_sec ==  now.second() )  	return;
old_sec =  now.second();

sprintf( str, "%2i:%2i:%2i",
			   now.hour(), now.minute(), now.second() );

lcd.setCursor(0, 0);
lcd.print (str); 
sprintf( str, "%4i/%2i/%2i",
			   			   now.year(), now.month(), now.day() );

lcd.setCursor(0, 1);
lcd.print (str); 

}

так работает ?
мигание потом сделаем

Неактивний

#17 2016-03-14 23:51:18

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

Нет. Пустой экран((

Мигание не критично.

P.S. такой код мне совершенно не понятен. Как этому можно научится? Никакой логики...

Неактивний

#18 2016-03-15 10:58:28

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

как вариант arduino не поддерживает %2i
такой вариант проще?

char str[32] = {0};

void  prepare_2d_sto_str ( int position, int data )
{
 if ( data >= 100 )
 {
 str[position  ] =  '*';
 str[position+1] =  '*';
 return;
 }
 str[position  ] =  data     %10;
 str[position+1] =  (data/10)%10;
}  
			   
void time_on_lcd()
{

// "--:--:--        "
// "--/--/--        "
static unsigned char old_sec = 0xFF ;
int foo;

if  ( old_sec ==  now.second() )  	return;
old_sec =  now.second();

// clear str
for ( foo = 0; foo < 32; foo++ )
str[foo] = ' ';

str[2] = ':';
str[5] = ':';

str[18] = '/';
str[21] = '/';

prepare_2d_sto_str ( 0, now.hour() );
prepare_2d_sto_str ( 3, now.minute() );
prepare_2d_sto_str ( 6, now.second() );

prepare_2d_sto_str ( 16+0, now.year() );
prepare_2d_sto_str ( 16+3, now.month() );
prepare_2d_sto_str ( 16+6, now.day() );

lcd.setCursor(0, 0);
for ( foo = 0; foo < 32; foo++ )
	lcd.write(str[foo]);
}

покажите тот код что используете, лучше почтой, что б тему не засорять
что то мне не нравится в вашем релизе,
мой код без проверки )


самое стёмное для отладки в примерах ниже, особенно если где то не уследил и накосячил с памятью )
но встречается редко

 (*&f)();
 void (*pf)(void) = &f;
 (*pf)();
 typedef void (*funcType)(void);
 funcType pf2 = &f;
 (*pf2)();

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

Неактивний

#19 2016-03-15 22:04:45

Jugun
Учасник
Зареєстрований: 2016-03-12
Повідомлень: 9

Re: Проблема с работой программы. Нужен совет програмиста.

В последней версии (той, что скинул на почту) программа внезапно перестала давать збой в части повторяющейся мелодии после сработки таймера... Буду следить дальше.

Неактивний

#20 2016-03-21 10:26:37

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Проблема с работой программы. Нужен совет програмиста.

код с почты )
исправление отправил, но как вариант не читаете )

//Выбор мелодии пользователем
void bell_menu()
{
  char key  = 0;
  key = customKeypad.getKey();
 
  if (( key >= '0' ) && ( key <= '9' ));
  play_selected_music ( key - 0x20);

}

  if (( key >= '0' ) && ( key <= '9' ));
классическая ошибка ) ";" в неправильном месте, warning наверняка был, но кто ж их читает )

правильный код
if (( key >= '0' ) && ( key <= '9' ))
{
  play_selected_music ( key - 0x20);
}
иначе условие не срабатывает
и выполняется   play_selected_music ( key - 0x20);
с случайными параметрами

Остання редакція NoName (2016-03-21 10:28:28)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму