ds1307 running to slow on attiny85 - arduino

Someone know why ATTiny85 connect to ds1307 crystal get time the refresh frequency to slow?
The new time value refresh change at 4 second.
It running normal on arduino(UNO).
ATTiny clock (internal 8 Mhz)
Thx.
#include <TinyWireM.h>
#include "TinyRTClib.h"
#include <Tiny4kOLED.h>
RTC_DS1307 rtc;
void setup() {
// put your setup code here, to run once:
oled.begin();
oled.clear();
oled.on();
oled.switchRenderFrame();
rtc.begin();
rtc.adjust(DateTime(2019, 3, 30, 15, 38, 0));
}
void loop(){
if (! rtc.isrunning()) {
return disconnectCrystal();
}
DateTime now = rtc.now();
oled.fill(0xFF);
oled.clear();
oled.switchFrame();
oled.setFont(FONT6X8);
oled.setCursor(32, 2);
..
oled.print(now.hour(), DEC);
oled.print(':');
oled.print(now.minute(), DEC);
oled.print(':');
oled.print(now.second(), DEC);
..
delay(1000);
}

Try using millis() instead of delay()
https://gist.github.com/kubilisr/eaf9d488e258a2175313fb38f6f80aa2

Related

RTC DS3231 does not loop after initializing

