Hi, I want to use Arduino as a function generator to output square wave. For example, it could output 1V 0.5Hz square wave for 1 hour and then stop for 1 hour, and then run for 1 hour ( and stop for 1 hour), repeat this circle for 24 hours.
I was wondering if anyone can help me to finish this code, especially about the circling part, at least give me a direction to learn?
Too slow for tone() function, you can have a faster blink without delay running inside a faster blink without delay.
So maybe something like this.
unsigned long toneTimer;
unsigned long durationTimer;
unsigned long oneHour = 3600000; // 1000ms x 60 sec/min x 60 min/hr
unsigned long halfPeriod = 250; // one-fourth second
byte rumblePin = 2;
byte running = 1;
byte toneState = 0;
void setup(){
pinMode (rumblePin, OUTPUT);
}
void loop(){
currentTime = millis();
if ( (currentTime - durationTimer) >= oneHour ){ // change running state
running = 1 - running; // result is 1, 0, 1, 0
durationTimer = currentTime; // sets up next running state
}
if (running ==1){
if (currentTime - toneTimer >= halfPeriod){
toneState = 1 - toneState; // result is 1, 0, 1, 0,
digitalWrite (rumblePin, toneState);
toneTimer = currentTime ; // sets up next toneState change
}
// do other stuff while those are trundling along keeping an eye on millis() for you.
}
#include "squareWave.h"
#include "blinker.h"
// First we start with creating a swithced waveform class out if the Legos we have avalible.
//
// switchedWave is a low frequency square wave that switches on and off a higher frequency
// square wave that outputs on a digital pin.
//
// In the constructor you pass in..
// pin number for the resultant output wave form.
// The high freqency pulse width in ms
// The high freqency period in ms (high time + low time)
// The low freqency pulse width in ms
// The low freqency period in ms
//
// You start and stop the process by calling
// setOnOff() with true or false for on & off.
//
class switchedWave : public squareWave {
public:
switchedWave(int pin,float hfPulse,float hfPeriod,float lfPulse,float lfPeriod);
virtual ~switchedWave(void);
virtual void pulseOn(void);
virtual void pulseOff(void);
blinker* hfWave;
};
// Contructor.
switchedWave::switchedWave(int pin,float hfPulse,float hfPeriod,float lfPulse,float lfPeriod)
: squareWave(lfPeriod,lfPulse) { hfWave = new blinker(pin,hfPulse,hfPeriod); }
// Destructor.
switchedWave::~switchedWave(void) { if (hfWave) delete(hfWave); }
// When LF pulse goes high, we tuen the HF waveform on.
void switchedWave::pulseOn(void) { hfWave->setOnOff(true); }
// When LF pulse goes high, we tuen the HF waveform off.
void switchedWave::pulseOff(void) { hfWave->setOnOff(false); }
// ***********************
// Sketch starts here.
// ***********************
// Create a switched wave object.
switchedWave ourWave(13,250,500,10000,20000); // This gives 20 blinks for 10 seconds then 10 seconds with no blinks.
// For and hour on and an hour off try (13,250,500,3600000,7200000);
// 7,200,000 * 1000 = 7,200,000,000 microseconds.. Hmm I wonder if that's to many?
// In setup() switch it on.
void setup() {
ourWave.setOnOff(true); // Fire it up.
}
// Call idle in loop(). Anything that runs in the background
// uses this. switchedWave would be one of those things.
void loop() {
idle(); // Let me all have some idle time.
}
Of course you'll need to grab LC_baseTools from the library manager. It has the bits that you use to put this together.
johnwasser:
This sets the output pin HIGH for half of each second during odd-numbered hours.
void loop()
{
unsigned long currentMillis = millis();
unsigned long current_hour = currentMillis / (1000UL * 60UL * 60UL);
unsigned long current_half_second = currentMillis / 500;
// Turn on output only if hour and half_second are both EVEN numbers.
if ((current_hour & 1) == 0 && (current_half_second & 1) == 0)
digitalWrite(OutputPin, HIGH);
else
digitalWrite(OutputPin, LOW);
}
I too wanted to stop my program after 1 hour or else.
Can I use this code but note that my program already use Millis(:))
Save the value of millis() when the program starts and set a boolean to true. Do this in setup(). Run the code in loop() only when the boolean is true. At the end of loop() test whether 1 hour has passed by subtracting the start time from the time now and if so, set the boolean to false and save the start time. When another hour has passed change the boolean to true
UKHeliBob:
Save the value of millis() when the program starts and set a boolean to true. Do this in setup(). Run the code in loop() only when the boolean is true. At the end of loop() test whether 1 hour has passed by subtracting the start time from the time now and if so, set the boolean to false and save the start time. When another hour has passed change the boolean to true
bool running = false;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
unsigned long period = 2000;
unsigned long periodx = 30000;
int ledPin1 = 10;
int ledPin2 = 12;//using the built in LED
int ledPin4 = 13;
byte count = 0;
int led1_State = LOW;
int led2_State = LOW;
void setup() {
// pinMode(LEDpin, OUTPUT);
//digitalWrite(LEDpin, HIGH);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
startMillis = millis();
running = true;
//pinMode(switchPin, INPUT);
//digitalWrite(switchPin, HIGH); // turn on pullup resistor
}
void loop() {
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (running == true){
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
//increment a counter variable: 0 => 1 => 2 => 3
count++;
//When the counter reaches 4, reset back to 0.
if(count == 4){
count = 0;
}
switch (count) {
case 0:
led1_State = HIGH;
period = 300;// or whatever delay you want for this cycle
break;
case 1:
led2_State = LOW;
period = 300; // 200ms added // or whatever delay you want for this cycle
break;
case 2:
led2_State = HIGH;
period = 300; // or whatever delay you want for this cycle
break;
case 3:
led1_State = LOW;
period = 300; // 200ms added // or whatever delay you want for this cycle
break;
}
digitalWrite(ledPin1, led1_State);
digitalWrite(ledPin2, led2_State);
startMillis = currentMillis;
}
}
if (currentMillis - startMillis >= periodx){
running == false;
digitalWrite(ledPin1, led1_State);
digitalWrite(ledPin2, led2_State);
startMillis = currentMillis;
}
}
i used bool variable but not worked with this code. i tried for 30 seconds to test it.
pcbbc:
You must use a separate variable for “startMillis” in your second timer from the first one.
This...
running == false;
Is a comparison, not an assignment.
Assignment is a single = sign.
To alternate between ON and OFF each hour you need to invert the state of running....
running = !running;
ok thank you i am done after using separate startmillis.
and i wanted to just stop after the required duration not to repeat after.
Actually i started my request for help in this topic not created by me but someone else requesting for 1 hiur duration and i was looking for the same
so my job is done with this thank you again now millis(:D)
pcbbc:
You must use a separate variable for “startMillis” in your second timer from the first one.
bool running = false;
unsigned long startMillis;
unsigned long startMillis2;
//some global variables available anywhere in the program
unsigned long currentMillis;
unsigned long period = 2000;
unsigned long periodx = 30000;
int ledPin1 = 10;
int ledPin2 = 12;//using the built in LED
int ledPin4 = 13;
byte count = 0;
int led1_State = LOW;
int led2_State = LOW;
void setup() {
// pinMode(LEDpin, OUTPUT);
//digitalWrite(LEDpin, HIGH);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
startMillis = millis();
startMillis2 = millis();
running = true;
//pinMode(switchPin, INPUT);
//digitalWrite(switchPin, HIGH); // turn on pullup resistor
}
void loop() {
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (running == true){
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
//increment a counter variable: 0 => 1 => 2 => 3
count++;
//When the counter reaches 4, reset back to 0.
if(count == 4){
count = 0;
}
switch (count) {
case 0:
led1_State = HIGH;
period = 300;// or whatever delay you want for this cycle
break;
case 1:
led2_State = LOW;
period = 300; // 200ms added // or whatever delay you want for this cycle
break;
case 2:
led2_State = HIGH;
period = 300; // or whatever delay you want for this cycle
break;
case 3:
led1_State = LOW;
period = 300; // 200ms added // or whatever delay you want for this cycle
break;
}
digitalWrite(ledPin1, led1_State);
digitalWrite(ledPin2, led2_State);
startMillis2 = currentMillis;
}
}
if (currentMillis - startMillis >= periodx){
running = false;
digitalWrite(ledPin1, led1_State);
digitalWrite(ledPin2, led2_State);
startMillis2 = currentMillis;
}
}
@pcbbc
I tried worked but program stops 10secs earlier
Instead of complete 30 secs. I used this code and corrected it see above
pcbbc:
Ooops. You forgot to change this “startMillis”...
if (currentMillis - startMillis >= periodx){
const int ledPin1 = 10; // PCBBC suggestion
const int ledPin2 = 11;
const int ledPin3 = 12;
const int ledPin4 = 13; // the pin numbers for the LEDs
int Reset = 4;
int Received = 0;
int count = 0;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long startMillis2;
unsigned long currentMillis;
unsigned long period = 3000; // number of millisecs that Motor is OFF
unsigned long periodx = 30000;
//------- VARIABLES (will change)
byte led1_State = LOW; // used to record whether the LEDs are on or off
byte led2_State = LOW; // LOW = off
byte led3_State = LOW;
byte led4_State = LOW; // so that it can be activated (HIGH)by digitalWrite
bool running = false;
//=====
void setup() {
Serial.begin(9600);
//Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
//------- set the Led pins as output:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
startMillis = millis(); //initial start time
startMillis2 = millis();
running = true;
//=====
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin4, HIGH); // deenergise relay to save power when microcontroller is powered ON.
digitalWrite(ledPin3, HIGH); // deenergise to enable manual mode as default.
digitalWrite(Reset, HIGH); // as my relay is ACTIVE LOW.
delay(200);
pinMode(Reset, OUTPUT);
Serial.println("wait");
}
//=====
void loop() {
if (Serial.available()>0){
Received = Serial.read();
}
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (running == true){
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
//increment a counter variable: 0 => 1 => 2 => 3
count++;
//When the counter reaches 4, reset back to 0.
if(count == 4){
count = 0;
}
switch (count) {
case 0:
led1_State = HIGH;
period = 3000; // or whatever delay you want for this cycle
break;
case 1:
led2_State = LOW;
period = 2200; // 200ms added // or whatever delay you want for this cycle
break;
case 2:
led2_State = HIGH;
period = 3000; // or whatever delay you want for this cycle
break;
case 3:
led1_State = LOW;
period = 2200; // 200ms added // or whatever delay you want for this cycle
break;
}
//digitalWrite(ledPin1, led1_State);
//digitalWrite(ledPin2, led2_State);
startMillis = currentMillis;
}
}
if (currentMillis - startMillis2 >= periodx){
running = false;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
startMillis2 = currentMillis;
}
if (Received == 'd'){
led3_State = LOW; // to enable device mode.
led4_State = LOW;
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
}
if (Received == 'b'){
led3_State = HIGH;
led4_State = HIGH;
led1_State = HIGH;
led2_State = HIGH;
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
// digitalWrite(Reset, LOW);
//digitalWrite(Reset, HIGH);
}
if (Received == '1'){
// this is the code that actually switches the LEDs on and off
digitalWrite(ledPin1, led1_State);
digitalWrite(ledPin2, led2_State);
// digitalWrite(ledPin3, led3_State);
// digitalWrite(ledPin4, led4_State);
}
else if(Received == 'a'){
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH); // if not received anything keep all HIGH
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH); //to deenergise relays being Active LOW.
}
//-------- Program Reset both android app and arduino program.
if (Received == '9'){
Serial.println("wait");
digitalWrite(Reset, LOW);
digitalWrite(Reset, HIGH);
delay(200);
}
}//===END===\\
yes the code works fine in simple led blink code with switch case but here in the above code (my original code)
it does not work at all.
do find issue with this otherwise your suggestions work good.