+1 голос

Нужно чтобы срабатывал ровно в ноль минут и ноль секунд.Проблема 4 раза пищит нормально (4 часа) и 4 раза (4 часа) скрежет как будто сразу два сигнала едут вместе одновременно но с задержкой относительно друг друга.
---------Грязный звук 30мкс-------=======Чистый звук 125мкс=====_____Пауза 125мкс_____=======Чистый звук 125мкс=====---------Грязный звук 60мкс------- А ДОЛЖЕН БЫТЬ ТАК =======Чистый звук 125мкс=====_____Пауза 125мкс_____=======Чистый звук 125мкс=====.

#include <TinyGPS++.h>        // include TinyGPS++ library
#include <TimeLib.h>          // include Time library
#include <SoftwareSerial.h>   // include Software serial library
#define _LCD_TYPE 1
#include <LCD_1602_RUS_ALL.h>
const uint8_t pinBF = 8;

TinyGPSPlus gps;

#define S_RX    4   // define software serial RX pin
#define S_TX    3   // define software serial TX pin

SoftwareSerial SoftSerial(S_RX, S_TX);   // configure SoftSerial library

// initialise the LCD 1602 I2C
LCD_1602_RUS <LiquidCrystal_I2C> lcd(0x27, 16, 2);

#define time_offset   18000  // define a clock offset of 18000 seconds (5 hours) ==> UTC + 5

// variable definitions
char Time[]  = "00:00:00";
char Date[]  = "00-00-2000";
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
unsigned long last_time = 0; //вот эта переменная

void setup(void)
{
  SoftSerial.begin(9600);  // initialize software serial at 9600 baud
  lcd.init();                  //инициализация дисплея i2c
  lcd.backlight();
  lcd.setCursor(2, 0); // move LCD cursor to column 2, row 0
  lcd.print("CLOCK");
  lcd.setCursor(0, 1); // move LCD cursor to column 0, row 1
  lcd.print("CLOCK UTC+5");
  delay(2000);
  lcd.clear();
}

void loop()
{
  if ((millis() - last_time) > 900)
  {
    if ((gps.time.minute() == 0 ) && (gps.time.second() == 0 ))
    {
      tone(pinBF, 4100, 125);
      delay(250);
      tone(pinBF, 4100, 125);
    }
    last_time = millis();
  }


  while (SoftSerial.available() > 0)
  {
    if (gps.encode(SoftSerial.read()))
    {
      // get time from GPS module
      if (gps.time.isValid())
      {
        Minute = gps.time.minute();
        Second = gps.time.second();
        Hour   = gps.time.hour();
      }
      // get date drom GPS module
      if (gps.date.isValid())
      {
        Day   = gps.date.day();
        Month = gps.date.month();
        Year  = gps.date.year();
      }

      if (last_second != gps.time.second()) // if time has changed
      {
        last_second = gps.time.second();

        // set current UTC time
        setTime(Hour, Minute, Second, Day, Month, Year);
        // add the offset to get local time
        adjustTime(time_offset);

        // update time array
        Time[0]  = hour()   / 10 + '0';
        Time[1]  = hour()   % 10 + '0';
        Time[3]  = minute() / 10 + '0';
        Time[4] = minute() % 10 + '0';
        Time[6] = second() / 10 + '0';
        Time[7] = second() % 10 + '0';

        // update date array
        Date[0]  =  day()   / 10 + '0';
        Date[1]  =  day()   % 10 + '0';
        Date[3]  =  month() / 10 + '0';
        Date[4] =  month() % 10 + '0';
        Date[8] = (year()  / 10) % 10 + '0';
        Date[9] =  year()  % 10 + '0';
        // print time & date
        print_wday(weekday());   // print day of the week
        lcd.setCursor(0, 0);     // move cursor to column 0 row 1
        lcd.print(Time);         // print time (HH:MM:SS)
        lcd.setCursor(0, 1);     // move cursor to column 0 row 0
        lcd.print(Date);         // print date (DD-MM-YYYY)
        lcd.setCursor(11, 1);     // move cursor to column 11 row 1
        lcd.print("UTC+5");       // print text
      }
    }
  }
}

// function for displaying day of the week
void print_wday(byte wday)
{
  lcd.setCursor(9, 0);  // move cursor to column 9, row 0
  switch (wday)
  {
    case 1:  lcd.print("ВОСКРЕС");   break;
    case 2:  lcd.print("ПОНЕДЕЛ");   break;
    case 3:  lcd.print("ВТОРНИК");   break;
    case 4:  lcd.print("СРЕДА  ");   break;
    case 5:  lcd.print("ЧЕТВЕРГ");   break;
    case 6:  lcd.print("ПЯТНИЦА");   break;
    default: lcd.print("СУББОТА");
  }
}

