![Управление на ATmega328p чрез серийна комуникация](http://ardudevelop.eu/wp-content/uploads/2025/01/Управление-на-ATmega328p-чрез-серийна-комуникация.jpg)
Въведение
Серийната комуникация е основа за взаимодействие между микроконтролери и външни устройства. Тя позволява обмен на данни чрез прост и надежден протокол, подходящ за множество приложения. В тази статия ще разгледаме как да използваме серийна комуникация за управление на платка, базирана на ATmega328p с Arduino UNO Bootloader (разгледайте подробното описание в статията). Ще демонстрираме основни и напреднали функционалности като управление на изходи, PWM сигнали и аналогово изчитане през серийна комуникация. Вече се запознахме с основите в този вид комуникация в статията ни: Серийна комуникация с Arduino UNO чрез USB или Bluetooth HC-05.
![Управление на ATmega328p чрез серийна комуникация PoE+RS_TTL](http://ardudevelop.eu/wp-content/uploads/2025/01/Управление-на-ATmega328p-чрез-серийна-комуникация-PoERS_TTL-1.jpg)
![Управление на ATmega328p чрез серийна комуникация Прототип](http://ardudevelop.eu/wp-content/uploads/2025/01/Управление-на-ATmega328p-чрез-серийна-комуникация-Прототип-1.jpg)
Проектът предоставя метод за управление на пиновете на ATmega328p чрез серийни команди, които могат да се изпращат както ръчно през терминал, така и автоматизирано чрез скриптове на Python или Shell. Това го прави изключително подходящ за различни приложения като домашна автоматизация, учебни проекти или прототипи. За осъществяване на комуникацията между компютъра и микроконтролера ще използваме USB-TTL конвертор, което осигурява лесна и надеждна връзка.
Този проект е създаден не толкова от практическа гледна точка, колкото с идеята да разберем какво точно представлява серийната комуникация и какво може да се управлява с нея!
Код за управление на ATmega328p чрез серийна комуникация
String command;
int pin0PWM = 0;
int pin1PWM = 0;
int pin2PWM = 0;
const int ledPin = 7;
int ledState = LOW;
unsigned long previousMillis = 0;
unsigned long interval = 1000;
// =================( PIN-0 / D-6 / PWM )====================
void pin0(void) {
if (command == "pin0 OUT") {
pinMode(6, OUTPUT);
Serial.println("pin(0) is Output Pin");
} else if (command == "pin0 UP") {
digitalWrite(6, HIGH);
Serial.println("pin(0) is UP");
} else if (command == "pin0 DOWN") {
digitalWrite(6, LOW);
Serial.println("pin(0) is DOWN");
} else if (command == "pin0 IN") {
pinMode(6, INPUT);
Serial.println("pin(0) is Input pin");
} else if (command == "pin0 read") {
Serial.print("pin0 status = ");
Serial.println(digitalRead(6));
} else if (command == "pin0 PWM") {
pinMode(6, OUTPUT);
digitalWrite(6, LOW);
Serial.println("pin(0) is PWM pin");
} else if (command == "pin0 setPWM") {
for (int i = 0; i < 5; i++) {
Serial.println("enter PWM value for pin(0)");
while (Serial.available() == 0) {} // Wait for input
char c = Serial.read();
pin0PWM = (c - '0') * 51;
if (pin0PWM >= 0 && pin0PWM <= 255) {
analogWrite(6, pin0PWM);
Serial.print("pin(0) set to = ");
Serial.println(pin0PWM);
break;
}
delay(500);
}
}
}
// ==========( PIN-1 / D-5 / PWM)================
void pin1(void) {
if (command == "pin1 OUT") {
pinMode(5, OUTPUT);
Serial.println("pin(1) is Output Pin");
} else if (command == "pin1 UP") {
digitalWrite(5, HIGH);
Serial.println("pin(1) is UP");
} else if (command == "pin1 DOWN") {
digitalWrite(5, LOW);
Serial.println("pin(1) is DOWN");
} else if (command == "pin1 IN") {
pinMode(5, INPUT);
Serial.println("pin(1) is Input pin");
} else if (command == "pin1 read") {
Serial.print("pin1 status = ");
Serial.println(digitalRead(5));
} else if (command == "pin1 PWM") {
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
Serial.println("pin(1) is PWM pin");
} else if (command == "pin1 setPWM") {
for (int i = 0; i < 5; i++) {
Serial.println("enter PWM value for pin(1)");
while (Serial.available() == 0) {} // Wait for input
char c = Serial.read();
pin1PWM = (c - '0') * 51;
if (pin1PWM >= 0 && pin1PWM <= 255) {
analogWrite(5, pin1PWM);
Serial.print("pin(1) set to = ");
Serial.println(pin1PWM);
break;
}
delay(500);
}
}
}
// ===============( PIN-2 / D-9 / PWM)==================
void pin2(void) {
if (command == "pin2 OUT") {
pinMode(9, OUTPUT);
Serial.println("pin(2) is Output Pin");
} else if (command == "pin2 UP") {
digitalWrite(9, HIGH);
Serial.println("pin(2) is UP");
} else if (command == "pin2 DOWN") {
digitalWrite(9, LOW);
Serial.println("pin(2) is DOWN");
} else if (command == "pin2 IN") {
pinMode(9, INPUT);
Serial.println(" pin(2) is Input pin");
} else if (command == "pin2 read") {
Serial.print("pin2 status = ");
Serial.println(digitalRead(9));
} else if (command == "pin2 PWM") {
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
Serial.println("pin(2) is PWM pin");
} else if (command == "pin2 setPWM") {
for (int i = 0; i < 5; i++) {
Serial.println("enter PWM value for pin(2)");
while (Serial.available() == 0) {} // Wait for input
char c = Serial.read();
pin2PWM = (c - '0') * 51;
if (pin2PWM >= 0 && pin2PWM <= 255) {
analogWrite(9, pin2PWM);
Serial.print("pin(2) set to = ");
Serial.println(pin2PWM);
break;
}
delay(500);
}
}
}
// ==============( PIN-3 / D-10 )====================
void pin3(void) {
if (command == "pin3 OUT") {
pinMode(10, OUTPUT);
Serial.println("pin(3) is Output Pin");
} else if (command == "pin3 UP") {
digitalWrite(10, HIGH);
Serial.println("pin(3) is UP");
} else if (command == "pin3 DOWN") {
digitalWrite(10, LOW);
Serial.println("pin(3) is DOWN");
} else if (command == "pin3 IN") {
pinMode(10, INPUT);
Serial.println("pin(3) is Input pin");
} else if (command == "pin3 READ") {
Serial.print("pin3 status = ");
Serial.println(digitalRead(10));
} else if (command == "pin3 PWM") {
Serial.println("pin(3) not support PWM mode");
}
}
// ==============( PIN-4 / D-11 )===============
void pin4(void) {
if (command == "pin4 OUT") {
pinMode(11, OUTPUT);
Serial.println("pin(4) is Output Pin");
} else if (command == "pin4 UP") {
digitalWrite(11, HIGH);
Serial.println("pin(4) is UP");
} else if (command == "pin4 DOWN") {
digitalWrite(11, LOW);
Serial.println("pin(4) is DOWN");
} else if (command == "pin4 IN") {
pinMode(11, INPUT);
Serial.println("pin(4) is Input pin");
} else if (command == "pin4 READ") {
Serial.print("pin4 status = ");
Serial.println(digitalRead(11));
} else if (command == "pin4 PWM") {
Serial.println("pin(4) not support PWM mode");
}
}
// ==============( PIN-5 / D-12 )================
void pin5(void) {
if (command == "pin5 OUT") {
pinMode(12, OUTPUT);
Serial.println("pin(5) is Output Pin");
} else if (command == "pin5 UP") {
digitalWrite(12, HIGH);
Serial.println("pin(5) is UP");
} else if (command == "pin5 DOWN") {
digitalWrite(12, LOW);
Serial.println("pin(5) is DOWN");
} else if (command == "pin5 IN") {
pinMode(12, INPUT);
Serial.println("pin(5) is Input pin");
} else if (command == "pin5 READ") {
Serial.print("pin5 status = ");
Serial.println(digitalRead(12));
} else if (command == "pin5 PWM") {
Serial.println("pin(5) not support PWM mode");
}
}
// ================( PIN-A0 )==============
void A0read(void) {
if (command == "pinA0 read") {
Serial.print("pinA0 = ");
Serial.println(analogRead(A0));
} else if (command == "pinA0 read int") {
Serial.println(analogRead(A0));
}
}
// =============( PIN-A1 )===============
void A1read(void) {
if (command == "pinA1 read") {
Serial.print("pinA1 = ");
Serial.println(analogRead(A1));
} else if (command == "pinA1 read int") {
Serial.println(analogRead(A1));
}
}
// ===============( PIN-A2 )===============
void A2read(void) {
if (command == "pinA2 read") {
Serial.print("pinA2 = ");
Serial.println(analogRead(A2));
} else if (command == "pinA2 read int") {
Serial.println(analogRead(A2));
}
}
// ==============( PIN-A3 )===============
void A3read(void) {
if (command == "pinA3 read") {
Serial.print("pinA3 = ");
Serial.println(analogRead(A3));
} else if (command == "pinA3 read int") {
Serial.println(analogRead(A3));
}
}
// ==============( PIN-A4 )==============
void A4read(void) {
if (command == "pinA4 read") {
Serial.print("pinA4 = ");
Serial.println(analogRead(A4));
} else if (command == "pinA4 read int") {
Serial.println(analogRead(A4));
}
}
// ===============( PIN-A5 )==============
void A5read(void) {
if (command == "pinA5 read") {
Serial.print("pinA5 = ");
Serial.println(analogRead(A5));
} else if (command == "pinA5 read int") {
Serial.println(analogRead(A5));
}
}
// =====================================================
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
command = Serial.readStringUntil('\n');
pin0();
pin1();
pin2();
pin3();
pin4();
pin5();
A0read();
A1read();
A2read();
A3read();
A4read();
A5read();
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
ledState = (ledState == LOW) ? HIGH : LOW;
digitalWrite(ledPin, ledState);
}
}
Обяснение на кода
Главни променливи и настройки
- String command: Използва се за съхранение на входящата команда от серийната комуникация.
- int pin0PWM, pin1PWM, pin2PWM: Променливи за стойности на PWM сигнали за пинове 0, 1 и 2.
- const int ledPin: Светодиод, който мига за индикация.
- unsigned long previousMillis, interval: Таймер за управление на мигащия светодиод. Този метод го разгледахме в статията ни: Arduino мигане без закъснение “Blink Without Delay”.
Функции за управление на пинове
pin0(), pin1(), pin2():
Тези функции обработват входни команди за пиновете 6, 5 и 9 (съответстващи на pin0, pin1 и pin2). Те поддържат следните операции:
- OUT: Настройка на пина като изход.
- IN: Настройка на пина като вход.
- UP/DOWN: Активиране/деактивиране на пина (HIGH/LOW).
- read: Чете текущото състояние на пина.
- PWM: Настройка на PWM режим и подаване на стойности (0-5 = 0, 51, 102, 153, 204, 255).
pin3(), pin4(), pin5():
Подобно на pin0–pin2, но пинове 10, 11 и 12 нямат поддръжка на PWM.
A0read() до A5read():
Четене на аналоговите пинове A0 до A5. Поддържат:
- pinA“x” read: Прочита стойност на аналоговия сигнал. Върнат отговор: “pinA0 = 318″
- pinA“x” read int: Прочита стойност в целочислен формат.Върнат отговор: “318“
Функции setup() и loop()
- setup(): Инициализира серийната комуникация и светодиода.
- loop(): Проверява за входни команди, извиква съответните функции за пинове и управлява мигащия светодиод.
Команди за управление
Команди за управление на цифрови пинове (PIN-0 до PIN-5):
PIN-0 (D-6)
- pin0 OUT – Настройка на PIN-0 (D-6) като изход.
- pin0 UP – Включване на PIN-0 (D-6).
- pin0 DOWN – Изключване на PIN-0 (D-6).
- pin0 IN – Настройка на PIN-0 (D-6) като вход.
- pin0 read – Четене на цифровото състояние на PIN-0 (D-6).
- pin0 PWM – Настройка на PIN-0 (D-6) за PWM.
- pin0 setPWM – Въвеждане на стойност за PWM за PIN-0 (D-6).
PIN-1 (D-5)
- pin1 OUT – Настройка на PIN-1 (D-5) като изход.
- pin1 UP – Включване на PIN-1 (D-5).
- pin1 DOWN – Изключване на PIN-1 (D-5).
- pin1 IN – Настройка на PIN-1 (D-5) като вход.
- pin1 read – Четене на цифровото състояние на PIN-1 (D-5).
- pin1 PWM – Настройка на PIN-1 (D-5) за PWM.
- pin1 setPWM – Въвеждане на стойност за PWM за PIN-1 (D-5).
PIN-2 (D-9)
- pin2 OUT – Настройка на PIN-2 (D-9) като изход.
- pin2 UP – Включване на PIN-2 (D-9).
- pin2 DOWN – Изключване на PIN-2 (D-9).
- pin2 IN – Настройка на PIN-2 (D-9) като вход.
- pin2 read – Четене на цифровото състояние на PIN-2 (D-9).
- pin2 PWM – Настройка на PIN-2 (D-9) за PWM.
- pin2 setPWM – Въвеждане на стойност за PWM за PIN-2 (D-9).
PIN-3 (D-10)
- pin3 OUT – Настройка на PIN-3 (D-10) като изход.
- pin3 UP – Включване на PIN-3 (D-10).
- pin3 DOWN – Изключване на PIN-3 (D-10).
- pin3 IN – Настройка на PIN-3 (D-10) като вход.
- pin3 READ – Четене на цифровото състояние на PIN-3 (D-10).
- pin3 PWM – Известие, че PIN-3 не поддържа PWM режим.
PIN-4 (D-11)
- pin4 OUT – Настройка на PIN-4 (D-11) като изход.
- pin4 UP – Включване на PIN-4 (D-11).
- pin4 DOWN – Изключване на PIN-4 (D-11).
- pin4 IN – Настройка на PIN-4 (D-11) като вход.
- pin4 READ – Четене на цифровото състояние на PIN-4 (D-11).
- pin4 PWM – Известие, че PIN-4 не поддържа PWM режим.
PIN-5 (D-12)
- pin5 OUT – Настройка на PIN-5 (D-12) като изход.
- pin5 UP – Включване на PIN-5 (D-12).
- pin5 DOWN – Изключване на PIN-5 (D-12).
- pin5 IN – Настройка на PIN-5 (D-12) като вход.
- pin5 READ – Четене на цифровото състояние на PIN-5 (D-12).
- pin5 PWM – Известие, че PIN-5 не поддържа PWM режим.
Команди за четене на аналогови пинове (A0 до A5):
- pinA0 read – Четене на аналоговата стойност на A0.
- pinA0 read int – Четене на аналоговата стойност на A0 и извеждане на целочислената стойност.
- pinA1 read – Четене на аналоговата стойност на A1.
- pinA1 read int – Четене на аналоговата стойност на A1 и извеждане на целочислената стойност.
- pinA2 read – Четене на аналоговата стойност на A2.
- pinA2 read int – Четене на аналоговата стойност на A2 и извеждане на целочислената стойност.
- pinA3 read – Четене на аналоговата стойност на A3.
- pinA3 read int – Четене на аналоговата стойност на A3 и извеждане на целочислената стойност.
- pinA4 read – Четене на аналоговата стойност на A4.
- pinA4 read int – Четене на аналоговата стойност на A4 и извеждане на целочислената стойност.
- pinA5 read – Четене на аналоговата стойност на A5.
- pinA5 read int – Четене на аналоговата стойност на A5 и извеждане на целочислената стойност.
Платки на проекта за управление на ATmega328p чрез серийна комуникация
![Управление на ATmega328p чрез серийна комуникация PCB](http://ardudevelop.eu/wp-content/uploads/2025/01/IMG_20190619_190453.jpg)
![Управление на ATmega328p чрез серийна комуникация PDF fritzing](http://ardudevelop.eu/wp-content/uploads/2025/01/rs.jpg)
![Управление на ATmega328p чрез серийна комуникация PoE](http://ardudevelop.eu/wp-content/uploads/2025/01/управление-на-ATmega328p-чрез-серийна-комуникация-PoE-PCB.jpg)
![Управление на ATmega328p чрез серийна комуникация PoE fritzing](http://ardudevelop.eu/wp-content/uploads/2025/01/управление-на-ATmega328p-чрез-серийна-комуникация-PoE-fritzing.jpg)
Схема на управление на ATmega328p чрез серийна комуникация
Управление-на-ATmega328p-чрез-серийна-комуникация-Схема-контролер Управление-на-ATmega328p-чрез-серийна-комуникация-Схема-захранване Управление-на-ATmega328p-чрез-серийна-комуникация-Схема-PoEЗаключение
Тази статия представя основите на серийната комуникация и нейното приложение за управление на микроконтролери. С тази основа могат да се изграждат по-сложни системи, включително с RS485 протокол. Командите и подходът могат да бъдат лесно адаптирани за различни проекти, което прави това решение подходящо за широк кръг от приложения, но най-вече за общо разбиране на това как работи серийната комуникация.
Офицялен источник и описание: Arduino Serial