"Hành trình vạn dặm bắt đầu từ những bước đi đầu tiên"

せんりのみちもいっぽから

DANH NGÔN

Hành trình vạn dặm bắt đầu từ một bước chân - Lão Tử
Showing posts with label arduino. Show all posts
Showing posts with label arduino. Show all posts

Sep 21, 2025

Hướng dẫn tự làm Chatbot AI xiaozhi trò chuyện bằng giọng nói tiếng việt dùng esp32 s3 và tft 1.54in

Nguồn: Điện Thông Minh Esmart,Bạn Nguyễn Công Huy

esp32-s3

esp32 kit v1

I. TÊN LINH KIỆN
  1. CẢM BIẾN ÂM THANH INMP 441 
  2. KIT ESP 32-S3 OR ESP32 KIT V1
  3. MÀN HÌNH TFT 1.54 INCH
  4. MẠCH KHUẾCH ĐẠI MAX98375A
  5. LOA 
II.   CODE  MẪU: TẠI ĐÂY
III. SERVER ,CODEhttps://xiaozhi.me/
V. MCP : imcp.pro
VI. Nguồn firmware: heylily.net






Sep 29, 2023

PHÁT NHẠC RA MP3 DÙNG ARDUINO NANO + MODULE DFPLAYER+ RFID RC522

 SẢN PHẨM : 

Máy đọc thẻ thông minh




I. PHẦN CỨNG

  1. ARDUINO NANO
  2. LOA 5V
  3. MODULE GIẢI MÃ DFPLAYER MINI
  4. MẠCH ĐỌC RFID RC522
  5. THẺ NHỚ 8GB,...
  6. LED
  7. TRỞ 220KOM
II. SƠ ĐỒ ĐẤU NỐI


III. LẬP TRÌNH:

#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

#define RST_PIN 9
#define SS_PIN 10
#define LED_PIN 7
// đọc rfid
MFRC522 mfrc522(SS_PIN, RST_PIN);
String allowedRFIDCards[] = { "863f2c9e", "4c03c2a226f80","4d03c2a226f80" };
// khởi tạo dfplayermini
SoftwareSerial mySerial(2, 3);
DFRobotDFPlayerMini player;
// định thời gian tắt led
bool isPlaying = false;
unsigned long playbackStartTime = 0;
const unsigned long playbackDuration = 5000;

void setup() {
  mySerial.begin(9600);
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println("Vui lòng đặt thẻ RFID lên đầu đọc...");
  if (!player.begin(mySerial)) {
    Serial.println(F("Lỗi! Không tìm thấy DFPlayer Mini."));
    while (true)
      ;
  }
  player.volume(30);
}

void loop() {
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    Serial.println("Thẻ RFID được phát hiện!");
    String rfidCode = getRFIDCode();
    Serial.println(rfidCode);
    if (rfidCode == "863f2c9e") {
      Serial.println("Thẻ 1 OK. MP3 play");
      toggleLED(1);
      playSound(2);
    } else if (rfidCode == "4c03c2a226f80") {
      Serial.println("Thẻ 2 OK. MP3 play");
      toggleLED(1);
      playSound(3);
    } else if (rfidCode == "4d03c2a226f80") {
      Serial.println("Thẻ 3 OK. MP3 play");
      playSound(1);
      toggleLED(1);
    } else {
      Serial.println("Thẻ không được chấp nhận.Tắt");
      toggleLED(0);
      playSound(0);
    }

    isPlaying = true;
    playbackStartTime = millis(); // bắt đầu đếm thời gian

    delay(2000);
  }

  if (isPlaying) {
    // Nếu mp3 phát >5S thì sẽ tắt led
    if (millis() - playbackStartTime >= playbackDuration) {
      toggleLED(0);
      isPlaying = false;
    }
  }
}

String getRFIDCode() {
  String rfidCode = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    rfidCode += String(mfrc522.uid.uidByte[i], HEX);
  }
  return rfidCode;
}

void toggleLED(int state) {
  digitalWrite(LED_PIN, state);
}

void playSound(int track) {
  player.play(track);
}


Sep 22, 2023

GIAO TIẾP ARDUINO NANO + RFID


Thứ tự nối chân Arduino nano- RFID


1. Arduino Nano + RFID-RC522 - Arduino Tutorial

2. Thư viện RFID MFR522

3.THẺ MIFARE LÀ GÌ?

