Click to follow “Stephen“,
Set as “pinned or starred”, to receive valuable content immediately

Table of Contents
- Microcontroller Basics
- Development Environment Setup
- Basic C Language
- GPIO Programming
- Timer Applications
- Interrupt System
- Serial Communication
- ADC Applications
- PWM Control
- Sensor Interfaces
- Comprehensive Projects
- Advanced Technologies
Microcontroller Basics
What is a Microcontroller?
A microcontroller (Microcontroller Unit, MCU) is a compact integrated circuit designed to govern a specific operation in an embedded system. It integrates a CPU, memory, and input/output peripherals, characterized by its small size, low power consumption, low cost, and high reliability, making it widely used in embedded systems.
Basic Components of a Microcontroller
- CPU: Central Processing Unit, executes instructions
- Memory: Program memory (Flash), data memory (RAM)
- Input/Output Interfaces: GPIO, UART, SPI, I2C, etc.
- Timer: Used for timing and counting
- Interrupt System: Handles external events
- ADC/DAC: Analog-to-Digital/Digital-to-Analog Conversion
Common Microcontroller Series
-
51 Microcontroller Series
- Features: Easy to start, abundant resources
- Representatives: AT89C51, STC89C52
- Suitable for: Basic learning
AVR Series
- Features: Good performance, moderate price
- Representatives: ATmega328P, ATmega2560
- Suitable for: Medium complexity projects
ARM Cortex-M Series
- Features: Powerful performance, rich functionality
- Representatives: STM32F103, STM32F407
- Suitable for: Complex projects
ESP32 Series
- Features: Integrated WiFi/Bluetooth
- Representatives: ESP32-WROOM-32
- Suitable for: IoT projects
Development Environment Setup
Hardware Preparation
-
Development Board Selection
- Beginner Recommendation: Arduino Uno or STM32F103C8T6
- Advanced Recommendation: STM32F407 or ESP32
- Professional Recommendation: STM32H7 Series
Essential Tools
- USB Data Cable
- Breadboard and Dupont Wires
- Common Electronic Components (LEDs, Resistors, Buttons, etc.)
- Multimeter and Oscilloscope (optional)
Software Environment
-
Arduino IDE (Recommended for beginners)
- Download Link: https://www.arduino.cc/
- Features: Simple and easy to use, suitable for beginners
- Supports: Arduino, ESP32, etc.
Keil MDK (For STM32 development)
- Download Link: https://www.keil.com/
- Features: Powerful, professional-level development
- Supports: ARM Cortex-M series
STM32CubeIDE (Free STM32 development)
- Download Link: https://www.st.com/
- Features: Free, fully functional
- Supports: All STM32 series
IAR Embedded Workbench
- Features: Professional-level development environment
- Supports: Various MCUs
- Price: Commercial software
Environment Configuration Steps
-
Install Development Software
- Download and install the selected IDE
- Configure compiler path
- Install necessary library files
Connect Hardware
- Connect the development board to the computer via USB
- Install drivers
- Confirm device recognition is normal
Test Environment
- Compile a simple program
- Download to the development board
- Verify the program runs correctly
Basic C Language
Basic Syntax
// Include header file
#include <stdio.h>
// Main function
int main() {
// Variable declaration
int a = 10;
float b = 3.14;
char c = 'A';
// Output statement
printf("Hello World!\n");
return 0;
}
Data Types
-
Integer
<span>char</span>: 8 bits, -128 to 127<span>int</span>: 16 bits or 32 bits<span>long</span>: 32 bits or 64 bits<span>unsigned</span>: Unsigned type
Floating Point
<span>float</span>: 32-bit floating point<span>double</span>: 64-bit floating point
Pointer Types
<span>int *p</span>: Integer pointer<span>void *ptr</span>: Generic pointer
Control Structures
// if statement
if (condition) {
// Execute code
} else {
// Other code
}
// for loop
for (int i = 0; i < 10; i++) {
// Loop code
}
// while loop
while (condition) {
// Loop code
}
Function Definition
// Function declaration
int add(int a, int b);
// Function definition
int add(int a, int b) {
return a + b;
}
Arrays and Pointers
// Array definition
int array[10];
// Pointer operation
int *ptr = &array[0];
*ptr = 100; // Assignment
GPIO Programming
Basic Concepts of GPIO
GPIO (General Purpose Input/Output) is a general-purpose input/output interface that can be configured as input or output mode.
Basic Operations
// Arduino example
void setup() {
pinMode(13, OUTPUT); // Set pin as output
pinMode(2, INPUT); // Set pin as input
}
void loop() {
digitalWrite(13, HIGH); // Output high level
delay(1000);
digitalWrite(13, LOW); // Output low level
delay(1000);
}
STM32 GPIO Example
// STM32 GPIO configuration
void GPIO_Init(void) {
// Enable GPIOA clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure GPIO structure
GPIO_InitTypeDef GPIO_InitStructure;
// Configure PA0 as output
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
// GPIO operations
void LED_On(void) {
GPIO_SetBits(GPIOA, GPIO_Pin_0);
}
void LED_Off(void) {
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}
Button Input
// Button detection
int buttonPressed(void) {
if (digitalRead(2) == LOW) {
delay(20); // Debounce
if (digitalRead(2) == LOW) {
return 1;
}
}
return 0;
}
Project Practice: LED Control
// LED blinking program
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT_PULLUP);
}
void loop() {
if (buttonPressed()) {
digitalWrite(13, !digitalRead(13)); // Toggle LED state
}
delay(100);
}
Timer Applications
Timer Basics
Timers are important peripherals in microcontrollers used for timing, counting, and PWM generation.
Timer Configuration
// STM32 timer configuration
void Timer_Init(void) {
// Enable timer clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Configure timer
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 999; // Auto-reload value
TIM_TimeBaseStructure.TIM_Prescaler = 7199; // Prescaler value
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// Enable timer
TIM_Cmd(TIM2, ENABLE);
}
Timer Interrupts
// Timer interrupt configuration
void Timer_Interrupt_Init(void) {
NVIC_InitTypeDef NVIC_InitStructure;
// Configure NVIC
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable timer interrupt
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
// Timer interrupt service function
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// Interrupt handling code
LED_Toggle();
}
}
Arduino Timer
// Arduino timer example
unsigned long previousMillis = 0;
const long interval = 1000; // 1 second
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Code to execute at intervals
digitalWrite(13, !digitalRead(13));
}
}
Interrupt System
Interrupt Basics
Interrupts are an important mechanism for microcontrollers to respond to external events, allowing timely handling of urgent events.
External Interrupt Configuration
// STM32 external interrupt configuration
void EXTI_Init(void) {
// Enable AFIO clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// Configure GPIO as input
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure external interrupt
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// Configure NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// External interrupt service function
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line0);
// Interrupt handling code
LED_Toggle();
}
}
Arduino Interrupt
// Arduino interrupt example
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT_PULLUP);
// Configure external interrupt
attachInterrupt(digitalPinToInterrupt(2), buttonISR, FALLING);
}
void loop() {
// Main loop code
}
// Interrupt service function
void buttonISR() {
digitalWrite(13, !digitalRead(13));
}
Serial Communication
Serial Basics
Serial communication (UART) is an important interface for microcontrollers to communicate with external devices.
Serial Configuration
// STM32 serial configuration
void UART_Init(void) {
// Enable GPIO and UART clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure UART
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
// Send data
void UART_SendByte(uint8_t data) {
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, data);
}
// Receive data
uint8_t UART_ReceiveByte(void) {
while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USART2);
}
Arduino Serial
// Arduino serial example
void setup() {
Serial.begin(115200);
Serial.println("Hello World!");
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
Serial.print("Received: ");
Serial.println(c);
}
delay(100);
}
Serial Communication Project
// Serial control LED
void setup() {
Serial.begin(115200);
pinMode(13, OUTPUT);
}
void loop() {
if (Serial.available()) {
char command = Serial.read();
switch (command) {
case '1':
digitalWrite(13, HIGH);
Serial.println("LED ON");
break;
case '0':
digitalWrite(13, LOW);
Serial.println("LED OFF");
break;
}
}
}
ADC Applications
ADC Basics
ADC (Analog-to-Digital Converter) converts analog signals into digital signals.
ADC Configuration
// STM32 ADC configuration
void ADC_Init(void) {
// Enable ADC clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// Configure ADC channel
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
// Enable ADC
ADC_Cmd(ADC1, ENABLE);
// ADC calibration
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
}
// ADC read
uint16_t ADC_Read(void) {
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
Arduino ADC
// Arduino ADC example
void setup() {
Serial.begin(115200);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.print("ADC Value: ");
Serial.print(sensorValue);
Serial.print(", Voltage: ");
Serial.println(voltage);
delay(1000);
}
Temperature Sensor Project
// LM35 temperature sensor
void setup() {
Serial.begin(115200);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
float temperature = voltage * 100; // LM35: 10mV/°C
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" °C");
delay(1000);
}
PWM Control
PWM Basics
PWM (Pulse Width Modulation) is used to control motors, LED brightness, etc.
PWM Configuration
// STM32 PWM configuration
void PWM_Init(void) {
// Enable clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure timer
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// Configure PWM
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; // 50% duty cycle
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
}
// Set PWM duty cycle
void PWM_SetDuty(uint16_t duty) {
TIM_SetCompare1(TIM2, duty);
}
Arduino PWM
// Arduino PWM example
void setup() {
pinMode(9, OUTPUT);
}
void loop() {
// Fade in
for (int i = 0; i <= 255; i++) {
analogWrite(9, i);
delay(10);
}
// Fade out
for (int i = 255; i >= 0; i--) {
analogWrite(9, i);
delay(10);
}
}
Servo Control
// Servo control example
#include <Servo.h>
Servo myservo;
void setup() {
myservo.attach(9);
}
void loop() {
myservo.write(0); // 0 degrees
delay(1000);
myservo.write(90); // 90 degrees
delay(1000);
myservo.write(180); // 180 degrees
delay(1000);
}
Sensor Interfaces
Common Sensors
- Temperature Sensors: DS18B20, LM35, DHT11
- Humidity Sensors: DHT11, DHT22
- Distance Sensors: HC-SR04 Ultrasonic
- Accelerometer Sensors: MPU6050
- Light Sensors: Photoresistor
DS18B20 Temperature Sensor
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
void setup() {
Serial.begin(115200);
sensors.begin();
}
void loop() {
sensors.requestTemperatures();
float temperature = sensors.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" °C");
delay(1000);
}
HC-SR04 Ultrasonic Sensor
const int trigPin = 9;
const int echoPin = 10;
void setup() {
Serial.begin(115200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Send ultrasonic wave
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read echo time
long duration = pulseIn(echoPin, HIGH);
// Calculate distance
float distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(1000);
}
MPU6050 Accelerometer Sensor
#include <Wire.h>
const int MPU_ADDR = 0x68;
void setup() {
Wire.begin();
Serial.begin(115200);
// Initialize MPU6050
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
}
void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 6, true);
int16_t AcX = Wire.read() << 8 | Wire.read();
int16_t AcY = Wire.read() << 8 | Wire.read();
int16_t AcZ = Wire.read() << 8 | Wire.read();
Serial.print("AcX: "); Serial.print(AcX);
Serial.print(" | AcY: "); Serial.print(AcY);
Serial.print(" | AcZ: "); Serial.println(AcZ);
delay(1000);
}
Comprehensive Projects
Project 1: Smart Temperature Monitoring System
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
OneWire oneWire(2);
DallasTemperature sensors(&oneWire);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int ledPin = 13;
const int buzzerPin = 8;
const float tempThreshold = 30.0;
void setup() {
Serial.begin(115200);
sensors.begin();
lcd.begin(16, 2);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
}
void loop() {
sensors.requestTemperatures();
float temperature = sensors.getTempCByIndex(0);
// Display temperature
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print("C");
// Temperature alarm
if (temperature > tempThreshold) {
digitalWrite(ledPin, HIGH);
tone(buzzerPin, 1000);
lcd.setCursor(0, 1);
lcd.print("ALARM!");
} else {
digitalWrite(ledPin, LOW);
noTone(buzzerPin);
lcd.setCursor(0, 1);
lcd.print("Normal");
}
Serial.print("Temperature: ");
Serial.println(temperature);
delay(1000);
}
Project 2: Smart Car
// Motor control pins
const int leftMotor1 = 5;
const int leftMotor2 = 6;
const int rightMotor1 = 9;
const int rightMotor2 = 10;
// Ultrasonic sensor
const int trigPin = 7;
const int echoPin = 8;
void setup() {
pinMode(leftMotor1, OUTPUT);
pinMode(leftMotor2, OUTPUT);
pinMode(rightMotor1, OUTPUT);
pinMode(rightMotor2, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(115200);
}
void loop() {
float distance = getDistance();
if (distance < 20) {
// Obstacle detected, stop and turn
stop();
turnRight();
delay(500);
} else {
// Move forward
forward();
}
delay(100);
}
void forward() {
analogWrite(leftMotor1, 200);
analogWrite(leftMotor2, 0);
analogWrite(rightMotor1, 200);
analogWrite(rightMotor2, 0);
}
void backward() {
analogWrite(leftMotor1, 0);
analogWrite(leftMotor2, 200);
analogWrite(rightMotor1, 0);
analogWrite(rightMotor2, 200);
}
void turnLeft() {
analogWrite(leftMotor1, 0);
analogWrite(leftMotor2, 200);
analogWrite(rightMotor1, 200);
analogWrite(rightMotor2, 0);
}
void turnRight() {
analogWrite(leftMotor1, 200);
analogWrite(leftMotor2, 0);
analogWrite(rightMotor1, 0);
analogWrite(rightMotor2, 200);
}
void stop() {
analogWrite(leftMotor1, 0);
analogWrite(leftMotor2, 0);
analogWrite(rightMotor1, 0);
analogWrite(rightMotor2, 0);
}
float getDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
return duration * 0.034 / 2;
}
Project 3: IoT Data Collection
#include <WiFi.h>
#include <HTTPClient.h>
#include <DHT.h>
const char* ssid = "YourWiFi";
const char* password = "YourPassword";
const char* serverUrl = "http://your-server.com/api/data";
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi connected");
}
void loop() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
String jsonData = "{\"temperature\":" + String(temperature) + ",\"humidity\":" + String(humidity) + "}";
int httpResponseCode = http.POST(jsonData);
if (httpResponseCode > 0) {
Serial.println("Data sent successfully");
} else {
Serial.println("Error sending data");
}
http.end();
}
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("°C, Humidity: ");
Serial.print(humidity);
Serial.println("%\n");
delay(5000); // Send data every 5 seconds
}
Advanced Technologies
RTOS Applications
#include <FreeRTOS.h>
#include <task.h>
// Task 1: LED control
void LEDTask(void *pvParameters) {
while (1) {
digitalWrite(13, HIGH);
vTaskDelay(1000 / portTICK_PERIOD_MS);
digitalWrite(13, LOW);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
// Task 2: Sensor reading
void SensorTask(void *pvParameters) {
while (1) {
float temperature = dht.readTemperature();
Serial.print("Temperature: ");
Serial.println(temperature);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
pinMode(13, OUTPUT);
dht.begin();
// Create tasks
xTaskCreate(LEDTask, "LED", 1000, NULL, 1, NULL);
xTaskCreate(SensorTask, "Sensor", 1000, NULL, 1, NULL);
}
void loop() {
// Empty loop, tasks are scheduled by RTOS
}
Low Power Design
#include <avr/sleep.h>
#include <avr/power.h>
void setup() {
Serial.begin(115200);
pinMode(2, INPUT_PULLUP);
// Configure external interrupt
attachInterrupt(digitalPinToInterrupt(2), wakeUp, FALLING);
}
void loop() {
Serial.println("Going to sleep...");
delay(1000);
// Enter sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
// Continue execution after waking up
sleep_disable();
Serial.println("Woke up!");
}
void wakeUp() {
// Interrupt wake-up handling
}
Firmware Upgrade
#include <Update.h>
void setup() {
Serial.begin(115200);
// Check for firmware updates
if (checkForUpdate()) {
performUpdate();
}
}
bool checkForUpdate() {
// Check if there is new firmware on the server
HTTPClient http;
http.begin("http://your-server.com/firmware");
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
return true;
}
return false;
}
void performUpdate() {
HTTPClient http;
http.begin("http://your-server.com/firmware");
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
int contentLength = http.getSize();
if (Update.begin(contentLength)) {
size_t written = Update.writeStream(http.getStream());
if (written == contentLength) {
if (Update.end()) {
Serial.println("Update successful");
ESP.restart();
}
}
}
}
}
Learning Suggestions
Learning Path
- Basic Stage: Master basic C language, familiarize with GPIO operations
- Intermediate Stage: Learn about timers, interrupts, and serial communication
- Application Stage: Master ADC, PWM, and sensor interfaces
- Project Stage: Complete comprehensive projects, accumulate practical experience
- Professional Stage: Learn about RTOS, low power design, and firmware upgrades
Practical Suggestions
- Hands-On Practice: Timely practice after theoretical learning
- Project-Driven: Learn relevant skills through projects
- Problem-Oriented: Look for solutions promptly when encountering problems
- Continuous Learning: Stay updated with new technologies and trends
Recommended Resources
- Official Documentation: Technical documents provided by manufacturers
- Online Tutorials: Official tutorials for Arduino, STM32, etc.
- Technical Forums: Electronics enthusiasts, 21ic, etc.
- Open Source Projects: Open source projects on GitHub
END
Follow Stephen, learn together, and grow together.
Click “” to support.