In embedded programming and digital electronics, "b" in binary most commonly refers to the 0b prefix used to denote a binary literal (like 0b1010), though it also refers to the hexadecimal digit 'B' (which equals 1011 in binary) or lowercase 'b' denoting bits in serial data rates. When you are writing firmware for an Arduino or ESP32, understanding which "b" you are dealing with is the difference between successfully toggling a hardware register and spending three hours debugging a serial buffer overflow.

The 0b Prefix: Writing Binary Literals in C/C++

In C and C++ (the languages underlying the Arduino IDE and ESP-IDF), the compiler needs to know what base a number is written in. By default, 140 is decimal. 0x8C is hexadecimal. But when you are manipulating hardware registers, you need to see the exact bit pattern. That is where the 0b prefix comes in. It tells the compiler, "Treat the following digits as base-2."

What this changes in a real circuit is profound: using the 0b prefix to write directly to a microcontroller's hardware port register changes the physical voltage state of multiple GPIO pins simultaneously in a single clock cycle. This bypasses the sequential, pin-by-pin overhead of standard digitalWrite() functions, which is critical when driving high-speed shift registers or generating precise software-based PWM signals.

Worked Numeric Example: Configuring an 8-Bit Port

Let's look at a real-world scenario on an ATmega328P (Arduino Uno). You want to set physical pins 2, 3, and 7 HIGH on PORTD, while leaving the others LOW.

  • Bit Position: 7 6 5 4 3 2 1 0
  • Target State: 1 0 0 0 1 1 0 0

Here is how you write that to the PORTD register using three different numerical bases:

// Binary literal (Most readable for pin mapping)
PORTD = 0b10001100; 

// Hexadecimal equivalent (Compact, common in datasheets)
PORTD = 0x8C;       

// Decimal equivalent (Hardest to visualize bitwise)
PORTD = 140;        

All three lines compile to the exact same machine code, but the 0b prefix allows you to visually map the code directly to the physical silicon pins. For deeper register manipulation on 32-bit architectures like the ESP32, you will use similar bitwise operations with 0b masks on registers like GPIO.out_w1ts (Espressif GPIO API Reference).

Hexadecimal 'B' to Binary Translation

The second time you will search for "b in binary" is when reading component datasheets. Integrated circuits like the MPU6050 accelerometer or the PCA9685 PWM driver document their I2C registers in hexadecimal. The hex digit B (or b) represents the decimal value 11.

Because hex is base-16 and binary is base-2, every single hex digit maps perfectly to a 4-bit binary "nibble." The hex digit B always translates to the binary nibble 1011.

Where You Meet This in Practice:
Suppose you are configuring the control register of a DS3231 Real Time Clock. The datasheet tells you to write 0x1B to disable the square wave output and enable alarms. To know exactly which bits you are flipping, you split the hex into nibbles:
Hex: 1 | B
Binary: 0001 | 1011
By converting the 'B' to '1011', you can see that bits 0, 1, 3, and 4 are being set HIGH, allowing you to cross-reference those specific bits against the datasheet's bitfield table.

The Lowercase 'b' Trap: Bits vs. Bytes in Serial Comms

What people most commonly confuse with binary literals is the unit notation for data rates. In serial communications (UART, SPI, I2C) and networking, a lowercase 'b' stands for bits, while an uppercase 'B' stands for Bytes. Confusing the two leads to an off-by-a-factor-of-eight error in your payload calculations, often resulting in dropped packets or buffer overflows.

Take the standard Arduino Serial baud rate of 115,200 bps (bits per second). Many beginners assume this means they can send 115,200 characters (Bytes) per second. This is physically impossible due to UART framing overhead.

In a standard 8N1 UART configuration (8 data bits, No parity, 1 stop bit), every Byte you send is wrapped in a 1-bit start frame and a 1-bit stop frame. That means it takes 10 bits of wire time to transmit 1 Byte of payload data.

  • Wire Speed: 115,200 bits per second (bps)
  • Frame Size: 10 bits per Byte
  • Actual Payload Throughput: 115,200 / 10 = 11,520 Bytes per second (B/s)

If you are writing a Python script on a Raspberry Pi to read serial data from an ESP32, and you allocate a buffer expecting 115 kilobytes a second, your script will choke. Always size your serial buffers based on 'B' (Bytes), not 'b' (bits).

Quick Reference: 'B' Conversions and Prefixes

Keep this table at your bench when translating between datasheets, logic analyzer outputs, and your C++ IDE.

Context Notation Base Decimal Value 8-Bit Binary Representation
C/C++ Literal 0b00001011 2 11 00001011
Hexadecimal Nibble 0xB (or 0x0B) 16 11 00001011
Decimal Integer 11 10 11 00001011
Data Rate (Bits) 11 bps N/A 11 bits/sec N/A (Serial framing applies)
Data Rate (Bytes) 11 B/s N/A 88 bits/sec N/A (Payload only)

FAQ: Common Questions About 'b' in Binary

What does 0b mean in Arduino code?

The 0b sequence is an integer constant prefix that tells the Arduino compiler to interpret the following numbers as base-2 (binary) rather than base-10 (decimal). For example, 0b11110000 evaluates to the decimal number 240. It is heavily used in Arduino integer constants to manipulate hardware registers, configure SPI/I2C control bytes, and drive shift registers like the 74HC595 (TI SN74HC595 Datasheet) where visual alignment of bits to physical output pins is necessary.

How do I convert hex B to binary without a calculator?

Memorize the 4-bit nibbles for the hex digits A through F. Hex 'A' is 10 (1010), and 'B' is 11 (1011). Because 16 is a power of 2, you can convert any hex number to binary by simply replacing each hex digit with its 4-bit binary equivalent. Therefore, the hex value 0xB4 instantly becomes 1011 (for B) and 0100 (for 4), resulting in 10110100.

Why does my ESP32 throw an error when I type 0b2 or 0b112?

The compiler throws an error because binary is strictly base-2, meaning it only recognizes the digits 0 and 1. If you type 0b112, the compiler hits the '2', realizes it is an invalid digit for base-2, and halts compilation. If you meant to write a hexadecimal number, use the 0x prefix (e.g., 0x112). If you meant decimal, drop the prefix entirely.

Is a lowercase 'b' always a bit and uppercase 'B' always a Byte?

In standard IEC 80000-13 and IEEE networking terminology, yes: lowercase 'b' is bits, uppercase 'B' is Bytes. However, in C/C++ code formatting, case sensitivity applies to variable names and hex prefixes (0xB and 0xb are identical to the compiler). The bits vs Bytes rule strictly applies to unit suffixes like Kbps (kilobits per second) versus KB/s (kilobytes per second) when calculating UART, SPI, or Ethernet throughput.