4. Code mẫu:

#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key;
int code[] = {32,154,149,117}; //This is the stored UID (Unlock Card)
int codeRead = 0;
String uidString;
void setup() {
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522
  Serial.println(F("MỜI QUẸT THẺ"));
}
void loop() {
  if(  rfid.PICC_IsNewCardPresent())
  {
      readRFID();
  }
  delay(100);
}
void readRFID()
{
  rfid.PICC_ReadCardSerial();
  Serial.print(F("\nPICC type: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));
  // Check is the PICC of Classic MIFARE type
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&

    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&

    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {

    Serial.println(F("THẺ KHÔNG HỢP LỆ "));
    return;
  }
    Serial.println("SỐ THẺ LÀ :");

    printDec(rfid.uid.uidByte, rfid.uid.size);
    uidString = String(rfid.uid.uidByte[0])+" "+String(rfid.uid.uidByte[1])+" "+String(rfid.uid.uidByte[2])+ " "+String(rfid.uid.uidByte[3]);
    int i = 0;
    boolean match = true;
    while(i<rfid.uid.size)
    {
      if(!(int(rfid.uid.uidByte[i]) == int(code[i])))
      {
           match = false;
      }
      i++;
    }
    if(match)
    {
      Serial.println("\n*** Unlock ***");
    }else
    {
      Serial.println("\nUnknown Card");
    }
   Serial.println("============================");
    // Halt PICC
  rfid.PICC_HaltA();
  // Stop encryption on PCD
  rfid.PCD_StopCrypto1();
}
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], DEC);
  }
}


II. BẬT LED VỚI RFID
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 9  // Chân kết nối RST của đầu đọc RFID
#define SS_PIN 10  // Chân kết nối SS của đầu đọc RFID
#define LED_PIN 7  // Chân kết nối LED

MFRC522 mfrc522(SS_PIN, RST_PIN); // Tạo đối tượng MFRC522

// Mảng chứa các mã số thẻ RFID cho phép
String allowedRFIDCards[] = {"863f2c9e", "9876543210"};

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  SPI.begin(); // Khởi động giao tiếp SPI
  mfrc522.PCD_Init(); // Khởi động đầu đọc RFID
  Serial.println("Vui lòng đặt thẻ RFID lên đầu đọc...");
}

void loop() {
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    Serial.println("Thẻ RFID được phát hiện!");
    String rfidCode = getRFIDCode(); // Lấy mã số thẻ RFID
    if (isAuthorized(rfidCode)) {
      Serial.println("Thẻ được chấp nhận. Bật LED.");
      digitalWrite(LED_PIN, 1); // Bật LED
      delay(1000); // Chờ 1 giây
      digitalWrite(LED_PIN, 0); // Tắt LED
    } else {
      Serial.println("Thẻ không được chấp nhận.");
      Serial.println(rfidCode);
    }
    delay(2000); // Chờ 2 giây trước khi tiếp tục quét thẻ tiếp theo
  }
}

String getRFIDCode() {
  String rfidCode = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    rfidCode += String(mfrc522.uid.uidByte[i], HEX);
  }
  return rfidCode;
}

bool isAuthorized(String rfidCode) {
  for (int i = 0; i < sizeof(allowedRFIDCards) / sizeof(allowedRFIDCards[0]); i++) {
    if (rfidCode == allowedRFIDCards[i]) {
      return true;
    }
  }
  return false;
}

Sep 19, 2023

Cải tiến kính dẫn đường



I. Thiết bị bao gồm
1. Arduino promini
2. Mạch tăng áp dc-dc.
3. Loa
4. Cảm biến khoảng cách sharp
5. Motor rung
6. Box in 3d
II. Nguyên lý hoạt động dưới video :


III. Code mẫu:
#include <SharpIR.h>
#define ir A0
#define model 20150
int imotor = 4;
int ibuzz = 3;
int icount = 0;
SharpIR SharpIR(ir, model);
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(imotor, OUTPUT);
  pinMode(ibuzz, OUTPUT);
}