I'm trying to use the RTC DS3231 - but it does not loop after Initializing in void setup(). I only tried the example codes so far:
/*
DS3231: Real-Time Clock. Date Format
Read more: www.jarzebski.pl/arduino/komponenty/zegar-czasu-rzeczywistego-rtc-ds3231.html
GIT: https://github.com/jarzebski/Arduino-DS3231
Web: http://www.jarzebski.pl
(c) 2014 by Korneliusz Jarzebski
*/
#include <Wire.h>
#include <DS3231.h>
DS3231 clock;
RTCDateTime dt;
void setup()
{
Serial.begin(9600);
// Initialize DS3231
Serial.println("Initialize DS3231");;
clock.begin();
// Set sketch compiling time
clock.setDateTime(__DATE__, __TIME__);
// Set from UNIX timestamp
// clock.setDateTime(1397408400);
// Manual (YYYY, MM, DD, HH, II, SS
// clock.setDateTime(2014, 4, 13, 19, 21, 00);
}
void loop()
{
dt = clock.getDateTime();
Serial.print("Long number format: ");
Serial.println(clock.dateFormat("d-m-Y H:i:s", dt));
Serial.print("Long format with month name: ");
Serial.println(clock.dateFormat("d F Y H:i:s", dt));
Serial.print("Short format witch 12h mode: ");
Serial.println(clock.dateFormat("jS M y, h:ia", dt));
Serial.print("Today is: ");
Serial.print(clock.dateFormat("l, z", dt));
Serial.println(" days of the year.");
Serial.print("Actual month has: ");
Serial.print(clock.dateFormat("t", dt));
Serial.println(" days.");
Serial.print("Unixtime: ");
Serial.println(clock.dateFormat("U", dt));
Serial.println();
delay(1000);
}
Output looks like this:
10:15:16.623 -> Initialize DS3231
Does that mean it doesn't work at all? Or that it doesn't continue to loop after calling void setup?
Any help would be appreciated, that can't be that much of a problem..
Insert
Wire.begin();
before the clock initializes
void setup()
{
Serial.begin(9600);
Wire.begin();
// Initialize DS3231
Serial.println("Initialize DS3231");;
clock.begin();
.
.
.

Having problems with the DS3231.h library

Dear Stack Exchange community.
I'm a beginner Arduino user and am attempting to replicate a 24-hour alarm clock demonstrated in a tutorial found at: https://diyhacking.com/arduino-alarm-clock-using-real-time-clock-lcd-screen/.
I downloaded and installed all the most updated libraries associated with the DS3231 Real Time Clock module.
When I attempt to run the following program (I am not the author of this code, as it is directly taken from the page I linked above), I am met with an error that seems to be a result of missing a key library.
Can anyone tell me which libraries I need to install to eliminate the error?
#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
DS3231 rtc(SDA, SCL);
Time t;
#define buz 11
int Hor;
int Min;
int Sec;
void setup() {
Wire.begin();
rtc.begin();
Serial.begin(9600);
pinMode(buz, OUTPUT);
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("DIYHacking.com");
lcd.setCursor(0,1);
lcd.print("Arduino Alarm ");
delay(2000);
}
void loop() {
t = rtc.getTime();
Hor = t.hour;
Min = t.min;
Sec = t.sec;
lcd.setCursor(0,0);
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
lcd.setCursor(0,1);
lcd.print("Date: ");
lcd.print(rtc.getDateStr());
if( Hor == 11 && (Min == 32 || Min == 33)) {
//Comparing the current time with the Alarm time
Buzzer();
Buzzer();
lcd.clear();
lcd.print("Alarm ON");
lcd.setCursor(0,1);
lcd.print("Alarming");
Buzzer();
Buzzer();
}
delay(1000);
}
void Buzzer() {
digitalWrite(buz,HIGH);
delay(500);
digitalWrite(buz, LOW);
delay(500);
}
The error returned when I compile and run this program is as follows:
sketch_oct29c:17: error: no matching function for call to
'DS3231::DS3231(const uint8_t&, const uint8_t&)'
DS3231 rtc(SDA, SCL);
^
Can anyone suggest a fix for this?
The following libraries are those that I installed:
DS3231,
MD_DS3231,
Rtc_by_Makuna,
RTClib,
RTCtime
Cheers!
Encountered the same error and had to google for a number of days to get it sorted out. Seems the issue is being caused by the library.
You need to download the Rinky Dink DS 3231 library. You can download it from here
Once downloaded, extract the DS3231 folder and place it into the libraries folder of your Arduino. Once you've done that, run the program and it would work. Hopefully.

How to obtain a more accurate value for RPM

I am trying to build a rev counter using a Hall effect sensor and an Arduino Uno. I'm using Arduino software and I have wrote the following code:
#include <LiquidCrystal.h>
int sensorPin = 2; // hall effect
float revs;
float rpm;
volatile byte rpmcount;
long previousmicros = 0;
long interval = 500000;
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);
void setup()
{
// setup serial - diagnostics - port
Serial.begin(115200);
// setup pins
pinMode(sensorPin, INPUT);
// setup interrupt
attachInterrupt(0, RPM, RISING);
}
void RPM()
{
rpmcount++;
}
void loop()
{
unsigned long currentmicros = micros();
int sensorValue = digitalRead(sensorPin); // sensor value is read
if (currentmicros - previousmicros > interval)
{
previousmicros = currentmicros;
detachInterrupt(0);
revs=10.0/rpmcount;
rpm =600.0/revs;
Serial.print("rpmcount : ");
Serial.print(rpmcount);
Serial.print(" rpm : ");
Serial.println(rpm);
lcd.clear();
lcd.begin(16, 2);
lcd.print("RPM = ");
lcd.setCursor(6,0);
lcd.print(rpm,0);
rpmcount=0;
attachInterrupt(0, RPM, RISING);
}
}
This works and measures the RPM correctly however the value is always a factor of 60. How can I change this so that it will measure the RPM more accurately, to say +-5 RPM? I tried playing about with my revs and rpm formulas but had little success.
Right now you have
rpm =60.0*rpmcount;
You will have to store the count over a longer time and calculate the value from that (or change how often loop is run)
In the ISR instead of increment a count, compute the amount of time elapsed since the last ISR fire.
unsigned long someArray[2] = {0,0};
unsigned char rpmindex = 0;
void RPM_isr()
{
rpmindex ^= 1;
someArray[rpmindex] = micros();
}
// And then in the main body
{
// Disable interrupts
// Copy someArray to a localArray
// reEnable interrupts
// Compute the interval between ISR fires
unsigned long interval = abs(localArray[0] - localArray[1]);
// Compute RPM
unsigned int rpm = (60*1000000)/interval;
}
Pseudo code interpreted at your own risk.
Edit: For bad math on RPM computation.

RTC + Scheduler using Arduino mini

