A simple Arduino alarm is not working - arduino

Using the alarm library, I don't get the alarm to work:
#include <Time.h>
#include <TimeAlarms.h>
void setup()
{
Serial.begin(9600);
while (!Serial)
{
;
}
setTime(8,29,0,1,1,10); // set time to 8:29:00am Jan 1 2010
Alarm.timerRepeat(15, Repeats);
}
void Repeats()
{
Serial.print("alarmed timer!");
digitalWrite(10,1);
}
void loop()
{
}

I suppose you are using this library.
If you read in the help, you can see this:
Normal Running Usage
Alarm.delay(milliseconds); Alarms and Timers are only checks and their
functions called when you use this delay function. You can pass 0 for
minimal delay. This delay should be used instead of the normal Arduino
delay(), for timely processing of alarms and timers.
so in order for the alarms to be called, you have to add this:
void loop(){
Alarm.delay(1000); // wait one second between clock display
}
If you prefer to check the alarm faster, you can use a lower delay (e.g. 100). You can also use 0, so the function doesn't block, but it is not mandatory for your application.
By the way, I THINK (so I can be wrong) that the call to setTime is used just by the other functions, not by the timer. So you can omit it. Moreover you missed the pinmode statement..
In the end.. Try this code and let us know.
#include <Time.h>
#include <TimeAlarms.h>
void setup()
{
Serial.begin(9600);
while (!Serial) ;
pinMode(10, OUTPUT);
Alarm.timerRepeat(15, Repeats);
}
void Repeats()
{
Serial.print("alarmed timer!");
digitalWrite(10,1);
}
void loop()
{
Alarm.delay(500);
}

Add Alarm.delay(0); this way your program won't freeze and your alarm will work...

Related

AC Dimmer EpS32

I have an application on to control ESP32 Light Dimmer from the temperature read from a temperature sensor. The rule is very simple, when my sensor reads the temperature of more than 27ºC the lamp should be turned off by the Dimmer. However, this is not happening.
What the code does is, when the system is turned on the lamp turns on and the temperature is read from time to time, but when the temperature exceeds 27ºC the dimmer does not turn off the lamp. I think it might be something I'm doing wrong in the zero_crosss_int routine, because when the temperature reaches its limit the message "TRIAC OFF" is displayed.
Below the code used.
#define ZERO_CROSS 2
#define DIMMER_CONTROL 4
int dimming=64;
float programedTemp = 27.0;
int halfDimming=128;
int maxDimming=64;
void power(void *parameters){
tempSensor.requestTemperaturesByIndex(0);
temp=tempSensor.getTempCByIndex(0);
if(temp<programedTemp){
dimming=maxDimming;
if(temp<(programedTemp-1.0)){
dimming=maxDimming;
} else if(temp<programedTemp){
dimming++;
}
} else if(temp>programedTemp+0.9){
dimming=128;
}else{
dimming=halfDimming;
}
delay(4000);
}
void zero_crosss_int() {
if(dimming>=128){
delayMicroseconds(8.333);
digitalWrite(DIMMER_CONTROL, LOW); // triac Off
Serial.println((String) "=====>>> TRIAC OFF <<<=====");
}else{
int dimtime = (65*dimming);
delayMicroseconds(dimtime); // Off cycle
digitalWrite(DIMMER_CONTROL, HIGH); // triac firing
delayMicroseconds(8.333);
digitalWrite(DIMMER_CONTROL, LOW); // triac Off
}
}
void setup() {
pinMode(DIMMER_CONTROL, OUTPUT);
pinMode(ZERO_CROSS, INPUT);
attachInterrupt(ZERO_CROSS, zero_crosss_int, RISING);
Serial.begin(115200);
xTaskCreatePinnedToCore(power,"controlDimm",10000,NULL,0,&mainsPower,0);
}
void loop() {
}
You're doing way too much in your interrupt handler. It's amazing that it isn't just crashing constantly... the only reason that's not happening is likely because you don't do anything in loop().
It's not safe to call most of the functions you're calling in the interrupt handler. Interrupt handlers need to run for as little time as possible - other interrupts may be locked out and they may interfere with the network stack and other housekeeping functions. You absolutely should not be calling delayMicroseconds() or any Serial methods in an interrupt handler, or spending any more time there than is absolutely necessary. Almost all ESP-IDF or Arduino Core functions are not safe to call from inside an interrupt handler - the interrupt handler may interrupt another call to them while they're in an inconsistent state, or may change hardware settings while they're in the middle of using that hardware.
Your code would be much better if you structured it like this:
volatile bool zero_crossing_flag = false;
void IRAM_ATTR zero_cross_int() {
zero_crossing_flag = true;
}
void loop() {
if(zero_crossing_flag) {
zero_crossing_flag = false;
if(dimming>=128){
delayMicroseconds(8.333);
digitalWrite(DIMMER_CONTROL, LOW); // triac Off
Serial.println((String) "=====>>> TRIAC OFF <<<=====");
}else{
int dimtime = (65*dimming);
delayMicroseconds(dimtime); // Off cycle
digitalWrite(DIMMER_CONTROL, HIGH); // triac firing
delayMicroseconds(8.333);
digitalWrite(DIMMER_CONTROL, LOW); // triac Off
}
}
}
The IRAM_ATTR attribute on zero_cross_int() tells the compiler that this code must always be available. If you write an interrupt handler without IRAM_ATTR it's basically luck if it executes properly.
Restructuring your code this way will probably not solve the problem you're asking about, but it will allow it to run in a stable, reproducible way, which it's unlikely to the way it's written now.
Use your ZCD input to generate an interrupt. In the ISR start a Timer which generates another interrupt within 0ms(Full power) to 10ms(completely off) of the ZCD interrupt.
I don't understand to Switch off the lamp why are you using TRIAC instead of a Relay.