void loop() {
  unsigned long startTime = millis();
  int khoangcach = SharpIR.distance();
  Serial.println(khoangcach);
  unsigned long endtime = millis() - startTime;
  if (khoangcach > 10 && khoangcach <= 100) {
   
    //Serial.println("RUN :");
    digitalWrite(imotor, LOW);
     icount++;
    // Ghi lại thời điểm phát hiện vật cản

  } else {
    //Serial.println("STOP HERE : ");
    digitalWrite(imotor, HIGH);
    icount = 0;
  }
  if (icount >= 3) {

    digitalWrite(ibuzz, LOW);

  } else {
    digitalWrite(ibuzz, HIGH);
  }
   //Serial.println(icount);

  delay(1000);
}
IV. ĐỐI TƯỢNG:
NGƯỜI KHIẾM THỊ

Sep 3, 2023

Hướng dẫn MODE Ch340 (USB -> UART) nạp cho Arduino promini

 I. Chuẩn bị

1. USB to UART CH340

2. Tụ gốm 104

3. Mỏ hàn

II. Tiến hành mổ xẻ

B1:Xác định thứ tự chân của jump để câu dây. Ta có thứ tự chân như hình vẽ.

Chân số 13


B2: Kết nối chân 13(DTR) của chip ch340 với tụ C104 

Các bạn sử dụng loại tụ này nhé 

Tụ gốm 104




Sơ đồ kết nối tụ gốm 104 với ch340






Chân 13 là chân DTR: Data terminal relay. 

B3. Kết nối Ch340 với arduino pro mini


Trên arduino promini kết nối vào chân DTR - DTR



Tiến hành nạp code . Chúc các bạn thành công!

Tham khảo :Arduino.vn

>>Tụ gốm


Jun 24, 2023

Thực hành lập trình điều khiển Robot Car for Arduino

Lắp ráp và code mẫu của osoyoo :

Dec 8, 2022

Tổng Quan Màn hình LCD 16×2 Arduino , giao tiếp i2c

 Màn hình LCD 16×2 là một linh kiện được sử dụng rộng rãi trong trong các dự án điện tử và lập trình.

Vậy cách để hiển thị các ký tự các thông số lên LCD 16×2 như thế nào?

Có dễ dàng hay không?

Qua bài viết hôm nay chúng ta sẽ đi sâu vào tìm hiểu các sử dụng LCD và giao tiếp với module IC2 nhé.

Giới thiệu LCD 16×2

Thông số kỹ thuật LCD 16×2

LCD 16×2 được sử dụng để hiển thị trạng thái hoặc các thông số.

LCD 16×2 có 16 chân trong đó 8 chân dữ liệu (D0 – D7) và 3 chân điều khiển (RS, RW, EN).

5 chân còn lại dùng để cấp nguồn và đèn nền cho LCD 16×2.

Các chân điều khiển giúp ta dễ dàng cấu hình LCD ở chế độ lệnh hoặc chế độ dữ liệu.

Chúng còn giúp ta cấu hình ở chế độ đọc hoặc ghi.

LCD 16×2 có thể sử dụng ở chế độ 4 bit hoặc 8 bit tùy theo ứng dụng ta đang làm.

Module I2C Arduino

LCD có quá nhiều nhiều chân gây khó khăn trong quá trình đấu nối và chiếm dụng nhiều chân trên vi điều khiển. 

Module I2C LCD ra đời và giải quyết vấn để này cho bạn.

Thay vì phải mất 6 chân vi điều khiển để kết nối với LCD 16×2 (RS, EN, D7, D6, D5 và D4) thì module IC2 bạn chỉ cần tốn 2 chân (SCL, SDA) để kết nối.

Module I2C hỗ trợ các loại LCD sử dụng driver HD44780(LCD 16×2, LCD 20×4, …) và tương thích với hầu hết các vi điều khiển hiện nay.


Ưu điểm

Tiết kiệm chân cho vi điều khiển.

Dễ dàng kết nối với LCD.

Thông số kĩ thuật

Điện áp hoạt động: 2.5-6V DC.

Hỗ trợ màn hình: LCD1602,1604,2004 (driver HD44780).

Giao tiếp: I2C.

Địa chỉ mặc định: 0X27 (có thể điều chỉnh bằng ngắn mạch chân A0/A1/A2).

Tích hợp Jump chốt để cung cấp đèn cho LCD hoặc ngắt.

Tích hợp biến trở xoay điều chỉnh độ tương phản cho LCD.

Để sử dụng màn hình LCD giao tiếp I2C sử dụng Arduino thì ta cần cài đặt thư viện Liquidcrystal_I2C. Tại đây

Các lỗi thường gặp khi sử dụng I2C LCD

