Ir para conteúdo
  • Cadastre-se

dúvida Relogio com arduino

Avalie este tópico:


joseca3

Posts em destaque

Veja se isso te faz sentido:

Você não tem permissão para ver links. Faça login ou cadastre-se.

 




 

 

Mais pesquisa sobre o assunto : 

O que for necessário é só adicionar um código extra.

Flw...

Editado: por nagkiller
  • Joinha 1
Link para o comentário
Compartilhar em outros sites

Aquivo RelogioAlarme.ino

// #include <Arduino.h>
#include "Ds1302.h"

#define PIN_SET_HORA	3
#define PIN_ENA			  5
#define PIN_CLK			  6
#define PIN_DAT			  7
#define PIN_RELE		  8

Ds1302 rtc(PIN_ENA, PIN_CLK, PIN_DAT);

volatile Ds1302::DateTime tempoAtual;
static int ultimoSegundo = 0;
static int minutoAtual = 61;
static int tolerancia = 5;      // 5 segundos de tolerancia
boolean alarmeAtivo = false;    // Vamos usar essa boolean para dizer que houve ou nao o alarme

static uint8_t char_idx = 0;
const int bufferSize = 13;
static char buffer[bufferSize];

// Constante para o dia da semana
const static char* WeekDays[] = {
  "Segunda",  // 1 para segunda
  "Terca", 	  // 2 para terca
  "Quarta",	  // 3 para quarta
  "Quinta", 	// 4 para quinta
  "Sexta",  	// 5 para sexta
  "Sabado",	  // 6 para sabado
  "Domingo"	  // 7 para domingo
};

void setup() {
  pinMode(PIN_SET_HORA, INPUT_PULLUP);
  pinMode(PIN_RELE, OUTPUT);
  digitalWrite(PIN_RELE, LOW);
  rtc.init();
  adicionarHoraPadrao();
  Serial.begin(9600);
}

void loop() {
  rtc.getDateTime(&tempoAtual);
  int minutos = tempoAtual.minute;
  int segundos = tempoAtual.second;

  // Se o botao de setar hora for pressionado
  if (!digitalRead(PIN_SET_HORA)) { // Se o botao for pressionado
    delay(100);
    if (!digitalRead(PIN_SET_HORA)) { // Se o botao for pressionado
      Serial.println("Digite a data e hora no formato (YYMMDDWhhmmss)");
      Serial.println("Exemplo : 17:42:00 Quarta 25/09/2024 ficará =>  2409253123100");
      alterarDataHora();              // Alterar a hora usando o Monitor Serial
    }
  }
  if (!alarmeAtivo && ( minutos == 00 && segundos < tolerancia )) {   // Tolerancia, para não haver repique. Evento acontece a cada 60 minutos!
    alarmeAtivo = true;
    Serial.println("Acionando o Relay");
    digitalWrite(PIN_RELE, HIGH); // Atraca o relay
    delay(1000); // Deixar preso em um delay de 1 segundo ligado
    Serial.println("Desligando o Relay");
    digitalWrite(PIN_RELE, LOW); // Desatraca o relay
  }
  if ( alarmeAtivo && (segundos > tolerancia)) { // Se o alarmeAtivo está ativo, então desliga
    alarmeAtivo = false;
  }

  if (ultimoSegundo % 30 == 0) { // A cada minuto exibe a hora no Monitor Serial
    imprimirDataHora();
  }

  if (Serial.available()) {
    buffer[char_idx++] = Serial.read();
  }
}

uint8_t parseDigits(char* str, uint8_t count) {
  uint8_t val = 0;
  while (count-- > 0) val = (val * 10) + (*str++ - '0');
  return val;
}

void alterarDataHora() {
  if (char_idx >= bufferSize) {
    tempoAtual.year = parseDigits(buffer, 2);         // Pega os dois primeiros digitos para ano
    tempoAtual.month = parseDigits(buffer + 2, 2);    // Pega os dois proximos para o mes
    tempoAtual.day = parseDigits(buffer + 4, 2);      // Pega os dois proximos para o dia
    tempoAtual.dow = parseDigits(buffer + 6, 1);      // Pega o proximo para o dia da semana => Ver o WeekDays acima
    tempoAtual.hour = parseDigits(buffer + 7, 2);     // Pega os dois proximos para a hora
    tempoAtual.minute = parseDigits(buffer + 9, 2);   // Pega os dois proximos para minutos
    tempoAtual.second = parseDigits(buffer + 11, 2);  // Pega os dois proximos para os segundos

    rtc.setDateTime(&tempoAtual);   // set the date and time
    imprimirDataHora();
    char_idx = 0;
    for (int i = 0; i < bufferSize; ++i) {
      buffer[i] = '\0';
    }
  }
}