(24 баллов) 1 3 8

1 Ответ

+3 голосов
 
Лучший ответ
 if ((millis() - last_time) > 900)
  {
    if ((gps.time.minute() == 0 ) && (gps.time.second() == 0 ))
    {
      tone(pinBF, 4100, 125);
      delay(250);
      tone(pinBF, 4100, 125);
//delay(250);//?
    }
    last_time = millis();
  }

125мкс_

Скорее всего вы имели в виду 125 миллисекунд (1/1000 секунды) , да и функция tone принимает миллисекунды.

Причины могут быть разные. Есть вероятность, что аппаратный таймер 2 используется , чем-нибудь ещё , например:

#include <SoftwareSerial.h>   // include Software serial library

Так как вы все равно используете delay, можно заменить tone на "безтаймерую" генерацию частоты:

const byte per =122; // (1млн микросек./4100)/2 
for(int i=1024;i--;i>0)
{
digitalWrite(pinBF,1);
delayMicroseconds(per);
digitalWrite(pinBF,0);
delayMicroseconds(per);
}
delay(125);
for(int i=1024;i--;i>0)
{
digitalWrite(pinBF,1);
delayMicroseconds(per);
digitalWrite(pinBF,0);
delayMicroseconds(per);
}

или подобрать альтернативную библиотеку tone...