Hiển thị một dãy ô vuông.

Màn hình chỉ in ra một ký tự đầu.

Màn hình nhấp nháy.

Các lỗi này chủ yếu là do sai địa chỉ bus, để fix lỗi các bạn thay địa chỉ mặc định là “0x27” thành “0x3F.

Trong trường hợp vẫn không được các bạn fix lỗi bằng cách nạp code tìm địa chỉ bus của I2C.

Sau khi tìm xong các bạn thay địa chỉ vừa tìm được vào vị trí “0x27” là xong.


Các bạn có thể tải code tìm địa chỉ bus ở đây. Tải ngay.

Giao tiếp I2C LCD Arduino

Module I2C LCD 16×2 Arduino UNO

Uno

GND GND

VCC 5V

SDA A4/SDA

SCL A5/SCL

Mega 2560

GND GND

VCC 5V

SDA SDA

SCL        SCL


Sơ đồ đấu nối arduino mega 2560




Sơ đồ đấu nối arduino uno



Sơ đồ đấu nối giao tiếp IC2 với LCD 16×2.

Code Mẫu:

#include <Wire.h> 

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2); 


void setup()

{

  lcd.init();                    

  lcd.backlight();

  lcd.setCursor(2,0);

  lcd.print("Arduino");

  lcd.setCursor(0,1);

  lcd.print("Hello world");

}


void loop()

{

}


Tham Khảo:https://arduinokit.vn/giao-tiep-i2c-lcd-arduino/#google_vignette 

May 13, 2022

Điều khiển tốc độ ,vị trí vs arduino

May 12, 2022

Điều khiển động cơ DC bằng 2 nút bấm , bằng IR remote , Bằng iphone

>>Những thiết bị giúp cuộc sống trở nên thông minh hơn

I.Chuẩn bị :

1. Board arduino uno

2. Mạch L298N

3. 2 x Nút Bấm

4 . 1 Motor 12vdc

5. Nguồn 12 vdc

6. 2 trở 10k

7.  1x IR receved

II.Ứng dụng:

  1. Làm rèm cửa tự động
  2. https://youtu.be/9SZgd7-JKys
  3. Làm máy bơm nước tự động
  4. Làm Máy sát khuẩn tự động
  5. Làm ô tô điều khiển từ xa

....

1. Điều khiển động cơ thông bằng 2 nút bấm:

#define IN1  7

#define IN2 6

#define IN3 5

#define IN4 4

#define MAX_SPEED 255 //từ 0-255

#define MIN_SPEED 0

int BtnNext = 2;

#define BtnPrev 8

bool btien;

bool blui;

void setup()

{

  Serial.begin(9600);

  pinMode(BtnNext, INPUT);

  pinMode(BtnPrev, INPUT);

  pinMode(IN1, OUTPUT);

  pinMode(IN2, OUTPUT);

  btien = false;

  blui = false;

}


void motor_1_Dung() {

  digitalWrite(IN1, LOW);

  digitalWrite(IN2, LOW);

}


void motor_2_Dung() {

  digitalWrite(IN3, LOW);

  digitalWrite(IN4, LOW);

}


void motor_1_Tien(int speed) { //speed: từ 0 - MAX_SPEED

  speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain

  digitalWrite(IN1, HIGH);// chân này không có PWM

  analogWrite(IN2, 255 - speed);

}


void motor_1_Lui(int speed) {

  speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain

  digitalWrite(IN1, LOW);// chân này không có PWM

  analogWrite(IN2, speed);

}



void loop()

{

  int buttonStatusNext = digitalRead(BtnNext);

  int buttonStatusPrev = digitalRead(BtnPrev);


  if (buttonStatusNext != 0 && buttonStatusPrev == 0) {

    Serial.println("tien");

    motor_1_Tien(MAX_SPEED);

    delay(1000);

  } 

  else if (buttonStatusNext == 0 && buttonStatusPrev != 0) {

motor_1_Lui(MAX_SPEED);

    Serial.println("Lui");

    delay(1000);


  } else {

    Serial.println("Stop");

    motor_1_Dung();

    delay(1000);

  }

}

2. Điều khiển động cơ bằng IR remote:

#include<IRremote.h>

#define IN1  7

#define IN2 6

#define IN3 5

#define IN4 4

#define MAX_SPEED 255 //từ 0-255

#define MIN_SPEED 0

int BtnNext = 2;