void imprimirDataHora() {
  if (tempoAtual.day < 10) Serial.print('0');
  Serial.print(tempoAtual.day);     // 01-31
  Serial.print('/');
  if (tempoAtual.month < 10) Serial.print('0');
  Serial.print(tempoAtual.month);   // 01-12
  Serial.print('/');
  Serial.print("20");
  Serial.print(tempoAtual.year);    // 00-99
  Serial.print(' ');
  if (tempoAtual.hour < 10) Serial.print('0');
  Serial.print(tempoAtual.hour);    // 00-23
  Serial.print(':');
  if (tempoAtual.minute < 10) Serial.print('0');
  Serial.print(tempoAtual.minute);  // 00-59
  Serial.print(':');
  if (tempoAtual.second < 10) Serial.print('0');
  Serial.print(tempoAtual.second);  // 00-59
  Serial.println();
}

void adicionarHoraPadrao() {
  Ds1302::DateTime dataPadrao = {
    .year = 24,
    .month = 9,
    .day = 25,
    .hour = 12,
    .minute = 00,
    .second = 25,
    .dow = 3
  };
  rtc.setDateTime(&dataPadrao);
}


Aquivo Ds1302.h

/** Ds1302.h
 *
 * Ds1302 class.
 *
 * @version 1.0.3
 * @author Rafa Couto <caligari@treboada.net>
 * @license GNU Affero General Public License v3.0
 * @see https://github.com/Treboada/Ds1302
 *
 */

#ifndef _DS_1302_H
#define _DS_1302_H

#include <stdint.h>

class Ds1302
{
    public:

        typedef struct {
            uint8_t year;
            uint8_t month;
            uint8_t day;
            uint8_t hour;
            uint8_t minute;
            uint8_t second;
            uint8_t dow;
        } DateTime;

        /**
         * Months of year
         */
        enum MONTH : uint8_t {
            MONTH_JAN = 1,
            MONTH_FEB = 2,
            MONTH_MAR = 3,
            MONTH_APR = 4,
            MONTH_MAY = 5,
            MONTH_JUN = 6,
            MONTH_JUL = 7,
            MONTH_AUG = 8,
            MONTH_SET = 9,
            MONTH_OCT = 10,
            MONTH_NOV = 11,
            MONTH_DEC = 12
        };

        /**
         * Days of week
         */
        enum DOW : uint8_t {
            DOW_MON = 1,
            DOW_TUE = 2,
            DOW_WED = 3,
            DOW_THU = 4,
            DOW_FRI = 5,
            DOW_SAT = 6,
            DOW_SUN = 7
        };

        /**
         * Constructor (pin configuration).
         */
        Ds1302(uint8_t pin_ena, uint8_t pin_clk, uint8_t pin_dat);

        /**
         * Initializes the DW1302 chip.
         */
        void init();

        /**
         * Returns when the oscillator is disabled.
         */
        bool isHalted();

        /**
         * Stops the oscillator.
         */
        void halt();

        /**
         * Returns the current date and time.
         */
        void getDateTime(DateTime* dt);;

        /**
         * Sets the current date and time.
         */
        void setDateTime(DateTime* dt);

    private:

        uint8_t _pin_ena;
        uint8_t _pin_clk;
        uint8_t _pin_dat;

        void _prepareRead(uint8_t address);
        void _prepareWrite(uint8_t address);
        void _end();

        int _dat_direction;
        void _setDirection(int direction);

        uint8_t _readByte();
        void _writeByte(uint8_t value);
        void _nextBit();

        uint8_t _dec2bcd(uint8_t dec);
        uint8_t _bcd2dec(uint8_t bcd);
};

#endif // _DS_1302_H

 

Aquivo Ds1302.cpp

/** Ds1302.cpp
 *
 * Ds1302 class.
 *
 * @version 1.0.3
 * @author Rafa Couto <caligari@treboada.net>
 * @license GNU Affero General Public License v3.0
 * @see https://github.com/Treboada/Ds1302
 *
 */