I am using Arduino mini 5V for my project and RTC - Real Time Clock Module DS1307
I would like to wake the board at a certain time and run a function. (Buzzer is connected to D3)
When I use the TimeAlarm alone and manually set the time everything works fine:
#include "Time.h"
#include "TimeAlarms.h"
void setup(){
setTime(22,29,55,12,31,14); // set time to Saturday 8:29:00am Jan 1 2011
Alarm.alarmRepeat(10,30,0,buzz); // 10:30am every day
Alarm.alarmRepeat(16,30,0,buzz); // 4:30pm every day
Alarm.alarmRepeat(22,30,0,buzz); // 10:30pm every day
Serial.begin(9600);
}
void loop(){
digitalClockDisplay();
Alarm.delay(1000);
}
void buzz(){
tone(3, 220, 1000);
}
void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
}
void printDigits(int digits){
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
However when I use RTC the buzzer function wouldn't get called, it still prints the time though
#include <Wire.h>
#include "RTClib.h"
#include "Time.h"
#include "TimeAlarms.h"
RTC_Millis rtc;
void setup(){
rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
Alarm.alarmRepeat(10,30,0,buzz); // 10:30am every day
Alarm.alarmRepeat(16,30,0,buzz); // 4:30pm every day
Alarm.alarmRepeat(22,30,0,buzz); // 10:30pm every day -- modify this to your current time when running the example
Serial.begin(9600);
}
void loop(){
//printing the current time
DateTime now = rtc.now();
Serial.print(now.year());
Serial.print('/');
Serial.print(now.month());
Serial.print('/');
Serial.print(now.day());
Serial.print(' ');
Serial.print(now.hour());
Serial.print(':');
Serial.print(now.minute());
Serial.print(':');
Serial.print(now.second());
Serial.println();
Alarm.delay(1000); // wait one second between clock display
}
void buzz(){
tone(3, 220, 1000);
}
OK so I found the answer:
First problem was: using RTC_DS1307 instead of RTC_Millis
RTC ds1307 is referring to pin 12C which in Arduino mini they are above A3 and VCC. They require soldering. Once that's done they should be connected to SDA and SCL, using M/F wires
SDA -> to the pin above A3
SCL -> to the pin above VCC
Then I changed the code to the following:
#include <Wire.h>
#include "RTClib.h"
#include "Time.h"
#include "TimeAlarms.h"
RTC_DS1307 rtc;
const int output = 3;
uint32_t syncProvider()//function which sets up the RTC as the source of external time{
return rtc.now().unixtime();
}
void setup(){
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(__DATE__, __TIME__));//comment this out when the RTC has been set
setSyncProvider(syncProvider); // the function to get the time from the RTC
Alarm.alarmRepeat(10,30,0,buzzer); // 10:30am every day
Alarm.alarmRepeat(16,30,0,buzzer); // 4:30pm every day
Alarm.alarmRepeat(22,30,00,buzzer); // 10:30pm every day
pinMode(output , OUTPUT);//new line
Serial.begin(9600);
}
void loop(){
//printing the current time
DateTime now = rtc.now();
Serial.print(now.year());
Serial.print('/');
Serial.print(now.month());
Serial.print('/');
Serial.print(now.day());
Serial.print(' ');
Serial.print(now.hour());
Serial.print(':');
Serial.print(now.minute());
Serial.print(':');
Serial.print(now.second());
Serial.println();
Alarm.delay(1000); // wait one second between clock display
}
void buzzer(){
//Do Stuff
}
Just to help noob like me who did tried this code by using copy paste and get error
named return values are no longer supported Error compiling.
After searching through the net found that the { the infamous curly bracket is part of comment so please change the same to
uint32_t syncProvider() { //function which sets up the RTC as the source of external time
return rtc . now() . unixtime();
}

Arduino Wire program seems to stop reading bytes after first i2c payload

I am trying to write a program that receives string data from i2c and displays it on an LCD. The first time data is received to the arduino, it renders it, however subsequent i2c payloads are ignored. My onReceive function has a status line display on the second line of the lcd which display the seconds() field from the timer chip. The seconds number does not seem to increment. However, the per-second dot flash as rendered in loop() does continue to blink, so the mcu is not frozen.
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Time.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
void setup()
{
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
}
void loop()
{
lcd.setCursor(15,1);
if (second() % 2 == 0)
lcd.write(".");
else
lcd.write(" ");
delay(100);
}
void receiveEvent(int howMany)
{
//char buf[howMany];
int i=0;
char output[16];
lcd.clear();
while(Wire.available())
{
char c = Wire.read(); // receive byte as a character
lcd.setCursor(i,0);
lcd.write(c);
i++;
//buf[i++]=c;
//buf[i+1]=0;
}
lcd.setCursor(0,1);
sprintf(output,"s%dNB%dI%d",second(),howMany,i);
lcd.write(output);
}
Your Arduino may be trapped in here:
while(Wire.available())
{
//...
Use:
if(Wire.available() > 0) {
//stuff
}
instead.

Resources