#define BtnPrev 3

const int receiverPin = 8;

IRrecv irrecv(receiverPin); // tạo đối tượng IRrecv mới

decode_results results;// lưu giữ kết quả giải mã tín hiệu

bool btien;

bool blui;

void setup()

{

  Serial.begin(9600);

  irrecv.enableIRIn();  //bat day nhan tin hieu IR

  pinMode(BtnNext, INPUT);

  pinMode(BtnPrev, INPUT);

  pinMode(IN1, OUTPUT);

  pinMode(IN2, OUTPUT);

  btien = false;

  blui = false;

}

void giaima() {

  //Serial.println("HIHI");

  if (irrecv.decode(&results)) // nếu nhận được tín hiệu

  {

    //Serial.println(results.value, HEX); // in ra Serial Monitor

    delay(200);

    irrecv.resume(); // nhận giá trị tiếp theo

  }

}


void motor_1_Dung() {

  digitalWrite(IN1, LOW);

  digitalWrite(IN2, LOW);

}


void motor_2_Dung() {

  digitalWrite(IN3, LOW);

  digitalWrite(IN4, LOW);

}


void motor_1_Tien(int speed) { //speed: từ 0 - MAX_SPEED

  speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain

  digitalWrite(IN1, HIGH);// chân này không có PWM

  analogWrite(IN2, 255 - speed);

}


void motor_1_Lui(int speed) {

  speed = constrain(speed, MIN_SPEED, MAX_SPEED);//đảm báo giá trị nằm trong một khoảng từ 0 - MAX_SPEED - http://arduino.vn/reference/constrain

  digitalWrite(IN1, LOW);// chân này không có PWM

  analogWrite(IN2, speed);

}

void dknutbam() {

  int buttonStatusNext = digitalRead(BtnNext);

  int buttonStatusPrev = digitalRead(BtnPrev);


  if (buttonStatusNext != 0 && buttonStatusPrev == 0) {

    Serial.println("tien");

    motor_1_Tien(MAX_SPEED);

    delay(1000);

  }

  else if (buttonStatusNext == 0 && buttonStatusPrev != 0) {

    motor_1_Lui(MAX_SPEED);

    Serial.println("Lui");

    delay(1000);


  } else {

    Serial.println("Stop");

    motor_1_Dung();

    delay(1000);

  }

}

void hamgiaima() {

  switch (results.value) {

    case 0x10EF807F://so1

      Serial.println("tien");

      motor_1_Tien(MAX_SPEED);

      delay(1000);

      break;

    case 0x10EF40BF://so2

      motor_1_Lui(MAX_SPEED);

      Serial.println("Lui");

      delay(1000);

      break;

    case 0x10EFC03F://so 3

      Serial.println("Stop");

      motor_1_Dung();

      delay(1000);


      break;


  }

}

  void loop()

  {

    giaima();

    hamgiaima();

  }

3. Điều khiển động cơ bằng iphone kết hợp vs 1 bộ điều khiển trung tâm 

Thay vì sử dụng IR remote ta sử dụng Iphone để điều khiển . Nhưng kết hợp thêm bộ điều khiển trung tâm ở đây mình dùng thêm bộ điều khiển bam bam remote controller. Mục đích để nhận giải mã của remote , gửi chuỗi lên một server chung sau đó đẩy về qua mạng internet .

Về nguyên lý điều khiển tương tự Remote 

(Updating....)



tham khảo. Arduino.vn

Apr 28, 2022

Điều khiển động cơ DC bằng Arduino

 Nguồn: https://vietmachine.com.vn/dieu-khien-arduino-dc-l298n-pwm-mach-cau-h.html

https://howtomechatronics.com/

https://www.youtube.com/c/HowToMechatronics/videos

Điều khiển động cơ DC bằng Arduino

Trong Hướng dẫn Arduino này, chúng ta sẽ tìm hiểu cách điều khiển động cơ DC bằng Arduino. Chúng tôi cũng xem xét một số kỹ thuật cơ bản để điều khiển động cơ DC và đưa ra hai ví dụ thông qua đó chúng tôi sẽ tìm hiểu cách điều khiển động cơ DC bằng trình điều khiển L298N và board Arduino.

Điều khiển động cơ PWM DC

Chúng ta có thể điều khiển tốc độ của động cơ DC bằng cách điều khiển điện áp đầu vào của động cơ và phương pháp phổ biến nhất để làm điều đó là sử dụng tín hiệu PWM.

