switch(mode) {
case 0:
if (millis() - timer >= 100) {
file.play();
timer = millis();
}
break;
case 1:
if (millis() - timer >= 1000) {
file1.play();
timer = millis();
}
break;
}
I want create a time-based program like a traffic light.
It will play the sound and last 3 seconds. After 3 second, it will turn into another sound and last 10 seconds.After 10 second, it will turn into first sound. And so on. How can i count the time for two case?
The conditions you use to compare millis() and timer look of in terms of logic. You might want to change the values to be 3 and 10 seconds (instead of 0.1 and 1 seconds)
It feels like you simply need 3 states:
It will play the sound and last 3 seconds.
After 3 second, it will turn into another sound and last 10 seconds
After 10 second, it will turn into first sound.
Something like this:
int mode;
int timer;
void setup() {
println("starting in 1st mode, seconds:",second());
}
void draw() {
switch(mode) {
case 0:
if (millis() - timer >= 3000) {
println("play sound 1, seconds:",second());
timer = millis();
mode = 1;//change to the state to the next one
}
break;
case 1:
if (millis() - timer >= 3000) {
print("play sound 2, seconds:",second());
timer = millis();
mode = 2;//go to next mode
}
break;
case 2:
if (millis() - timer >= 10000) {//wait 10s
println("\n10s passed, going to 1st mode, seconds:",second());
timer = millis();
mode = 0;//go to next mode, after 10s
}
break;
}
}
In terms of timing, you should have states looping in 3s, 3s and 10s increments.
I'm not 100% if sound will play as expected, but test with some println() commands first to see if what state happens at what time you expect it to, then simply trigger the sound you need in it's right place.
demo time:
var mode = 0;
var timer;
function setup() {
createCanvas(100,100);
timer = millis()
console.log("starting in 1st mode, seconds:",second());
}
function draw() {
background(255);
text("mode: " + mode + "\nseconds: " + second(),10,10);
switch(mode) {
case 0:
if (millis() - timer >= 3000) {
console.log("play sound 1, seconds:",second());
timer = millis();
mode = 1;//change to the state to the next one
}
break;
case 1:
if (millis() - timer >= 3000) {
console.log("play sound 2, seconds:",second());
timer = millis();
mode = 2;//go to next mode
}
break;
case 2:
if (millis() - timer >= 10000) {//wait 10s
console.log("10s passed, going to 1st mode, seconds:",second());
timer = millis();
mode = 0;//go to next mode, after 10s
}
break;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.5/p5.min.js"></script>
Related
It's my first time learning arduino uno and I do not know what to do
const int ledPin = LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
for(int interval = 500; interval >= 20; interval++)
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
The delay for every interval the led turns On and Off increases by 1 seconds everytime the loop restarts.
Please make sure you ask your question in the question itself, not the title and also give us some more information about what you're trying to accomplish, what's working and what isn't working so we can help.
If I understand correctly, you want the LED to stay on longer and longer each time it blinks. First cycle 1 second, second cycle 2 seconds, third cycle 3 seconds, etc. You are pretty close, just need some tweaking of your logic.
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) { //Check if LED duration has expired
//Toggle LED
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
interval += 1000; //Increase the interval by 1 second
digitalWrite(ledPin, ledState); //Set the LED
previousMillis = currentMillis; //Set the time of the last transition to now
}
}
I want to write a function to let labels in the GUI fade in. I use a for loop. Each step in that loop i set the color values of that label higher. After each step i have a time delay of 200 milliseconds.
The following code works, except that the changes in label-color are only visible after the loop is done.
```
void fade(System::Windows::Forms::Label^ label) {
for (int i = 0; i < 10; i++) {
label->ForeColor = System::Drawing::Color::FromArgb(0, (i + 1) * 20, 0);
Sleep(200); // milliseconds
}
}
```
Is there a way to force the GUI to show changes immediately?
Or is there another way to let labels fade in?
label->Update(); did the trick. Thank you very much Hans.
void fade(System::Windows::Forms::Label^ label) {
for (int i = 0; i < 100; i++) {
label->ForeColor = System::Drawing::Color::FromArgb(0, (i + 1) * 2, 0);
Sleep(1); // milliseconds
label->Update();
}
}
#include "mbed.h"
Timeout flipper;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
void flip()
{
led2 = !led2;
}
int main()
{
led2 = 1;
flipper.attach(&flip, 2.0); // setup flipper to call flip after 2 seconds
// spin in a main loop. flipper will interrupt it to call flip
while (1) {
led1 = !led1;
ThisThread::sleep_for(200);
}
}
With this code, is it possible to vary the amount of time the Timeout flipper will be attached for so it could start at 2 seconds, then 3 then 4 etc? And how?
I am working on an Arduino stopwatch, where it needs a start, stop, and reset button. To reset it, I am using a variable called starttime that is updated to equal to millis(), and then take the difference to display time. However, past thirty seconds, the starttime does not update correctly, and the resulting difference between starttime and millis() is equivalent to 65 seconds. Can someone explain why this is happening?
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int start = 8;
const int stp = 9;
const int reset = 10;
int seconds;
int minutes;
int timedif;
int starttime = -1;
int timestall = 0;
bool onoff = true;
void setup()
{
pinMode(start, INPUT);
pinMode(stp, INPUT);
pinMode(reset, INPUT);
lcd.begin(16, 2); //Initialize the 16x2 LCD
lcd.clear(); //Clear any old data displayed on the LCD
Serial.begin(9600);
}
void loop()
{
int bsta = digitalRead(start);//sees if start switch is pressed
int bstp = digitalRead(stp);//records if stop switch is pressed
int bres = digitalRead(reset);//records if reset switch is pressed
lcd.setCursor(0,0);
lcd.print("Stopwatch");//prints stopwatch top row
lcd.setCursor(0,1);
if (starttime == -1) { //if running first time, time dif is initiated
starttime = millis();
}
timedif = (millis() - starttime )/1000 + timestall; //will get difference in terms of seconds
minutes = floor(timedif/60); // divides by sixty, drops decimal
seconds = timedif%60; //gets remainder of divided by 60
lcd.print(minutes);
lcd.print(":");
lcd.print(seconds);
if (seconds < 10) {
lcd.setCursor(3,1);
lcd.print(' ');
}
if (bstp == HIGH) {
onoff = false;
while(onoff == false) {
if (digitalRead(start) == HIGH) {
onoff = true;
}
}
timestall = timedif;
starttime = millis();
}
if (bres == HIGH) {
delay(100);
timestall = 0;
starttime = millis();
timedif = 0;
lcd.clear();
Serial.println("stall:");
Serial.println(timestall);
Serial.println("dif");
Serial.println(timedif);
Serial.println("start");
Serial.println(millis() - starttime);
}
}
You should use long or unsigned long instead if int to declare variables that hold time values.
A int variable can only hold 32,767 millisecond hence the 32 sec. where a long variable can hold 2,147,483,647 millisecond which is something like 48 days. A unsigned long can hold double of that but can not hold a negative value.
Excuse my ignorance, but I ran into a problem that turned out to be challenging for my current knowledge in programming with Processing, even though the idea is quite simple. You see, I need to add 1 unit to a variable every 10 seconds. This is the code:
int i = 0;
void setup()
{
frameRate(60);
}
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
i++;
} else {}
System.out.println("-------------------------------\n" +
"Timer: " + time + "\n"
+ "Adding 1 every 10 seconds: : " + i + "\n"
+ "-------------------------------");
}
The problem is that because draw() loops 60 times per second, as soon as time reaches 9 the second it last makes the if statement to be executed 60 times and it ends adding 60 to i every 10 seconds and I just need to be adding 1.
I tried to apply some kind of algorithm that subtracts the unnecessary numbers as they increase like so:
int i = 1;
int toSubstract = 0; //Variable for algorithm
void setup()
{
frameRate(60);
}
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
i++;
algToSubstract();
} else {}
System.out.println("-------------------------------\n" +
"Timer: " + time + "\n"
+ "Adding 1 every 10 seconds: : " + i + "\n"
+ "-------------------------------");
}
void algToSubstract() //<--- This is the algorithm
{
i = i - toSubstract;
toSubstract++;
if (toSubstract > 59)
{
toSubstract = 0;
} else {}
}
...but I couldn't make it work. The idea was something like this:
time reaches 9, if statement executes, i = 1 and toSubstract = 0.
i increases 1 so i = 2.
i = i - toSusbract (i = 2 - 0 so i = 2).
toSusbract increases 1 so toSusbract = 1.
i increases 1 so i = 3.
i = i - toSusbract (i = 3 - 1 so i = 2).
toSusbract increases 1 so toSusbract = 2.
... Process continues...
toSubstract gets bigger than 59 so it is restarted to 0.
time stops being 9.
The other answers are fine general approaches, but they don't take advantage of the features that Processing provides for you.
For example, you could use the frameCount variable to check how many frames have elapsed. Since draw() is called 60 times per second, 10 seconds is 600 frames. Something like this:
void draw(){
if(frameCount % 600 == 0){
// 10 seconds has elapsed
}
}
Another way to do this is to store the last time 10 seconds elapsed, and then check that against the current time to see if 10 seconds has elapsed since then. Something like this:
int previousTime = 0;
void draw(){
if(millis() > previousTime + 10*1000){
// 10 seconds has elapsed
previousTime = millis();
}
}
More info can be found in the reference.
Ringo has a solution that's perfectly fine.
Another way you can do this easily is:
bool addOnce = false;
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
if(!addOnce) {
addOnce = true;
i++;
}
} else { addOnce = false; }
}
As long as time == 9, we'll only get through if(!addOnce) one time.
After it changes, we reset the flag.
You could store the last number of seconds in a static (or global) variable, and only increment i when the current number of seconds is higher than the oldsecs
void draw() {
static int oldsecs = 0;
int secs = millis() / 1000;
if (secs > oldsecs) {
i++;
oldsecs = secs;
}
...
Assuming the language is C, and the int type is not overflowed by the number of seconds.