Arduino interrupt returning unreliable values

I have a simple app to count water flux using a sensor that is equipped with a reed switch.
So the app should only count the number of times the switch closes.
My first code was:
const int sensorPin = 2;
volatile int counter = 0;
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), sensorISR, FALLING);
}
void loop() {
Serial.print("Counter: ");
Serial.println(counter);
}
void sensorISR() {
counter++;
}
And once a bottle of 20 liters was full the counter would show something like 120.
Then I changed the code as follows:
const int sensorPin = 2;
volatile int counter = 0;
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(sensorPin), sensorISR, FALLING);
}
void loop() { }
void sensorISR() {
counter++;
Serial.print("Counter: ");
Serial.println(counter);
}
And counter went down to 40 (using the same 20 liters bottle).
The count should be 20L but that is not my problem as it results from bouncing of the reed switch (I will address that latter).
As the project will have 3 sensors and 3 ISRoutines I wonder why putting the Serial.print() command into the main loop can result in such strange results.
Thanks
Paulo
Serial print statements rely on interrupts that are disabled during your ISR. So Serial.print statements don't belong in an ISR.
The reason your count went down is that now your ISR takes longer to execute and it covers up some of the bounce. There are innumerable tutorials on how to debounce something with an Arduino. You can surely find one.
The two easiest are to use a capacitor between the pin and ground for a hardware debounce or to just use millis or micros to note the time that an interrupt occurs and ignore any interrupts that occur within some small time of that.

Can't use two SPI devices at the same time

I can use the MFRC522 using the following code:
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
And it works great. I can also use the dot-matrix (8x8) using the following code:
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
void setup() {
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
}
And it works just fine as well. However, when I try to use both of them using the following code:
#include <SPI.h>
#include <MFRC522.h>
#include "LedControl.h"
LedControl lc = LedControl(12,11,8,1);
MFRC522 mfrc522(10, 9);
void setup() {
SPI.begin();
mfrc522.PCD_Init();
lc.shutdown(0,false);
lc.setIntensity(0,3);
lc.clearDisplay(0);
lc.setLed(0,2,5,true);
lc.setLed(0,5,5,true);
lc.setLed(0,2,2,true);
lc.setLed(0,3,1,true);
lc.setLed(0,4,1,true);
lc.setLed(0,5,2,true);
}
void loop() {
if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
// Do stuff
}
}
In that case only one of them works (the MFRC522). I know that since they are connected in SPI mode they need to have different SS pins, so I used pin 10 for MFRC522 and pin 8 for dot-matrix. So, what's wrong? Why dot-matrix doesn't work at the same code with MFRC522??
Without the datasheets at hand, I'd first suspect that the two SPI devices have clock rates that are incompatible. You need to find the clock rates for each one and either clock them off two different timers, or switch timing on a single timer to provide the correct clock rate for the currently selected device. Incompatible clock rates has been the only problem I've ever had with SPI devices.

Out of time Timer5 interrupt Arduino

I have this code , I try to restart Timer5 when it out of time. But i can't, may you help me ?
#include <TimerFive.h>
#include <TimerOne.h>
#include <openGLCD.h>
#define OLDWAY
unsigned long timer5_started=0;
void setup() {
Serial.begin(9600);
Timer1.stop();
Timer1.detachInterrupt();
Timer1.initialize(500000);
Timer1.attachInterrupt(Timer1Handle);
Timer1.start();
Timer5.stop();
Timer5.detachInterrupt(); //detach interrupt
Timer5.initialize(100000);
Timer5.attachInterrupt(Timer5Handle);
Timer5.start();
///---
}
void loop() {
while(1){
Serial.println("loop...");
delay(500);
}
}
void Timer5Handle(){
timer5_started=millis();
Serial.println("timer 5...");
while(1){
int a=0;
}
}
void Timer1Handle(){
if(millis()-timer5_started>100000){
Serial.println("restart...");
Timer5.restart();
}
}
When Timer5 out of time, the Interupt is stop, how can i restart it ?
When Timer5 out of time, the Interupt is stop, how can i restart it ?
Well, I don't even understand what are you trying to do in that interrupt handler:
void Timer5Handle(){
timer5_started=millis();
Serial.println("timer 5...");
while(1){
int a=0;
}
}
However your interrupt handler is called in actual IRS, so everything else stops including all other Interrupts (including millis counting and delays). And because of infinite loop, it's forever. Interrupt handler should be as short as possible to ensure others are not missed or so.

I2C onReceive-handler called only once

I'm having trouble communicating between Arduino's over I2C. For some reason, the onReceive handler is only called once.
Master Code (sender):
#include <Wire.h>
#include "i2csettings.h" // defines address
void setup()
{
Wire.begin(I2C_MASTER_ADDRESS);
}
void loop()
{
Wire.beginTransmission(I2C_SLAVE_ADDRESS);
Wire.write(0x11);
Wire.endTransmission();
delay(1000);
}
Slave Code (receiver):
#include <Wire.h>
#include "i2csettings.h"
void takeAction(int);
void setup()
{
Serial.begin(9600);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(takeAction);
}
void loop()
{}
void takeAction(int nBytes)
{
Serial.println("Action!");
}
The idea in this test-setup is to have the sender send a byte every second, and let the receiver act on this by printing a message. However, the message is only printed once. When I reset the Slave, it's printed again, but just once.
Any ideas where this may come from?
You have to make sure you read all the bytes from the stream.
Other wise it seems to block.
Make your event handler look like this. So you can call it multiple times.
void takeAction(int nBytes)
{
Serial.println("Action!");
while(Wire.available())
{
Wire.read();
}
return;
}

Resources