Open the Blink.ino example. Remove all the comments so that we get this
void setup() { pinMode(LED_BUILTIN, OUTPUT);}
void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(1000);
digitalWrite(LED_BUILTIN, LOW); delay(1000);}
Compile and we see a very small sketch
Upload to a board and watch the built in LED connected to pin13 blink.
Our code become instructions to a program called a compiler. The compiler translates our source program to machine code. We can call pin13 LED_BUILTIN because the compile will substitute for us. HIGH means 1 and LOW equals 0. Like standing at the photocopier compiling your prints into double sided chapters.
Digital NumbersWe are used to decimal base 10 numbers. Arduino sketches allow us to use binary, octal and hexadecimal numbers as well. We write them differently so that we know how to understand them.
Bits are binary digits. A byte is 8 bits together, also called a char for character. The bytes can mean letters or digits, sound samples or colours. How many combinations of lights can you have with 8 light switches? 255.
We will focus on a byte named PORTB that has an address in memory. Bit B5 is the sixth bit in that byte 0b0010000 because we start counting at B0. In hexadecimal we write 0x20. Decimal 32 is 2 multipled 5 times 2x2x2x2x2 = 2^5.
PORTB pin 5Arduino sketches will PORTB as a reserved keyword. PORTB is also a hardware set of latching data circuits, it can hold an 8 bit number and output it to the world as little voltages. To software it is an 8bit value and is located at address 37 (0x25).
The same wires can be inputs. PINB at address 35 (0x23) is an input register that sees either a voltage coming (1) or no voltage (0). Our software also reserves the words HIGH and LOW.
DDRB Data Direction Register for PORTB at address 36 (0x24) controls whether pins on PORTB are outputs. Some of our sketches activate more than one output.
Inside the AVR ATmega328pThe MCU microcontroller unit in the Arduino is an 8bit processor because it works with 8bit words of data. Clever software means the Arduino can put two bytes together and perform calculations up to 65000. u8 means unsigned 8 bit byte.
Watch what happens with our Blink sketch. When PORTB=0b00100000 we output a voltage and the LED lights up. When PORTB=0b00000000 the light goes out. The circuit shows the LED is connected to pin B5 of the chip.
Think of pin13 as a lamp circuit you are turning on and off. pin13 is connected to a switch at B5 of the chip. The Arduino software has a reserved keyword PB5 for this location. Chip pin B0 is connected to pin8 of the board, B1 to pin9, Pin0 to pin7 on the board belong to PORTD.
Hardware ConnectionsAll 8 physical pins of PORTD are wired to the header on the board. Pin13 is the last pin for PORTB and PB6 and PB7 are used by software but there is no physical connection.
Since we begin counting from zero bit5 of our byte is the sixth binary digit. From pin8 add 6 more pins we get to pin13 where the LED connects to PORTB.
You may wonder why PINB sees voltages coming in on pins we are not using. PINB reads input voltages because of pull-up circuits. Pull-up circuits connect the pins through a resistor so that they are pulled up to +5Volts.
BinaryOpen a new sketch and put this code into it. It is the same blink program but written differently. We tell DDRB that PB5 will be an output and we turn that output on and off like a wall switch.
void setup(){ DDRB =0b00100000;}
void loop() { PORTB=0b00100000; delay(1000);
PORTB=0b00000000; delay(1000);}
Upload to a board and it makes the light blink. Our code is exactly the same as the original blinky. The compiler takes this sketch and makes the light blink.
Compiles nice. Smaller hex file.
Like putting a mathematical mask over the other bits so they aren't affected. It's a logic function where |=0x20 makes sure bit5 is on. &=0xDF uses the AND function to turn bit5 off. It makes more sense in binary.
0b00100000 OR anything will turn bit5 on
0b11011111 AND anything turns bit5 off
It works like this.
You can work it out on paper.
void setup(){ DDRB = 0b00100000;}
void loop() { PORTB |= 0b00100000; delay(1000); // turns on
PORTB &= 0b11011111; delay(1000);} // turns off
The Arduino uses it like this. Same blinky program.
It is not as clear when the commands are written with hexadecimal numbers.
PORTB |= 0x20; delay(1000); // turns on
PORTB &= 0xDF; delay(1000); // turns off
Bitwise NotInverts all the bits in our byte. Ones are changed to zeros and zeros become ones. The ~ character is called a tilde on a key in the upper left next to esc escape key. In setup( ) DDRB = 0xFF sets all 8 IOs to output and we initialize PORTB by setting it to 0x55.
void setup() { DDRB = 0xFF; PORTB = 0b01010101; }
void loop() { PORTB = ~PORTB; delay(500); }
In loop( ) PORTB is turned into ~PORTB and all the bits flip over. The LED blinks.
The bits going out of PORTB are read by PINB. Your sketches can still read the on/off voltage on the pins. If you have LEDs then add them to Arduino pins 8, 9, 10, 11, 12 and 13. This sketch makes the LED on your board blink.
Boolean Not is !PORTB and it just toggles between 0x00 and 0x01. This toggles pin8 so BUILTIN_LED does not light.
<< Shift Left - Shift Right >>Take a binary number like 0b00000001 and you shift 5 positions to the left you get 0b00100000 in decimal that is 32 and hexadecimal 0x20. If we #define PB5 5 then (1 << PB5) is the position where the LED is connected.
#define byteL 8
void setup() { DDRB = 0xFF;}
void loop() {
for (int i=0; i < byteL ;i++) { PORTB = (1 << i); delay(500);}
for (int i=0; i < byteL ;i++) { PORTB = (128 >> i); delay(500);}
}
This sketch moves a single bit from pin8 on the Arduino up to pin13. Then the bit will walk back down the connectors. The compiler will use the number 8 where ever it sees byteL. Do you know why 128 is a single bit?
Increment++PORTB++ is whatever number PORTB is we use it then increment. Delay. Push the number into the circuit and repeat. Useful for checking wiring connections. There are also PORTB--, ++PORTB, --PORTB commands.
void setup() { DDRB = 0xFF;}
void loop() { PORTB++, delay(50); }
Demo Code
Comments