Hello i-m looking for a way to make lets say an LED to turn on wen it sees an input state change ( low to high). More exactly i want the led to turn on after a preset duration ( in ms) and stay on for an preset duration ( in ms).
Hello oracol
Take a view here to gain the knowledge.
Write out (for yourself), a simple flow of how and when the code moves through different states.
While you could implement a ‘state machine’, it’s not really necessary yet - but will help you draft out what needs to be detected, and done in your project.
as you move forward, post your best efforts, let us know what works and what doesn’t- maybe we can push you forward.
I think it will boil down to a (simple) state machine. After all, you will have a few states as you already indicated
(( yeah, I didn’t want to scare him off ! ))
As a simple project, it’s a really good starting point as well as non blocking techniques…
here is a peace of code that i'm struggling with , no mater what value i put the output goes to high as son as the input goes to high with no delay. (stpDlay supposed to be the delay between the input high state and the output high state )
unsigned long stampOfftime; // variable to store the time
unsigned long valv_1State = 0; // varible to store the state
unsigned long sensor_1State = 0; // variable to store the state
unsigned long peviosStampMillis; //varoable to store the time
int lastsensor_1State = 0; // variable to store the state
unsigned long stpDlay ; // variable to store the time set
unsigned long stpAct; // varible to store the time set
const int VALVE_1 = 15; // output
const int SENSOR_1 = A9; // input
void setup() {
pinMode(SENSOR_1, INPUT); // declare the tipe of IO
pinMode(VALVE_1, OUTPUT); // declare the tipe of IO
digitalWrite(VALVE_1, LOW); // start with the valve off
}
void loop() {
stpDlay = 1000; // time to delay the activation of the valv after the sensor is activated HIGH
stpAct = 500; // time for the valve to stay active (HIGH)
if (millis()>= stampOfftime) //ceking the state of the stamp valve to determin if is low and if not to pul it low if the time pased
{
digitalWrite(VALVE_1, LOW); // puul the vlve low
valv_1State = false; //set the state of the valve
}
sensor_1State = digitalRead(SENSOR_1); //read the input from the sensor
if (sensor_1State != lastsensor_1State) // if sensor state changed go forward with the next comand
{
lastsensor_1State = sensor_1State; //save the state
if (sensor_1State == HIGH ) // if the sensor is activated go forward wit the code to activate output depanding on the delays neded
{
if (millis() - peviosStampMillis >= stpDlay) // if time pased (stpDlay) from the state chage of the sensor then pull high the output
{
peviosStampMillis = millis(); // here we update the time sored
valv_1State = !valv_1State; // here we note the valve state change
//delay(stpDlay); // with delay works fine but holds the rest of the code
digitalWrite(VALVE_1, HIGH); // here we pull high the output
valv_1State = true; // change the state of the output
stampOfftime = millis() + stpAct; // here we update the time
//delay(stpAct); // this delay worked fine but do not want to use delay
}
}
}
}
- check for the input condition to go HIGH (no need to debounce)
- use delay() to wait to turn the led on
- use delay() to wait to the turn the led off
of course there are more sophisticated ways to do this when doing other things
I don't want to use delay because i have other senors monitoring at the same time and delay will stop the code for the delay time. Everything else works fine only have issue with the fact that i can not make it work to wait a set time before activate the output wen a input is detected.
sorry, i just read the description, not the title
const byte ButPin = A1;
const byte LedPin = LED_BUILTIN;
byte butState;
int state = 0;
unsigned long msecPeriod;
unsigned long msecLst;
enum { Off = HIGH, On = LOW };
// -----------------------------------------------------------------------------
void
loop (void)
{
unsigned long msec = millis ();
if (state && msec - msecLst > msecPeriod) {
Serial.print (" tmr ");
Serial.println (state);
if (1 == state) {
digitalWrite (LedPin, On);
state = 2;
msecPeriod = 2000;
msecLst = msec;
}
else if (2 == state) {
digitalWrite (LedPin, Off);
state = 0;
}
}
byte but = digitalRead (ButPin);
if (butState != but) {
butState = but;
delay (20); // debounce
Serial.println ("but");
if (LOW == but) {
state = 1;
msecPeriod = 1000;
msecLst = msec;
}
}
}
void
setup (void)
{
Serial.begin (9600);
pinMode (LedPin, OUTPUT);
digitalWrite (LedPin, Off);
pinMode (ButPin, INPUT_PULLUP);
butState = digitalRead (ButPin);
}
Thanks , I will try and implement it and get back to you.
Hello oracol
Check and try this small example sketch using C++.
How many monoflops with pre-trigger do you need?
// https://forum.arduino.cc/t/using-millis-to-turn-on-output-after-preset-time-and-turn-it-back-off-after-a-nother-presete-time/1056985
/*
Using millis() to turn on output after preset time and turn it back off after a nother presete time
*/
struct TIMER
{
unsigned long stamp;
const unsigned long Duration;
int onOff;
};
struct MONOFLOP
{
const byte ButtonPin;
const byte LedPin;
TIMER preTrigger;
TIMER trigger;
};
MONOFLOP monoFlop
{
A0,8,0,2000,0,0,3000,0,
};
void setup()
{
pinMode (monoFlop.ButtonPin,INPUT_PULLUP);
pinMode (monoFlop.LedPin,OUTPUT);
}
void loop()
{
unsigned long currentTime=millis();
if (!digitalRead(monoFlop.ButtonPin)) monoFlop.preTrigger.stamp=currentTime, monoFlop.preTrigger.onOff=true;
if (currentTime-monoFlop.preTrigger.stamp>=monoFlop.preTrigger.Duration && monoFlop.preTrigger.onOff)
{
monoFlop.preTrigger.onOff=false;
digitalWrite(monoFlop.LedPin,HIGH);
monoFlop.trigger.stamp=currentTime;
monoFlop.trigger.onOff=true;
}
if (currentTime-monoFlop.trigger.stamp>=monoFlop.trigger.Duration && monoFlop.trigger.onOff)
{
monoFlop.trigger.onOff=false;
digitalWrite(monoFlop.LedPin,LOW);
}
}
I'm using in total 3 sensor inputs and 4 outputs, only an 2 outputs i need pretriger timer , thanks a lot for the help i will try yourk code .
I tested your code it work like i wanted by its own , now i have to try and to implement something similar in the entire project. I might have to learn and do the entire project with state machine.Basically my project has 3 optical sensors and 4 electromagnetic valves: when i se a state change( from LOW to HIGH) in sensor 1 activate valve1 with no delay , when sensor2 state changes( from LOW to HIGH) i wait some set time and activate valve2 for a other set time period and then turn to LOW valve1 & valve 2.For sensor 3 when i see a state change ( from LOW to HIGH) activate valve 3 with no delay, based on sensor3 count the number of activation and at a set number activate valve 4 with a set period and hold it active for a other set period.All periods i should be able to display on an 2x40 lcd and change with buttons.
not sure i completely understood you requirements, but maybe instead of states you set the delays.
you could also set function pointers for different actions after each delay
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.