#include "Ds1302.h"

#include <Arduino.h>

#define REG_SECONDS           0x80
#define REG_MINUTES           0x82
#define REG_HOUR              0x84
#define REG_DATE              0x86
#define REG_MONTH             0x88
#define REG_DAY               0x8A
#define REG_YEAR              0x8C
#define REG_WP                0x8E
#define REG_BURST             0xBE


Ds1302::Ds1302(uint8_t pin_ena, uint8_t pin_clk, uint8_t pin_dat)
{
    _pin_ena = pin_ena;
    _pin_clk = pin_clk;
    _pin_dat = pin_dat;
    _dat_direction = INPUT;
}


void Ds1302::init()
{
    pinMode(_pin_ena, OUTPUT);
    pinMode(_pin_clk, OUTPUT);
    pinMode(_pin_dat, _dat_direction);

    digitalWrite(_pin_ena, LOW);
    digitalWrite(_pin_clk, LOW);
}


bool Ds1302::isHalted()
{
    _prepareRead(REG_SECONDS);
    uint8_t seconds = _readByte();
    _end();
    return (seconds & 0b10000000);
}


void Ds1302::getDateTime(DateTime* dt)
{
    _prepareRead(REG_BURST);
    dt->second = _bcd2dec(_readByte() & 0b01111111);
    dt->minute = _bcd2dec(_readByte() & 0b01111111);
    dt->hour   = _bcd2dec(_readByte() & 0b00111111);
    dt->day    = _bcd2dec(_readByte() & 0b00111111);
    dt->month  = _bcd2dec(_readByte() & 0b00011111);
    dt->dow    = _bcd2dec(_readByte() & 0b00000111);
    dt->year   = _bcd2dec(_readByte() & 0b01111111);
    _end();
}


void Ds1302::setDateTime(DateTime* dt)
{
    _prepareWrite(REG_WP);
    _writeByte(0b00000000);
    _end();

    _prepareWrite(REG_BURST);
    _writeByte(_dec2bcd(dt->second % 60 ));
    _writeByte(_dec2bcd(dt->minute % 60 ));
    _writeByte(_dec2bcd(dt->hour   % 24 ));
    _writeByte(_dec2bcd(dt->day    % 32 ));
    _writeByte(_dec2bcd(dt->month  % 13 ));
    _writeByte(_dec2bcd(dt->dow    % 8  ));
    _writeByte(_dec2bcd(dt->year   % 100));
    _writeByte(0b10000000);
    _end();
}


void Ds1302::halt()
{
    _prepareWrite(REG_SECONDS);
    _writeByte(0b10000000);
    _end();
}


void Ds1302::_prepareRead(uint8_t address)
{
    _setDirection(OUTPUT);
    digitalWrite(_pin_ena, HIGH);
    uint8_t command = 0b10000001 | address;
    _writeByte(command);
    _setDirection(INPUT);
}


void Ds1302::_prepareWrite(uint8_t address)
{
    _setDirection(OUTPUT);
    digitalWrite(_pin_ena, HIGH);
    uint8_t command = 0b10000000 | address;
    _writeByte(command);
}


void Ds1302::_end()
{
    digitalWrite(_pin_ena, LOW);
}


uint8_t Ds1302::_readByte()
{
    uint8_t byte = 0;

    for(uint8_t b = 0; b < 8; b++)
    {
        if (digitalRead(_pin_dat) == HIGH) byte |= 0x01 << b;
        _nextBit();
    }

    return byte;
}


void Ds1302::_writeByte(uint8_t value)
{
    for(uint8_t b = 0; b < 8; b++)
    {
        digitalWrite(_pin_dat, (value & 0x01) ? HIGH : LOW);
        _nextBit();
        value >>= 1;
    }
}

void Ds1302::_nextBit()
{
        digitalWrite(_pin_clk, HIGH);
        delayMicroseconds(1);

        digitalWrite(_pin_clk, LOW);
        delayMicroseconds(1);
}


void Ds1302::_setDirection(int direction)
{
    if (_dat_direction != direction)
    {
        _dat_direction = direction;
        pinMode(_pin_dat, direction);
    }
}


uint8_t Ds1302::_dec2bcd(uint8_t dec)
{
    return ((dec / 10 * 16) + (dec % 10));
}


uint8_t Ds1302::_bcd2dec(uint8_t bcd)
{
    return ((bcd / 16 * 10) + (bcd % 16));
}



