Level Up Your Arduino Code: External Interrupts

แชร์
ฝัง
  • เผยแพร่เมื่อ 15 พ.ค. 2024
  • We recommend viewing the lesson on registers before tackling the concepts shown in this video: • Level Up Your Arduino ...
    We examine external interrupts on this episode of Adventures in Science as we continue our journey learning about the inner workings of Arduino. External interrupts are anything that’s outside (but connected to) the microcontroller and can interrupt the main execution thread to perform some action. We look at the attachInterrupt() Arduino function and then break it apart to set up an interrupt by manually writing to registers.
  • วิทยาศาสตร์และเทคโนโลยี

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

  • @sparkfun
    @sparkfun  6 ปีที่แล้ว +22

    Ready for another level up? We tackle timer interrupts on the next episode: th-cam.com/video/2kr5A350H7E/w-d-xo.html

    • @davetriplett4779
      @davetriplett4779 6 ปีที่แล้ว

      Thank you for this Information!! So Clear & Fun))

    • @davetriplett4779
      @davetriplett4779 6 ปีที่แล้ว

      does SparkFun make Funduino?? Keyes??

    • @seanblake4291
      @seanblake4291 4 ปีที่แล้ว

      If it interrupts whats happening and takes overs perhaps we could petition to call it the "Mansplaining Method"?

  • @jacoblakies1053
    @jacoblakies1053 3 ปีที่แล้ว +18

    Wow you just taught me more about low level programming in one video than I've learned in 3 years of school

  • @tigeruby
    @tigeruby 6 ปีที่แล้ว +13

    loving these tutorial style videos Sparkfun! Keep 'em going!

  • @randomrandom420
    @randomrandom420 6 ปีที่แล้ว +1

    Awesome! A masterclass in 2 vids! Now it's time to try it making some tests as exercise.
    Thanks, Professor!

  • @rishabhbhatnagar6795
    @rishabhbhatnagar6795 6 ปีที่แล้ว

    Extremely awesome!! I've no words to appreciate your awesome work.

  • @lucsonnelson8037
    @lucsonnelson8037 2 ปีที่แล้ว +1

    Man I have to tell you're the best of the best teacher, cause you give me all I need as basics to enter this arduino world, which was dark to me as no experience in coding/programming. So clear and explicit, keep going teaching us brother, God gives you heath, and wisdom to continue your service for this arduino community. 😎👏👏👏

  • @Tyrell_Hopkins
    @Tyrell_Hopkins 6 หลายเดือนก่อน +1

    You are a great instructor. Always so well done.

  • @davewreski6900
    @davewreski6900 4 ปีที่แล้ว

    I so enjoy and learn so much fro m your video learning series. I cannot thank you enough. I can't wait until the next one. Thanks again Dave.

  • @dennismcdonald4261
    @dennismcdonald4261 2 ปีที่แล้ว +1

    Wow. Great video. The most clear and concise presenter I have ever heard. Every word is clear and although he talks quickly I can slow down it to make it easier. I'm a 71yr old newbie in Arduino and this guy is sharp.Kudos

  • @waltoler1754
    @waltoler1754 4 ปีที่แล้ว

    Really excellent job of presenting this material. THANKS!!!!

  • @lucsonnelson8037
    @lucsonnelson8037 2 ปีที่แล้ว

    I started understanding better what code is since I follow you. Wish I had discovered your videos before today, I would have had done way better with my robotic mower project. I was mad and frustrated the fact that I couldn't find any helpful examples. Some people built good one but selfish about to share with others, I got it "money ideas for later". Yeah, I had bad headaches trying to think about a way around it to bring my ideas to life. I'm going to keep up with you to see where it'll lead me. So far awesome to follow you and probably my favorite and interesting human to receive notifications from. Thanks again.

  • @nicholascamatti3162
    @nicholascamatti3162 4 ปีที่แล้ว

    Very good tutorial over here. Thanks for the quality content.

  • @afnansayed5523
    @afnansayed5523 3 ปีที่แล้ว

    This smart short video is loaded with tons of useful info, keep up the awesome videos ;)

  • @nexus2056
    @nexus2056 ปีที่แล้ว +1

    Thank you so much for helping with this. This was an absolute life-saver!

  • @disaleamol
    @disaleamol 6 ปีที่แล้ว

    Great Video SparkFun and good explanation Shawn!!

  • @gingsSon
    @gingsSon 4 ปีที่แล้ว +1

    Thanks for the fantastic explanation! I used some of these methods in my own projects and they have worked well.
    I would like to add from my own project experience that it may help to add a cap to ground at the INT0 pin in order to prevent unwanted/false falling edge detections. This may be an issue if you have a cheap button that has a ripple to it, or perhaps there are just ripples in your system in general.

  • @skfalpink123
    @skfalpink123 5 ปีที่แล้ว

    Excellent video and genuinely enlightening

  • @timothec.8216
    @timothec.8216 4 ปีที่แล้ว +1

    Great explanation, very clear.
    Thank you very much!

  • @lowiehojas5525
    @lowiehojas5525 2 ปีที่แล้ว

    indeed, you video sparked fun in learning electronics. thank you so much!

  • @rajmankar4440
    @rajmankar4440 4 ปีที่แล้ว

    Shawn, It's really a great video would like to see more...!

  • @nssalon
    @nssalon 2 ปีที่แล้ว

    I really needs more tuitotial like this, thank you.

  • @johnson554671
    @johnson554671 3 ปีที่แล้ว +1

    I really enjoy how these videos are made to reduce down to the arduino code to basic instructions. It feels like these tutorials are for real programmers (like myself) and I'm learning all these new and neat little tricks with & | ~ and ^

  • @danblankenship5744
    @danblankenship5744 4 ปีที่แล้ว +9

    Wow, I just finished the Register video and was feeling good that I got it finally. So I jumped into this video and all was going great until 1 second before 12:00. For the next 2:30 seconds I felt I was listening to a new language. I rewound the section countless times and read the sections over and over in the datasheet, and I finally the parts started to make sense and I finally understood your code.
    I appreciate your video, if I had to rely on the datasheet alone I would give up my project completely. You have given me new hope that I can figure out how to make my code work.
    I swear there was a point when I was reading the datasheet that I almost had to hit a AA meeting or the bar. It felt like if I had a couple drinks in me then I could better understand where the guy was coming from when he wrote that datasheet.
    There is one part I don't understand and perhaps someone can clarify it for me.
    When I was reading about the "External Interrupts" it mentions that they can be triggered by either INT1 or INT0, and it also mentions that any of the other pins (PCINT 23-0) can also trigger an external interrupt. I see that the EICRA bit configures how and when the trigger is detected (low-level, rising-edge, or falling-edge) for the INT0/1 registers, but I don't see a similar register for the PCINT pins. Am I missing something here?

    • @seaofcuriosity
      @seaofcuriosity 2 ปีที่แล้ว

      Is the project done ?

    • @stevenrogersfineart4224
      @stevenrogersfineart4224 2 ปีที่แล้ว

      Haha yeah. I grew up with a Commodore 64 and I still had a little trouble grasping registers. Its pretty cool once you get it :D

  • @ahmedalhallag3338
    @ahmedalhallag3338 6 ปีที่แล้ว

    You're Awesome Shawn !

  • @drakkorvladimir4012
    @drakkorvladimir4012 5 ปีที่แล้ว +1

    What a GREAT tutorial!!!! Thank you : )

  • @robertparenton7470
    @robertparenton7470 6 ปีที่แล้ว

    Thank You! Valuable information.

  • @johndripper
    @johndripper 6 ปีที่แล้ว

    thank you for this episode :) was eagerly waiting for it nice job

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว +1

      Thanks! Glad it helped :)

  • @delawarepilot
    @delawarepilot 6 ปีที่แล้ว

    That’s all kind of useful. Thanks for this video.

  • @devincress5258
    @devincress5258 2 ปีที่แล้ว

    Spent an hour last night trying to figure out why changing a variable value wasn't working and IT NEEDED TO BE VOLATILE. Thank you!

  • @gauravkapadia2514
    @gauravkapadia2514 6 ปีที่แล้ว

    Very nice and helpful.. please make video using timers and Analog digital conversion

  • @artemyevtushenko8722
    @artemyevtushenko8722 4 ปีที่แล้ว

    Super informative. Would an interrupt function break an established WiFi connection of a WiFi enabled Arduino like the mkr1000?

  • @jerzonemingui2943
    @jerzonemingui2943 4 ปีที่แล้ว

    Amazing video!!Is there any way I can use other digital Pins for external interrupt?Thanks

  • @swaransinghsandhu
    @swaransinghsandhu 6 ปีที่แล้ว +1

    V informative video so v thanks sir

  • @civiltronics
    @civiltronics 6 ปีที่แล้ว

    Awesome video

  • @NormanNodDunbar
    @NormanNodDunbar 3 ปีที่แล้ว

    Even simpler, in the ISR, toggle the led_pin by writing a 1 to its bit in PIND:
    PIND |= (1

  • @superliegebeest544
    @superliegebeest544 2 ปีที่แล้ว

    Good video. I have a question, if I have a convayorbelt with ir sensors I can use interupts so the motor starts running the belt as long as the ir sensors see a object. As soon as the object dissapears(at the end of the belt) it stops again. I understand how they should work if u mount them sideways as a gate. But I was thinking to use them length wise on the belt. Or is it better to use a while statement. Like while sensor x is hight run motor ect.

  • @bobsamuel1567
    @bobsamuel1567 3 ปีที่แล้ว

    Very useful video, thank you. One question: Is a down loadable PDF of the video’s narrative available?

  • @amadeujacintofurgeri625
    @amadeujacintofurgeri625 2 ปีที่แล้ว

    Congratulation teacher.

  • @Olavotemrazaodenovo
    @Olavotemrazaodenovo 4 ปีที่แล้ว

    Excellent

  •  5 ปีที่แล้ว

    Muchas gracias por compartir.

  • @ivanchristian549
    @ivanchristian549 4 ปีที่แล้ว

    I want to ask a question. in my project, I use ultrasonic sensor. I want to do an interrupt when a sensor value change to a certain value. . should I use an external interrupt or internal interrupt? thank you
    #can you also give me an example so I can understand better. thank you

  • @DieselBoulder
    @DieselBoulder 2 ปีที่แล้ว

    Is there a benefit to controlling the registers directly rather than using the digitalPinToInterrupt() and attachInterrupt routines? Other than more control and a better understanding of what's going on. For example, would it be faster to do it "manually" like in the video?

  • @johngrund2567
    @johngrund2567 ปีที่แล้ว +1

    Yeah, this & the few other videos that led me here are outstanding. I have many questions, but I want to focus on one. Around 9 min in there’s a statement “led_state = !led_state” for toggling. Defined as “LOW” (pre-setup) w/ uint8_t. If uint8_t has 0-255 as possibilities, how does a ‘!’ simply toggle between only the two states “HIGH” and “LOW”? Does “HIGH” set the 8 bits of uint8_t to 11111111 and the ‘!’ is saying to toggle all 8 of led_state’s bits to “opposite” being 00000000 for a value equivalent to “LOW”?

  • @hopechannelhopemusic
    @hopechannelhopemusic 3 ปีที่แล้ว

    What is the best and powerful mcu board to run interrupt function ?

  • @AhmadAsmndr
    @AhmadAsmndr 5 ปีที่แล้ว

    you are amazing Thank you

  • @kpsquickmobileservicepadap6863
    @kpsquickmobileservicepadap6863 6 ปีที่แล้ว

    thanks somach sir

  • @jonasaskenobis
    @jonasaskenobis 3 ปีที่แล้ว

    great work though, thanks for the lesson :)

  • @oncom81
    @oncom81 2 ปีที่แล้ว

    hi Sir,,,
    how to stop and start in the loop manually?

  • @rohit-lohar
    @rohit-lohar 6 หลายเดือนก่อน +1

    also make on uart, spi, i2c, protocol and ADC

  • @josephtierney1217
    @josephtierney1217 2 ปีที่แล้ว

    good video very helpful,but for the flag wouldn't it be easier to call cli at the beginning of the interrupt and sei at the end similar to how you normally disable an interrupt when you open it in kernel.

  • @koudelap
    @koudelap 5 ปีที่แล้ว +2

    Hello, thank you for all your videos. I've learned lots of new things. So, but i have problem with Interrupts. My LED doesn't work like yours. My LED turn on and off more than one times, when I push button one times. Probably i need some debounce, but your sketch working without debounce. Any idea please?

    • @toastrecon
      @toastrecon 3 ปีที่แล้ว

      You might need to add a capacitor to the switch, or have a separate routine that "listens" to the switch for a few ms to debounce on the software side.

  • @anlaz1
    @anlaz1 5 ปีที่แล้ว

    Hello, help to solve this problem: There is a need for the Arduino platform on the command (external button - for example) to turn on the stepper motor.
    After performing the specified number of revolutions (1000), stop it and turn on the second stepper motor with a similar task (say 2000 revolutions)and stop.
    After receiving the second command, the program runs everything in reverse order.
    First the second motor 2000 rpm in the reverse direction, then the first 1000 revolutions in the opposite direction.
    Need a sketch of the program, if possible with detailed comments, as your humble servant is a kettle in programming
    With respect and hope.

  • @MrSirPain
    @MrSirPain 2 ปีที่แล้ว

    Is there a max number of external interrupts? I need 4 external interrupts and 2 timer interrupts.

  • @idogendel
    @idogendel 6 ปีที่แล้ว +60

    What, actually reading the Datasheet?! Blasphemy! :-D

    • @DCFusor
      @DCFusor 6 ปีที่แล้ว +7

      You're giving away the deepest secret of mastery...

    • @idogendel
      @idogendel 6 ปีที่แล้ว +2

      :-)

    • @squirlmy
      @squirlmy 5 ปีที่แล้ว +1

      Fits with the "interrupts" jokes 🤢, though.

  • @pawatjoy9669
    @pawatjoy9669 3 ปีที่แล้ว

    If external interrupt and timer interrupt occur at same time which one will Arduino do first?

  • @aqualk3722
    @aqualk3722 2 ปีที่แล้ว

    Is there lesson about output compare

  • @davey2k12
    @davey2k12 6 ปีที่แล้ว

    now he's killed it omg talking about upgrade code ffs bro I confused now lmao

  • @PezhvakIMV
    @PezhvakIMV 4 ปีที่แล้ว

    perfect

  • @lalchandra4590
    @lalchandra4590 5 ปีที่แล้ว

    Wow. Beginner to advance.

  • @SHANUSHAH
    @SHANUSHAH 6 ปีที่แล้ว

    wish you could zoom into the codes and in focus into it so to see what they are, sorry I am new to this.

  • @jasmine2501
    @jasmine2501 4 ปีที่แล้ว

    Minor point here but the timers cause an EXTERNAL interrupt. The timer is separate hardware not part of the CPU, and if it causes an interrupt, that comes into the CPU from the "external" timer. See my video on timers in ATTiny which explains this.

  • @padalavamsiujpnquxgri3475
    @padalavamsiujpnquxgri3475 4 ปีที่แล้ว +3

    The video is good but it is not working with Nodemcu, Please help me to attach external interrupts for Nodemcu or ESP8266.

    • @lenkoduster
      @lenkoduster 4 ปีที่แล้ว +1

      Does this help? www.electronicwings.com/nodemcu/nodemcu-gpio-interrupts-with-arduino-ide

  • @mikelemon5109
    @mikelemon5109 6 ปีที่แล้ว +1

    Thanks quite useful but lost you at the DDRD stuff at the code no relation or explanation of how to use it and where it comes from, seeking to see the timer interrupt tutorial.

    • @knucklecorn
      @knucklecorn 6 ปีที่แล้ว +1

      Just watch the previous episodes like Shawn said.

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว +1

      I didn't mention it in the video, but the description points you to the previous video (which discusses reading and writing to registers like DDRD): th-cam.com/video/6q1yEb_ukw8/w-d-xo.html

    • @DCFusor
      @DCFusor 6 ปีที่แล้ว +2

      I'm an old hand, and just for communication's sake you should perhaps point out that

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว

      Good suggestions, thank you!

    • @DCFusor
      @DCFusor 6 ปีที่แล้ว +1

      The hardest part about teaching anything - and it gets harder(!) - is remembering how it was before you knew any of it and it was all a total mystery. Things you don't need to think about any more than breathing now - will hang up a student till they get some critical mass of background. Messes me up all the time - I do pretty well, but don't teach that well myself - it's kind of the flip side of the saying "those who can't do, teach" - those who can do...have more trouble teaching sometimes! An editor of mine used to say you have to say everything 3 times in three different ways to get it across. But once you know this stuff cold - it's really hard to make yourself take that time, you're anxious to get on with the next thing - and so are the students who "get it" right away. This makes it near-impossible to please everyone - some people need all 3 ways. Of course, those with too short an attention span who also need all 3 ways needn't bother complaining, but they will anyway...

  • @BFC24
    @BFC24 3 ปีที่แล้ว

    How I do interrupt when signal low and interrupt break when signal is come to high

  • @ilyashick3178
    @ilyashick3178 4 ปีที่แล้ว

    Followed this lesson. Found, in case of PORT's when button is pushed LED not stable or not working at all. Solution, add 10 k resister between +5 and pin 2. Again, it is only for PORTs.

  • @ufohunter3688
    @ufohunter3688 6 ปีที่แล้ว

    I am not sure what you mean by "software interrupt"!
    Do you mean for example interrupt on a carry from an ALU operation?
    or do you mean interrupts generated from within the code?

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว

      A software interrupt can be caused by some condition in the processor itself or by a special instruction that throws an interrupt (this Wiki page explains the difference: en.wikipedia.org/wiki/Interrupt). Many low-power microcontrollers, like the AVR, do not natively support software interrupts, but you can trick them into generating one (here is a discussion in it: www.avrfreaks.net/forum/software-interrupts ).

    • @ufohunter3688
      @ufohunter3688 6 ปีที่แล้ว

      Thanks for the reply. I still don't find a single practical use for a software interrupt in a small micro controller like the ATMEL!
      26 sources of interrupt has been enough for anything I have done on a MCU.
      Can you provide an example of a use, that can not be done with the existing interrupt vectors?

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว

      UFOhunter Since most of my programming has been on microcontrollers as well, I don't have much experience with software interrupts. However, they seem to be prevalent in larger systems (e.g. those with microprocessors). From what I understand, you could have a "divide by 0" instruction throw an interrupt or generate interrupts when read or write commands to a hard disk have completed. Additionally, programs can create interrupts in order to interact with the kernel. A microcontroller has little need for these types of interrupts, which is why we usually don't see them when programming for embedded systems.

    • @ufohunter3688
      @ufohunter3688 6 ปีที่แล้ว

      Thanks. Exactly what I thought. I didn't want to miss out on anything if there was something to miss out on :)

    • @Blacklab412294
      @Blacklab412294 6 ปีที่แล้ว

      BTW- please put a after the word Interrupt in your link. The ")" gets sent to Wiki and it has no idea what you mean. thanks.

  • @samdeur
    @samdeur 2 ปีที่แล้ว

    One question and one request: could you direct me to a vid that uses and explains milis with a button press and a led. Request/ comment: I love what you guy’s are doing and I want to see your products sold here in the Netherlands we have Amazon if that helps?

  • @0LoneTech
    @0LoneTech 6 ปีที่แล้ว +2

    It's an ATmega 32 8, not 3 28. The 32 is actually the program memory size.

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว +5

      LoneTech You say toe-mato, I say to-mahto.

  • @alasdairdougall7868
    @alasdairdougall7868 3 ปีที่แล้ว

    Like the fact this is so European, as you talk about Poles and Czech in a loop. Only joking, it was a nice intro to interrupts.

  • @squirlmy
    @squirlmy 5 ปีที่แล้ว

    This is an easy "why not Rasberry Pi" response to any PC programmer. Arduinos teach how microcontrollers are different. You could stick to Linux or Android forever in microprocessor world, but needing or wanting to program microcontrollers is slightly different. I suppose that's why Basic Stamp sold for so long. IoT makes the Arduino IDE, JavaScript and Micropython more interesting, for professional and hobbyists, but it's still microcontrollers vs microprocessors.

  • @meepk633
    @meepk633 5 ปีที่แล้ว +1

    I still don't understand the bit shifting. Like I have no idea how or why you are doing that. I watched the previous video a couple times. I just don't get it.

    • @jerryschwarzbach3253
      @jerryschwarzbach3253 5 ปีที่แล้ว

      I see your comment is 2 months ago, have you figured it out? I can try explaining it.

    • @meepk633
      @meepk633 5 ปีที่แล้ว +1

      @@jerryschwarzbach3253 I think I understand the basics now. Thanks though. I did a couple tutorials. I still don't really understand it intuitively, but I never really work on any projects that need that level of speed/efficiency.

  • @jcjensenllc
    @jcjensenllc 3 ปีที่แล้ว

    Please comment each line of code with what it does.

  • @gacherumburu9958
    @gacherumburu9958 3 ปีที่แล้ว

    👍..

  • @antoni2nguyen
    @antoni2nguyen 5 ปีที่แล้ว +1

    Why don't you need to declare "volatile" for led_state?

    • @lukaslundgren8448
      @lukaslundgren8448 3 ปีที่แล้ว

      You should! What happens otherwise is decided by your compiler. If it is non-optimizing you are generally fine, but if if optimizes you might run into problems.

  • @swaransinghsandhu
    @swaransinghsandhu 6 ปีที่แล้ว

    Spark fun Electrónics ch. Is best from each other

  • @jonasaskenobis
    @jonasaskenobis 3 ปีที่แล้ว

    at 9:30 you mentioned internal interrupts, then very rapidly changed the theme, people might get confused, thinking you're explaining internal interrupts for the rest of video

  • @cx3268
    @cx3268 6 ปีที่แล้ว

    Internal interrupts, we are on our own.
    This is a MAJOR functionality of Arduino that is missing.
    How to do an internal interrupt using Arduino????????????????

    • @ShawnHymel
      @ShawnHymel 6 ปีที่แล้ว

      There's really no easy way to set up internal interrupts on Arduino without manually writing to registers. There are some functions, however, that rely on internal interrupts. For example, analogWrite() uses compare and overflow interrupts to create a PWM signal. So, internal interrupts are there, but they've been abstracted away into other Arduino functions for the most part.

    • @DCFusor
      @DCFusor 6 ปีที่แล้ว +1

      IIRC, there was a way to do it but it required adding some lib and I was tight on space. Here's an example of using a counter overflow to update the top half of a longword (used in a geiger counter project):
      //////////////////////////////////////////////// subs called from setup
      void t1set() // setup timer1 as a counter that interrupts on overflow
      {
      TCCR1A = 0; // turn off all the weird compare/capture modes etc
      TCCR1B = 6; // clock on falling edge (7 for rising)
      TIFR1 = _BV(TOV1); // clear initial overflow - shouldn't need to, but do.
      TCNT1 = 0; //zero out timer
      TIMSK1 = _BV(TOIE1);// sets the timer overflow interrupt enable bit
      }
      /////////////////////////////////////////////////////////
      //////// manual isr setup, you bet, saves a whole library
      // actual isr for hardware counter 1
      ISR(TIMER1_OVF_vect)
      {
      c1counts += 0x00010000; // add one to top half of longword
      }
      ////////////////////////////////////////////////
      So yeah, writing to registers is used here...not that it's super hard, but finding the info took some google-fu.

  • @danny117hd
    @danny117hd 4 ปีที่แล้ว

    Let's pretend we had a bool variable type and we could use it where hi and low are used and we also could flip it with a simple line. X=!X;. Then we pretend to turn on a light digitalWrite (8,X);. Then wonder if it's wrong.

  • @joejoe6949
    @joejoe6949 4 ปีที่แล้ว

    Yo level 200

  • @ompandya9240
    @ompandya9240 5 ปีที่แล้ว

    This video is much more confusing then the register video

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

    it was toooo hard

  • @lpcoral2000
    @lpcoral2000 3 ปีที่แล้ว

    khe? ._.

  • @WhiskyLima
    @WhiskyLima 4 ปีที่แล้ว

    Why use simple arduino code when you can use complicated and difficult to remember random letters instead?! I just got done learning the basics only to find I haven't got a f"£$%^& clue what I'm doing here ha ha!

  • @Mike-qh5bn
    @Mike-qh5bn 3 ปีที่แล้ว

    very bad quality, all text on the screen is out of focus and unreadable

  • @geoffkelland5606
    @geoffkelland5606 2 ปีที่แล้ว

    Way too complicated. I'm out