Serial Communication
Serial communication is a widely-used method for data exchange between devices. It transmits data one bit at a time over a single wire, which is ideal for long-distance communication. In the context of Arduino, serial communication is typically used for communication between the microcontroller and the computer, as well as between various serial devices.
Characteristics
Asynchronous: Does not require a clock signal. Devices must agree on a common baud rate.
Baud Rate: The speed of communication, usually measured in bits per second (bps).
Full-Duplex: Allows simultaneous two-way communication.
Common Uses: Debugging with the Serial Monitor, communication with GPS modules, Bluetooth modules, etc.
Serial.begin(speed)
Opens the serial port and sets the baud rate for serial data transmission. The typical baud rate for communicating with the computer is 9600, although other speeds are also supported, i.e., 300, 600, 1200, 2400, 4800, 9600, 14,400, 19,200, 28,800, 38,400, 57,600, or 115,200.
Serial.begin(speed)
Parameters
speed: set the baud rate
Returns
None
It should be noted that the digital pins 0 (RX) and 1 (TX) cannot be used at the same time when using serial communication.
Serial.available()
Receives the number of bytes (characters) available for reading from the serial port. This is data that has already arrived and been stored in the serial receive buffer.
Serial.available()
Parameters
None
Returns
the number of bytes available to read
Remember, the hardware serial port on the Arduino microcontroller has a buffer that can store up to 128 bytes of information so that it is not lost. If no data is waiting for us, it will return 0. On the other hand, if any data is available, the function will return a value other than 0, which will signify true.
Serial.read()
Reads incoming serial data.
Serial.read()
Parameters
None
Returns
the first byte of incoming serial data available (or
–1 if no data is available) –int
This function simply returns the first byte of information available in the serial buffer. Because of the way our serial communications are structured, each character that we send to the Arduino through the Serial Monitor will be converted to that character’s ASCII character value. For example, if we were to send the Arduino the number 1, instead of receiving the numerical integer 1, the Arduino will actually receive the numerical value 49 corresponding to that character’s ASCII character code.
Serial.print(val)
Prints data to the serial port as human-readable ASCII text.
Serial.print(val)
Parameters
val: the value to print – any data type
Returns
None
This command can take many forms. Numbers are printed using an ASCII character for each digit. Floats are similarly printed as ASCII digits, defaulting to two decimal places. Bytes are sent as a single character.
SPI (Serial Peripheral Interface) Protocol
SPI is a synchronous serial communication protocol used primarily for short-distance communication in embedded systems. It operates in a master-slave architecture with a single master and one or more slave devices.
Characteristics
Synchronous: Uses a clock signal (SCK) to synchronize data transfer.
Full-Duplex: Data is sent and received simultaneously.
Speed: Typically faster than I2C and UART, with data rates up to several Mbps.
Lines: Four main lines – MOSI (Master Out Slave In), MISO (Master In Slave Out), SCK (Serial Clock), and SS (Slave Select).
Common Uses: Communication with sensors, SD cards, and display modules.
SPI.begin()
Initializes the SPI bus and sets the SCK, MOSI, and SS/CS pins to output.
SPI.begin()
Parameters
None
Returns
NoneSPI.transfer()
Transfers a byte of data to the SPI device and receives a byte back simultaneously.
byte SPI.transfer(byte data);
Parameters
data: The byte of data to send.
Returns
The byte received from the SPI device.
SPI.beginTransaction()
Begins an SPI transaction with specified settings.
SPI.beginTransaction(SPISettings clock, MSBFIRST, SPI_MODE0);
Parameters
SPISettings: Specifies the SPI settings including clock speed, bit order, and data mode.
Returns
None
SPI.endTransaction()
Ends an SPI transaction.
SPI.endTransaction();
Parameters
None
Returns
NoneSPI.end()
Disables the SPI bus and releases the SPI pins.
SPI.end();
Parameters
None
Returns
None
I2C (Inter-Integrated Circuit) Protocol
I2C is a synchronous, multi-master, multi-slave, packet-switched, single-ended, serial communication bus. It is widely used for communication between microcontrollers and peripheral devices such as sensors, displays, and EEPROMs.
Characteristics
Synchronous: Uses a clock signal (SCL) along with data (SDA) lines.
Multi-Master: Allows multiple master devices on the same bus.
Addressing: Each device has a unique 7-bit address.
Two-Wire: Uses only two lines – SCL (Serial Clock Line) and SDA (Serial Data Line).
Speed: Standard mode (100 kbps), Fast mode (400 kbps), and High-Speed mode (3.4 Mbps).
Common Uses: Communication with sensors, RTCs (Real-Time Clocks), and other low-speed peripherals.Wire.begin()
Initializes the Wire library and joins the I2C bus as a master or slave.
Wire.begin(address);
Parameters
address (optional): If provided, sets the device as a slave with the given address (7–bit).
Returns
NoneWire.requestFrom()
Requests bytes from a slave device on the I2C bus.
Wire.requestFrom(address, quantity);
Parameters
address: The 7–bit address of the I2C device to request data from.
quantity: The number of bytes to request.
Returns
The number of bytes returned from the slave device.Wire.beginTransmission()
Begins a transmission to the I2C slave device with the given address.
Wire.beginTransmission(address);
Parameters
address: The 7–bit address of the I2C device to transmit to.
Returns
NoneWire.write()
Writes data to the I2C device.
Wire.write(value);
Wire.write(string);
Wire.write(data, length);
Parameters
value: A value to send as a single byte.
string: A string to send.
data: An array of data to send.
length: The length of the data array.
Returns
The number of bytes written.
Wire.endTransmission()
Ends a transmission to the I2C device and transmits the data.
Wire.endTransmission();
Wire.endTransmission(stop);
Parameters
stop (optional): If false, the bus will be held active after the transmission.
Returns
0: success
1: data too long to fit in transmit buffer
2: received NACK on transmit of address
3: received NACK on transmit of data
4: other error
Interrupts
Interrupts are a powerful feature in embedded systems that allow the microcontroller to respond to external events immediately. An interrupt signals the microcontroller to pause its current execution and execute an interrupt service routine (ISR). After completing the ISR, the microcontroller resumes its previous task.
Types of Interrupts
External Interrupts: Triggered by external signals on specific pins.
Pin Change Interrupts: Triggered by any change (rising or falling) on a set of pins.
Timer Interrupts: Triggered by the internal timers of the microcontroller.
Interrupt Functions
attachInterrupt(digitalPinToInterrupt(pin),ISR,mode)
The attachInterrupt() function enables hardware interrupts and links a hardware pin to an ISR to be called when the interrupt is triggered. This function also specifies the type of state change that will trigger the interrupt. Its syntax is as follows:
attachInterrupt(digitalPinToInterrupt(pin),ISR,mode)
Parameters
interrupt: the number of the interrupt (int)
pin: the pin number
ISR: the interrupt service routine (ISR) to call when the
interrupt occurs; this function must take no
parameters and return nothing. This function is
sometimes referred to as an interrupt service routine.
mode: defines when the interrupt should be triggered. Four
constants are predefined as valid values:
LOW to trigger the interrupt whenever the pin is low,
CHANGE to trigger the interrupt whenever the pin changes value
RISING to trigger when the pin goes from low to high,
FALLING for when the pin goes from high to low.
Returns
None
detachInterrupt(interrupt)
In some cases, we might need to change the mode of an enabled interrupt. For example, we may change the mode from RISING to FALLING. For this, we need to first stop the interrupt by using the detachInterrupt() function. Its syntax is as follows
detachInterrupt(interrupt)
Parameters
interrupt: the number of the interrupt to disable
Returns
None
With only one parameter to determine which interrupt we are disabling, this parameter is specified as either 0 or 1. Once the interrupt has been disabled, we can then reconfigure it using a different mode in the attachInterrupt() function.
interrupts()
All interrupts in Arduino can be enabled by the function interrupts(). The syntax is as follows:
Interrupts()
Parameters
None
Returns
None
Interrupts allow certain important tasks to run in the background and are enabled by default. Some functions will not work while interrupts are disabled, and incoming communication may be ignored. Interrupts can slightly disrupt the timing of a code, however, and may be disabled for particularly critical sections of code
noInterrupts()
To deactivate all interrupts, we can use the function noInterrupts(). The syntax is as follows.
noInterrupts()
Parameters
None
Returns
None