callahan248 / chickenscarebox

0 stars 0 forks source link

Timed Events within each state #1

Open callahan248 opened 2 years ago

callahan248 commented 2 years ago

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.

jehall commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

Scarebox_V3_mar07a (1).zip Error Code.txt

jehall commented 2 years ago

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

Screenshot_20220312-175528-696

callahan248 commented 2 years ago

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 commented 2 years ago

https://forum.arduino.cc/t/can-multiple-millis-be-used-for-independent-events-without-slowing-the-loop/291868/6

This has some decent information so far.

jehall commented 2 years ago

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 commented 2 years ago

I totally agree. I’m just stuck. I’ve been trying everything and I’m sure I’m just overthinking now. I’ll probably step away for a bit and try again when I’m not so frustrated.

On Sat, Mar 12, 2022 at 20:01 Joe @.***> wrote:

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.

— Reply to this email directly, view it on GitHub https://github.com/callahan248/chickenscarebox/issues/1#issuecomment-1066011133, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQPFVXYBMHBPA47FZA63SODU7VK73ANCNFSM5QIHST7Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were assigned.Message ID: @.***>

jehall commented 2 years ago

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

callahan248 commented 2 years ago

I’ve gotten it to compile, it isnt behaving as intended. It’s getting there, slowly but surely. I got anything that blinks done pretty easily, just working on the duration based events now. Battling between using variable states or just digitalRead on individual pins. I’ll send you an updated code here shortly.

On Mon, Mar 14, 2022 at 10:36 Joe @.***> wrote:

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

— Reply to this email directly, view it on GitHub https://github.com/callahan248/chickenscarebox/issues/1#issuecomment-1067040111, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQPFVX7MX7QQH6Z7YWYU2NDU75TJJANCNFSM5QIHST7Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were assigned.Message ID: @.***>

jehall commented 2 years ago

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 commented 2 years ago

Jack_In_theBox.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.