Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timed Events within each state #1

Open
callahan248 opened this issue Mar 9, 2022 · 14 comments
Open

Timed Events within each state #1

callahan248 opened this issue Mar 9, 2022 · 14 comments
Assignees
Labels
good first issue Good for newcomers

Comments

@callahan248
Copy link
Owner

The state machine without timers is the newest code.

I cant find a good solution for the 3 different events that would use time. I've tried the millis () function and cant find a good solution for 3 different timers. Delays interrupt the whole cloud based system so those wont work either.

1.) Blink the yellow or Red LED while in the "Disarmed" state.
2.) When the solenoid activates, it needs to last 5 seconds and the return to LOW.
3.) The sound-bytes only need a quick "HIGH" signal in order to trigger the full sound. After Testing, 100-200 MS seems to work fine. So when those activate, they just need a 100-200MS Timer.

@callahan248 callahan248 added the good first issue Good for newcomers label Mar 9, 2022
@jehall
Copy link
Collaborator

jehall commented Mar 10, 2022

How were you using millis() when you tried it? Can you show the code?
millis() should work for all three with the proper usage. Here is an example for blinking LED.
I recommend you fully understand this example and also read the millis() docs thoroughly if you haven't already.

Let me know if you have more questions about the blinking LED case once you've gone through those docs.

Once you have the LED blink, we can talk more about the other two applications.

@callahan248
Copy link
Owner Author

callahan248 commented Mar 10, 2022

Yeah that link was exactly what I followed when trying the examples. I had for (each event):

Globals:

const int yellowLed; 

int yellowLedState; 
// int soundState; 
// int solenoidState; 

const long blinkInterval = 500; 
// const long soundInterval = 100; 
// const long solenoidInterval = 5000; 

unsigned long prevMillis = 0;

After that, I tried to set ( unsigned long currentMillis = millis(); ) in multiple different locations and it kept calling errors saying it "wasn't defined". I tried within the void loop (), at the beginning of "DoInState", and within the outputs section of the "disarmed" section as well.

At the beginning of the Disarmed state is where I put my if statement:

if (currentMillis - previousMillis >= blinkInterval) {
    previousMillis = currentMillis;

    if (yellowLedState == LOW) {
      yellowLedState = HIGH;
    } else {
      yellowLedState = LOW;
    }
    digitalWrite(yellowLedPin, yellowLedState);
  }

I tried multiple different variations of this as well and it seemed like I could only get the Led off or on in a solid state depending on its previous state. Hopefully that all makes sense. I feel like I studied a ton of material but couldn't seem to get it working right.

@jehall
Copy link
Collaborator

jehall commented Mar 11, 2022

See yellow LED blink using millis() #2
It compiles and blinks the built-in LED on my Nano 33 BLE Sense board if I just switch the yellow LED pin number to LED_BUILTIN

@jehall
Copy link
Collaborator

jehall commented Mar 12, 2022

For the other timers you'll want something like this

// Global
unsigned long timestampStartForSolenoid;
unsigned long timestampNowForSolenoid;

. . .

// In EnterState
timeStampStartForSolenoid = millis(); // get time at start
digitalWrite(pin_solenoid, HIGH); // fire the solenoid

. . .

// In DoInState
timestampNowForSolenoid = millis();
if( timestampNowForSolenoid - timeStampStartForSolenoid > 5000)
{
   digitalWrite(pin_solenoid, LOW); // stop the solenoid
  Transition FSM( SOLENOID_TMR_DONE );
}

@callahan248
Copy link
Owner Author

@jehall
Copy link
Collaborator

jehall commented Mar 13, 2022

The error gives a suggestion. The problem is a capitalization typo

Screenshot_20220312-175528-696

@callahan248
Copy link
Owner Author

Yeah I corrected all of those and even tried changing them to something different. Still no progress. It sounds like the millis function really only states the value of the current time that the arduino has been turned on. You can call and reference it but I don't think you can restart a new millis value multiple times.

I'm going to keep looking for solutions, such as a counter to count the event timers as an integer, and once it reaches a defined integer, it'll return to its previous state.

@callahan248
Copy link
Owner Author

@jehall
Copy link
Collaborator

jehall commented Mar 13, 2022

Yes, millis() just gives you the number of milliseconds which have elapsed since the last time the Arduino was reset. That's why the code example gets and stores the value of millis() when entering the state as the Start time and then every time it goes through the loop() in the DoInState it grabs the value of millis() as the Now time and checks whether the difference between the two is more than 5000ms. I'm not sure why your code isn't working, but it's not because you need a different solution. It's just some subtle typo or misplaced line. The solution should work.

@callahan248
Copy link
Owner Author

callahan248 commented Mar 13, 2022 via email

@jehall
Copy link
Collaborator

jehall commented Mar 14, 2022

Is it not compiling or not behaving as intended after programming the board?

@callahan248
Copy link
Owner Author

callahan248 commented Mar 14, 2022 via email

@jehall
Copy link
Collaborator

jehall commented Mar 14, 2022

I looked at your code on a laptop finally and noticed some weird syntax errors which might explain the problems. Try finding where you have errors like these (red) and fix them with these changes (green) and try it:

@@ -178,7 +178,7 @@ void DoInState(void)

     if (triggerButton == HIGH)
     {
-      void TransitionFSM(TransitionEvent_e TRG_BTN);
+      TransitionFSM(TRG_BTN);
     }
     break;

@@ -189,14 +189,14 @@ void DoInState(void)

     if (pir_sensor == HIGH) //|| (Gy > 50 || Gy < -50))
     {
-      void TransitionFSM(TransitionEvent_e TRG_SIG);
+      TransitionFSM(TRG_SIG);
     }
     break;

   case TRIGGERED:
     if (stopButton == HIGH)
     {
-      void TransitionFSM(TransitionEvent_e STOP_BTN);
+      TransitionFSM(STOP_BTN);
     }
     break;

@@ -209,7 +209,6 @@ void DoInState(void)

 void OnArmButtonChange() // Takes the App booleans and we use those to transition
 {
-  TransitionEvent_e event;
   if (armButton == true)
   {
     TransitionFSM(ARM_ON);
@@ -222,7 +221,6 @@ void OnArmButtonChange() // Takes the App booleans and we use those to transitio

 void OntriggerButtonChange()
 {
-  TransitionEvent_e event;
   if (triggerButton == true)
   {
     TransitionFSM(TRG_BTN);
@@ -231,7 +229,6 @@ void OntriggerButtonChange()

 void OnstopButtonChange()
 {
-  TransitionEvent_e event;
   if (stopButton == true)
   {
     TransitionFSM(STOP_BTN);

@callahan248
Copy link
Owner Author

Jack_In_the_Box_.zip

Here's what I got today. I got some functioning blinking LED's within each state (Some of the code is probably overcomplicated). Here's How its working:

DISARMED =
Yellow LED Blinks every 500 ms (Sometimes it starts out blinking way faster than that but it eventually slows down.
Green LED Comes on if I manually deactivate it, but doesn't come on initially.

Armed =
Red LED ON (SOLID)

TRIGGERED =
Red LED Flashes at a 250 ms rate
Solenoid goes from "Low" to "High" for 5000 ms and keeps switching on and off (Ideally, only happens once but this is a start).

Now, I need to do the same thing with each Sound trigger. (Armed, Disarmed, and Trigger sounds are on different pins)
Again, I would like for those to only happen for the 200 ms interval as well, and only once during the triggered state.
Finally, finish the "TMR_DONE" transition inside of the triggered state so I dont have to push the stop button every time. I tried messing around with that as you'll see but I didn't get very far with it.

We're super close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants