Faster Digital Writes with Arduino Tutorial! - Direct Port & Register Manipulation

แชร์
ฝัง
  • เผยแพร่เมื่อ 11 ก.พ. 2016
  • In this video I'll show you how flipping bits in ports and registers work. I was doing a lot of this in the Low Power Series videos.
    But remember that I did the same kind of thing in my LED Cube project, but that was to speed up the turn ON and OFF of digital pins.
    I never got into how much faster it was, so in this video we'll measure it!
    Here's the link to the cheater board I designed - I've been sending these out as a thank-you to the Patrons of this channel:
    www.kevindarrah.com/wiki/index...
    Check out my Tindie store (trigBoard is available) www.tindie.com/stores/kdcircu...
    Thanks to all the Patrons for dropping a few bucks in the tip jar to help make these videos happen!
    / kdarrah
    Twitter: / kdcircuits
    For inquiries or design services:
    www.kdcircuits.com
  • วิทยาศาสตร์และเทคโนโลยี

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

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

    I have watched a few videos on the subject but managed to grasp the concept after watching this one. Thank you.

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

    I don't quite understand everything here but that byte reduction is INCREDIBLE! Can't wait to try this out!

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

    I´ve learned so much from your videos Kevin! I went back over them a few times in a couple of years, and now direct port manipulation seem the shizzle... ;) Thanks!

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

    Thanks again Kevin. Very well explained as usual!
    This reminds me of the Uni guy David on the EEVblog channel rewriting C++ math functions
    to speed up his 3D printer. Sure, higher level code is good, but at a major price in overhead.

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

    So Kevin, I've watched several of your videos now over a period of time of course. I started with the Shift Registers and somehow always stumble across your videos when trying to learn about whatever it is I'm working on at the moment. So I think it's more than appropriate to like and subscribe.
    Now this video shed some light from the power series I watched prior. This more or less pulled the blinds up to let the light in. So now here goes that really dumb question at lightspeed. I'm currently working on some LoRa Feathers I bought from Adafruit. The idea with this project is sense PIR statuses and send that data via radio packets to another radio. Now in order for this to be a feasible project I am going to manage power much as you described in the Power series. But I also want to use interrupts and the like. So in other words these radios will be just chilling around the backyard, the solar panels will be feeding the batteries until a motion is sensed. At which point the Feather will wake up do the radio TX/RX and go back to sleep. Long story short, Can I use these methods on just about any Atmel even though it's on an Arduino Compatible of various sorts? I don't need any special IDE settings? Or a library to use code bits like portd?

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

    Exactly what I've been needing. Perfect. Thank you!

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

    Great video, thanks Kevin.
    It's interesting that some of the comments demonstrate exactly why functions like digitalWrite () exists. Many arduino programmers don't understand the avr microcontroller and/or the math needed to twiddle bits...
    It's great though to see everyone having fun with arduino. Some may even get interested enough toin look at Atmel's atmega328p datasheets and some AVR microcontroller programming books. If they do they won't be sorry... It will be like taking off the training wheels.

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

    Liked and subscribed. I have to build a circuit for short duration pulse. I am shifting my home tomorrow and decided i should finish this and many more works before i leave my township that i stayed for 23 yeaRs . Thank u so much ! I dont know if u will read this .. but thank u

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

    Kevin, thanks for this and all the other vids you have been doing so far. All very clear and inspiring. I may be off topic here, but I'd like to know your opinion about particle Photon. thanks.

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

    Thanks so much for this video ! It made many things clearer to me (including what bit shifting is, and how it's done ;) ). Do you have any idea of what "digitalWrite" is doing that it is so much slower?

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

    Nice technique. Its interesting if we can see what maximum frequency you can toggle the port using the two methods.
    Thanks.

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

    At last!!! Someone could explain this.
    Thank you very much !

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

    what happens if you remove the sleep, then measure the frequency it switches the led on your scope? I bet with the direct port manipulation you'd notice you could switch at a higher frequency. unless your arduino's clocks are synced, I don't think you can measure delay like that. not sure though

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

    hi. could you explain how i should connect the osciloscope probe to the pin of the Mcu

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

    Is it possible to do a parallel input using a Port command and how is this done?

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

    It would also be instructive to see how long it takes from the interrupt line going low to the LEDs turning on.

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

    Hmm, might be nice to turn 3 phase bldc motor faster, have to try sometimes when I find dead hard drive.
    Your tutorials are excellent and useful, eg. low power designs, I can learn from them a lot.

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

    This is the consequence for the easy entry in programming with the Arduino IDE.
    You will learn a lot about processors if you go into registers and clock cycles.
    All those arduino functions are compiled with a lot of jumps, stack pushing, RAM operations and finaly register operations.
    Every 16 clock cycles used for those operations more, slows down your execution by 1us.
    Bit-operations is something every programmer should learn.

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

    Thanks for this buddy. Nice work.

  • @jean-christophesicotte-bri1315
    @jean-christophesicotte-bri1315 5 ปีที่แล้ว

    Hi Kevin, I'm not sure why wouldnt it be simpler to just use the function bitset() to turn on a single bit in a byte, instead of using and or equals, shift to the right and all that good stuff? is because bitSet() cant be used with ports and registers? if so, I guess we could use a byte variable and bitSet whatever in it in order to pass its value to the port we want to change? Would that work?thanks!

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

    Great explanation Kevin.

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

    Hey, Kevin
    Do you happen to have a hardcover book with this weird stuff explaned with lots of examples.
    Direct port manipulation, registers & timers for Arduino Uno Nano (Atmega 328)

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

    i really enjoy your videos thank you for your time

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

    So, when you do this 'quicky' thing, you're simultaneously changing the state of other pins too I assume; correct me if I'm wrong.....thanks :)

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

    What is his USB to serial chip?

  • @rajeshsharma-ng3cb
    @rajeshsharma-ng3cb 6 ปีที่แล้ว +1

    Can you make a tutorial about timer interrupt in arduino I'll love to see it

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

    brilliant - thanks Kevin.

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

    I don't quite understand how it could be quicker unless it is a api inefficiency. You should request it to be implemented into the api, unless there is a very specific reason the api version is inefficient.

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

    Nice work. Thank you.

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

    Apologies if this is a dumb question... Instead of shifting 1, four times to the left to get the correct bit value / mask, could you just use "16" or "0xF" are they not 00010000 without the bitwise shift operations?
    (I saw a reply below suggesting using 0b00010000 if that would work?)
    Thanks for the video - it explained it really clearly :D

  • @rajeshsharma-ng3cb
    @rajeshsharma-ng3cb 6 ปีที่แล้ว

    Thanxx loved the way you explained

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

    Excellent information sir! Thanks of the time (no pun intended).

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

    Nice one Kevin, would appreciate if you could do one on interrupts with some examples likes of the old school PIC timers etc i.e. tmr0 and tmr1 stuff and how we can implement them in arduino efficiently

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

      +Syed Mazahir Rizvi yea, was thinking about that. The AVR has some pretty powerful timers/counters. The input capture counter is cool too - did a line frequency monitor project with that recently.

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

    How about using assembly code ?

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

    Great example. Thanks!

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

    Good explanation understand very well.

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

    Awesome man!

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

    Would it be faster to just use B00010000 or H10 instead of (1

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

    Great video Kevin, you shaved off 4+9 microseconds on a on off. Imagine the savings in loop with 1000s of iterations.

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

      +roy douce actually about 9us total - see David's comment below

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

    keep the vids going!

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

    thx, it helped me a lot!

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

    Wow man..great video..Thanks

  • @henkoegema6390
    @henkoegema6390 ปีที่แล้ว

    Clear explanation. 👋

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

    Hey Kevin .
    I have a pro mini and what i want is turn State of A1 and A0 simultaneously
    OLD WAY
    if Something
    digitalWrite(A0, LOW);
    digitalWrite(A1, HIGH);
    else
    digitalWrite(A1, LOW);
    digitalWrite(A0, HIGH);
    end
    New way
    if Something
    PORTC = (PORTC & B11111101) | B00000001;
    else
    PORTC = (PORTC & B11111110) | B00000010;
    end
    Is this Correct? if considering the used platform(arduino pro mini.)
    Thanks in advance

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

      I'd have to check the datasheet for the PORT assignment, but you if you want to tangle both, you could just shift over something like a B11, instead of (1

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

    Since the processor and ports are not bit addressable, the libraries will be doing the same operations for the bit twiddling. Either their implementation is extra super crappy (unlikely), or you are waiting out a port write (or a sequence of port writes) setting each pin with each digitalWrite(), depending on its implementation. The delay being a factor of the clock speed seems to indicate something along this line.
    The more interesting problem is setting multiple pins in sequence. With just the digital pins, you are setting up to 14 pins, that means a delay of somewhere between 4 us and 56 us (14 * 4) calling digitialWrite() for individual pins. The time depending on how many pins you are setting. Direct port manipulation is just however long it takes for the bit twiddling in the registers (fast) plus either one or two port writes take (depending on the number of pins set) for the same operation.

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

      +David Kirtley I recently changed my code from digitalWrite to PORTB and PORTD, and it drastically increased my speed.. I was multiplexing Nine 7 Segment displays at 60Hz with a binary to 7Segment IC and a Binary to Decimal IC. And you could see the haze of the previous/next value about to be wrote on the segments since I couldn't change the number and digit fast enough with 8 digitalWrites.. But after the changed to PORTB and PORTD writes, it is crystal clear.

  • @AliG.G
    @AliG.G 6 ปีที่แล้ว

    So whats the conclusion? There is no difference between digitalWrite or Direct port manipulation? Also I am lost where it says ~4ms.

    • @93Hotshot
      @93Hotshot 6 ปีที่แล้ว

      Ali G in a few words: your arduino acts faster with port manipulation, it change the pin states 4 microsecondes faster than the digital write function

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

    I learned that the shifting might take some cycles, how about writing to the port like this:
    PORTB = 0x01 or PORTB = 1
    Isn't it faster than writing a shifted value like:
    PORTB |= (1

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

      Yes, simply writing a byte value to a port is faster as it avoids all the shifting of a bit and the ANDing and ORing and NOTing. But it also wipes out the settings for all the other bits in the port. These other bits are digital inputs and outputs too, so altering 8 pins at a time when you only want to change 1 could really make your peripherals go nuts. Hence the need to only affect the target port bit when setting or clearing one pin - and that introduces the requirement for bit shifting and logic operations.

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

    Is there some way to digitalRead() with direct port manipulation?

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

      Please read: www.arduino.cc/en/Reference/PortManipulation

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

      Priyabrata Saha sure read pins register and mask off the unneeded bits and you can test for a 0 or greater than 0 to see if it was hi.

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

      portState = (PORTD & (1 > portNumber;
      To explain, "(1

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

    thanks u're the best !

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

    Why not use PORTD &= (0

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

      +Mahdi Shaban You cannot use (0

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

      +Colin Richardson ahh I see thanks for the reply

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

      So, I guess you could also use PORTD &= 10000

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

    i am assuming arduino does not support things like portd.4 & 00001000B.

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

      I was thinking why make another instruction operation of shift when you can use OR and the binary number wanted. As the same to reset. With the AND instruction.

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

    Can't you just do
    PORTD = (0

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

      no, because you want all the other bits in the register to remain unchanged - with your method, you would set them all to 0.

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

    Hey Kevin as always love your videos. I did a similar test a few years ago here...damage-designs.com/blog/2012/8/17/arduino-speed-test.html
    Question for you, does the shift operation itself (1

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

      +damage.cc good question - I've been wanting to write my own code to drive the WS2812 LEDs now for a while, so I'll need the writes to execute as fast possible. Might keep on trying new things to get them even faster.

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

      +damage.cc Compiler must convert it to a static value. Using the shift operation vs using a binary constant produces identical code. i.e. (1

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

      +Richard Casey wonder if it's compiler specific. Also, wonder if B00010000 and 0b00010000 turn out the same too.. So many ways to represent the same number.

  • @rasmushaun1773
    @rasmushaun1773 5 ปีที่แล้ว +4

    Nice video (:
    You could also just do:
    PORTD = B00010000;
    delayMicroseconds(5000);
    PORTD = B00000000;
    Or is it wrong? (:

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

      i think you could make
      PORTD = PORTD | B00010000; //Puts bit 4 High without the risk of changing any other bit
      delay(2500);
      PORTD = PORTD & B11101111; //Puts bit 4 Low without the risk of changing any other bit.
      delay(2500);
      i tested this in atmel studio 7

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

    You shouldn't use delay in interrupt

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

    OK so direct port manipulation is faster but is not assembly language even faster?

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

      It depends on the programmer. ;) But yes, assembly code is generally faster to run than any compiled language.
      The trade-off is that a compiled language will take care of many "fiddly bits" for you and is easier to write and usually easier to understand, while assembly code requires the programmer to think of everything (pretty much literally everything) and is a bit more difficult to understand.

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

      @jasonMasters I thing it is a Byte more difficult to understand

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

    you can do it in another way just simply do PORTB=40;

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

    Those circuits you show in your circuit don't look like Arduinos. Are they Microcontrollers?

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

    Wow, this is hard enough to understand without all the mistakes.... can you do it again please?!

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

    I heard you liked breadboards, so I got you some breadboards for your breadboards so you can bread while you board.

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

    Quinn from Homeland?

  • @szafran1543
    @szafran1543 8 ปีที่แล้ว +5

    Dude, you looks like Leonardo Dicaprio :D:D:D

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

      if leonardo dicaprio and johny deep have a child

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

    if you showing any code....zoom in...it annyos the hell out of me if i have to go to my PC and look your videos there...

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

    Instead of PORTD &= ~(1

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

      +Srijal Poojari nice, yea, that should work too

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

      Kevin Darrah cool, thanks!

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

      this will toggle the bit

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

      Oreganodealer LS OG What do you mean?

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

      PORTD ^= (1

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

    You know fastwrite but dont know to increase font size.

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

    if this is better than why is there DigitalWrite at all?

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

      +mattibboss humanized command.

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

      digitalWrite () uses the arduino mapped pins. digitalWrite () calls library functions to find the mapped AVR port and port bit #.
      Using digitalWrite () simplifies coding at the expense of performance. Also, it only sets or clears one bit at a time, which creates a ton of unnecessary overhead if you need to set/clear several bits in the same port.
      Run your arduino code from debugger and you will see all the function calls needed to find the port/bit to set/clear.
      digitalWrite() simpifies arduino programming so you won't need to reference the atmel atmega328p datasheets, which a lot of people (especially beginners) find a bit confusing.

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

    ... or you could just learn to program in your Arduino's native language via assembly code. ;)

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

    Why would anyone use those stupid arduino libraries on such a simple mcu?!