RTC + Scheduler using Arduino mini - arduino

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();
}

Related

warning: overflow in implicit constant conversion [-Woverflow] in Arduino Mega 2560 WI-Fi R3

i want to record a long data for like 2 to 3 hours using microcontroller Arduino Mega 2560 WI-FI R3 but I got this warning in my code
below is the picture of the warning i got.
enter image description here
the warning come up when I put the time out constant more than 30000 milliseconds
below is the code I used for the Arduino
#include "DHT.h"
// Pin Definitions
#define DHT_PIN_OUT A1
#define DHTTYPE DHT11
#define MQ3_PIN_OUT A2
#define MQ4_PIN_OUT A3
#define MQ7_PIN_OUT A4
// Global variables and defines
// object initialization
DHT dht(DHT_PIN_OUT, DHTTYPE);
// define vars for testing menu
const int timeout = 180000; //define timeout of 1 hour
char menuOption = 0;
long time0;
// Setup the essentials for your circuit to work. It runs first every time your circuit is powered with electricity.
void setup()
{
// Setup Serial which is useful for debugging
// Use the Serial Monitor to view printed messages
Serial.begin(9600);
while (!Serial) ; // wait for serial port to connect. Needed for native USB
Serial.println("start");
dht.begin();
menuOption = menu();
}
// Main logic of your circuit. It defines the interaction between the components you selected. After setup, it runs over and over again, in an eternal loop.
void loop(){
if(menuOption == '1') {
delay(500); //delay 0.5 second
// DHT11 Humidity and Temperature Sensor
// Reading humidity in %
float dhtHumidity = dht.readHumidity();
// Read temperature in Celsius, for Fahrenheit use .readTempF()
float dhtTempC = dht.readTemperature();
float Alcohol = analogRead(MQ3_PIN_OUT);
float Methane = analogRead(MQ4_PIN_OUT);
float CarbonMonoxide = analogRead(MQ7_PIN_OUT);
Serial.print(F("Humidity: ")); Serial.print(dhtHumidity); Serial.print(F("[%]\t"));
Serial.print(F("Temp: ")); Serial.print(dhtTempC); Serial.print(F("[C]\t"));
Serial.print(F("Alcohol: ")); Serial.print(Alcohol); Serial.print(F(" \t"));
Serial.print(F("Methane: ")); Serial.print(Methane); Serial.print(F(" \t"));
Serial.print(F("Carbon Monoxide: ")); Serial.println(CarbonMonoxide); Serial.println(F(" \t"));
}
if (millis() - time0 > timeout){
menuOption = menu();
}
}
// Menu function for selecting the components to be tested
// Follow serial monitor for instrcutions
char menu(){
Serial.println(F("\nSensor Array"));
Serial.println(F("Press (1) to start the sensor array"));
while (!Serial.available());
// Read data from serial monitor if received
while (Serial.available()){
char c = Serial.read();
if (isAlphaNumeric(c))
{
if(c == '1')
Serial.println(F("Now running the sensor array"));
else{
Serial.println(F("illegal input!"));
menuOption = menu();
return 0;
}
time0 = millis();
return c;
}
}
}
sorry for my bad programming and silly question, I'm new to this kind of thing. and I just found out that people usually get answers from StackOverflow, so I just wanted to try asking because I have tried to google the answer but I can't find it.

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();
.
.
.

Arduino interrupts interfering with TimeAlarms.h

I have and arduino sketch that needs to do several operations on a timed schedule using the TimeAlarms.h library. However, one of the operations, reading a hall sensor via interrupts, seems to interact poorly with the TimeAlarms library.
I'm using the TimeAlarms library from here: http://www.pjrc.com/teensy/td_libs_TimeAlarms.html
And have adapted the hall sensor script from here:
http://www.seeedstudio.com/wiki/G3/4_Water_Flow_sensor
I can run the hall sensor code on it own fine. However, when I try to run the hall sensor code along with Alarm.timerRepeat it hangs after entering the check_flow function.
Running the code below outputs only enter CF and then hangs. The same occurs if you try the check_flow_alarm_delay function instead, which uses the TimeAlarm version of Delay.
However, if you comment out Alarm.timerRepeat(10, showseconds); in setup
and Alarm.delay(0); in loop the hall sensor works fine.
Strangely, if you comment out sei(); and cli(); in the check_flow function the script works fine, and seems to count properly with the hall sensor. Why would this work? And should I be concerned that I'm not actively setting the time between sei() and cli(), leading to reliability issues in the sensor?
Note: you should be able to run the code without actually having a hall sensor, the output will just be 0 L/hr.
// reading liquid flow rate using Seeeduino and Water Flow Sensor from Seeedstudio.com
// Code adapted by Charles Gantt from PC Fan RPM code written by Crenn #thebestcasescenario.com
// http:/themakersworkbench.com http://thebestcasescenario.com http://seeedstudio.com
#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
volatile int NbTopsFan; //measuring the rising edges of the signal
int Calc;
int hallsensor = 2; //The pin location of the sensor
void rpm () //This is the function that the interupt calls
{
NbTopsFan++; //This function measures the rising and falling edge of the hall effect sensors signal
}
void setup() //
{
Serial.begin(9600); //This is the setup function where the serial port is initialised,
pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
attachInterrupt(0, rpm, RISING); //and the interrupt is attached
Alarm.timerRepeat(10, showseconds);
}
void loop ()
{
// Serial.println( second() );
// stalls at enter CF
// check_flow();
// stalls at enter CF
check_flow_alarm_delay();
Alarm.delay(0);
}
void showseconds ()
{
Serial.println( second() );
}
void check_flow ()
{
Serial.println("enter CF");
int Calc;
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
// sei(); //Enables interrupts
delay(1000); //Wait 1 second
// cli(); //Disable interrupts
Calc = (NbTopsFan * 60 / 5.5); //(Pulse frequency x 60) / 5.5Q, = flow rate in L/hour
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a new line
}
void check_flow_alarm_delay ()
{
Serial.println("enter CFAD");
int Calc;
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
// sei(); //Enables interrupts
Alarm.delay(1000); //Wait 1 second
// cli(); //Disable interrupts
Calc = (NbTopsFan * 60 / 5.5); //(Pulse frequency x 60) / 5.5Q, = flow rate in L/hour
Serial.print (Calc, DEC); //Prints the number calculated above
Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a new line
}
delay() uses interrupts. Disabling them interferes with the function.

Read/Write EEPROM Arduino

I have a new ATmega328P CH340G Arduino Uno R3 board.
When I input a two-digit number (like 29), after power off and power on, the board shows only one digit (only 9). I want to show two digits.
enter image description here
Can you help me?
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
int addr = 5;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup() {
lcd.init();
Serial.begin(9600);
// initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0,0);
lcd.write(EEPROM.read(addr));
}
void loop() {
if (Serial.available()) {
while (Serial.available() > 0) {
char myValue = Serial.read();
EEPROM.write(addr,myValue);
lcd.write(myValue);
}
}
}
You are always writing to the same addr (i.e. 5) so you are most likely overwriting the previous character. Try incrementing your address after a write like this:
EEPROM.write(addr++, myValue);
(notice the ++ to increment the address)

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