(2.7 тыс. баллов) 6 17 38
выбран
Спасибо.( Обновлено .Увы нет не работает опять скрежет(с громкостью решил)Вроде работает но звук очень тихий слышно только в плотную(пассивная пищалка пъезо ).Когда подсоединяешь обычный электромагнитную то на расстоянии 10 см слышно.Перепаять увы на активную нельзя,часы залиты эпоксидной смолой толщиной 1 см.Да миллисекунды,просто в осциллографе забыл переставить символы.Может Millis c Gps конфликтует.Или вот этот кусочек кода

unsigned long last_time = 0; //вот эта переменная.

Часы подводные до 100 метров.Антенна наружная.
Проблема точно не физическая потому-что на макетке 2 штуки также работают с разными комплектующими GPS отключаешь работает (пиликает) нормально.Думал пины (3 и 11)конфликтуют менял их тоже самое.Может конечно самовозбуждение Arduino от GPS но наврятли потому-что промежутки равные.да скрежет на 12000 герцах вроде.
Попробуйте запрещать прерывания на время работы пищалки :

const byte per =122; // (1млн микросек./4100)/2
noInterrupts();
for(int i=1024;i--;i>0)
{
digitalWrite(pinBF,1);
delayMicroseconds(per);
digitalWrite(pinBF,0);
delayMicroseconds(per);
}
delay(125);
for(int i=1024;i--;i>0)
{
digitalWrite(pinBF,1);
delayMicroseconds(per);
digitalWrite(pinBF,0);
delayMicroseconds(per);
}
interrupts ();
Огромное Большое Спасибо.Вроде разобрался (ДОБАВЛЕНО).,тоже думал про остановку прерывания но забыл.У вас ошибка в delay(125); надо 25000 тогда правильно срабатывает пауза,Может ошибка в  if ((millis() - last_time) > 900) и delayMicroseconds(per);
ошибка есть в общем два сигнала не разделенные едут и получается 4 сигнала То есть 2 сигнала по 125 мс и 2 сигнала по 125 мс..едут ну и задержка в 2 секунды на дисплей и сигнал сам по 250 мс едет Надо по 125 мс.. То-есть



Получается =====125 мс=====_0 мс_=====125 мс=====_________0 мс__________=====125 мс=====_0 мс_=====125 мс=====  .Все вроде решил.

#include <TinyGPS++.h>        // include TinyGPS++ library
#include <TimeLib.h>          // include Time library
#include <SoftwareSerial.h>   // include Software serial library
#define _LCD_TYPE 1
#include <LCD_1602_RUS_ALL.h>
int pinBF = 8;

TinyGPSPlus gps;

#define S_RX    4   // define software serial RX pin
#define S_TX    3   // define software serial TX pin

SoftwareSerial SoftSerial(S_RX, S_TX);   // configure SoftSerial library

// initialise the LCD 1602 I2C
LCD_1602_RUS <LiquidCrystal_I2C> lcd(0x27, 16, 2);

#define time_offset   18000  // define a clock offset of 18000 seconds (5 hours) ==> UTC + 5

// variable definitions
char Time[]  = "00:00:00";
char Date[]  = "00-00-2000";
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
unsigned long last_time = 0; //вот эта переменная

void setup(void)
{
  SoftSerial.begin(9600);  // initialize software serial at 9600 baud
  lcd.init();                  //инициализация дисплея i2c
  lcd.backlight();
  lcd.setCursor(2, 0); // move LCD cursor to column 2, row 0
  lcd.print("CLOCK");
  lcd.setCursor(0, 1); // move LCD cursor to column 0, row 1
  lcd.print("CLOCK UTC+5");
  delay(2000);
  lcd.clear();
  pinMode(pinBF, OUTPUT);
}

void loop()
{
  if ((millis() - last_time) > 640)
  {
    if ((gps.time.minute() == 0 ) && (gps.time.second() == 0 ))
    {
      const byte per = 119;
      noInterrupts();
      for (int i = 512; i--; i > 0)
      {
        digitalWrite(pinBF, 1);
        delayMicroseconds(per);
        digitalWrite(pinBF, 0);
        delayMicroseconds(per);
      }
      delay(25000);
      for (int i = 512; i--; i > 0)
      {
        digitalWrite(pinBF, 1);
        delayMicroseconds(per);
        digitalWrite(pinBF, 0);
        delayMicroseconds(per);
      }
      interrupts ();
    }
    last_time = millis();
  }


  while (SoftSerial.available() > 0)
  {
    if (gps.encode(SoftSerial.read()))
    {
      // get time from GPS module
      if (gps.time.isValid())
      {
        Minute = gps.time.minute();
        Second = gps.time.second();
        Hour   = gps.time.hour();
      }
      // get date drom GPS module
      if (gps.date.isValid())
      {
        Day   = gps.date.day();
        Month = gps.date.month();
        Year  = gps.date.year();
      }

      if (last_second != gps.time.second()) // if time has changed
      {
        last_second = gps.time.second();

        // set current UTC time
        setTime(Hour, Minute, Second, Day, Month, Year);
        // add the offset to get local time
        adjustTime(time_offset);

        // update time array
        Time[0]  = hour()   / 10 + '0';
        Time[1]  = hour()   % 10 + '0';
        Time[3]  = minute() / 10 + '0';
        Time[4] = minute() % 10 + '0';
        Time[6] = second() / 10 + '0';
        Time[7] = second() % 10 + '0';

        // update date array
        Date[0]  =  day()   / 10 + '0';
        Date[1]  =  day()   % 10 + '0';
        Date[3]  =  month() / 10 + '0';
        Date[4] =  month() % 10 + '0';
        Date[8] = (year()  / 10) % 10 + '0';
        Date[9] =  year()  % 10 + '0';
        // print time & date
        print_wday(weekday());   // print day of the week
        lcd.setCursor(0, 0);     // move cursor to column 0 row 1
        lcd.print(Time);         // print time (HH:MM:SS)
        lcd.setCursor(0, 1);     // move cursor to column 0 row 0
        lcd.print(Date);         // print date (DD-MM-YYYY)
        lcd.setCursor(11, 1);     // move cursor to column 11 row 1
        lcd.print("UTC+5");       // print text
      }
    }
  }
}

// function for displaying day of the week
void print_wday(byte wday)
{
  lcd.setCursor(9, 0);  // move cursor to column 9, row 0
  switch (wday)
  {
    case 1:  lcd.print("ВОСКРЕС");   break;
    case 2:  lcd.print("ПОНЕДЕЛ");   break;
    case 3:  lcd.print("ВТОРНИК");   break;
    case 4:  lcd.print("СРЕДА  ");   break;
    case 5:  lcd.print("ЧЕТВЕРГ");   break;
    case 6:  lcd.print("ПЯТНИЦА");   break;
    default: lcd.print("СУББОТА");
  }
}
Добро пожаловать на Бредборд! Сайт вопросов и ответов на тему Arduino, Raspberry Pi и хоббийной электроники в целом. Цель Бредборда — быть максимально полезным. Поэтому мы строго следим за соблюдением правил, боремся с холиворами и оффтопиком.
  1. Aromik

    69 балл(ов)

  2. Un_ka

    54 балл(ов)

  3. parovoZZ

    12 балл(ов)

  4. sser

    6 балл(ов)

  5. Тёмик

    5 балл(ов)

  6. NesteruS

    5 балл(ов)

Награды месяца
1-е место: OLED-дисплей (Troyka-модуль)
2-е место: Графический экран 128×64
3-е место: Текстовый дисплей 16×2 (Troyka-модуль)

...