Unit III - Embedded Programming
Unit III - Embedded Programming
Programming
Prepared By
M. Vivek Anand
AP II/CSE
Embedded Programming
Fundamentals
• Embedded Software or Program allow Hardware to monitor external events
(Inputs / Sensors) and control external devices (Outputs) accordingly.
• Program for an Embedded System may have to directly manipulate the internal
architecture of the Embedded Hardware like the processor, Timers, Serial
Communications Interface, Interrupt Handling, and I/O Ports etc
• There are many programming languages that are used for Embedded Systems
like Assembly (low-level Programming Language), C, C++, JAVA (high-level
programming languages), Visual Basic, JAVA Script (Application level
Programming Languages), etc.
Embedded Programming
Fundamentals
Factors for selecting Embedded programming
• Size: The memory that the program occupies is very important as Embedded
Processors like Microcontrollers have a very limited amount of ROM (Program
Memory).
• Speed: The programs must be very fast i.e., they must run as fast as possible.
The hardware should not be slowed down due to a slow running software .
• Portability: The same program can be compiled for different processors.
• Ease of Implementation
• Ease of Maintenance
• Readability
Embedded Programming
Fundamentals
Embedded C as the main Programming Language:
• C and Embedded C are ISO Standards that have almost same syntax, datatypes, functions,
etc.
• There are two ways you can write comments: one is the single line comments
denoted by // and the other is multiline comments denoted by /*….*/.
• In case of 8051, Keil Compiler has the file “reg51.h”, which must be written
at the beginning of every Embedded C Program.
• Global Variables: are Global to the program i.e., they can be accessed
anywhere in the program.
• Main Function: Every C or Embedded C Program has one main function, from
where the execution of the program begins.
Example of Embedded C
Program
The following image shows the circuit diagram for the example circuit. It contains an 8051 based Microcontroller (AT89S52)
along with its basic components (like RESET Circuit, Oscillator Circuit, etc.) and components for blinking LEDs (LEDs and
Resistors). In order to write the Embedded C Program for the above circuit, we will use the Keil C Compiler.
Sample Code
#include<reg51.h> // Preprocessor Directive
void delay (int); // Delay Function Declaration
void main(void) // Main Function
{
P1 = 0x00;
/* Making PORT1 pins LOW. All the LEDs are OFF.
* (P1 is PORT1, as defined in reg51.h) */
while(1) // infinite loop
{
P1 = 0xFF; // Making PORT1 Pins HIGH i.e. LEDs are ON.
delay(1000);
/* Calling Delay function with Function parameter as 1000.
* This will cause a delay of 1000mS i.e. 1 second */
P1 = 0x00; // Making PORT1 Pins LOW i.e. LEDs are OFF.
delay(1000);
}
}
void delay (int d) // Delay Function Definition
{
unsigned int i=0; // Local Variable. Accessible only in this function.
AND (& in C)
• AND compares each bit and returns 1 if the two bits are 1 (TRUE) otherwise 0
(FALSE). So: C = A & B;
00111011………………..(A=0x3B)
& 10010110………………..(B=0x96)
00010010
The value of C will be 0x12 or in binary 00010010. That is where there is a 1 in each
bit for both values.
Bitwise Operations in Embedded
Programming
• OR (| in C)
• OR will return a 1 if there is a 1 in either value at that bit. So: C = A | B;
00111011………………..(A=0x3B)
| 10010110………………..(B=0x96)
10111111
^ 10010110………………..(B=0x96)
10101101
When we assign value directly to any register. This may change the value of other
bits which might be used to control other hardware feature. To avoid such scenario
best practice is to use bit masking. This is why we must know bit masking while
using bitwise operations in embedded programming
Bitwise Operations in Embedded
Programming
Setting bits, Inverting bits
Let’s say we have variable called bits and we have asked to set the bit-7. This can be
achieved by writing this single line of code.
while( ~(bits & (1<<4)) ) // monitor for 4th bit changing from 1 to 0
{
.......
.......
}
Bitwise operators save memory and it is fast. This leads to improved performance.
Port Control
Port control in C
Port control refers to directly manipulating the microcontroller’s input/output ports using Embedded C. the
functions like digitalWrite() and digitalRead(), direct port manipulation using registers provides faster and
more efficient control, making it suitable for time-sensitive applications.
Arduino boards like Uno and Mega are based on AVR microcontrollers (e.g., ATmega328P), which have three
primary ports:
•PORTB: Controls digital pins 8 to 13
•PORTC: Controls analog pins A0 to A5
•PORTD: Controls digital pins 0 to 7
Registers for Port Control in Arduino
DDRx (Data Direction Register)
•Configures a pin as an Input (0) or Output (1).
•Example: DDRB |= (1 << PORTB5); // Pin 13 as Output
PORTx (Data Register)
•Controls the output state of a pin as HIGH (1) or LOW (0).
•Example: PORTB |= (1 << PORTB5); // Set Pin 13 HIGH
PINx (Pin Register)
•Reads the input state from a pin.
•Example: if (PINB & (1 << PORTB5)) { /* Pin 13 is HIGH */ }
Port Control
Advantages of Using Port Control in Arduino
•Faster Execution: Port manipulation is significantly faster than using digitalWrite() and digitalRead().
•Efficient for Multiple Pins: Control multiple pins in a single operation.
•Low-Level Access: Provides greater flexibility for complex tasks like waveform generation or bitwise
operations.
•Reduced Memory Usage: Direct register access uses fewer resources.
Example of Port Control
Set Pin 13 as Output and Blink an LED
void setup() {
DDRB |= (1 << PORTB5); // Configure Pin 13 as Output
}
void loop() {
PORTB |= (1 << PORTB5); // Turn LED ON
delay(500);
PORTB &= ~(1 << PORTB5); // Turn LED OFF
delay(500);
}
This program uses Embedded C for port-level control, directly accessing the registers for
efficient LED blinking
Port Control
Control LED using Push Button (Port Control)
void setup() {
// Set Pin 13 (LED) as Output
DDRB |= (1 << PORTB5);
void loop() {
// Check Button State using PIND
if (PIND & (1 << PORTD7)) {
PORTB &= ~(1 << PORTB5); // LED OFF
} else {
PORTB |= (1 << PORTB5); // LED ON
}
}
•DDRD &= ~(1 << PORTD7)Configures Pin 7 as input.
•PORTD |= (1 << PORTD7)Enables the internal Pull-up resistor (active high input).
•PIND & (1 << PORTD7)Reads the input state of Pin 7 using PIND.
•LED ON/OFF When the button is pressed, Pin 7 reads LOW (active low) → LED turns ON.
Interrupt Handling
• Interrupts are used to handle critical tasks by
pausing the main program and executing a specific
function when an event occurs.
• Instead of constantly checking for a condition using
loops, interrupts efficiently respond to external or
internal events like button presses, sensor triggers,
or timer overflows.
Interrupt handling-Example
Toggle an LED using a button press on Pin 2 (INT0).
#include <avr/io.h>
#include <avr/interrupt.h> Explanation
void setup() { 1.DDRB |= (1 << PORTB5);
// Configure Pin 13 as Output Set Pin 13 as output for the LED.
DDRB |= (1 << PORTB5); 2.EICRA |= (1 << ISC01);
// Configure Pin 2 (INT0) as Input Configure FALLING EDGE detection on Pin 2 using INT0.
DDRD &= ~(1 << PORTD2);
3.EIMSK |= (1 << INT0);
// Enable Internal Pull-up for Pin 2 Enable External Interrupt INT0.
PORTD |= (1 << PORTD2); 4.sei();
Enable global interrupts using the sei() (Set Enable Interrupt)
// Configure External Interrupt on Falling Edge (Button function.
Press) 5.ISR(INT0_vect)
EICRA |= (1 << ISC01);
EICRA &= ~(1 << ISC00);
Interrupt Service Routine (ISR) for handling the interrupt.
// Enable INT0 (External Interrupt 0) PORTB ^= (1 << PORTB5); toggles the LED on each button press.
EIMSK |= (1 << INT0); Expected Output Behavior
1.Initial State:
// Enable Global Interrupts 1. The LED on Pin 13 (built-in LED on most Arduino boards) will be OFF.
sei(); 2.Button Pressed:
} 1. When you press the button connected to Pin 2, an Interrupt will trigger.
2. The LED on Pin 13 will Toggle (Change state: OFF → ON or ON → OFF).
ISR(INT0_vect) { 3.Button Released:
// Toggle LED on Interrupt 1. The LED will remain in the same state until the button is pressed again.
PORTB ^= (1 << PORTB5); 4.Every Button Press:
} 1. The LED state will toggle (ON → OFF → ON → OFF, etc.).
void loop() {
// Main loop does nothing; Interrupt handles the LED
}
Firmware
Firmware is a specialized software that is embedded into a
hardware device to control its functions.
It provides a control over the hardware components, acting as a
bridge between the hardware and the software (such as operating
systems or applications).
Firmware is often stored in non-volatile memory (e.g., ROM, Flash
Memory) and can be updated if necessary.
• A firmware application is a specific type of program written to
perform a dedicated function on embedded systems.
• Unlike general-purpose software, firmware applications work directly
with hardware registers and peripherals.
• Examples include device drivers, sensor monitoring programs, and
control systems.
Difference Between Embedded Application and
Firmware Application
• Embedded Application:
• It is generally a user-level application running on microcontrollers or
microprocessors using pre-built firmware (e.g., Arduino sketches).
• Examples: LED blinking, sensor data logging, motor control using Arduino
IDE.
• Firmware Application:
• Firmware is a low-level, permanent software that directly controls
hardware.
• It often includes direct register-level manipulation, efficient memory
management, and hardware-specific optimizations.
• Examples: Device drivers, low-level control software for sensors, and motor
controllers.
Firmware Applications
Characteristics:
• Hardware-Specific: Designed for particular hardware components.
• Real-Time Operation: Often requires real-time processing using microcontrollers.
• Resource-Constrained: Operates with limited memory, processing power, and energy.
• Embedded Control: Provides direct control over device operations.
Advantages:
• Lower power consumption.
• Faster response time.
• Direct control over hardware components.
• Efficient memory management.
Applications:
Temperature Monitoring System: Monitors temperature using a sensor and sends data to a display or network.
Smart Light Control: Uses sensors (e.g., LDR) to control the brightness of lights automatically.
Motor Control Application: Controls the speed and direction of a motor using a microcontroller.
IoT Device Control: Collects sensor data and sends it to the cloud for further processing.
Test Cases:
Scenario Expected Output LED Status
LDR Value: 600
Bright Room (LDR Value > 500) Light OFF OFF
LDR Value: 300
Dark Room (LDR Value < 500) Light ON ON
LDR Value: 500
Partial Shade (LDR Value ≈ 500) Light OFF OFF
Optimizing firmware application
Optimization:
Problem 1:
•The Arduino is constantly running, consuming unnecessary power.
Solution:
•Implement Sleep Mode when the device is idle using avr/sleep.h.
•Wake up the microcontroller when a significant change in light is detected.
Problem 2:
•The light threshold is static and may not work well in different lighting conditions.
Solution:
•Implement an Adaptive Thresholding system using an average LDR value over time.
Optimizing firmware application
Implementing Sleep Mode when device is idle
#include <avr/sleep.h> void loop() {
int ldrValue = analogRead(ldrPin);
const int ldrPin = A0;
if (ldrValue < lightThreshold) {
const int ledPin = 9; digitalWrite(ledPin, HIGH);
int lightThreshold = 500; Serial.println("Light ON");
} else {
void setup() { digitalWrite(ledPin, LOW);
pinMode(ledPin, OUTPUT); Serial.println("Light OFF");
}
Serial.begin(9600); Serial.print("LDR Value: ");
} Serial.println(ldrValue);
EnterSleepMode(); // Enter low power mode
void EnterSleepMode() {
delay(500);}
set_sleep_mode(SLEEP_MODE_ADC); // Sleep mode
during ADC Output 1: Output 3:
sleep_enable(); LDR Value: 720 LDR Value: 490
Light OFF Light ON
sleep_cpu();
Output 2: Output 4:
sleep_disable(); LDR Value: 510 LDR Value: 250
} Light OFF Light ON
Optimizing firmware application
Benefits on implementing Sleep Mode when device is idle
Energy Saving: Ideal for battery-operated devices like solar-powered or remote
sensors. Increases the lifespan of both microcontroller and power source.
No Wasted Cycles: The CPU remains inactive while waiting for sensor input.
Suitable for Low-Power IoT Applications
Remote Operation: Useful in remote areas with solar power or battery-operated
lighting.
No Manual Adjustments: The system automatically controls the LED based on the
environment.
Smart Home Automation: Efficiently controls lighting based on sunlight, reducing
electricity usage.
Environmental Monitoring: Sensors can be deployed for long periods without
maintenance.
Optimizing firmware application
Implementing an Adaptive Thresholding system
The given code introduces an adaptive threshold to dynamically adjust the light
threshold using real-time sensor data. This makes the smart lighting system
more intelligent and responsive to environmental changes.
Code:
int adaptiveThreshold() { if (ldrValue < lightThreshold) {
int sum = 0; digitalWrite(ledPin, HIGH);
Serial.println("Light ON");
for (int i = 0; i < 20; i++) { }
sum += analogRead(ldrPin); else {
digitalWrite(ledPin, LOW);
delay(10); Serial.println("Light OFF");
} }
return sum / 20 - 50; // Dynamic adjustment with a
margin Serial.print("LDR Value: ");
Serial.println(ldrValue);
} Serial.print("Adaptive Threshold: ");
void loop() { Serial.println(lightThreshold);
delay(500);
int ldrValue = analogRead(ldrPin); }
lightThreshold = adaptiveThreshold();
Optimizing firmware application
Implement an Adaptive Thresholding system
Scenario 1: Bright Light Scenario 2: Moderate Light Scenario 3: Low Light Condition
Condition Condition •LDR Value: Low (e.g., 200-300)
•LDR Value: Medium (e.g., 480-520) •Adaptive Threshold: Adjusts to
• LDR Value: High (e.g., 700-800) around 400
•Adaptive Threshold: Adjusts to
• Adaptive Threshold: Adjusts to around 500 •LED Status: ON
around 650 •LED Status: OFF or ON depending Output:
• LED Status: OFF on slight variations LDR Value: 250
Adaptive Threshold: 400
Output: Light ON
Output:
• LDR Value: 720 LDR Value: 510 Scenario 4: Sensor Malfunction or
• Adaptive Threshold: 650 Adaptive Threshold: 500 Disconnection
Light OFF •LDR Value: 0 or Invalid
• Light OFF •Adaptive Threshold: Can show abnormal
LDR Value: 490 values
Adaptive Threshold: 500 •LED Status: ON (Failsafe)
Light ON Output:
LDR Value: 0
Adaptive Threshold: 50
Light ON
Optimizing firmware application
Benefits on Implementing an Adaptive Thresholding system
Dynamic Adjustment: The threshold is updated based on the average of recent
sensor readings, reducing errors caused by sudden light changes.
Environmental Adaptability: Works efficiently in environments where light
intensity varies throughout the day.
Noise Reduction: The averaging mechanism reduces fluctuations and noise in LDR
sensor readings.
Stable Output: Prevents unwanted switching of the LED in scenarios with minor
light variations.
Smart Control: The adaptive threshold minimizes unnecessary LED usage by
accurately detecting ambient light.
Lower Power Consumption: Reduced LED on-time results in extended battery life
in battery-powered applications.
Seamless Automation: Users don’t need to manually adjust the light threshold
depending on the time of day or environment.
Consistent Lighting: Ensures a comfortable lighting experience without constant
manual tuning.
Thank you