Điều khiển bằng tín hiệu PWM

PWM hay thay đổi độ rộng xung là một kỹ thuật cho phép chúng ta điều chỉnh giá trị trung bình của điện áp đến thiết bị điện tử bằng cách bật và tắt nguồn với tốc độ nhanh. Điện áp trung bình phụ thuộc vào chu kỳ xung, hoặc lượng thời gian tín hiệu BẬT so với lượng thời gian tín hiệu TẮT trong một khoảng thời gian quy định.

Biểu đồ tín hiệu xung

Vì vậy: Tùy thuộc vào kích thước của động cơ, chúng ta có thể chỉ cần kết nối đầu ra Arduino với chân cua điện trở hoặc chân của MOSFET và điều khiển tốc độ của động cơ bằng cách điều khiển đầu ra PWM. Tín hiệu Arduino công suất thấp bật và tắt chân tại MOSFET thông qua đó động cơ công suất cao được điều khiển.

sơ đồ mạch điều khiển

Sơ đồ mạch điều khiển động cơ Arduino PWM DC

Lưu ý: Arduino GND và nguồn cung cấp năng lượng động cơ GND nên được kết nối với nhau.

Điều khiển động cơ DC bằng mạch cầu H

Mặt khác, để điều khiển hướng quay, chúng ta chỉ cần đảo ngược hướng của dòng điện qua động cơ, và phương pháp phổ biến nhất để làm điều đó là sử dụng mạch cầu H. Một mạch cầu H chứa bốn chân chuyển mạch, điện trở hoặc MOSFET, với động cơ ở trung tâm tạo thành một cấu hình giống như chữ H. Bằng cách kích hoạt hai công tắc cụ thể cùng một lúc, chúng ta có thể thay đổi hướng của dòng điện, do đó thay đổi hướng quay của động cơ.

mạch cầu

Vì vậy, nếu chúng ta kết hợp hai phương thức này, PWM và H-Bridge, chúng ta có thể kiểm soát hoàn toàn động cơ DC. Có nhiều trình điều khiển động cơ DC có các tính năng này và L298N là một trong số đó.

Chip L298N

L298N là trình điều khiển động cơ H-Bridge kép cho phép điều khiển tốc độ và hướng của hai động cơ DC cùng một lúc. Mô-đun có thể điều khiển động cơ DC có điện áp trong khoảng từ 5 đến 35V, với dòng điện cực đại lên đến 2A.

bộ điều khiển L298N

Trình điều khiển động cơ cầu đôi L298N

Chúng ta hãy xem xét kỹ hơn về sơ đồ chân của mô-đun L298N và giải thích cách thức hoạt động của nó. Mô-đun này có hai nhóm chân cho động cơ A và B, và một chân ở giữa cho chân Ground, VCC cho động cơ và chân 5V có thể là đầu vào hoặc đầu ra.

sơ đồ đấu nối dây điện

Điều này phụ thuộc vào điện áp được sử dụng tại động cơ VCC. Mô-đun này có bộ điều chỉnh 5V trên board được bật hoặc tắt bằng cách sử dụng dây nối. Nếu điện áp cung cấp động cơ lên ​​đến 12V, chúng ta có thể kích hoạt bộ điều chỉnh 5V và chân 5V có thể được sử dụng làm đầu ra, ví dụ để cấp nguồn cho board Arduino của chúng ta. Nhưng nếu điện áp động cơ lớn hơn 12V, chúng ta phải ngắt kết nối dây vì những điện áp đó sẽ làm hỏng cho bộ điều chỉnh 5V trên board. Trong trường hợp này, chân 5V sẽ được sử dụng làm đầu vào vì chúng ta cần kết nối nó với nguồn điện 5V để IC hoạt động bình thường.

Chúng ta có thể lưu ý ở đây rằng IC này làm giảm điện áp khoảng 2V. Vì vậy, ví dụ, nếu chúng ta sử dụng nguồn điện 12V, điện áp tại các chân động cơ sẽ vào khoảng 10V, điều đó có nghĩa là chúng ta sẽ không thể cung cấp tốc độ tối đa ra khỏi động cơ DC.

đô điện áp

Giảm điện áp L298N