Não testei, mas deve funcionar.

Flw...

Editado: por nagkiller
Link para o comentário
Compartilhar em outros sites

Ola amigo,muito obrigado pelo retorno !

Obrigado pelo circuito,mas a parte fisica(o hardware)eu já tenho em mente,que é o seguimte:

Um fet de potencia IRF840 ira acionar uma solenoide de 12 volts que ira dar um pulso bem rapido num disco de ferro redondo que produz um som de sino.

Muito bem,esse circuito eu ja tenho montado no arduino Uno e estou usando como teste o exemplo "blink"gravado no mesmo.

Como não tenho muita experiencia em programação queria saber onde adaptar esse exemplo num codigo de relogio que tem por ai,isto é.queria que ao mudar as horas desse esse pulso na solenoide,como sinal sonoro(dai a idéia de um relogio carrilhão)

 

  • Joinha 1
Link para o comentário
Compartilhar em outros sites

O código com millis pode ser alterado conforme o exemplo:

Você não tem permissão para ver links. Faça login ou cadastre-se.

 

 

#define PIN_RELE      8 // Use o pino desejado aqui para a saída do mosfet

unsigned long previousMillis = 0;
unsigned long tempoAtualRelay = 0;
const long interval = 1000; // 1000 milissegundos = 1 segundo
int horas = 15; // Hora sincronizada com o PC
int minutos = 59; // Hora sincronizada com o PC 
int segundos = 45; // Hora sincronizada com o PC 
int tempoReleAcionado = 100; // 100 milissegundos é o tempo que o pino de relay está em nivel logico 1 (Acionado)
boolean passouUmaHora = false;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); // SAIDA
  pinMode(PIN_RELE, OUTPUT);    // ENTRADA
  digitalWrite(PIN_RELE, LOW);  // DESLIGADO
  Serial.begin(9600);      // PORTA SERIAL PARA MONITORAR AS MENSAGENS
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    segundos++;
    if (segundos > 59) { // 60 segundos = 1 minuto
      segundos = 0;
      minutos++;
    }
    if (minutos > 59) { // 60 minutos = 1 hora
      minutos = 0;
      horas++;
      passouUmaHora = true;
      Serial.println(F("Acionando o Relay"));
    }
    if (horas > 23) {
      horas = 0;
    }
    imprimirHora();
    digitalWrite(LED_BUILTIN, 1 ^ digitalRead(LED_BUILTIN)); // Led pisca a cada 1 segundo
  }

  // INDICA AQUI QUE SE PASSOU UMA HORA E ACIONA O PINO DO RELAY
  if (passouUmaHora) {
    unsigned long tempoDecorrido = millis();
    digitalWrite(PIN_RELE, HIGH); // Acionou relay
    if ( tempoDecorrido - tempoAtualRelay >= tempoReleAcionado ) { // Se o tempo em segundos for maior ou igual a 100ms, desliga Relay
      tempoAtualRelay = tempoDecorrido;
      Serial.println(F("Desligando o Relay"));
      digitalWrite(PIN_RELE, LOW); // Desatraca o relay
      passouUmaHora = false;
    }
  }
}
// EXIBE NO TERMINAL A HORA ATUAL
void imprimirHora() {
  if (horas < 10) Serial.print("0");
  Serial.print(horas);
  Serial.print(":");
  if (minutos < 10) Serial.print("0");
  Serial.print(minutos);
  Serial.print(":");
  if (segundos < 10) Serial.print("0");
  Serial.println(segundos);
}


Flw...

Editado: por nagkiller
  • Joinha 1
Link para o comentário
Compartilhar em outros sites

Participe agora da conversa!

Você pode postar agora e se cadastrar mais tarde. Se você tiver uma conta, faça login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Restaurar formatação

  Apenas 75 emoticons máximos são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir apenas como um link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Você não pode colar imagens diretamente. Envie ou insira imagens do URL.

SOBRE O ELETRÔNICABR

EletrônicaBR é o melhor fórum técnico online, temos o maior e mais atualizado acervo de Esquemas, Bios e Firmwares da internet. Através de nosso sistema de créditos, usuários participativos têm acesso totalmente gratuito. Os melhores técnicos do mundo estão aqui!
Técnico sem o EletrônicaBR não é um técnico completo! Leia Mais...
×
×
  • Criar Novo...