Hi all,
glad to be part of this community. I am very new to arduino and I need the support of you guy.
In an experiment that I am creating, I want a vibrator motor to turn on for 2 sec randomly within every 20 s window for 12 hr (from 8Pm to 8am). Aside from an arduino, I have a DS3231 RTC module. Indeed initially, I was planning to use code in which I define several time for the motor to be on and off (but it would require me to define 2160 values) ..... but there must be something quicker that I am not aware of.
The help of a senior arduino expert woudl much appreciate.
Thank you
What exactly does this mean? Do you want the motor is always turned on in each period sometimes running from say a start at 5 seconds and end end at 7 and in another period a start at 14 seconds and end at 16 seconds? Or do you mean that in each period the motor is randomly either turned on or left off ?
Have you written any code so far? Can you read the rtc and run the motor?
Dear cattledog thank you to get back to me.
For example during the first 20 s I would it like to be from the 7th sec to the 9th, during the following 20s interval from the first to the third and so on with a random pattern. The remeaing 18s of each 20s intervals the motor need to be off. As mentioned before, I managed to have the rtc and motor to run but then I realised that it would be to long to achieve what I want to do with those statements.
This is the code that I have but it is not random and I would have to define 2160 time the on and off periods
int motor = 3;
DS3231 rtc(SDA, SCL);
Time t;
const int OnHour1 = 17; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin1 = 50;
const int OnSec1 = 00;
const int OffHour1 = 17; //SET TIME TO OFF RELAY
const int OffMin1 = 50;
const int OffSec1 = 10;
const int OnHour2 = 17; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin2 = 50;
const int OnSec2 = 15;
const int OffHour2 = 17; //SET TIME TO OFF RELAY
const int OffMin2 = 50;
const int OffSec2 = 20;
You should post code by using code-tags. There are two simple ways to do this.
First way is to click on the code tags icon at the top of the posting window
Another wasy is to use an automatic function for doing this in the Arduino-IDE.
Three steps
1)press Ctrl-T for autoformatting your code
2)do a rightclick with the mouse and choose "copy for forum"
3)paste clipboard into write-window of a posting
The more that I read the more it make me think that I need to use the random function. I found this which could be very interesting. I need to figure out how to include this loop in the RTC code
int randNumber;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // turn the LED on/off
randNumber = random(1, 500);
delay(randNumber); // wait
}
Use the RTC to determine whether you're in the hours when the system is active.
Use millis to time twenty second periods. At the beginning of each, use random to see which second to turn on. Two seconds later, turn off.
Here's some example code to help demonstrate that idea. It is typical delayed start timing code but with a random period. The example uses delay for the two second on/off timing. If other elements in the code can't tolerate the use of delay(), then it will need to be reworked so that the on off timing period does not block. A state machine could be used.
boolean onDelayTiming = false;
unsigned long onDelay;
unsigned long timingStart;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(115200);
randomSeed(analogRead(A1));
Serial.println("Starting");
}
void loop()
{
static unsigned long lastTime;
if (millis() - lastTime >= 20000ul)
{
lastTime = millis();
Serial.println("new 20 second period");
timingStart = millis();
onDelay = (1000ul * random(0 - 18));
Serial.print("Two second pulse in ");
Serial.print(onDelay / 1000);
Serial.println(" seconds");
onDelayTiming = true;
}
if (onDelayTiming == true and millis() - timingStart >= onDelay)
{
onDelayTiming = false;
Serial.print("on...");
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(13, LOW);
Serial.println("off");
}
}
See if you can work this on/off timing into your rtc enabled periods.
I have tried the code and it works perfectly.
I have tried to implement it without success.
My goal is to deliver the signal to the motor only between 8 pm to 8 am.
I have tried to use the code that I include here (see above) but it does not work. The motor is always on. I have a DS3231 module which is recognised by the Arduino board. I am not able to get around it. Would alarmtime be aq way to go?
boolean onDelayTiming = false;
unsigned long onDelay;
unsigned long timingStart;
//#include <alarms.h>
#include <Time.h>
#include <Wire.h>
#include <DS3231.h>
DS3231 rtc (SDA,SCL); // Init the DS3231 using the hardware interface
Time t; // Init a Time-data structure
const int OnHour1 = 13; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin1 = 30;
const int OnSec1 = 00;
const int OffHour1 = 13; //SET TIME TO OFF RELAY
const int OffMin1 = 45;
const int OffSec1 = 10;
void setup()
{
pinMode(13, OUTPUT); // set on pin 13
Serial.begin(115200);
randomSeed(analogRead(A1));
Serial.println("Starting");
rtc.begin();
}
void loop()
{ t = rtc.getTime();
Serial.print(t.hour);
Serial.print(" hour(s), ");
Serial.print(t.min);
Serial.print(" minute(s)");
Serial.print(t.sec);
Serial.print(" second(s)");
Serial.println(" ");
if(t.hour == OnHour1 && t.min == OnMin1 && t.sec == OnSec1) {
static unsigned long lastTime;
if (millis() - lastTime >= 20000ul)
{
lastTime = millis();
Serial.println("New 20 second period");
timingStart = millis();
onDelay = (1000ul * random(0 - 18));
Serial.print(" Two second pulse in ");
Serial.print(onDelay / 1000);
Serial.println(" seconds");
onDelayTiming = true;
}
if (onDelayTiming == true and millis() - timingStart >= onDelay)
{
onDelayTiming = false;
Serial.print(" Vibration on...");
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(13, LOW);
Serial.println("Vibration off");
}
else if (t.hour == OnHour1 && t.min == OnMin1 && t.sec == OnSec1)
{
digitalWrite(13, LOW);
}
}
}
I'm not certain your conditional brackets are correct
I would separate the global time conditions for the activation period and use a new boolean variable enableCycle. This variable will control the 20 second on/off cycle.
I would not use seconds in the enabled/disabled control. You could miss an exact second, and minutes should be fine enough for the global control.
boolean onDelayTiming = false;
unsigned long onDelay;
unsigned long timingStart;
boolean cycleEnabled = false; //add new variable
//#include <alarms.h>
#include <Time.h>
#include <Wire.h>
#include <DS3231.h>
DS3231 rtc(SDA, SCL); // Init the DS3231 using the hardware interface
Time t; // Init a Time-data structure
const int OnHour1 = 13; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin1 = 30;
//const int OnSec1 = 00;
const int OffHour1 = 13; //SET TIME TO OFF RELAY
const int OffMin1 = 45;
//const int OffSec1 = 10;
void setup()
{
pinMode(13, OUTPUT); // set on pin 13
Serial.begin(115200);
randomSeed(analogRead(A1));
Serial.println("Starting");
rtc.begin();
}
void loop()
{
t = rtc.getTime();
Serial.print(t.hour);
Serial.print(" hour(s), ");
Serial.print(t.min);
Serial.print(" minute(s)");
Serial.print(t.sec);
Serial.print(" second(s)");
Serial.println(" ");
if (t.hour == OnHour1 && t.min == OnMin1)
{
cycleEnabled = true;
}
else if (t.hour == OffHour1 && t.min == OffMin1)
{
cycledEnabled = false;
}
//if (t.hour == OnHour1 && t.min == OnMin1 && t.sec == OnSec1)
if (cycleEnabled)
{
static unsigned long lastTime;
if (millis() - lastTime >= 20000ul)
{
lastTime = millis();
Serial.println("New 20 second period");
timingStart = millis();
onDelay = (1000ul * random(0 - 18));
Serial.print(" Two second pulse in ");
Serial.print(onDelay / 1000);
Serial.println(" seconds");
onDelayTiming = true;
}
if (onDelayTiming == true and millis() - timingStart >= onDelay)
{
onDelayTiming = false;
Serial.print(" Vibration on...");
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(13, LOW);
Serial.println("Vibration off");
}
} //add bracket here
//else if (t.hour == OnHour1 && t.min == OnMin1 && t.sec == OnSec1)
else //cycleEnabled = false
{
digitalWrite(13, LOW);
}
//}
}