Tiếp theo là các đầu vào điều khiển logic. Các chân Bật A và Bật B được sử dụng để bật và kiểm soát tốc độ của động cơ. Nếu một dây có mặt trên chân này, động cơ sẽ được kích hoạt và hoạt động ở tốc độ tối đa, và nếu chúng ta loại bỏ dây, chúng ta có thể kết nối một đầu vào PWM với chân này và theo cách đó kiểm soát tốc độ của động cơ. Nếu chúng ta kết nối chân này với Ground, động cơ sẽ bị vô hiệu hóa.

sơ đồ mạch điện

Sơ đồ khối L298N Lưu lượng hiện tại và Cách hoạt động

Tiếp theo, các chân Đầu vào 1 và Đầu vào 2 được sử dụng để điều khiển hướng quay của động cơ A và đầu vào 3 và 4 cho động cơ B. Sử dụng các chân này, chúng tôi thực sự điều khiển các công tắc của mạch cầu H bên trong IC L298N. Nếu đầu vào 1 ở mức THẤP và đầu vào 2 là CAO thì động cơ sẽ di chuyển về phía trước và ngược lại, nếu đầu vào 1 ở mức CAO và đầu vào 2 ở mức THẤP thì động cơ sẽ di chuyển lùi. Trong trường hợp cả hai đầu vào đều giống nhau, cùng THẤP hoặc CAO, động cơ sẽ dừng. Điều tương tự áp dụng cho đầu vào 3 và 4 và động cơ B.

Arduino và L298N

Bây giờ hãy làm một số ứng dụng thực tế. Trong ví dụ đầu tiên, chúng tôi sẽ điều khiển tốc độ của động cơ bằng biến trở và thay đổi hướng quay bằng nút ấn. Đây là sơ đồ mạch.

sơ đồ mạch điện với arduino

Sơ đồ mạch Arduino và L298N Điều khiển động cơ DC

Vì vậy: chúng ta cần một trình điều khiển L298N, động cơ DC, biến trở, nút ấn và board Arduino.

Các linh kiện cần thiết:

  • Bộ điều khiển L298N
  • Động cơ DC 12 V
  • Board Arduino
  • Breadboard và dây nối

Code Arduino

Đây là mã Arduino:

#define enA 9
#define in1 6
#define in2 7
#define button 4

int rotDirection = 0;
int pressed = false;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(button, INPUT);
  // Set initial rotation direction
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
}

void loop() {
  int potValue = analogRead(A0); // Read potentiometer value
  int pwmOutput = map(potValue, 0, 1023, 0 , 255); // Map the potentiometer value from 0 to 255
  analogWrite(enA, pwmOutput); // Send PWM signal to L298N Enable pin

  // Read button - Debounce
  if (digitalRead(button) == true) {
    pressed = !pressed;
  }
  while (digitalRead(button) == true);
  delay(20);

  // If button is pressed - change rotation direction
  if (pressed == true  & rotDirection == 0) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    rotDirection = 1;
    delay(20);
  }
  // If button is pressed - change rotation direction
  if (pressed == false & rotDirection == 1) {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    rotDirection = 0;
    delay(20);
  }
}

Mô tả: Vì vậy, trước tiên chúng ta cần xác định các chân và một số biến cần thiết cho chương trình. Trong phần thiết lập, chúng ta cần đặt các chế độ chân và hướng quay ban đầu của động cơ. Trong phần vòng lặp, chúng tôi bắt đầu bằng cách đọc giá trị biến trở và sau đó ánh xạ giá trị mà chúng tôi nhận được từ 0 đến 1023, giá trị từ 0 đến 255 cho tín hiệu PWM, hoặc đó là chu kỳ nhiệm vụ 0 đến 100% của Tín hiệu PWM. Sau đó, bằng cách sử dụng chức năng analogWrite (), chúng tôi gửi tín hiệu PWM đến chân Bật của board L298N, điều khiển động cơ.

Tiếp theo, chúng tôi kiểm tra xem chúng tôi đã nhấn nút chưa và nếu đã bật, chúng tôi sẽ thay đổi hướng quay của động cơ bằng cách đặt trạng thái Đầu vào 1 và Đầu vào 2 ngược lại. Nút ấn sẽ hoạt động như nút chuyển đổi và mỗi lần chúng ta nhấn nó, nó sẽ thay đổi hướng quay của động cơ.

Điều khiển xe Arduino bằng bộ điều khiển L298N

