Julian Investigates: How Slow is Arduino?

แชร์
ฝัง

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

  • @deangreenhough3479
    @deangreenhough3479 9 ปีที่แล้ว +2

    Interesting, thoughtful and intelligently explained. You have a gift Julian, once again you just make it sound so easy to understand

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

    Love this video. Ever since school I've wanted a reason to buy an oscilloscope- now I gave one!
    Seriously, another great and well explained video. I learnt a lot!

  • @das250250
    @das250250 8 ปีที่แล้ว +51

    Julian - As always a very well explained video . You are the master of complexity made simple : a great teacher.

    • @JulianIlett
      @JulianIlett  8 ปีที่แล้ว +12

      +graham kaveman Many thanks Graham. Much appreciated.

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

      The Kaveman so true

  • @jeffbeck6501
    @jeffbeck6501 9 ปีที่แล้ว

    This video gets better and better every time I watch it. Jam packed with amazing info. Thank you Jullian.

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

    Excellent stuff, extremely well explained and also showed why we should be cautious about what we see on a scope.

  • @nunyabiznez4408
    @nunyabiznez4408 9 ปีที่แล้ว

    Very insightful. Thanks for answering these questions, I wish more folks would do the same.

  • @DasIllu
    @DasIllu 9 ปีที่แล้ว

    As always i learn something from your videos. It's never wasted time. Thank you

  • @AlexBlate
    @AlexBlate 9 ปีที่แล้ว +11

    And to the many folks who have suggested that Julian take up AVR assembly programming... I would remind you of two important principles. The first, paraphrasing the great Don Knuth, is, "a cardinal sin in computer science is premature optimization." Put simply, focus on getting your code and algorithms correct and then address performance issues as needed. The second is Amdhal's Law, which basically says that you should focus optimizations on code that is both slow and which takes up a significant percent of processing time. Julian followed both of these rules -- he wrote a correct program, assessed its performance, and then optimized the bits that were causing performance issues. Granted, this is a very simple example. But, unless one just really enjoys coding in assembly, one is best advised to avoid it except in the (generally) rare circumstances where it's appropriate to insert it. And, at that, one should examine the machine code generated by the compiler *first* before claiming that the compiler didn't/doesn't do a good job or that it can be done substantively better by hand and that the cost of doing so in terms of readability, portability, and time invested is really worth it.
    And, for the record, yes, the Arduino libraries do introduce overheads, sometimes very large ones. So, if timing or performance is critical, bypassing them, which is generally quite easy to do without abandoning the Arduino IDE, is certainly the right thing to do... or, perhaps, write better ones and contribute them back to the community. :)

  • @clearwavepro100
    @clearwavepro100 8 ปีที่แล้ว

    Thank you for creating and sharing this! My favorite part about(of) this video, is the awesomely good perspective to have(applicable to anyone, really) that doesn't point a finger at anyone, just points a finger to the answer!!!! Perfect, thank you. :)

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

    Wow, I've been using Arduino for years and had no idea I was incurring this kind of overhead. I guess I've been lucky that it hasn't mattered for any my projects yet, but it's good to know. Thanks for sharing!

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

    Thanks for bringing this to my attention. I can't see the need for it at the moment given the projects I'm playing around with, but it is good to be aware of these kinds of things in case I run into something very time-sensitive in future.
    That would probably have to be a very specific requirement though, as I very much appreciate ability to write once and compile for different systems, plus the readability of most Arduino commands, and the fact that I don't have to worry about taking all port values into account when using PORTB/C/D.

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

    Good Digital Design insights. Excellent presentation, Julian.

  • @mirkomueller3412
    @mirkomueller3412 9 ปีที่แล้ว

    How amazing - will probably come in handy with my next project. Great Job !

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

    I'm a very novice arduino user- You are a brilliant teacher. This should have been way over my head but you made it quite understandable.
    My mind boggles at how you know what you are talking about!

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

    That was a really neat experiment. Thanks for sharing it.

  • @mikeydk
    @mikeydk 9 ปีที่แล้ว +78

    Could be interesting to se to see how fast
    while(true)
    {
    PORTB = B001000000;
    PORTB = B000000000;
    }
    is, compared to loop(), the "while" should remove the arduino housekeeping on every loop()

    • @RWoody1995
      @RWoody1995 9 ปีที่แล้ว +6

      K5HJ wouldn't that just continually set PINB to 1 so it would just stay high?

    • @RWoody1995
      @RWoody1995 9 ปีที่แล้ว

      K5HJ ah gotcha, forgot about those, been using them a lot while programming xmega chips and for some reason assumed the older mega chips didnt have the same functionality and could only directly write to the pins hehe... >

    • @AnsyCrofts
      @AnsyCrofts 9 ปีที่แล้ว +3

      K5HJ Good Grief! Never used that!!!
      When I've finished Windows 10 upgrade, I'll give it a shot! Time to re-read the datasheet. Knew Xmegas had it, but...

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

      K5HJ that is very cool actually

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

      Of course, you could unroll the loop and just insert a hundred identical lines of:
      PINB = B00100000;
      PINB = B00100000;
      PINB = B00100000;
      PINB = B00100000;
      ...
      That would be much faster 99% of the time, limiting the loop overhead to just one ‘sputtering’ every 100 instructions. It’s a hack, but it would show more clearly how many times Arduino can actually switch a pin on and off in a microsecond.

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

    For what it is, and what it costs, it is still an impressive little piece of hardware. Thanks for the insightful video,

  • @malgailany
    @malgailany 9 ปีที่แล้ว

    Thanks Julian, good to know this kind of information.

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

    Quite interesting and fun! Thanks for trying and sharing this with the internet =) Great video! =)

  • @Disillusioned_one
    @Disillusioned_one 8 ปีที่แล้ว +2

    Julian, I used atmel studio 6 and wrote the blink program in C without delays. I loaded this compiled program and unset the div8 fuse, I scoped the output at 4mz I was amazed.

  • @spikekent
    @spikekent 7 ปีที่แล้ว

    Wow! That was fascinating and very expertly explained for a novice like me.

  • @makingthings277
    @makingthings277 9 ปีที่แล้ว

    Very inturesting! Good in depth check!

  • @MilanKarakas
    @MilanKarakas 8 ปีที่แล้ว

    Good examples! Thanks for the video.

  • @DrenImeraj
    @DrenImeraj 9 ปีที่แล้ว +19

    The Global Interrupt Enable is bit 7 of the Status Register (SREG)

    • @JulianIlett
      @JulianIlett  9 ปีที่แล้ว +5

      Dren Imeraj Ah, too simple! I missed the obvious. Thanks Dren.

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

      Julian Ilett No problem. Great video, as usual. Please keep them comin!

    • @superdau
      @superdau 9 ปีที่แล้ว +6

      Julian Ilett
      Or ignore the bit and just call "noInterrupts()". Yeah, it's that obvious ;) . And you get them back with "interrupts()". "cli()" and "sei()" do the same but might not be that obvious if you don't know AVR assembler.

    • @alexholguin4825
      @alexholguin4825 7 ปีที่แล้ว

      Dren Imeraj black movies play Wet Willie

  • @collingtech1
    @collingtech1 8 ปีที่แล้ว

    very good masterclass julian thanks for video , cheers

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

    Very interesting, I was going to make these mesures, thanks for the vid !

  • @rupertrooksby
    @rupertrooksby 9 ปีที่แล้ว

    I have only just begun playing about with Arduinos this month (pretty much due to your videos - you are responsible for the postman visiting almost everyday this week with a new little free-shipping treat).
    But the first thing I did after Blink was throw the Arduino IDE and its libraries overboard. I understand the beginner-friendly broad-appeal thing they were going for, and it probably works for that, but as your video clearly shows, too much is happening behind the curtain. For me anyway, I think a lot of the fun of mucking about with this whole embedded caper is to be right down there, and just that little bit closer to the silicon. You can't do that with Arduino libraries slowly moving the scenery behind your back.
    So for me that means using something like SublimeText, makefiles, and writing code just based directly off the Atmel datasheet and lots of google. Very happy with that setup. Fast and direct. There's a steeper learning curve for sure, but that's more than half the fun.

  • @davidkempton2894
    @davidkempton2894 9 ปีที่แล้ว

    Hey Julian, that was really interesting. Thanks.

  • @raccoonnyc
    @raccoonnyc 9 ปีที่แล้ว

    Nicely done, thanks!

  • @joseperezmiranda6226
    @joseperezmiranda6226 8 ปีที่แล้ว

    Very well explained. Thanks.

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

    Very good explanation

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

    Thanx Julian!!!
    This is very commen on high-level coding, as it is more easy for beginners to get something going, it creates also a lot of overhead in the final code. Best example here is BASIC. As it is an interpreter language and it also creates lots and lots of code to be executed, when you use a compiler BASIC.
    But you can always do some "inline-assember" for quick execution, but it you do so you have to deal with all this "unwanted" side-effects witch made assembler coding more difficult....
    Speed or simplicity YOU have to choose.....and as always, it all depends on YOUR very own needs;)
    Julian, you may take a look at the final output ASM-code to be executed by the AtM168 when using the arduino envoirement. As it clearly shows the overhead created by the arduino IDE....;)

  • @AxelWerner
    @AxelWerner 8 ปีที่แล้ว +7

    btw: there is a "arduino function" to disable interrupts. i think its " nointerrupts() " . you should also try using bitwise or and bitwise and operations to set and delete bits on a register. dont know it its faster, but it clearly does not overwrite or clear any other bits in the register. Also if you want to be in total controll or timing and things to happen, it might be a good idea to NOT USE the "loop()" routine, but making your own "while" loop. that is, because if you disabled interrupts in your own while loop there will be nothing else but what you wrote yourself. with the "loop()" loop its more likely that this is "NOT" a real loop, there are things happening before and after one "loop()" run. things that are not interrupt driven, but may interfere with your expected timing.

    • @AxelWerner
      @AxelWerner 8 ปีที่แล้ว +13

      +Julian Ilett , i did some more research and testing. i was able to bring it up to 2.6MHz. see my results and screenshots here: bit.ly/1P00hKn

  • @AlexBlate
    @AlexBlate 9 ปีที่แล้ว

    Great tutorial on high-performance Arduino magic.
    To avoid the overhead of the loop() routine, you can enclose the body of loop() in an infinite loop, e.g.,
    void loop() {
    while(1) {
    //your code here
    }
    }
    At minimum, this avoids the overhead of returning from loop() and calling it again from the Arduino libraries. This should also obviate the need for any delays between the writes, though parasitics may still give you an "ugly" square wave.
    Another useful trick along the same lines as what you presented is to change the state of multiple pins (on the same port/bank) simultaneously. Due to the goofy mapping of Arduino canonical pin names and the actual ports, you sometimes end up with goofy combinations of pins... but, if you wanted to do a simple bit-banged 8-bit DAC, for example, this would do the trick. (I think W2AEW used this trick in one of his videos a while back).
    Cheers, mate!
    Alex

  • @k.chriscaldwell4141
    @k.chriscaldwell4141 ปีที่แล้ว

    Fascinating, and good info. Thanks.

  • @james7145
    @james7145 9 ปีที่แล้ว

    Excellent video.

  • @mortensentim511
    @mortensentim511 9 ปีที่แล้ว

    I did exactly this experiment before Christmas for a project I'm working on. Port masking and manipulation are more confusing to deal with, but the overhead of DigitalWrite is huge. Nice catch with the interrupts, I didn't think about that.
    After that was sorted the ADC became the bottleneck, it's a shame the Arduino has such a slow ADC compared to say a Nucleo board.

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

    And this is precisely why I do all my Arduino programming in Atmel studio. You lose all the Arduino functions and libraries, but you actually know what your code is doing.

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

    I like your Arduino videos, especially the finer points in this video, as well as your MPPT videos. Maybe you could create a how it's done video on the MPPT graphing -- really cool.

  • @PetRatty
    @PetRatty 9 ปีที่แล้ว

    Great work Julian, this extract is taken from the core library arduino folder/hardware/arduino/cores/arduino/wiring_digital.c
    void digitalWrite(uint8_t pin, uint8_t val)
    {
    uint8_t timer = digitalPinToTimer(pin);
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    volatile uint8_t *out;
    if (port == NOT_A_PIN) return;
    // If the pin that support PWM output, we need to turn it off
    // before doing a digital write.
    if (timer != NOT_ON_TIMER) turnOffPWM(timer);
    out = portOutputRegister(port);
    uint8_t oldSREG = SREG;
    cli();
    if (val == LOW) {
    *out &= ~bit;
    } else {
    *out |= bit;
    }
    SREG = oldSREG;
    }
    As you can see there are loads of C commands just to change the pin state.

  • @JerryEricsson
    @JerryEricsson 7 ปีที่แล้ว

    Cool video, I dug out one of my old Nano's and installed Tiny Basic in it, now I can play around with the first programming language I ever used, and on such a small platform. It is really cool that I can reach it with both the Arduino programmer or cool term, actually cool term makes it feel more like programming on the C=128, my first computer, and, of course my first love.

  • @ArcAiN6
    @ArcAiN6 7 ปีที่แล้ว

    and now that i've watched the rest of the video, i see you've already figured that out :D

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

    Yes, the C compiler leaves a lot of guesswork for bit-banging. Look at the machine code, then write in machine code, or simply do it in assembly language which can be done on Arduino if you can find an assembler. Microchip was more my style since that is native assembly language. At first and still, I was disappointed with Arduino, trying to figure out what it was doing and immediately started on a difficult path looking for an Arduino assembler to make the Arduino do what I wanted it to do. Not much luck, except that assembly language with Arduino is possible or fast machine code can be inserted into the compiler for critical fast timing.
    Thank you Julian for scoping the Arduino and showing the C compiler confusion trying to make the Arduino do what you wanted to do and what you know is possible.

  • @sbern42
    @sbern42 9 ปีที่แล้ว +6

    It should most definitely be a crystal. They get smaller than that. :)
    Also, if you set your scope probes to 10x (and tell your scope that's what they're set at) it should show a better square shape. 1x mode usually lowpass filters the input at around 8MHz or so.
    And if you put a while(1) { } inside the loop() around the PORTB:s, it should reduce the overhead a little bit more in the jump back to the start again.

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

    excellent tutorial!

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

    Thanks. I enjoyed very much

  • @neildarlow
    @neildarlow 9 ปีที่แล้ว

    Let us analyse what is going on here:
    1) digitalwrite(output, state)
    The output number has to be translated to a specific bit of a specific port. This involves two lookups using tables. One lookup determines the port associated with the output and the other constructs a bitmask to associate with the output. Finally the action of setting or clearing the bit has to be determined from the state parameter. Given that the lookups incur significant overhead it is not surprising that digitalwrite takes a good amount of time to execute.
    2) loop function
    Associated with the loop function there is some housekeeping code. It is small but it is executed once per loop function iteration. I believe this housekeeping is associated with managing serial I/O at a low level.
    You should be wary of using direct port I/O for the reasons that Julian described but it is important to make your I/O operations atomic to prevent side-effects caused by code executed in e.g. interrupt service routines from clashing with the values you wish to write and causing undesirable effects. At a high level you can use the &=, |= and ^= assigmnent-with-modification syntax to only operate on the bit(s) you intend to modify but this requires that the compiler handles these assignments atomically. At a lower level, assembly language bit-set and bit-clear instructions are a better solution because they are atomic by design.

  • @TKomoski
    @TKomoski 9 ปีที่แล้ว +13

    Morning Julian - If you really want to push the speed limit try Assembly Language. The native code that all micro's normally use. What Arduino does is disassemble your code into assembly language so that the micro can execute it. Assembly is quite lengthy and cryptic, understanding the Instruction Set is the key. I would suggest using Atmel Studio 6.X because you have the benefit of a full fledged programmer. If you don't want to use assembly try using C+ because it is the closest thing to it. I'm sure that you are aware of this and your channel is geared toward the beginers side. Since Atmel Studio is FREE for Windows users I never use Arduino to code any more. Sure the learning curve for steep, but there is ton's of info online to get you started. Code you write in Arduino is the same as in Atmel Studio, but the major difference is that you're not restricted to one language. Thanks for all the great video's, Cheers ;-)

    • @originalmianos
      @originalmianos 9 ปีที่แล้ว +8

      T Komoski C is closer the machine than c++. Yep, good idea to try Atmel Studio of you don't mind the 2G download but the problem here is the overhead in the 'arduino' libraries and chip setup, and that's how the majority of people here are going to be using the boards.
      Also, I use gcc with my own waf 'makefiles'. You can use -S with to output the actually assembly language generated. If you do that in this case you will see there are surprisingly few instructions emitted for this code. The problem here is all in the 'arduino' framework.

    • @RogerKeulen
      @RogerKeulen 7 ปีที่แล้ว +3

      Thanx for the advice... I'm downloading it now !
      I hate these higher languages for simple devices. Now i can use my old C64 tricks to optimize for speed but also important SIZE ! (speeds doesn't cost money, memory size does)

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

      Under GCC, identical C and C++ code produces identical output. C++ classes and C++ iterators are zero-cost abstractions (compared to the same thing in C).
      avr-gcc is pretty smart; it is able to turn PORTB |= (1

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

    If you don't want to go through the trouble of using port manipulation, there is a great library called "Fast digital I/O for Arduino" from Jan Dolinay which is way more convenient but still gives you a considerably faster code execution

  • @DJignyte
    @DJignyte 9 ปีที่แล้ว

    Excellent stuff!

  • @DeeegerD
    @DeeegerD 8 ปีที่แล้ว

    Did something similar a few months back using a logic analyzer. I was able to get the Arduino board to 4 MHz and could see those glitches in the pattern as well. I did not set interrupts off - just bit toggled the one pin off and on.

  • @tobortine
    @tobortine 9 ปีที่แล้ว +13

    Some one has already suggested this but I will repeat it. If you're going to do these type of experiments then use assembler. The Arduino IDE is designed to make development easy but in so doing it introduces masses of overhead. Even the loop in the code is generating many, many instructions. The IDE abstraction prevents you from getting accurate results at the level you're measuring.

    • @superdau
      @superdau 9 ปีที่แล้ว +19

      tobortine
      That's why he wrote "How slow is Arduino?" and not "how slow is an atmega?". It wouldn't be Arduino if you are programming in assembler.

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

      superdau but then i guess then it is "how slow are arduino functions" and not "how slow is arduino" since arduino doesn't limit you to using the provided libraries.

    • @tobortine
      @tobortine 9 ปีที่แล้ว

      superdau
      Ardiuino = Atmel processor + Peripherals + IDE
      The peripherals are only used to load the code so the IDE (libraries, macros, etc) are what slow down the native chip. If you're making a video about how slow an Arduino can be then showing the relative speed of the native chip with efficient code illustrates the point.

    • @RWoody1995
      @RWoody1995 9 ปีที่แล้ว

      tobortine i don't think so to be honest, i think if you are comparing arduino code to something you should compare it to C because C is the language someone looking to transition away from arduino is most likely to be moving to.
      you dont compare a sports car to a race car when your audience really want a supercar do you? :P

    • @AlexBlate
      @AlexBlate 9 ปีที่แล้ว

      megaspeed2v2 At last check, the Arduino development environment already uses C++... some code does actually use the object-oriented features in C++, but most doesn't or cleverly hides it from you; so, without starting a religious war about C vs. C++, Arduino programmers are already programming in C. The point, though, is that you *can* develop high-performance applications while retaining some of the Arduino IDE and toolchain's benefits; you just have to RTFM a little more. The nice thing is that you can decide how much deep magic you wish to explore and are not thrust headlong into a raw microcontroller development environment with all of the attendant arcane goo that's required just to get a simple program working.

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

    I really love your idea of trying to get the most out of these microcontrollers, and the video is really nice to watch.
    I'm not sure if it works for this specific chip, but the avr libs include the functions "cli()" (clear interrupt) and "sei()" (set interrupt), which disable or enable all kinds of interrupts (timers, external, etc), I don't think it wouod change anything though as you disabled the timer0 interrupt already.
    Also I think digitalWrite and digitalRead are slower because to my knowledge function calls (depending on the used calling convention) just happen to be slow (pushing parameters, creating stack frame, jumping to function, jumping back etc). I could imagine though that these time critical functions are inlined and I don't know if function calls are the same on microcontrollers, I have way more experience on Intel/AMD CPUs in regular home computers.
    Keep up your work!

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

    Try 'cli();' to disable all interrupts.

  • @suelinerr
    @suelinerr 9 ปีที่แล้ว

    Thanks for sharing.

  • @espenbgh2540
    @espenbgh2540 8 ปีที่แล้ว

    The glory of the Arduino isnøt all that glory and the 16 MHz througput isn't allways 16 MHz. Brilliant show Julian.

  • @GoodScienceForYou
    @GoodScienceForYou 8 ปีที่แล้ว

    When doing mechanical "operations" as on a machine (calling out functions) the Arudino is so fast that humans can't tell there is a delay. When "this" goes on and "that" goes off, or from the time the button is pressed and 16 relays are switched It is less than 1/2 second. It is an amazingly easy to use device for controlling a lot of things. I am using a Mega board for my project and all but 4 pins are empty.

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

    Two things. C++ is closer to the metal but it is not assembler.
    1) Each line of code will be 1 to n lines of assembler.
    2) any function call in c++ pushes values onto the stack and the return pops those values off the stack... Or potentially anyway. Pushes and pops are moving registers to / from memory and take time.
    3) use an xor to flip the bit. That should leave the other bits of the register alone.

  • @k0ppit
    @k0ppit 9 ปีที่แล้ว

    +Julian Ilett A trick to toggle an output pin is to write 1 to that pins "Input Pins Register". Use "cli()" end "sei()" to disable/enable global interrupts.

    • @k0ppit
      @k0ppit 9 ปีที่แล้ว

      k0ppit
      Got an Arduino Diecimila to toggle pin 8 at 2,66MHz and 50% duty cycle with this code.
      void setup() {
      cli(); // clear global interrupt
      DDRB |= 1

    • @k0ppit
      @k0ppit 9 ปีที่แล้ว

      k0ppit
      Got an Arduino Diecimila to toggle pin 8 at 4MHz and 25% duty cycle with this code.
      void setup() {
      cli(); // clear global interrupt
      DDRB |= 1

  • @DeepankarMaithani
    @DeepankarMaithani 9 ปีที่แล้ว

    Great video

  • @pedromms8908
    @pedromms8908 9 ปีที่แล้ว

    And that's why I allways used AVR Studio to develop Arduino ASSEMBLY scripts when I needed a "fast" arduino response time.
    I now it was slow, but I never thought that "arduino IDE style" sketches were so slow!

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

    How much is the current draw on this in an hour?

  • @eight-double-three
    @eight-double-three 7 ปีที่แล้ว

    There's a valid reason to doing the mapping dynamically: This way you're able to use digital write with the port number from a variable. Analysing the code, and replacing the ones where the pin number argument to digitalWrite() is a constant would be a solution, but that's not a trivial job on one hand, and would pretty much make the timing with different digitalWrite() calls inconsistent.

  • @jameslamb4573
    @jameslamb4573 9 ปีที่แล้ว

    I'm surprised you didn't reverse the order, i.e. off then on, to check it was the loop introducing the delay and not some weird propagation problem or capacitance etc. effect.
    Funny how programming goes back to basics, it's as if machine code has decided to make itself known to a whole new generation of programmers.
    Nice work!

  • @aitorsierra
    @aitorsierra 9 ปีที่แล้ว

    I recently made this test with the same Arduino code but also i made other tests with other boards such as Stellaris (Texas Instruments), Arduino M0 Pro and Microchip PIC. I will upload a video with the results

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

    Hi, love watching your videos, thought i would do a comparison between arduino bootloader and using Atmel Studio, Atmel Studio was 120ns between port on and off where as Arduino was 400us. Massive diference!!

  • @mantaz111
    @mantaz111 9 ปีที่แล้ว +2

    What if you put port output set instructions in a while(true) loop, so that function loop() doesn't have to end?

    • @RonNewsham
      @RonNewsham 9 ปีที่แล้ว +2

      mantaz111 I was wondering the same thing and dug out the code that Arduino executes. There is behind the scenes a main() that does some stuff including:
      setup();
      for (;;) {
      loop();
      if (serialEventRun) serialEventRun();
      }
      It is fairly clear that there is the overhead of calling the loop() function (so that's a few instructions to throw some registers onto the stack, perform the call then restore the registers from stack) - not too much, but nonetheless a function call.
      But then there is also the test to decide whether to run a serial event.
      The bottom line here is that there is the overhead of convenience (being able to use pin 13 rather than port D bit 5 or whatever), and the overhead of the framework (additional function calls, overhead of timers) that may be useful and helpful, or not.
      The nice thing is that you generally have a choice - use the Arduino and the convenience (and limitations), or use the lower-level machine instructions (either in C or assembly language).

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

    the digitalWrite actually performs a hell of hand-holding to try and prevent unexpected behaviour like writing digitally to a pin reserved by a peripheral and stuff like that, that's why they do it at runtime (they check a bunch of registers to see if it should actually do stuff to the port). also the loop does other stuff in the background like checking/managing a system timer etc, this most likely introduces the overhead. also remember arduino is derived from C++, this might also introduce a small call overhead as opposed to C, also loop is an actual function, so not just a jump-back has to be performed but also stack stuff and calling/returning.
    tl;dr: safer/nicer for hobbyists who aren't that much into low level programming or just too lazy to care for a small project that doesn't have to run that performant, but introduces a LOAD of overhead. that's why I try not to use it if possible (avr-gcc/libc and a few small libraries to link to for common tasks is just fine) but it's great it exists, gets people into microcontrollers :)

  • @mankav
    @mankav 8 ปีที่แล้ว

    Interesting video

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

    The issue is loop overhead. Calling a subroutine is very tedious. This is fixable by applying Bit-Banging which is port read right of all 8 pins in a port in one step. Reading a port the same way is much faster. Also clocking loop out using while(1) {...} to contain the action speeds up things by about 62 clock cycles vs the loop() { .... } thing

  • @JerryEricsson
    @JerryEricsson 9 ปีที่แล้ว

    Nice to see a fellow can still get to the raw insides of one of these little gems. Shades of the old C=64 machine language programmer that came with RUN magazine or one of those Commodore magazines, perhaps it was Commodore?

  • @36trooper
    @36trooper 9 ปีที่แล้ว

    Do you still need the pinmode function in the setup if you're using port assignments instead of the digital out command?

  • @reggiebacci
    @reggiebacci 9 ปีที่แล้ว

    I think the reason for the runtime conversion is so that you're able to specify the Arduino output pin as a variable, so you can loop through or address a number of pins e.g. for (myPin...) {digitalWrite (myPin, HIGH); }
    Obviously this wouldn't be possible if these were translated as constants at compile time.

  • @BokoMoko65
    @BokoMoko65 8 ปีที่แล้ว

    Have you tried to invert the order of the high/low ? Just to make sure the overhead is actually from the flow control and not the high/low process itself.

  • @RaoulRacingRC
    @RaoulRacingRC 8 ปีที่แล้ว

    Nice video, I got a question after watching this video. What do I need to use instead of analogWrite, analogRead and digitalRead? If my porgram still contains analogWrite, analogRead or digitalRead it is slowing down on that isn't it?

  • @kuyanatnatdkrx7
    @kuyanatnatdkrx7 9 ปีที่แล้ว

    if you want to remove the noise which is caused from the built pre coded interrupts you can type noInterupt() function to disable them and type interrupts() to reable them. If you really want a high efficient code for tasks that require high precision time based code then I think it is best to stick to the original type of microcontroller coding and that is doing it the hard way. Also note when I say efficient I mean being able to type code like _asm("wfi") and save power but that would be redundant in the arduino IDE and libraries as there is interrupts happening everywhere.

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

    The fastest possible output is 4 MHz for 16 MHz Atmega328P. But, it has 62.5 ns ON state, and three times that (three cycles, or 187.5 ns) OFF state (if one want equal ON and OFF state - out freq is 2.6666...7 MHz, so un-comment asm codes if needed):
    void setup(){
    TIMSK0=0; //disable watchdog interrupt
    DDRB = DDRB | B00100000;//only pin13 (PB5) as output
    while(1){
    PORTB=(1

  • @IGBeTix-Electronique
    @IGBeTix-Electronique 9 ปีที่แล้ว

    Exact, my mesurements where approximately 5 microseconds for the "high 13" instruction (on the parallax propscope).

  • @TechBuild
    @TechBuild 7 ปีที่แล้ว

    Which is the fastest and the slowest Arduino board?

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

    Time frame 8:50 > this is because of the parasitic on board capacitor and the sampling capability of your scope. If you use a scope with much higher sampling capability, and probes with better isolation, then you may be able to see that flat top ON section of your "Square" wave. Since you are still using the brackets of your loop then that takes relatively much more time to execute and that why the OFF period is way much longer that ON. If you use assembly code and the Atmel Studio I bet you will get way much better response / without having to duplicate PORTB = B00100000 and slow down the CPU execution speed > better yet, use PORTB.5 to slightly speed it up. Atmel Studio is easy to use and has very powerful features and I highly recommend that everyone use it along with Arduino IDE. That also looks good on your resume.

  • @Jadinandrews
    @Jadinandrews 9 ปีที่แล้ว

    Great video, I see a lot of people saying you should have used assembly, but then you wouldn't really be assessing the performance of an 'Arduino'. I'd rather switch to a more powerful micro if performance was that big a deal before learning assembly. That said, it would be real interesting to see how far the atmega 328 can be pushed with assembly.

  • @aaaafaaaaf
    @aaaafaaaaf 8 ปีที่แล้ว

    Julian,
    Ca you please tell me what installer you used to program the arduino nano, I purchased 6 of them to save on shipping, but I am not able to attach to it via the USB. Can you tell the model number and where you go it, THANK YOU in advance.

  • @EZ_shop
    @EZ_shop 8 ปีที่แล้ว

    Very interesting.

  • @MithiSevilla
    @MithiSevilla 9 ปีที่แล้ว

    Thanks for this! Great video!
    I do hope the developers find a way to optimize the conversion eventually.
    For example from pololu's library this command:
    set_digital_output(IO_D3, HIGH);
    compiles to this in assembly:
    sbi 0x0b, 3 ;i.e. PORTD |= 1

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

    That is some really rustic looking soldermask and silkscreen on that arduino. Looks almost like when you get a PCB from the 80s where the solder mask goes all crinkly.

  • @jpl0087
    @jpl0087 8 ปีที่แล้ว +3

    arduino might use bitwise operation to change only 1 output. so your test ist missleading since you make 2 total different compairison. write the second part manipulation in a way that the other 7 bits are ignored. now you set acctually 1 bit high and 7 low. since it is an 8 bit processor you can manipulate 8 outputs in parallel. thanks for a follow-up

    • @NGC1433
      @NGC1433 7 ปีที่แล้ว

      Atmegas ALWAYS overwrite the whole buffer at once, disregarding how much bits you change, it is a single cycle instruction.

    • @jpl0087
      @jpl0087 7 ปีที่แล้ว +2

      yes, but to get a 8 bit row of outputs changed, you need some math, and that takes time. modify one complete Port in AVR, and you bypass the arduino implementation.
      DDRB = 0b11111111; //set all pins of port b as outputs
      PORTB = 0xFF; //write data on port
      This will be the faster way. It is regular C AVR programming and no arduino interaction is being processed.

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

    Fascinating.

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

    Pin-Toggle on AVRs like the M328: PINB = (1

  • @n3qxc
    @n3qxc 7 ปีที่แล้ว

    if you lowered the cycle frequency on pin 13 to an audible tone.... can that interrupt signal be detected in a speaker or audio amplifier?

  • @MilanKarakas
    @MilanKarakas 8 ปีที่แล้ว

    My last comment is about the "fastest possible" output of only 4 MHz from Arduino working on 16 MHz. It can do better - 8 MHz, but only in burst mode - switching on and off by some sort of lookup table. The code:
    void setup(){
    TIMSK0=0; //disable watchdog interrupt
    DDRB = DDRB | B00100000;//only pin13 (PB5) as output
    }
    void loop(){
    eightMHzBurst();
    }
    void eightMHzBurst(){
    PORTB=(1

  • @NiCadHeliPilot
    @NiCadHeliPilot 8 ปีที่แล้ว

    Great vid. That's quite a surprise on how slow the Arduino Bootloader (the firmware that uses the stuff that you've typed up in the IDE) actually is.
    I suppose it wouldn't matter so much for most general stuff, but I"m wonderin' how much would that hold back something like a brushless ESC?

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

    Thank you. Extremely well explained. Doesn't the Arduino also have a 'micros' function which keeps a count of the elapsed microseconds? Does this also use an interrupt?

  • @PeterBrockie
    @PeterBrockie 9 ปีที่แล้ว

    I think A0-A5 are defined as D14+ under Arduino if you don't need the analog functions.

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

    You can use bitwise OR with a bitmask, this will set only the bit needed.

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

    Hi Julian, at first, well explained and easy to understand, but you can do something to bring the speed up to nearly 8MHz ( 2 clockcycles), without using Assembler. For example, try a "while 1- loop" (like Captain-Slow sad) with Portmanipulation. I know, its not good in a program, but works fine. At second, You don't have to write only "1" to Pin 13 and at last once "0", if you "copy-paste" the "ON-OFF-command" a serval times, the speed will increase drastically. ^^) (I tried with about 100, 200, 400 and 21000 changes within the while(true) [last one doesn't work --> little joke :) ] )
    I know you are a few steps ahead of me, but I like it if someone gives me a little push to see new/better results. ^^)

  • @yoramstein
    @yoramstein 7 ปีที่แล้ว

    QUESTION- if an Arduino gets 5Volts Vcc what should be input at one of the Analog inputs in order that it will show 1024 reading from its A/D converter? is it also 5volts?

    • @JulianIlett
      @JulianIlett  7 ปีที่แล้ว

      Interesting question. The A/D converter can't return 1024, the maximum result is 1023. This does not indicate a precise voltage - it indicates a voltage range - very close to 5V but with about 5mV of latitude.

  • @a1fliema1fie
    @a1fliema1fie 9 ปีที่แล้ว

    As others have said , a while true loop and a single bit toggle is the fastest. For reference I got around 4MHz from an arduino uno. Also, I noticed you get a much cleaner signal if the usb power is supplied by a wall wart. Mty laptop usb produces an unacceptable amount of noise.

  • @nickpelov
    @nickpelov 9 ปีที่แล้ว

    the arduino is probably doing more than just a jump in the loop function. What you could try is to do the direct portB write instructions in a while loop.

  • @tengelgeer
    @tengelgeer 9 ปีที่แล้ว

    Julian, as you might have found by now there is a interrupt enable bit. It's (for a Atmega168) bit 7 of the SREG register. But there is a quick macro for it, cli() (CLear Interrupt) en sei() (SEt Interrupt).
    And yeay, Arduino has a lot of overhead. But it's always a trade of between fast, versatile and complex or slower, more static but a lot easier. And the last part is the whole reason, making it easy to use.
    But what are you planning on doing? Sounds like you should just use the PWM.

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

    1:00] 16m not k, thanks for sharing, they come in handy for replacing a few old custom ics made in late 70's early 80's.