{"id":9732,"date":"2020-11-19T12:43:02","date_gmt":"2020-11-19T12:43:02","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/logical-operations-and-port-manipulation"},"modified":"2022-08-04T15:47:08","modified_gmt":"2022-08-04T15:47:08","slug":"logical-operations-and-port-manipulation","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation","title":{"rendered":"Logical operations and port manipulation"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About the post<\/h2>\n\n<p>In many articles, including my last one on <a href=\"https:\/\/wolles-elektronikkiste.de\/ir-remote-controls?lang=en\" target=\"_blank\" rel=\"noopener noreferrer\">IR remote controls<\/a>, I have used logical operations and port manipulation. By this I mean expressions such as <code>PORTD |= (1&lt;&lt;PD2)<\/code> instead of <code>digitalWrite(2, HIGH)<\/code>. In this article, I would like to address this issue separately.<\/p>\r\n<p>Granted, this is a little \u201cdry\u201d. It doesn\u2019t really get interesting until you apply it. So far, however, due to the size of this topic there has been no room for it in my posts so far. So consider this post as a kind of reference that I will refer to when I use binary logic and port manipulation again.<\/p>\n\n<p>I will start with logical operations (bitwise operations) and then turn to the ports of the ATmega328P and port manipulation. Then I\u2019ll have a little practical exercise for you. Finally, there is a speed comparison and I answer the question of why port manipulation is so much faster.<\/p>\n\n<h2 class=\"wp-block-heading\">Why are logical operations and port manipulation relevant?<\/h2>\n\n<p>Port manipulation, i.e. direct access to Arduino pins (or other boards or microcontrollers) via its ports, is much faster than the usual Arduino functions. Most of the time it doesn\u2019t matter, but sometimes it does. And the logical operations with their bitwise operators are the tool for this. The grammar, so to speak.<\/p>\r\n\r\n<p>Actually, I don\u2019t really like the term \u201cport manipulation\u201d. It sounds like it would be forbidden. Basically, however, it is the more natural way to program microcontrollers. <code>digitalWrite<\/code>, <code>pinMode<\/code> and Co, on the other hand, actually obscure the view of what is actually happening at the hardware level.<\/p>\n\n<p>Logical Operations come into play even when you are generally involved in programming registers, such as in sensors. One often has to deal with tasks such as \u201cwrite 101 into the bits 3-5 of the register XY&#8221;. This can only be reasonably done with logical (bitwise) operations.<\/p>\r\n\n<h2 class=\"wp-block-heading\">Logic operations: the bit operators<\/h2>\n\n<h3 class=\"wp-block-heading\">Bit operators and shift operators<\/h3>\n\n<p>The main bit operators are:<\/p>\r\n<ul>\r\n \t<li><strong>&amp;<\/strong> logical AND UND<\/li>\r\n \t<li><strong>|<\/strong> logical OR<\/li>\r\n \t<li><strong>^<\/strong> exclusive OR (XOR)<\/li>\r\n \t<li><strong>~<\/strong> negation (NOT)<\/li>\r\n<\/ul>\r\n<p>A major difference from the usual operators such as plus or minus is that the bit operators are applied bit by bit. The shift operators are: <\/p>\r\n<ul>\r\n \t<li><strong>&gt;&gt;<\/strong> right shift<\/li>\r\n \t<li><strong>&lt;&lt;<\/strong> left shift<\/li>\r\n<\/ul>\n\n<h4 class=\"wp-block-heading\">Bit operator AND (&amp;)<\/h4>\n\n<p>The bit operator AND checks whether the two operands are 1 (true). If this is the case, then the result is 1, otherwise 0 (false).<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0 &amp; 0 = 0\r\n1 &amp; 0 = 0\r\n0 &amp; 1 = 0\r\n1 &amp; 1 = 1<\/pre>\r\n<p>Applied to bytes:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0b10011100 &amp; 0b01010111 = 0b00010100<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Bit operator OR (|)<\/h4>\n\n<p>The bit operator OR checks whether <em>at least<\/em> one of the two operands is 1 (true). If so, then the result is 1, otherwise 0.<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0 | 0 = 0\r\n1 | 0 = 1\r\n0 | 1 = 1\r\n1 | 1 = 1 <\/pre>\r\n<p>Applied to bytes:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0b10011100 | 0b01010111 = 0b11011111<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Bit operator XOR (^)<\/h4>\n\n<p>The bit operator XOR checks whether exactly one of the two operands is 1. If this is the case the result is 1, otherwise it is 0. In contrast to OR this operator delivers 0 even if both operands are 1.<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0 ^ 0 = 0\r\n1 ^ 0 = 1 \r\n0 ^ 1 = 1 \r\n1 ^ 1 = 0<\/pre>\r\n<p>Applied to bytes:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">0b10011100 ^ 0b01010111 = 0b11001011<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Bit operator NOT (~)<\/h4>\n\n<p>The bit operator NOT has only one operand. NOT reverses the value, so 1 (true) becomes 0 (false) and vice versa.<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">~0 = 1\r\n~1 = 0<\/pre>\r\n<p>Applied to bytes:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">~0b10011100 = 0b01100011<\/pre>\r\n\n<h4 class=\"wp-block-heading\">Shift operators<\/h4>\n\n<p>Shift operators shift a number bitwise to the right or left. A shift of x digits to the left corresponds to a multiplication of 2<sup>x<\/sup>. A shift of x digits to the right corresponds to a division by 2<sup>x<\/sup>.<\/p> \r\n<p>Shifting to the right eliminates all digits that are moved behind the first digit (LSB = least significant bit). Moving to the left eliminates all digits that are outside the value range of the variable (beyond the MSB = most significant bit).<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">(0b1 &lt;&lt; 1) = 10\r\n(0b101 &lt;&lt; 1) = 1010\r\n(0b111 &gt;&gt; 1) = 11\r\n(0b11110000 &lt;&lt; 1) = 0b11100000 \/\/ if 0b11110000 has been defined as byte<\/pre>\r\n\n<p>There are a few pitfalls. What will be the output of the following sketch\r\nshiftoperator_test.ino?\r\n<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-group=\"shiftoperator_test.ino\" data-enlighter-title=\"shiftoperator_test.ino\">byte a,b,c;\r\nunsigned int d;\r\nint e;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  a = 0b1111;\r\n  b = a&lt;&lt;5;\r\n  c = a&gt;&gt;1;\r\n  d = a&lt;&lt;5;\r\n  e = a&lt;&lt;12;\r\n  Serial.print(\"a = \"); Serial.println(a, BIN);\r\n  Serial.print(\"b = \"); Serial.println(b, BIN);\r\n  Serial.print(\"c = \"); Serial.println(c, BIN);\r\n  Serial.print(\"d = \"); Serial.println(d, BIN);\r\n  Serial.print(\"e = \"); Serial.println(e, BIN); \r\n  Serial.print(\"e(dezimal) = \"); Serial.println(e); \r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>Here&#8217;s the (expected?) result, if you are using an AVR based board. In case you use a SAMD or ESP32 based board try and replace <code>e = a&lt;&lt;12<\/code> by <code>e = a&lt;&lt;28<\/code> and see what happens.<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/ausgabe_shift_sketch.png\"><img loading=\"lazy\" decoding=\"async\" width=\"734\" height=\"331\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/ausgabe_shift_sketch.png\" alt=\"Applied logic operations: output of the sketch shiftoperator_test.ino\" class=\"wp-image-8270\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/ausgabe_shift_sketch.png 734w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/ausgabe_shift_sketch-300x135.png 300w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/a><figcaption>Output of the sketch shiftoperator_test.ino<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">The ports of the Arduino UNO<\/h2>\n\n<p>The Arduino UNO has fourteen digital I\/O pins (0 \u2013 13) and the six \u201cquasi-analog\u201d I\/O pins A0 to A5. If you look at the data sheet of the ATmega328P, the core of the Arduino, you will find the pins in a different organizational structure.<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Pinout-Atmega-328P-vs-Arduino-UNO.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Pinout-Atmega-328P-vs-Arduino-UNO-1024x495.png\" alt=\"Pinout scheme of the Atmega328P; next to it: the Arduino UNO equivalents\" class=\"wp-image-8271\"\/><\/a><figcaption>Pinout of the ATmega328P, left and right of it the Arduino UNO equivalents<\/figcaption><\/figure>\n<p>The I\/O pins are organized in ports B, C and D. The pin designations are correspondingly PBx, PCx and PDx with x = 0 to a maximum of 7. For these groups there are three 8 bit registers, which I will discuss in a moment, namely DDRx, PORTx and PINx with x = B, C or D.<\/p>\r\n\n<p>The pins PB6 and PB7 are not accessible when using the Arduino UNO because the 16 MHz clock is hard-wired to them. PC6 is set as reset on the Arduino board and is therefore not accessible as an I\/O pin. PC7 simply does not exist.<\/p>\r\n\n<h3 class=\"wp-block-heading\">The data direction registers DDRx<\/h3>\n\n<p>If you want to use an I\/O pin as input or output, you do this setting in the \u201cArduino language\u201d via the <code>pinMode<\/code> function. In the ATmega328P, the corresponding bits are set in the relevant direction register (DDR = Data Direction Register). Here is the structure of the direction register for port B as an example:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"176\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB-1024x176.png\" alt=\"Data Direction register DDRB\" class=\"wp-image-8272\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB-1024x176.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB-300x52.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB-768x132.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/DDRB.png 1268w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Data Direction register DDRB<\/figcaption><\/figure>\n<p>As an example, I would like to set the digital pin 13 of the Arduino to OUTPUT. This corresponds to pin PB5 according to the pinout scheme from above. This means that bit No. 5 must be set in the DDRB register. Access to the register is easy. The following assignment is sufficient:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 0b100000<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 0x20<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 32<\/code><\/p>\r\n<p>It&#8217;s that easy because \u201cDDRB\u201d contains the necessary instructions via a <code>#define<\/code> statement in the AVR libraries (avr\/io.h &#8211;&gt; avr\/iom328p.h):<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#define DDRB _SFR_IO8(0x04)<\/code><\/p>\r\n<p>If you want to set several pins of port B to OUTPUT, e.g. pin 5 and pin 3, then the statement looks like this:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 0b101000<\/code>, or hexadecimal: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 0x28<\/code>, or decimal: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">DDRB = 40<\/code><\/p>\r\n\n<h3 class=\"wp-block-heading\">The port data register PORTx<\/h3>\n\n<p>If you want to set an I\/O pin that you had previously set to OUTPUT into the HIGH state, you will access the responsible port data register (PORTx) as part of port manipulation. Here PORTB as an example:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"173\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB-1024x173.png\" alt=\"PORTB data register\" class=\"wp-image-8273\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB-1024x173.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB-300x51.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB-768x129.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PORTB.png 1281w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>PORTB data register<\/figcaption><\/figure>\n<p>A pin is HIGH if you have set the corresponding bit. To stick to the example above of Arduino pin 13:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB = 0b100000<\/code> equals <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">digitalWrite(13, HIGH)<\/code><\/p>\r\n\n<p>Stop! Of course, the equivalence only applies to the effect on pin 13 (PB5) because the first assignment switches all other PORTB pins to LOW. On the other hand, <code>digitalWrite<\/code> is selective.<\/p>\r\n\n<h3 class=\"wp-block-heading\">The Port Input Pin Register PINx<\/h3>\n\n<p>You can query the state, i.e. LOW or HIGH, of an input pin via the corresponding PINx (x = B, C, D) register. For Arduino Pin 13 for example:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PINB == 0b100000<\/code>&nbsp;instead of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">digitalRead(13)<\/code><\/p>\r\n<p>Here, too, the restriction applies that digitalRead is selective while the PINB query in this form checks whether <em>only<\/em> PB5 is HIGH. <\/p>\r\n\n<h2 class=\"wp-block-heading\">Use of logical operations in port manipulation<\/h2>\n\n<h3 class=\"wp-block-heading\">Selective setting of bits<\/h3>\n\n<p>To <em>selectively<\/em> set a single or multiple bits, one uses the logical OR. For example, you can set PB5 to HIGH without affecting the remaining pins of the PORTB<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB = PORTB | 0b100000<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB |= 0b100000<\/code> or, preferrably:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB |= (1&lt;&lt;PB5)<\/code><\/p>\r\n<p>PB5 is simply defined as 5 by a #define assignment. So, you might as well write <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB |= (1&lt;&lt;5)<\/code>. You could even replace PB5 with PC5 or PD5. Of course, this would not be easy to read.<\/p><p>Several bits, such as PB5 and PB3, are set as follows: &nbsp;<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB |= (1&lt;&lt;PB5) | (1&lt;&lt;PB3)<\/code> because:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">(1&lt;&lt;PB5) | (1&lt;&lt;PB3) = 0b100000 | 0b1000 = 0b101000<\/code>&nbsp;<\/p>\r\n<p>Occasionally, you will also find _BV(x) instead of (1&lt;&lt;x). \u201cBV\u201d stands for bit value. Both are identical as a look into the library file sfr_defs.h shows: <\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">#define _BV(bit) (1 &lt;&lt; (bit))<\/code><\/p>\r\n\n<h3 class=\"wp-block-heading\">Selective deletion of bits<\/h3>\n\n<p>The selective deletion of bits is also simple, but it is not necessarily obvious at first sight. Again, I take PB5 as an example: <\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB &amp;= ~(1&lt;&lt;PB5)<\/code>, synonymous with:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB &amp;= ~(0b100000)<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB &amp;= 0b11011111<\/code><\/p>\r\n<p>Of course, you can also delete several bits simultaneously, here for example PB3 and PB5: <\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB &amp;= ~((1&lt;&lt;PB5)|(1&lt;&lt;PB3))<\/code><\/p>\r\n\n<h3 class=\"wp-block-heading\">Selective inverting of bits<\/h3>\n\n<p>The logical XOR is suitable for inverting individual bits. One takes advantage of the fact that <code>^1<\/code> turns 1 to 0 and vice versa. <code>^0<\/code>, on the other hand, is neutral. This way you invert PB5 selectively: <\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB ^= (1&lt;&lt;PB5)<\/code><\/p>\r\n<p>Or, if multiple bits shall be inverted:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB ^= (1&lt;&lt;PB5)|(1&lt;&lt;PB3)<\/code><\/p>\r\n<p>If you want to invert an entire port, two variants are possible: <\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB = ~PORTB<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PORTB ^= 0b11111111<\/code><\/p>\r\n\n<h3 class=\"wp-block-heading\">Selectively querying pin states<\/h3>\n\n<p>This is no surprise. The expression<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">PINB &amp; (1&lt;&lt;PB5) <\/code><\/p>\r\n<p>returns 0, i.e. false if PB5 is LOW. If PB5 is HIGH, then the expression is unequal to zero, i.e. true. The exact value, here 0b100000, i.e. 32, is not relevant.<\/p>\r\n\n<h2 class=\"wp-block-heading\">A little exercise sketch<\/h2>\n\n<p>Now you can try it out if you want. For this purpose, build the following circuit:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"754\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test-1024x754.png\" alt=\"Logical operations - Circuit for the sketch Portmanipulation_test.ino\" class=\"wp-image-8274\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test-1024x754.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test-300x221.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test-768x565.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/PortManipulation_Test.png 1189w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Wiring for the Sketch Portmanipulation_test.ino<\/figcaption><\/figure>\n<p>Then try the following sketch and play around with it a bit. Does it do what you have expected?<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-group=\"Portmanipulation_test.ino\" data-enlighter-title=\"Portmanipulation_test.ino\">int dTime = 2000; \/\/delay time \r\n\r\nvoid setup(){ \r\n  DDRD = 0xFF; \r\n} \r\n\r\nvoid loop() { \r\n  PORTD = 0b10101010; \r\n  delay(dTime); \r\n  PORTD |= (1&lt;&lt;PD6); \r\n  delay(dTime); \r\n  PORTD ^= (1&lt;&lt;PD6)|(1&lt;&lt;PD7);\r\n  delay(dTime);\r\n  PORTD |= (1&lt;&lt;PD0)|(1&lt;&lt;PD2)|(1&lt;&lt;PD4); \r\n  delay(dTime); \r\n  PORTD = (PORTD &gt;&gt; 3); \r\n  delay(dTime); \r\n  PORTD &amp;= ~((1&lt;&lt;PD0)|(1&lt;&lt;PD2)); \r\n  delay(dTime); \r\n  PORTD = ~PORTD; \r\n  delay(dTime);\r\n }<\/pre>\r\n<p>&nbsp;<\/p>\r\n\n<h2 class=\"wp-block-heading\">Port manipulation on other microcontrollers<\/h2>\n\n<p>Transferring what you have just learned about port manipulation to other microcontrollers is easy, at least as far as AVR representatives like ATmegas and ATtinys are concerned. A look at the pinout scheme, which you will find in the data sheet, is usually sufficient. For example, the ATtinys 25 \/ 45 \/ 85 have only PORTB with pins PB0 to PB5:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"187\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1-1024x187.png\" alt=\"\" class=\"wp-image-8047\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1-1024x187.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1-300x55.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1-768x140.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/06\/Attiny25_45_85-1.png 1111w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Pinout of the ATtiny 25 or 45 or 85<\/figcaption><\/figure>\n<p>85For non-AVR microcontrollers, direct port access can vary widely. For example, for the ESP8266 ESP01, there is one register for setting the bits and another for deleting them:<\/p>\r\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">GPOS |= (1&lt;&lt;Pin)<\/code> for HIGH, or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">GPOC |= (1&lt;&lt;Pin)<\/code> for LOW<\/p>\r\n\n<h2 class=\"wp-block-heading\">A small speed test<\/h2>\n\n<h3 class=\"wp-block-heading\">Port manipulation vs. digitalWrite<\/h3>\n\n<p>How much differs port manipulation from <code>digitalWrite<\/code> in terms of speed? To clarify this question, I used the following mini sketch and looked at the result of both methods on the oscilloscope.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-group=\"Portmanipulation_vs_digitalWrite.ino\" data-enlighter-title=\"Portmanipulation_vs_digitalWrite.ino\">void setup() {\r\n  DDRD = 0xFF;\r\n}\r\n\r\nvoid loop() {\r\n  \/\/PORTD |= (1&lt;&lt;PD3);\r\n  \/\/PORTD &amp;= ~(1&lt;&lt;PD3);\r\n  digitalWrite(3, HIGH);\r\n  digitalWrite(3, LOW);\r\n}<\/pre>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_DW.png\"><img loading=\"lazy\" decoding=\"async\" width=\"807\" height=\"514\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_DW.png\" alt=\"\" class=\"wp-image-8276\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_DW.png 807w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_DW-300x191.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_DW-768x489.png 768w\" sizes=\"auto, (max-width: 807px) 100vw, 807px\" \/><\/a><figcaption>Maximum frequency with digitalWrite<\/figcaption><\/figure>\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_PM.png\"><img loading=\"lazy\" decoding=\"async\" width=\"805\" height=\"513\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_PM.png\" alt=\"\" class=\"wp-image-8277\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_PM.png 805w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_PM-300x191.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Frequenz_mit_PM-768x489.png 768w\" sizes=\"auto, (max-width: 805px) 100vw, 805px\" \/><\/a><figcaption>Maximum frequency with port manipulation<\/figcaption><\/figure>\n<p>HIGH\/LOW cycles, when using <code>digitalWrite<\/code>, have a maximum frequency of 113 kHz, with port manipulation it is 2 MHz, so a good 17 times faster. 2 MHz means that only 8 processor clocks per cycle are required.<\/p>\r\n\n<h3 class=\"wp-block-heading\">Port manipulation vs. digitalRead<\/h3>\n\n<p>To determine the speed of <code>digitalRead<\/code> vs. <code>PINx &amp;= (1&lt;&lt;Pin)<\/code> I used both 100,000 times and determined the time required to do so.<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-group=\"PIND_Abfrage_vs_digitalRead.ino\" data-enlighter-title=\"PIND_Abfrage_vs_digitalRead.ino\">unsigned long numberOfReads = 100000;\r\nunsigned long startTime = 0;\r\nunsigned long readTimeLength = 0;\r\nbool pinStatus;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600); \r\n  pinMode(5,INPUT); \r\n}\r\n\r\nvoid loop() {\r\n  startTime = millis();\r\n  for(unsigned long i=0; i&lt;numberOfReads; i++){\r\n    pinStatus = digitalRead(5);\r\n  }\r\n  readTimeLength = millis() - startTime;\r\n  Serial.print(\"digitalRead: \");\r\n  Serial.print(readTimeLength);\r\n  Serial.print(\" ms \");\r\n  Serial.print(\" \/ \");\r\n  delay(1000);\r\n  \r\n  startTime = millis();\r\n  for(unsigned long i=0; i&lt;numberOfReads; i++){\r\n    pinStatus = (PIND &amp; (1&lt;&lt;PD5));\r\n  }\r\n  readTimeLength = millis() - startTime;\r\n  Serial.print(\"PIND Abfrage: \"); \r\n  Serial.print(readTimeLength);\r\n  Serial.println(\" ms\");\r\n  delay(5000);\r\n}<\/pre>\r\n\n<p>The result:<\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/c_vs_arduino_output.png\"><img loading=\"lazy\" decoding=\"async\" width=\"734\" height=\"333\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/c_vs_arduino_output.png\" alt=\"digitalRead vs. direct PINx query - the advantage of logical operations and port manipulation\" class=\"wp-image-8275\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/c_vs_arduino_output.png 734w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/c_vs_arduino_output-300x136.png 300w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/a><figcaption>digitalRead vs. direct PINx query<\/figcaption><\/figure>\n<p>The direct PIND query is therefore a good eight times faster than <code>digitalRead<\/code>. Division by 100000 shows that the <code>digitalRead<\/code> function requires about 3.5 \u00b5s, while direct querying only takes about 0.44 \u00b5s. Of course, this is not exactly the case, as the loop processing itself takes some time. But it shows at least that the difference is significant. <\/p>\r\n\n<h3 class=\"wp-block-heading\">Where does the difference come from?<\/h3>\n\n<p>The reason for difference in speed is that <code>digitalRead<\/code> and <code>digitalWrite<\/code> do much more than the simple port manipulation functions. The additional measures that <code>digitalRead<\/code> and <code>digitalWrite<\/code> take, make the functions more robust against errors. If you don\u2019t need the speed gain due to port manipulation, then you can still use <code>digitalRead<\/code> and <code>digitalWrite<\/code>. As an example here is the definition of the <code>digitalWrite<\/code> function that you can find in the file Arduino\\hardware\\arduino\\avr\\cores\\arduino\\wiring_digital.c\r\n<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-group=\"digitalWrite_function\" data-enlighter-title=\"digitalWrite_function\">void digitalWrite(uint8_t pin, uint8_t val)\r\n{\r\n  uint8_t timer = digitalPinToTimer(pin);\r\n  uint8_t bit = digitalPinToBitMask(pin);\r\n  uint8_t port = digitalPinToPort(pin);\r\n  volatile uint8_t *out;\r\n\r\n  if (port == NOT_A_PIN) return;\r\n\r\n  \/\/ If the pin that support PWM output, we need to turn it off\r\n  \/\/ before doing a digital write.\r\n  if (timer != NOT_ON_TIMER) turnOffPWM(timer);\r\n\r\n  out = portOutputRegister(port);\r\n\r\n  uint8_t oldSREG = SREG;\r\n  cli();\r\n\r\n  if (val == LOW) {\r\n    *out &amp;= ~bit;\r\n  } else {\r\n    *out |= bit;\r\n  }\r\n\r\n  SREG = oldSREG;\r\n}<\/pre>\r\n<p>&nbsp;<\/p>\r\n\n<h2 class=\"wp-block-heading\">Acknowledgement<\/h2>\n\n<p>I have taken the Arduino in the post image from <a href=\"https:\/\/pixabay.com\/de\/users\/LenaertsDaan-535541\/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1128227\" target=\"_blank\" rel=\"noopener noreferrer\">Daan Lenaerts<\/a> on <a href=\"https:\/\/pixabay.com\/de\/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1128227\" target=\"_blank\" rel=\"noopener noreferrer\">Pixabay<\/a>. The zeros and ones (which I cut out, colored and inserted as a layer) I owe to <a href=\"https:\/\/pixabay.com\/de\/users\/geralt-9301\/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3253681\" target=\"_blank\" rel=\"noopener noreferrer\">Gerd Altmann<\/a>, also on <a href=\"https:\/\/pixabay.com\/de\/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3253681\" target=\"_blank\" rel=\"noopener noreferrer\">Pixabay<\/a>.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article. <\/p>\n","protected":false},"author":1,"featured_media":8269,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[543],"tags":[956,556,961,967,968,960,972,963,964,965,958,970],"class_list":["post-9732","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-boards-and-microcontrollers","tag-_bv-en","tag-arduino-en-2","tag-bitwise-operators","tag-digitalread-en","tag-digitalwrite-en","tag-logical-operations-en","tag-port-manipulation-en-2","tag-portb-en-2","tag-portc-en","tag-portd-en","tag-portmanipulation-en","tag-speed"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Logical operations and port manipulation &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Logical operations and port manipulation &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-19T12:43:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-08-04T15:47:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"1280\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Logical operations and port manipulation\",\"datePublished\":\"2020-11-19T12:43:02+00:00\",\"dateModified\":\"2022-08-04T15:47:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation\"},\"wordCount\":1818,\"commentCount\":10,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/Beitragsbild.jpg\",\"keywords\":[\"_BV\",\"Arduino\",\"bitwise operators\",\"digitalread\",\"digitalwrite\",\"logical operations\",\"port manipulation\",\"PortB\",\"PORTC\",\"PORTD\",\"portmanipulation\",\"speed\"],\"articleSection\":[\"Boards and Microcontrollers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation\",\"name\":\"Logical operations and port manipulation &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/Beitragsbild.jpg\",\"datePublished\":\"2020-11-19T12:43:02+00:00\",\"dateModified\":\"2022-08-04T15:47:08+00:00\",\"description\":\"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/Beitragsbild.jpg\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/Beitragsbild.jpg\",\"width\":1280,\"height\":1280},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/logical-operations-and-port-manipulation#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Logical operations and port manipulation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Logical operations and port manipulation &#8226; Wolles Elektronikkiste","description":"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation","og_locale":"en_US","og_type":"article","og_title":"Logical operations and port manipulation &#8226; Wolles Elektronikkiste","og_description":"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation","og_site_name":"Wolles Elektronikkiste","article_published_time":"2020-11-19T12:43:02+00:00","article_modified_time":"2022-08-04T15:47:08+00:00","og_image":[{"width":1280,"height":1280,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg","type":"image\/jpeg"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Logical operations and port manipulation","datePublished":"2020-11-19T12:43:02+00:00","dateModified":"2022-08-04T15:47:08+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation"},"wordCount":1818,"commentCount":10,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg","keywords":["_BV","Arduino","bitwise operators","digitalread","digitalwrite","logical operations","port manipulation","PortB","PORTC","PORTD","portmanipulation","speed"],"articleSection":["Boards and Microcontrollers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation","url":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation","name":"Logical operations and port manipulation &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg","datePublished":"2020-11-19T12:43:02+00:00","dateModified":"2022-08-04T15:47:08+00:00","description":"Portmanipulation is much faster than the classic Arduino functions. For this, logical operations are the basic tool. Both will be explained in this article.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/12\/Beitragsbild.jpg","width":1280,"height":1280},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/logical-operations-and-port-manipulation#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Logical operations and port manipulation"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/9732","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=9732"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/9732\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/8269"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=9732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=9732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=9732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}