Vì vậy, một khi chúng ta đã biết được điều này, bây giờ chúng ta có thể chế tạo chiếc xe robot Arduino của riêng mình. Đây là sơ đồ mạch:

sơ đồ kết nối mạch điện

Điều khiển xe Arduino sử dụng sơ đồ mạch điều khiển L298N

Tất cả những gì chúng ta cần là 2 Motor DC, trình điều khiển L298N, board Arduino và cần điều khiển. Về nguồn điện, tôi chọn sử dụng ba pin Li-ion 3.7V, cung cấp tổng cộng 11V. Tôi đã làm cho khung xe bằng ván ép dày 3 mm, gắn các động cơ vào nó bằng khung kim loại, gắn bánh xe vào động cơ và phía trước gắn một bánh xe xoay.

xe đều khiển

Arduino Robot Car DIY Khung gầm

Bây giờ chúng ta hãy xem code Arduino và xem nó hoạt động như thế nào.

int xAxis = analogRead(A0); // Read Joysticks X-axis
int yAxis = analogRead(A1); // Read Joysticks Y-axis

Sau khi xác định các chân, trong phần vòng lặp, chúng ta bắt đầu với việc đọc các giá trị trục X và Y của phím điều khiển. Cần điều khiển thực sự được làm bằng hai biến trở được kết nối với đầu vào analog của Arduino và chúng có giá trị từ 0 đến 1023. Khi cần điều khiển ở vị trí trung tâm, giá trị của cả hai biến trở hoặc trục là khoảng 512.

Joysticks

Điều khiển chuyển động xe Arduino

Chúng tôi sẽ thêm một chút dung sai và có giá trị từ 470 đến 550 là chính. Vì vậy, nếu chúng ta di chuyển trục Y của phím điều khiển lùi và giá trị xuống dưới 470, chúng ta sẽ đặt hướng quay của hai động cơ về phía sau bằng bốn chân đầu vào. Sau đó, chúng tôi sẽ chuyển đổi các giá trị giảm dần từ 470 thành 0 thành tăng giá trị PWM từ 0 đến 255, đây là tốc độ của động cơ.

// Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }

Tương tự, nếu chúng ta di chuyển trục Y của cần điều khiển về phía trước và giá trị vượt quá 550, chúng ta sẽ có các động cơ di chuyển về phía trước và chuyển đổi số đọc từ 550 sang 1023 thành giá trị PWM từ 0 đến 255. Nếu cần điều khiển ở giữa tốc độ động cơ sẽ bằng không.

Tiếp theo, hãy xem cách chúng tôi sử dụng trục X cho điều khiển bên trái và bên phải của xe.

// X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }

Vì vậy, một lần nữa, trước tiên chúng ta cần chuyển đổi số đọc trục X thành giá trị tốc độ từ 0 đến 255. Để di chuyển sang trái, chúng tôi sử dụng giá trị này để giảm tốc độ động cơ bên trái và tăng tốc độ động cơ bên phải. Ở đây, do các hàm số học, chúng tôi sử dụng hai câu lệnh if để giới hạn phạm vi tốc độ động cơ từ 0 đến 255.

sơ đồ lắp ráp khung cơ khí

Arduino Robot Xe điều khiển trái và phải

Phương pháp tương tự được sử dụng để di chuyển xe sang phải.

Tùy thuộc vào điện áp ứng dụng và động cơ chính, ở tốc độ thấp hơn, động cơ không thể bắt đầu di chuyển và nó tạo ra âm thanh ù. Trong trường hợp của tôi, các động cơ không thể di chuyển nếu giá trị của tín hiệu PWM dưới 70. Do đó, sử dụng hai câu lệnh if này tôi đã giới hạn ở phạm vi tốc độ từ 70 đến 255. Cuối cùng, chúng tôi chỉ gửi tốc độ động cơ cuối cùng hoặc Tín hiệu PWM đến các chân cho phép của trình điều khiển L298N.

// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B

Đây là code hoàn chỉnh của ví dụ xe robot Arduino:

#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int motorSpeedA = 0;
int motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() {
  int xAxis = analogRead(A0); // Read Joysticks X-axis
  int yAxis = analogRead(A1); // Read Joysticks Y-axis

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}

Kết nối bạn bè

Wikipedia

Search results

Video Nổi bật

Cảm ơn các bạn đã ghé thăm

 
Please Enable Javascript!Enable JavaScript