I was wrong about millis: how to write non blocking code: (Arduino Uno Programming for Beginners)

แชร์
ฝัง
  • เผยแพร่เมื่อ 26 มิ.ย. 2024
  • I was wrong about millis: how to write non blocking code: (Arduino Uno Programming for Beginners)
    In this video I really show you how to write non blocking code using millis. How you handle the overflow correctly.
    0:00 intro
    0:23 millis basics
    2:23 non blocking code
    5:25 talking about my mistakes
    8:49 better way of using millis
    10:01 exercise
    11:36 outro

ความคิดเห็น • 43

  • @playduino
    @playduino  4 หลายเดือนก่อน +1

    you can find the code on git:
    github.com/playduino/arduino-uno-programming

  • @Volker-Dirr
    @Volker-Dirr 4 หลายเดือนก่อน +5

    Very nice video. Also not just rerecording and only showing the correct code, but also talking about why the old code is wrong is a perfect solution. Guys can learn much more by such a code review. Maybe as a task for every viewer: rethink why the old problems do not appear anymore. Think exactly about the 2 situations that lead to the old bugs. The first one is easy to explain. The second one is more difficult to explain.

    • @playduino
      @playduino  4 หลายเดือนก่อน

      Thank you :) I agree, I really tried but it is very hard to explain and I had a hard time understanding the issue in the first place.

    • @Volker-Dirr
      @Volker-Dirr 4 หลายเดือนก่อน

      @@playduino Well, rethinking about bug 1 and 2 again in fact the first code was even faster buggy than I thought. Since if the if statement is executed in less than 1ms, this means that the storeTimeStamp is (at the end) always set to millis() (because of bug 2). So it will be set to the max value also and that mean bug 1 will occur 100%. Luckily you fixed it now.

    • @playduino
      @playduino  4 หลายเดือนก่อน +1

      OMG true, so the code would stop after 50days for sure

  • @navassherif3839
    @navassherif3839 2 หลายเดือนก่อน

    Awesome teacher

  • @yoyohuba
    @yoyohuba 4 หลายเดือนก่อน +3

    This is one of the best videos on youtube! Congrats!

    • @playduino
      @playduino  4 หลายเดือนก่อน

      Thank you!

  • @mrasrrcom111
    @mrasrrcom111 3 หลายเดือนก่อน

    Its very good to know how the nuts and bolts of this stuff works so you know how to properly use it and know it's advantages. Now I'll shamelessly plug the NoDelay library that helps you use millis for timing without having to write that many lines of code yourself. Great for multiple timing loops

  • @hakanpolat6495
    @hakanpolat6495 4 หลายเดือนก่อน +1

    Thanks bro! Enjoying your videos👍

    • @playduino
      @playduino  4 หลายเดือนก่อน +1

      thank you! I'm glad

  • @AlexHerman-qj3pi
    @AlexHerman-qj3pi 4 หลายเดือนก่อน

    You are a great teacher 😊

    • @playduino
      @playduino  4 หลายเดือนก่อน

      Thank you 😊

  • @DRUMsetINkeyboard
    @DRUMsetINkeyboard 2 หลายเดือนก่อน

    im the 1000 subscriber :)

    • @playduino
      @playduino  2 หลายเดือนก่อน

      well done =D

  • @NormanNodDunbar
    @NormanNodDunbar 4 หลายเดือนก่อน +3

    Your new code will work just fine! However, if you don't fancy waiting almost 50 days for a rollover, do this In setup to adjust the millis counter.
    extern unsigned long timer0_millis;
    unsigned long untilOverflow = 1500;
    noInterrupts();
    timer0_millis = 0xffffffff - untilOverflow;
    Interrupts();
    Now wait 1500 milliseconds and the millis count will overflow.
    Cheers,
    Norm.
    (Author of Arduino Software Internals and Arduino Interrupts)

    • @playduino
      @playduino  4 หลายเดือนก่อน +1

      Awesome, this is very useful, I will give it a try! Thank you very much!

    • @evanbarnes9984
      @evanbarnes9984 3 หลายเดือนก่อน +1

      Nice! I'm going to check your book out. I'm in the interesting position of being what I would consider an intermediate programmer writing code for Arduino that will go into production in toys, so I'm doing as hard a crash course in C, C++, and Arduino/AVR programming as I can manage. Your book looks great!

    • @victormikecharlie1596
      @victormikecharlie1596 2 หลายเดือนก่อน

      There aren't any need for checking overflow when you use milis

    • @NormanNodDunbar
      @NormanNodDunbar 2 หลายเดือนก่อน

      @@victormikecharlie1596 There is! But it depends on how the test was written. The result of millis() doesn't go negative, obviously, but it does overflow from 0xffffffff to zero. That's the problem for some calculations. As described in the video.
      Cheers,
      Norm.

    • @NormanNodDunbar
      @NormanNodDunbar 2 หลายเดือนก่อน

      ​@@victormikecharlie1596 this is why overflow is a problem
      Arduino millis function, plus rollover.
      Don't do this:
      if (millis() - lastTime > 1000)
      doSomething();
      Because roll over leaves millis() less than lastTime. Do this:
      if (millis() < (lastTime + 1000))
      doSomething();
      That always works.
      Cheers,
      Norm.

  • @philtaylor1483
    @philtaylor1483 4 หลายเดือนก่อน

    Will the code cause both LEDs to change, out of time, on the ~50day overflow ?

    • @playduino
      @playduino  4 หลายเดือนก่อน

      I think it should not 🤔

  • @larsniklassonhede3798
    @larsniklassonhede3798 3 หลายเดือนก่อน

    Thanks. Now the LED starts off and it's take 1 sek to light up. If I want the LED to start at once and then starts to blink. I tried to move the !-sign first but it's not accepted. Can you suggest something?

    • @playduino
      @playduino  3 หลายเดือนก่อน +1

      hmm one solution is to turn on the LED in the setup, directly after pinMode.

  • @cadillacescalade5428
    @cadillacescalade5428 2 หลายเดือนก่อน

    Hi, I have 2 blocking coded that both have delay
    I have a servo code that goes from 30 to 60 and from 60 to 30 with a delay of (15) speed back an forth. And also a DF-Mini player that has delays..
    I'm not to familiar with Arduino so am needing some assistance

    • @playduino
      @playduino  2 หลายเดือนก่อน +1

      Hi, instead of delay(15) you could use the code shown in this video and then handle the servos instead of blinking the led (what I did)

    • @cadillacescalade5428
      @cadillacescalade5428 2 หลายเดือนก่อน

      @@playduino would you still have the code ?

    • @playduino
      @playduino  2 หลายเดือนก่อน +1

      Hi the thing is, I do not know exactly what you are trying to do. However I think in your case the simplest solution is actually to use a library called TimerOne. You can keep your working blocking DF-Mini code in the loop. And then have a timer isr function called every 15ms. Inside you change the angle of the servo. You will need two static volatile global variables, one for current angle (int) and one for the direction(bool). Inside or the isr you increment the angle if direction true and decrement the angle is the direction is false.
      If you hit the maximum angle you need to change direction to false.
      If you hit the minimum angle you need to change direction to true.
      Put all this logic into ISR, but don’t put a delay into the ISR. You do not need it, because the ISR is called every 15ms.
      I’ll upload a video about TimerOne soon. But if you look at example code I’m sure you can do it

    • @cadillacescalade5428
      @cadillacescalade5428 2 หลายเดือนก่อน

      @playduino HI well what I am trying to put together is a sketch for a wig-wag (sweep servo) using a IR sensor and a DF-Mini player.

  • @cchstechguy
    @cchstechguy 3 หลายเดือนก่อน

    Before you deploy this to your nuclear power plant, what happens when currentMillis overflows and is less than the storedTimeStamp?

    • @playduino
      @playduino  3 หลายเดือนก่อน

      I would not deploy this to my nuclear power plant yet, but I am pretty confident that this will work because subtracting the big number will lead to a overflow that results in a small Number. Let's for a moment assume that we only have 8 bits. If storedTimeStamp = 255 and currentMillis is already very small, lets say 10.
      Now we calculate 10 - 255. it will overflow to the result 11.
      I just tried it by running the code:
      Serial.begin(9600);
      byte x = 10 - 255;
      Serial.print(x,DEC);

    • @cchstechguy
      @cchstechguy 3 หลายเดือนก่อน +1

      @@playduino Ah. I wasn't sure how Arduino handled types in conditional expressions, but it does look like it remains unsigned and overflows correctly. This is not always the case. Evaluating the difference of 2 unsigned types within a conditional can return a signed negative value on other platforms. Looks like you are safe to deploy after all. ;)

    • @playduino
      @playduino  3 หลายเดือนก่อน +1

      interesting. I assume as soon as one of the numbers in signed, the result will also be signed. Yeah all good, lets get this power plant up and running :D

  • @longdarkrideatnight
    @longdarkrideatnight 3 หลายเดือนก่อน

    You need to create a class so you can make timers without writing more code that is the same for each now timer.

    • @playduino
      @playduino  3 หลายเดือนก่อน

      Do you mean functions? I will talk about functions in 2 weeks. They are a great way to reduce code duplication

    • @longdarkrideatnight
      @longdarkrideatnight 3 หลายเดือนก่อน

      I have a classy example for you who would you like to send it to you, I can put it on drop box for you to pick up @@playduino

  • @stevenbennett6123
    @stevenbennett6123 3 หลายเดือนก่อน

    // Blink an LED on PA2 on an ATTiny1614 MCU
    // Pin definitions
    // Important - always use the full pin definition i.e. PXn where X is the port letter and n the pin number
    const int ledPinRed = PIN_PA2;// Pin 2 Port A
    const int ledPinBlue = PIN_PB1;// Pin 1 Port B
    // Variable definitions
    unsigned int A = 888; //dividend
    unsigned int B = 444; //divisor
    unsigned int C = 666; //dividend
    unsigned int D = 222; //divisor
    void setDefaultPinStates() {
    pinMode(ledPinRed, OUTPUT); //set as output
    pinMode(ledPinBlue, OUTPUT); //set as output
    digitalWrite(ledPinRed,HIGH); //start with LED off
    digitalWrite(ledPinBlue,HIGH); //start with LED off
    }
    void setup() {
    setDefaultPinStates();
    delay (1000);
    }
    void loop() {
    /*
    Flash the LEDs on PA2 & PB1 with a single line of code.
    The remainder of millis divided by A is compared to B
    and when greater the result is 1 and when less is 0, this binary result
    is written to the appropriate ledPin
    */
    digitalWrite(ledPinRed, millis() % A > B);
    digitalWrite(ledPinBlue, millis() % C > D);
    }

    • @playduino
      @playduino  3 หลายเดือนก่อน

      digitalWrite(ledPinRed, millis() % A > B)
      looks like a very interesting way to get blinking patterns, thanks for sharing

    • @stevenbennett6123
      @stevenbennett6123 3 หลายเดือนก่อน

      Not my idea I discovered to concept from th-cam.com/video/foiqs-rNHig/w-d-xo.html@@playduino