MATHANGSPK BLOG

Chia sẽ các thủ thuật về máy tính, tin học, các kiến thức điện tử cơ bản

Thứ Tư, 27 tháng 11, 2019

Configure Static IP Addresses On Ubuntu 18.04 LTS Server

I have just started testing Ubuntu 18.04 . The first thing I noticed was how different it handles network interfaces. The way Ubuntu manages network interfaces has completely changed.
Have you heard of NetPlan? Probably not, if you have, then you’re a step ahead of many. NetPlan is a new network configuration tool introduced in Ubuntu 17.10 to manage network settings.
It can be used write simple YAML description of the required network interfaces with what they should be configured to do; and it will generate the required configuration for a chosen renderer tool.
This new tool replaces the static interfaces (/etc/network/interfaces) file that had previously been used to configure Ubuntu network interfaces. Now you must use /etc/netplan/*.yaml to configure Ubuntu interfaces.
The new interfaces configuration file now lives in the /etc/netplan directory. There are two renderers. NetworkManager and networkd.
NetworkManager renderer is mostly used on desktop computers and networkd on servers. If you want NetworkManager to control the network interfaces, use NetworkManager as the renderer, otherwise use networkd.
When you use NetworkManager as the renderer, you will use the NetworkManager GUI to manage the interfaces.
Below is a sample file for a network interface using networkd as renderer using DHCP…. Networkd uses the command line to configure the network interfaces.
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses: []
            dhcp4: true
    version: 2
To save your changes, you run the commands below.
sudo netplan apply

Configuring Static IP Addresses with Networkd (Server)

To configure a static IP address using the new NetPlan tool on Ubuntu server, the file should look similar to the content below…
For example you might find a default netplan configuration file in the /etc/netplan directory called 50-cloud-init.yaml with a following content using the networkd deamon to configure your network interface via DHCP…..
sudo nano /etc/netplan/50-cloud-init.yaml
Then file should look like this one below:
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses: []
            dhcp4: true
    version: 2
The above is a default networkd redenrer configuration file for a Ubuntu server using DHCP IP configuration…. If you want to setup a static IP address, configure the file as shown below
sudo nano /etc/netplan/50-cloud-init.yaml
Then configure IPv4 addresses as shown below… take notes of the format the lines are written…
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses: [192.168.1.2/24]
            gateway4: 192.168.1.1
            nameservers:
              addresses: [8.8.8.8,8.8.4.4]
            dhcp4: no
    version: 2
Exit and save your changes by running the commands below
sudo netplan apply
You can add IPv6 addresses line, separated by a comma.. highlighted example below.
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses: [192.168.1.2/24]
            gateway4: 192.168.1.1
            nameservers:
              [192.168.1.2/24, '2001:1::2/64']
            dhcp4: no
    version: 2
Save your changes, apply and you’re done.
Save and apply your changes…
sudo netplan apply
sudo netplan --debug apply
This is how to set static IP addresses on Ubuntu 18.04 and 18.10 server and desktop… .
For more about NetPlay, visit this site.

Configure Network Interfaces with NetworkManager

NetworkManager sample configuration file.
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager
Next, open the network interfaces GUI on Ubuntu to manage the network.
Congratulations! You’ve just successfully configured static IP addresses on Ubuntu servers.
Enjoy!~
You may also like the post below:

Thứ Ba, 5 tháng 11, 2019

SSh là một chương trình gần giống như Remote desktop của Windows vậy.


Để cài đặt SSH của ubuntu server ta làm như sau:
Các thao tác được thực hiện trên máy cài đặt UBUNTU SERVER

Bước 1: Cài đặt OpenSSH server trên máy tính Ubuntu Linux
Đầu tiên chúng ta Update và Upgrade hệ thống lại

 sudo apt update
 sudo apt upgrade

Xong chúng ta sẽ cài đặt gói openssh-server

sudo apt install openssh-server

Bước 2: Xác nhận Service ssh đang chạy:

Gõ lệnh sau:

sudo systemctl status ssh




Nếu service không chạy thì chúng ta sẽ gõ các lệnh sau:

 sudo systemctl enable ssh
 sudo systemctl start ssh

Lúc này thì nó sẽ chạy thôi

Bước 3: Chúng ta phải cấu hình tường lửa để có thể truy cập ssh từ xa, bằng lệnh sau:

 sudo ufw allow ssh
 sudo ufw enable
 sudo ufw status

Khi mở port tường lửa thì port ssh mặc định sẽ là 22

Bao giờ thì chúng ta hãy thưởng thức thành quả của chúng ta thôi nào...

Lưu ý: Khi chúng ta mở port từ router để truy cập ssh qua internet thì mở port 22 ở dạng TCP and UDP mới được



Chủ Nhật, 27 tháng 10, 2019

Chia sẻ với các bạn đôi khi cái này các bạn cũng khá ít dùng, nhưng nó từng làm cho mình cũng mất một ít thời gian để tìm hiểu.
Đó là làm như thế nào để Enable Wifi trên máy dùng Winserver R2.
Câu chuyện là mình có dư một chiếc máy laptop của em mình đã sử dụng. Giờ mình không biết dùng nó vào mục đích gì nên cài Winserver để dùng.
Mình định dùng để nuôi account eBay (cái này thuộc lĩnh vượt Dropship). Nhưng khi cài hệ điều hành xong (mình cài bản Winserver 2012 R2 Standard), gắn dây mạng LAN vào thì bình thường, nhưng khi vào chỗ quản lý thiết bị mạng, vẫn thấy nhận card Wifi đúng với máy nhưng không tài nào Enable lên được.
Mà laptop tiện hơn máy tính bàn ở cái có tích hợp card wifi.
Và mình đã tìm kiếm trên mạng có 1 anh hướng dẫn và mình đã làm theo và đã thành công.
Các bước làm như sau:
1. Vào Server Manager
2. Click Mange trên góc phải màn hình
3. Click Add Poles and Features
4. Click Next  --> Next --> Next
5. Tại Server Selection chọn server của bạn
6. Click 2 cái Next nữa
7. Tại Features check Wireless LAN Services.
8. Click Next --> Install.
9. Restart Server của bạn
10. Kết nối vào wifi của bạn.


Nếu không được thì làm tiếp các bước tiếp theo sau đây:

Bước 1: Vào CMD Prompt bằng cách nhấn tổ hợp phím Windows + R
Bước 2: Gõ lệnh powershell
Bước 3: Nhập đoạn lệnh "Install-WindowsFeature -Name Wireless-Networking"
Bước 4: Enter --> Khởi động lại máy và cảm nhận kết quả


Thứ Năm, 3 tháng 10, 2019

Reset a MySQL root password


The MySQL root password allows the root user to have full access to the MySQL database. You must have (Linux) root or (Windows) Administrator access to the Cloud Server to reset the MySQL root password.
Note: The Cloud Server (Linux) root or (Windows) Administrator account password is not the same as the MySQL password. The Cloud Server password allows access to the server. The MySQL root password allows access only to the MySQL database.
Use the following steps to reset a MySQL root password by using the command line interface.

Stop the MySQL service

(Ubuntu and Debian) Run the following command:
sudo /etc/init.d/mysql stop
(CentOS, Fedora, and Red Hat Enterprise Linux) Run the following command:
sudo /etc/init.d/mysqld stop

Start MySQL without a password

Run the following command. The ampersand (&) at the end of the command is required.
sudo mysqld_safe --skip-grant-tables &

Connect to MySQL

Run the following command:
mysql -uroot

Set a new MySQL root password

Run the following command:
use mysql;

update user set authentication_string=PASSWORD("mynewpassword") where User='root';

flush privileges;

quit

Stop and start the MySQL service

(Ubuntu and Debian) Run the following commands:
sudo /etc/init.d/mysql stop
...
sudo /etc/init.d/mysql start
(CentOS, Fedora, and Red Hat Enterprise Linux) Run the following commands:
sudo /etc/init.d/mysqld stop
...
sudo /etc/init.d/mysqld start

Log in to the database

Test the new password by logging in to the database.
mysql -u root -p
Enter your new password when prompted.



Sau khi cài đặt mysql lên server xong, ở đây mình cài mysql server lên ubuntu 18.04


Dùng các lệnh sau đây:
  • sudo apt update
  • sudo apt install mysql-server
  • sudo mysql_secure_installation
Cũng khá dễ để cài đặt....

Khi thiết lập Secure_installation sẽ có bước cài password cho user root.

Đăng nhập mysql từ máy server( máy cài mysql) như sau:

mysql -u root -p (Enter)
Sẽ hỏi nhập password root:
Nhập Password root của mysql vào...

User lúc này sẽ có dạng root@localhost

Nếu đăng nhập thành công thì dùng lệnh này để check user trong database

SELECT user,authentication_string,plugin,host FROM mysql.user;

Sẽ hiện ra cái bảng tất cả các user.

Thường thì nếu các user không được cấp quyền để truy cập các database sẽ không connect được các ứng dụng remote.

Cách tạo user remote full quyền như sau:

Bước 1: Tạo mới 1 User

ALTER USER 'mathang'@'192.168.1.52' IDENTIFIED WITH mysql_native_password BY 'password';

Đây là mình tạo một user là mathang
Truy cập từ máy tính có địa chỉ IP là 192.168.1.52
Với password là 'password'

Bước 2: Tạo full quyền cho User ....

GRANT ALL PRIVILEGES ON *.* TO 'mathang'@'192.168.1.52' WITH GRANT OPTION;

Ok giờ user mathang được truy cập từ ip 192.168.1.52 đang có full quyền rồi đấy.

Lúc này nếu các bạn vẫn chưa thể truy cập mySQL được từ xa thì kiểm tra lại những bước sau:

1. Kiểm tra xem port mySQL (3306) đã mở chưa?
Cách mở như sau:

sudo ufw allow myslq
sudo ufw enable
sudo ufw status

Xong thử truy cập lại...
Thường thì sẽ hiện lỗi này.




Lỗi này là mysql Server của chúng ta đã nhập đúng user và password nhưng không có quyền truy cập từ Host '192.168.1.66'

Cách giải quyết như sau:

- Đầu tiên ta sẽ đăng nhập vào ubuntu server của chúng ta
- sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Tìm dòng bind-address = 127.0.0.1
Sửa IP server lại thành IP của máy tính.
VD: 192.168.1.236

Sau đó lưu file lại và restart lại service mysql với lệnh:

sudo systemctl restart mysql

Thử truy cập lại xem được chưa?
Nếu chưa tiếp tục tạo user mới như sau:

CREATE USER 'mathang'@'113.161.220.166' IDENTIFIED BY '@51209267192Cvv'; GRANT ALL ON *.* TO 'mathang'@'113.161.220.166';



Thứ Sáu, 12 tháng 7, 2019

Ở phần trước mình đã giới thiệu đến với các bạn các thao tác điều khiển nút nhấn trong arduino ở mức độ đơn giản, ở bài này mình sẽ giới thiệu tiếp cho các bạn các cách điều khiển nút nhấn ở mức độ sâu hơn.
Nếu các bạn thấy khó hiểu ở bài này có thể quay lại bài này để tìm hiểu lại từ đầu. Tại đây

Đề bài đặt ra như sau: Nhấn nút nhấn lần thứ nhất LED sáng, khi nhã ra LED vẫn sáng, nhấn lần thứ 2 LED tắt, nhã ra LED vẫn tắt, cứ tuần tự như vậy.

// Define the pins being used
int pin_LED = 10;
int pin_switch = 2;
 
// variables to hold the new and old switch states
boolean oldSwitchState = LOW;
boolean newSwitchState = LOW;
 
boolean LEDstatus = LOW;
 
void setup() 
{
    pinMode(pin_LED, OUTPUT);  
    digitalWrite(pin_LED,LOW); 
 
    pinMode(pin_switch, INPUT); 
}
 
void loop()
{
    newSwitchState = digitalRead(pin_switch);
 
    if ( newSwitchState != oldSwitchState ){
       // has the button switch been closed?
       if ( newSwitchState == HIGH ){
           if ( LEDstatus == LOW ){ 
             digitalWrite(pin_LED, HIGH);  
             LEDstatus = HIGH; }
           else{ 
             digitalWrite(pin_LED, LOW); 
             LEDstatus = LOW;  }
       }
       oldSwitchState = newSwitchState;
    }   
}

Giải thích code:
Chúng ta sẽ có các bit oldSwitchState, newSwitchState, LEDstatus để có thể kiểm soát được chương trình.
- Đầu tiên sẽ trạng thái nút nhấn hiện tại sẽ được lưu vào bit newSwitchState
- Tiếp đến sẽ kiểm tra xem trạng thái hiện tại có khác với trạng thái trước đó không? Nếu khác thì sẽ thực hiện các lệnh bên trong.
   + Ví dụ, nếu có nhấn, pin_switch sẽ lên 1, newSwitchState = 1, sẽ khác với giá trị 0 của oldSwitchState, đoạn code bên trong sẽ được thực thi, nếu giá trị mới của nút nhấn = 1 và trạng thái của LED đang OFF thì sẽ ra lệnh cho LED ON và lưu giá trị LEDstatus = 1, ngược lại nếu trạng thái LED đang ON thì sẽ ra lệnh cho LED OFF và lưu giá trị LEDstatus = 1. Lưu ý nếu giá trị mới của nút nhấn bằng 0 sẽ không thực hiện gì cả.

Các bạn hãy xem video dưới đây để dễ hiểu hơn nhé.


Ở bài viết này mình xin giới thiệu các bạn đến chức năng rất hay thường dùng trong arduino, đó là giao tiếp với nút nhấn, để điều khiển LED. Nếu điều khiển được LED, đồng nghĩa với việc bạn có thể điều khiển được bất cứ cơ cấu chấp hành nào. Vì đơn giản chúng có 1 nguyên lý hoàn toàn giống nhau.
Sơ đồ tổng quan.
Sơ đồ đấu nối phần cứng:

Chân D2 là chân sẽ nhận tín hiệu: Theo như mạch trên Bình thường khi chưa tác động nút nhấn chân D2 sẽ được nối xuống Mass lúc này D2 nhận tín hiệu 0V và sẽ là mức 0 trong logic, khi switch được nhấn sẽ có một điện áp 5V đi qua điện trở 10KOhm xuống mass, lúc này hiệu điện thế giữa chân D2 và Mass là 5V. Chân D2 nhận mức logic là 1.
Một câu đặt ra, liệu chúng ta có thể nối trực tiếp nguồn 5V qua switch và đưa thẳng vào chân D2 có được không? Đó là một ý kiến theo tôi là không hay nhưng nó hoàn toàn được, vì trước khi vào Vi Xử lý thì nó đã có 1 điện trở 10megaOhm.
Nhưng nếu đấu mạch như sơ đồ trên thì sẽ tránh được trường hợp tín hiệu vào chân D2 bị nhiễu, là một điểm đôi khi khá nhức đầu, nếu ta gặp sự cố khi mạch hoạt động như chúng ta mong muốn. Và tốt nhất thì các bạn nên đấu mạch như sơ đồ trên là một điều được khuyên dùng.

Phần trên là phần mình giới thiệu nguyên lý mạch và cách thức làm việc, tiếp đến sẽ đến phần viết code cho Arduino.

Về phần code thì đây là các hàm đơn giản nên các thư viện cơ bản khi các bạn cài Arduino IDE đã có đầy đủ, chỉ cần code thôi là chạy được rồi.


//  D10 to resister and LED
//  D2 to push button switch
//
 
// Define the pins being used
int pin_LED = 10;
int pin_switch = 2;
 
void setup() 
{
    pinMode(pin_LED, OUTPUT);  
    digitalWrite(pin_LED,LOW); 
 
    pinMode(pin_switch, INPUT); 
}
 
void loop()
{
    if ( digitalRead(pin_switch) == HIGH) 
    {
       digitalWrite(pin_LED, HIGH);
    }
    else
    {
       digitalWrite(pin_LED, LOW);
    }   
}

Giải thích code chút xíu cho các bạn nào mới có thể dễ hiểu hơn nhé.
Đầu tiên là khai báo:

int pin_LED = 10;
int pin_switch = 2;

Đây là phần thiết lập, khởi tạo khi Arduino khởi động (chỉ chạy duy nhất 1 lần khi on nguồn).
void setup() 
{
    pinMode(pin_LED, OUTPUT);  
    digitalWrite(pin_LED,LOW);  
    pinMode(pin_switch, INPUT); 
}
pinMode (pin_LED, OUTPUT) --> cấu hình cho chân pin_LED là ngỏ ra

digitalWrite(pin_LED,LOW) --> Set mức 0 cho chân pin_LED --> Đồng nghĩa khi khởi động xong thì chúng ta sẽ thấy LED tắt.

pinMode(pin_switch, INPUT) --> Cấu hình cho chân pin_switch là ngỏ vào.

Ok bây giờ các bạn hãy thử nạp code vào để chạy thử xem như thế nào?


Kết quả, Khi mình nhấn nút nhấn thì LED sẽ sáng và khi mình nhã nút nhấn ra LED sẽ tắt đúng không các bạn?

Đến bước này các bạn đã thấy hứng thú với việc chơi với em này chưa?
Hãy theo đường dẫn này để đến được với mô phỏng các bạn nhé. Tại đây

Đến với ví dụ thứ 2: Phần cứng chúng ta sẽ không thay đổi nhưng phần mềm sẽ có chút thay đổi, chúng ta sẽ sửa lại code một chút như sau:

int pin_LED = 10;
int pin_switch = 2;
boolean newButtonState = 0;
boolean oldButtonState = 0;
void setup()
{
  pinMode(pin_LED, OUTPUT);
  pinMode(pin_switch, INPUT);
}

void loop()
{
  newButtonState = digitalRead(pin_switch);
  if(newButtonState != oldButtonState){
    if(digitalRead(pin_switch)==HIGH){
      digitalWrite(pin_LED, HIGH);
    }else  digitalWrite(pin_LED, LOW);
    oldButtonState = newButtonState;
  }  
}

Ở đây chúng ta sẽ khai báo thêm 1 cặp biến mới được gán là trạng thái mới và cũ của nút nhấn của chúng ta:
boolean oldButtonState = 0;
boolean newButtonState = 0;
Ở trong vòng lặp loop(), chúng ta có code như sau:
- Đầu tiên, chúng ta sẽ cập nhật trạng thái biến newButtonState = tín hiệu hiện tại mà chân pin_switch nhận về.
- Tiếp theo, là bước so sánh giữa trạng thái mới và trạng thái cũ trước đó, nếu khác nhau được dùng != trong ngôn ngữ so sánh khác, thì trạng thái của LED sẽ được thay đổi.
- Nếu trạng thái mới không thay đổi thì đoạn chương trình sẽ không làm gì cả.

Chúng ta sẽ chạy chương trình bằng tay như sau:
- Khi nút nhấn chưa được nhấn, nghĩa là chân pin_switch sẽ là mức 0.
- newButtonState sẽ bằng 0.
- Vì giá trị gán ban đầu của oldButtonState = 0 nên newButtonState = oldButtonState nên sẽ thực hiện gì tiếp cả vì không đủ điều kiện để thực hiện.
- Khi nút nhấn được nhấn, nghĩa là chân pin_switch sẽ là mức 1.
- newButtonState sẽ bằng 1.
- Lúc này thỏa điều kiện newButtonState khác với oldButtonState sẽ làm LED sáng lên vì lúc này pin_switch = 1.
- Và oldButtonState sẽ được cập nhật giá trị là 1.
- Và nếu vẫn còn giữ thì LED sẽ sáng mãi vì lúc này oldButtonState và newButtonState đều bằng 1, không thỏa điều kiện để thay đổi LED, cho tới khi nhả nút nhấn ra.

Sau đây là sản phẩm thực tế:


Kết thúc ví dụ thứ 2, vậy các bạn sẽ hỏi, vậy ở ví dụ 1 và 2 khác nhau ở điểm nào. Ở ví dụ 1 chúng ta cũng nhấn nút và LED sáng, nhã nút nhấn thì LED tắt, ở ví dụ 2 cũng vậy, đâu có khác gì đâu.

Bây giờ chúng ta sẽ thêm 1 vài dòng code vào 2 ví dụ để kiểm nhận sự khác biệt các bạn nhé.
Ta xét ở ví dụ 1, thay đổi code như sau:

int pin_LED = 10;
int pin_switch = 2;
void setup()
{
  Serial.begin(9600);
  pinMode(pin_LED, OUTPUT);
  pinMode(pin_switch, INPUT);
}

void loop()
{
    if(digitalRead(pin_switch)==HIGH){
      digitalWrite(pin_LED, HIGH);
        Serial.println("LED ON");
    }
  else{  
      digitalWrite(pin_LED, LOW); 
      Serial.println("LED OFF");
  }
}

Thêm cấu hình hiển thị Serial Monitor ở baudrate 9600, khi chúng ta nhấn nút thì sẽ gửi qua Serial dòng chữ "LED ON" và nếu không nhấn thì sẽ gửi dòng chữ "LED OFF"



Theo như chúng ta thấy thì khi nhấn hoặc không nhấn thì Lệnh Serial được gửi liên tục, điều này sẽ rất khó để kiểm soát được việc thay đổi trạng thái của nút nhấn để điều khiển 1 bước nào đó. Nên chúng ta thử xét ở ví dụ 2, xem thế nào nhé các bạn.
Ở ví dụ 2, ta sẽ thay đổi code như sau:

int pin_LED = 10;
int pin_switch = 2;
boolean newButtonState = 0;
boolean oldButtonState = 0;
void setup()
{
  Serial.begin(9600);
  pinMode(pin_LED, OUTPUT);
  pinMode(pin_switch, INPUT);
}

void loop()
{
  newButtonState = digitalRead(pin_switch);
  if(newButtonState != oldButtonState){
    if(digitalRead(pin_switch)==HIGH){
      digitalWrite(pin_LED, HIGH);
        Serial.println("LED ON");
    }else{
        digitalWrite(pin_LED, LOW);
        Serial.println("LED OFF");
    }
    oldButtonState = newButtonState;
  }  
}

Chúng ta sẽ xem video để dễ hiểu hơn



Ở video các bạn thấy, khi arduino bắt đầu chạy thì Serial Monitor không hiển thị bất kỳ thứ gì cả, vì đâu có thỏa điều kiện đâu mà chạy, khi mình nhấn nút thì chỉ hiển thị LED ON lên một lần, và khi nhã nút nhấn ra chỉ hiển thị LED OFF một lần.
Điều này chứng tỏ, nếu ta dùng code này khi muốn nhấn thì sẽ tăng giá trị lên 1 chẳng hạn thì sẽ rất tốt. Vì khi nhấn vào thì đoạn code bên trong điều kiện thỏa chỉ được thực hiện 1 lần.

Như vậy chúng ta đã hiểu hơn về cách hoạt động của nút nhấn trong Arduino rồi. Mọi ý kiến hay chia sẽ gì rất mong các bạn để lại phần comment bên dưới các bạn nhé. Mọi ý kiến thắc mắc, các bạn có thể liên hệ qua fb hoặc e-mail của mình nhé, hẹn gặp các bạn ở topic tiếp theo

Thứ Sáu, 5 tháng 7, 2019

Ở phần lập trình arduino này mình sẽ chỉ trình bày sơ đồ giải thuật của đề tài và toàn bộ code, thư viện sử dụng trong đề tài này.

Các kiến thức các bạn cần nắm đẻ lập trình Arduino trong đề tài này:
- Giao tiếp IO, biết cách đọc tín hiệu từ nút nhấn, phân biệt mức 1 - 0. Xuất ngỏ ra output mức 1 - 0.
Tham khảo tại link này nhé.
- Giao tiếp hiển thị chữ trên LCD 16x02, qua board I2C LCD. Tham khảo bài viết ở đây.
- Sử dụng chương trình ngắt timer. Tham khảo ở đây.
- Sử dụng ngắt ngoại (external). Tham khảo ở đây.
- Giao tiếp với module Nhiệt độ, Độ ẩm DHT22. Tham khảo ở đây.

Thứ Năm, 4 tháng 7, 2019

Ở Phần 2 mình sẽ nói khá nhiều về lý thuyết, nhưng mình khuyên các bạn cũng nên bỏ một chút thời gian ra để đọc phần này, như vậy mình sẽ có 1 số kiến thức cơ bản. Mình sẽ viết rất dễ hiểu thôi.

Ở phần 2.1 này mình sẽ nói về lý thuyết điều khiển tự động, vấn đề cốt lõi của đề tài này.

Bài toán đặt ra như thế này: Điều khiển nhiệt độ bên trong thùng xốp kích thước (60cmx60cmx60cm), duy trì ở nhiệt độ 37.5 độ C.
Điều đầu tiên các bạn nghĩ đến là sẽ cấp nguồn cho 1 nguồn nhiệt nào đó để tạo ra một lượng nhiệt cho không gian bên trong thùng xốp đúng ko nào?
Chính xác rồi, vậy vật cấp nhiệt đó có thể là sợi gia nhiệt hoặc bóng đèn sợi đốt.
Ở đây mình lựa chọn là bóng đèn sợi đốt.
Giờ khi chưa bắt tay vào làm và chưa có gì trong tay thì các bạn hãy tưởng tượng theo mình nhé.
Khi bóng đèn sợi đốt được thắp sáng, nhiệt độ sẽ tăng và muốn nhiệt độ giảm thì mình sẽ tắt bóng đèn đi. Để giám sát được nhiệt độ thì chúng ta sẽ dùng cảm biến để theo dõi nhiệt độ (thành phần này trong lý thuyết điều khiển tự động gọi là feedback tạm dịch là phần hồi tiếp).
Tiếp đến khi có tín hiệu feedback bây giờ đến phần điều khiển bóng đèn để có được nhiệt độ 37.5 độ C như yêu cầu của đề bài.
Bước đầu tiên: Khi đọc tín hiệu nhiệt độ trong thùng xốp về nếu < 37.5 sẽ điều khiển ngõ ra cho bóng đèn sáng, đợi 1 thời gian thì nhiệt độ trong thùng xốp sẽ đạt được 37.5 độ C. Lúc này sẽ điều khiển ngõ ra tắt bóng đèn, ngắt nguồn nhiệt. Theo các bạn lúc tại thời điểm ngắt bóng đèn thì nhiệt độ trong thùng xốp có tăng lên nữa không ạ? Hay vừa ngắt nguồn nhiệt là nhiệt độ sẽ giữ ngay tại 37.5 độ C.
Câu trả lời là nhiệt độ sẽ tăng và tăng bao nhiêu là sẽ phụ thuộc vào công suất của bóng đèn và không gian thể tích của thùng xốp. Việc chỉ điều chỉnh On-Off bóng đèn như vậy rất khó để chúng ta điều khiển chính xác được nhiệt độ chúng ta mong muốn. Ở đây mình sẽ nói thêm 1 khái niệm khi bạn On bóng đèn, bóng đèn hoạt động với công suất 100% sẽ cho ta 1 lượng nhiệt, đến 37.5 độ C các bạn ngắt bóng đèn và nhiệt độ vẫn cứ tăng đến 1 nhiệt độ nào đó và khi nhiệt độ đó bắt đầu giảm xuống. Ví dụ như: Khi tắt bóng đèn Nhiệt độ đọc về từ sensor lên đến 39 độ C và bắt đầu giảm thì nhiệt độ 37.5 --> 39 độ C gọi là giá trị vọt lố (cái này cũng là 1 khái niệm trong điều khiển tự động).

Bước 2: Tìm cách giải quyết vấn đề ở trên. Để nhiệt độ duy trì ở nhiệt độ đặt chúng ta sẽ áp dụng lý thuyết điều khiển PID hệ điều khiển kín.


Phân biệt điều khiển vòng kín ở trên theo cách on_off cũng là 1 loại trong số đó và vẫn có phần hồi tiếp để điều khiển on_off. Nhưng ở đây mình muốn điều khiển nhuyễn hơn nên sẽ dùng hàm PID ở bộ Controller ở hình mô tả trên.

Bước 3: Mình đã sử dụng hàm truyền PID vào đề tài này như thế nào?
Ở đây mình sẽ trình bày theo cách mình hiểu và rút ra được từ thực tế mình làm, có thể những câu từ không chính xác như lý thuyết, nhưng theo kết quả mình nhận được thì ít nhất là nó khá ổn cho đề tài này. Lý thuyết điều khiển tự động thì rất bao la, bát ngát. Nên qua phần này mình chỉ muốn giúp các bạn có một cái nhìn thật trực quan về vấn đề tưởng như dễ mà khó, khó mà dễ này.


Ở đề tài này mình chỉ áp dụng hệ PI thôi thì thấy kết quả cũng khá ổn rồi, nên giờ chúng mình bắt đầu nhé.

Lại có thể các bạn phải tưởng tượng một chút nữa rồi.
Theo như hình ở trên thì 
+ giá trị error = giá trị setpoint - giá trị feedback.
+ giá trị error này có thể Dương >0 hoặc Âm <0.
Hàm truyền PI được viết như sau:
PI output = P_value + I_value
trong đó: 
P_value = Kp*error
I_value = I_value + (Ki*error)

Tới đây thì các bạn chắc cũng đã hơi có một chút hoang mang rồi. Nhưng các bạn đã làm tới phần mạch này chưa và dự án của các bạn đã chạy đến đâu rồi. Tạm ngưng lý thuyết ở đây giờ chúng ta sẽ chuyển sang phần lắp ráp phần điều khiển arduino cho đề tài này nhé. Mời các bạn đón xem phần tiếp theo, toàn bộ các kiến thức sử dụng arduino sử dụng trong đề tài này.





Thứ Ba, 2 tháng 7, 2019


Chắc hẳn nếu các bạn tìm đọc đến blog này của mình thì cũng đã từng biết cách điều khiển độ sáng của bóng đèn DC, cách điều khiển bóng đèn 12VDC thì cũng đơn giản hơn đôi chút. Và chúng điều có chung một lý thuyết giống nhau, để bóng đèn sáng mạnh thì cấp 1 mức điện áp bằng điện áp định mức, lúc này ta sẽ được kết quả bóng đèn hoạt động tối ưu tại giá trị thiết lập của nhà sản xuất, hay hiểu nôm na là hoạt động hết công suất của bóng đèn. Ví dụ đơn giản để một bóng đèn 60W - 220VAC (thông số này có ghi trên thân bóng đèn sợi đốt) hoạt động hết công suất tối đa của nó thì chúng ta phải cấp 1 điện áp là 220VAC cho nó.

? Vậy nếu chúng ta cấp 1 điện áp lớn hơn hay nhỏ hơn 220VAC thì điều gì sẽ xảy ra?

Trả lời cho trường hợp thứ nhất: Cấp mức điện áp lớn hơn điện áp định mức của bóng đèn, điều các bạn thấy có thể bóng đèn sẽ sáng hơn và điều tồi tệ hơn là nếu điện áp cấp vượt quá cao so với mức điện áp định mức thì bóng đèn sẽ bị đứt. (cái này thì đọc kỹ tài liệu nhà sản xuất chắc có ghi), thường thì mình thấy nếu đâu đó nếu điện áp tăng lên khoảng 10% thì bóng đèn vẫn có thể chịu được nhưng chắc tuổi thọ sẽ không bằng, bạn có quyền thử nghiệm để xem thực tế như thế nào, thử cấp 1 mức điện áp 240VAC cho bóng đèn xem nó có sáng hơn không hay là tối hơn. Tối hơn chỉ là khi nó đã bị hỏng và xin chia buồn với bạn vì điều đó.

Trả lời cho trường hợp thứ hai: Cấp mức điện ấp thấp hơn điện áp định mức của bóng đèn, bóng đèn sẽ sáng yếu đi và nếu thấp quá thì chúng ta sẽ không thấy bóng đèn sáng nữa.

Ở bài này mình sẽ giới thiệu cách bạn có thể điều chỉnh độ sáng của bóng đèn 220VAC bằng Arduino, nghe có vẻ hấp dẫn nhỉ, chúng ta cùng nhau bắt đầu thôi.

Để giải quyết làm sao để cấp 1 điện áp thay đổi được cho bóng đèn để bóng đèn có thể sáng tối khác nhau.

Ta sẽ thay đổi góc kích hình sine cho bóng đèn, được lái bởi con triac.
Khi góc kích con triac thay đổi sẽ thay đổi thời gian dẫn của bóng đèn, nếu trong 1/2 chu kỳ sine 180 độ triac chỉ được kích dẫn 50% thì điện áp chắc chắn sẽ còn 50%. Đó là ý tưởng của việc thay đổi độ sáng bòng đèn.
Để làm được điều này các bạn cần một mạch nữa là zero dectect circuit. Như hình dưới.

Mính sẽ giải thích nguyên lý của mạch trên như sau:
Đầu tiên điện áp 220VAC từ lưới sẽ được hạ dòng xuống khi qua 2 điện trở 33K 1/2W. Sau đó đi vào mạch cầu. Lúc này mạch cầu của chúng ta sẽ làm cho chu kỳ âm của sóng sine lật ngược lên trên hết.

Sau đó tín hiệu ngỏ ra của mạch cầu diode sẽ được điều khiển bởi 1 con octo cách ly, ngõ ra octo cách ly được định thiên bởi nguồn 5VDC và một trở 10KOhm. Đưa vào chân ngắt ngoại của Arduino để phát hiện điểm zero của sóng sine.

Giải thích luôn nguyên lý thay đổi góc kích cho triac, trong chương trình ngắt ngoại sẽ điều khiển thời gian kích dẫn triac.
Nếu Triac được kích ngay điểm zero có phải ngõ ra tải sẽ dường như đủ 360 độ không ạ?
Giờ muốn giảm thời gian thay đổi góc kích thì ta sẽ cho delay thời gian kích triac lại đúng không ạ?
Bây giờ quay qua tính toán một chút. Điện lưới của chúng ta đang dùng là 50Hz nghĩa là thời gian 1 chu kỳ 20ms 1/2 chu kỳ 10ms.

Ở hình trên đường nét cắt là điện áp 220VAC vào, Đường màu xanh dương là điện áp ra, và đường màu đỏ là điện áp kích từ arduino.
Khoảng thời gian t1 là khoảng thời gian cho G của Triac chưa được kích lúc này ngõ ra VAC sẽ là 0V. Khi ngõ ra G được kích thì sẽ có áp như hình trên, sau một khoảng thời gian t2 chân G sẽ được ngắt, nhưng lúc này triac vẫn dẫn cho đến khi chu kỳ sine tới điểm zero thì triac sẽ tự off, đợi tới chu kỳ kế tiếp kích chân G lên và cứ thế tiếp tục.

Và sau đây là code arduino cho chương trình:


int AC_LOAD = 10;    // Output to Opto Triac pin
int dimming = 0;  // Dimming level (0-128)  0 = ON, 128 = OFF
int count = 0;
int dimtime;
char val;
void setup()
{
  Serial.begin(9600);
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  attachInterrupt(1, zero_crosss_int, FALLING);  // Choose the zero cross interrupt # from the table above pin 2
}

//the interrupt function must take no parameters and return nothing
void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms 
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) 
  // For 60Hz => 8.33ms (10.000/120)
  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

  dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // Nzzzzzo longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
  count ++;
  if(count == 100){
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    count = 0;
  }
}

void loop()  {
    for (int i=0; i <= 115; i++){
      dimming=i;
      delay(500);
      Serial.print(dimming);
      Serial.print("\n");
      Serial.print(dimtime);
      Serial.print("\n");
     }
    if (Serial.available()) 
   { // If data is available to read,
     val = Serial.read(); // read it and store it in val
   }

    if(val == '1') dimming = dimming + 20;
    if(val == '2') dimming = dimming - 20;
}

Chủ Nhật, 30 tháng 6, 2019


Qua series bài viết này mình sẽ chia sẻ cho các bạn các kiến thức mà mình thu nhặt được để làm được 1 cái máy ấp trứng tự động:
Phần 1: Giới thiệu máy ấp trứng tự động, tổng quan các chức năng của máy ấp trứng.
Phần 2: Lý thuyết cần có để thực hiện đề tài ( phần này mình sẽ trang bị cho các bạn các kiến thức cơ bản mình áp dụng trong dự án này).
Phần 3: Kết luận và các ý tưởng phát triển đề tài.

Trên đây là mình chia ra nhiều phần để các bạn đọc cảm thấy đở chán, bên cạnh đó mỗi phần chỉ cung cấp một lượng kiến thức vừa phải, mong các bạn sẽ thoải mái khi đọc series này.

Bắt đầu thôi nào!

Ở phần giới thiệu này mình sẽ giới thiệu tác dụng khi sử dụng máy ấp trứng, máy ấp trứng dựa trên nguyên lý gia nhiệt 1 vùng chứa trứng ở một nhiệt độ xấp xĩ nhiệt độ con mái ấp trứng ~37.5 độ C. Và thỉnh thoảng đặt tính của các con gà, vịt mẹ sẽ đảo trứng. Lâu lâu đảo trứng 1 lần để tránh dính trứng vào vỏ.
Dựa vào đặt tính trên ta sẽ điều khiển nhiệt độ trong vùng không gian chứa trứng vừa khoảng 37.5 độ C. (Cái này ta sẽ dùng nguyên lý giống với nguyên lý lò nhiệt để thực hiện).
Việc đảo trứng thì đơn giản hơn, chúng ta sẽ sử dụng khay đựng trứng, cứ theo chu kỳ khoảng 2h chúng ta sẽ đảo hướng khay đựng trứng một cách từ từ, chậm rãi.

* Tiếp đến là phần chức năng của mạch:
1. Mạch có chức năng cài đặt được nhiệt độ sấy, sưỡi, phạm vi hoạt động từ 30-45 độ C. Sai số 0.1 độ C. Được điều khiển bằng 3 nút nhấn (SET, UP, DOWN).


2. Điều chỉnh được thời gian đảo khay trứng.
3. Chức năng nâng cao: Thay đổi được hằng số Kp,Ki trong hàm truyền PID.

* Các kiến thức cần trang bị để hiểu sâu hơn về đề tài này:
1. Lý thuyết điều khiển tự động, cái này mình sẽ nói sơ lược về kiến thức cơ bản mình áp dụng trong đề tài này, cũng không quá phức tạp nên các bạn đừng quá lo lắng, yên tâm nhé, sẽ rất dễ hiểu thôi.
2. Điện tử công suất, nói nghe hoành tráng vậy chứ chủ yếu áp dụng một số kiến thức để hiểu được cách mình điều chỉnh công suất ngỏ ra cho bóng đèn sưởi ( Bóng đèn càng sáng --> Nhiệt độ tăng và ngược lại) và cái này quan trọng cho các bạn hiểu được vai trò sử dụng linh kiện để làm mạch, vì các bạn đọc kỹ phần này mình sẽ chia sẻ không chỉ các chức năng của linh kiện mà có thể sử dụng các linh kiện tương đương để thay thế, và rất may mắn là các linh kiện mình sử dụng trong mạch rất dễ kiếm, chúng rất phổ thông.
3. Lập trình nhúng, Khi Arduino xuất hiện thì việc lập trình nhúng trở nên rất thuận tiện, nó hỗ trợ rất nhiều thư viện của cộng đồng và các bạn không cần hiểu quá sâu về chip nhưng vẫn có thể lập trình được ở mức chạy được, còn ở một level cau hơn để debug được lỗi thì em này cũng sẽ khiến chúng ta phải đầu tư khá nhiều thời gian đấy nhé. Sau khi các bạn dùng arduino để lập trình đề tài này thì các bạn sẽ nắm được 1 số kiến thức như sau:
- Điều khiển được các Input Output trong Arduino. Sử dụng được nút nhấn để thao tác các lệnh mình mong muốn.
- Đọc tín hiệu sensor Nhiệt độ DHT22 (con này có cả nhiệt độ và độ ẩm, đắt hơn DHT11 nhưng được cái độ phân giải 0.1 độ C) nên đó là lý do mình chọn, em này đọc nhiệt độ mình thấy khá ok. Thư viện lập trình đầy đủ và dĩ nhiên mình sẽ chia sẻ mọi thứ trong series này.

- Sử dụng ngắt ngoại (External Interrupt), trong đề tài này mình sử dụng ngắt ngoại để phát hiện điểm 0 (zero) của hình sin điện xoay chiều 220VAC. Từ đó là dữ liệu để đi điều khiển độ sáng của bóng đèn, phần này mình sẽ có 1 topic riêng để nói chi tiết, đọc xong chắc chắn các bạn cũng sẽ làm được, và mình cũng sẽ nêu 1 số bug mình gặp phải để các bạn có thể tránh khi thực hành. Tham khảo bài viết này nhé các bạn
- Sử dụng ngắt nội (internal interrupt) hay ngắt timer, trong đề tài này mình sử dụng ngắt timer để đọc dữ liệu Nhiệt độ, điều khiển PID và điều khiển chu kỳ đảo trứng. Sẽ có 1 một topic chi tiết về phần này và các bạn sẽ biết lý do tại sao mình sử dụng ngắt timer chứ không để các lệnh này chạy trong vòng lặp loop().
- Hiển thị các nội dung lên màn hình LCD 16x02, ở đề tài này mình dùng thêm module LCD I2C, để tiết kiệm IO cho vi xử lý.