Thứ Ba, 30 tháng 7, 2019

Cách sử dụng Unix/Linux Shell trong C code

Ok anh em... Sau đây mình có một số example cách sử dụng Unix Shell trong code C...

1. echo and C
#include <stdio.h>
#include <stdlib.h>

#define SHELLSCRIPT "\
#/bin/bash \n\
echo \"hello\" \n\
echo \"how are you\" \n\
echo \"today\" \n\
"

int main()
{
    puts("Will execute sh with the following script :");
    puts(SHELLSCRIPT);
    puts("Starting now:");
    system(SHELLSCRIPT);
    return 0;
}



Để chạy program:
$ cc cprog.c -o cprog

$ ./cprog



2. Lấy thời gian của lệnh ping

ping 192.168.1.1
PING 192.168.1.11 (192.168.1.11) 56(84) bytes of data.
64 bytes from 192.168.1.11: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 192.168.1.11: icmp_seq=2 ttl=64 time=0.027 ms
64 bytes from 192.168.1.11: icmp_seq=3 ttl=64 time=0.024 ms
64 bytes from 192.168.1.11: icmp_seq=4 ttl=64 time=0.031 ms
Ok,giờ muốn lấy tổng thời gian thực hiện các ICMP package... How to?

Solution:
ping -c 4 -n google.com | cut -d '=' -s -f4 | cut -d ' ' -f1
Ok,done...
Chú thích như sau:

  1. For the ping command:
    • -c 4: Stop after sending 4 packets
    • -n : Give numeric info only, not the associated names for the host address
  2. For the first cut command:
    • -d '=': Use the delimeter of the = sign
    • -f4 : Select the 4th field
    • -s : Do not print lines not containing delimiters
  3. For the second cut command:
    • -d ' ' : Use the delimeter of a space ' '
    • f1 : Select the first field

Còn 1 số Shell khá hay:
- Hiện thời gian thực:
ping 192.168.1.1 | grep -Po 'time=\K\S+'
Hoặc
ping 192.168.1.1 | perl -lne '/time=(\S+)/ && print $1'
Hoặc dùng Awk
ping 192.168.1.1 | awk -F'[= ]' '/time=/{print $(NF-1)}'


3. Đọc input từ Keyboard
Cái này giống như scanf() hay gets() trong C vậy...

Dữ liệu nhập vào sẽ được save trong biến $REPLY




read -p “ prompt_text”







4. Lưu dữ liệu trên Terminal

Để lưu lại các thao tác cũng như các dữ liệu hiển thị trên Terminal vào 1 File...
dùng: $script [file]
ví dụ:
$ script output.txt
Script started, file is output.txt

$ ls
output.txt  testfile.txt  foo.txt

$ exit
exit
Script done, file is output.txt

gõ exit để thoát và lưu vào File output.txt















Chủ Nhật, 28 tháng 7, 2019

Arduino và Module cảm biến bụi (Dust Sensor)

Ứng dụng
Do sự ô nhiễm môi trường không khí ngày càng trầm trọng. Nó trở thành một vấn đề được xã hội vô cùng quan tâm. Ô nhiễm môi trường ảnh hưởng trực tiếp tới sức khỏe mỗi con người. Vì vậy module cảm biến bụi sẽ giúp chúng ta biết được mức độ ô nhiễm môi trường không khí để có thể cải thiện chất lượng không khí. 
- Máy lọc không khí.
- Điều hòa.
- Máy giám sát không khí.
.v.v..
Thông số cơ bản của module 
- Độ nhạy: 0.5V / (100 mg / m3).
- Dải đo: 500μg / m3.
- Nguồn cung cấp: 2.5V ~ 5.5V.
- Dòng hoạt động: 20mA (tối đa).
- Nhiệt độ hoạt động: -10 ℃ ~ 65 ℃.
- Nhiệt độ bảo quản: -20 ℃ ~ 80 ℃.
- Thời gian sử dụng: 5 năm.
- Kích thước: 63.2mm × 41.3mm × 21.1mm.
- Kích thước lỗ khí: 9.0mm.


Sơ đồ kết nối chân
Sơ đồ kết nối
- Chân VCC: kết nối nguồn  2.5V ~ 5.5V.
- Chân GND: đất chung.
- Chân Aout : Analog output.
- Chân I led: Digital input.


Hoạt động
- Kích hoạt các diot hồng ngoại bằng cách thiết lập các pin LED ở mức HIGH.
- Chờ 0.28ms, sau đó bắt đầu để lấy mẫu điện áp từ pin Aout của module. Ghi chú rằng tín hiệu đầu ra sẽ mất 0.28ms để đạt trạng thái ổn định sau khi diot hồng ngoại được kích hoạt.
- Chu kì lấy mẫu là 0.004ms . Khi hoàn tất, thiết lập các pin LED LOW để vô hiệu hóa các diot hồng ngoại.
- Tính nồng độ bụi theo mối quan hệ giữa điện áp đầu ra và nồng độ bụi.
Bảng quan hệ giữa giá trị điện áp ra và nồng độ bụi.
Các tiêu chí chất lượng không khí.


Sensitivity (TYP) = 0.5V/(100ug/m3)... Đọc giá trị Analog trả về từ Sensor ta sẽ xác định được độ bụi không khí.


Ứng dụng minh họa: thiết bị đo và cảnh báo mức độ ô nhiễm trong văn phòng hiển thị thông số trên LCD.

Chuẩn bị phần cứng
Bạn có thể  xem hình sau đây
- Các bạn tham khảo hình sau đây :
-  Cắm dây USB 5V vào Arduino. Như vậy ta đã chuẩn bị xong phần cứng.
Phần lập trình , các bạn mở Arduino IDE lên và copy đoạn code dưới vào.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/****** HE THONG DO MUC O NHIEM CUA MOI TRUONG********
 *    **********************************************
 */
#include<LiquidCrystal.h>                                           // thu vien LCD
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);                                 // cau hinh chan LCD
#define        COV_RATIO                       0.2            //ug/mmm / mv
#define        NO_DUST_VOLTAGE                 400            //mv
#define        SYS_VOLTAGE                     5000           
/*
I/O
*/
const int iled = 2;                                            //pin 2 ket noi voi led cua sensor
const int vout = 1;                                            //analog input
/*
variable
*/
float density, voltage;
int   adcvalue, level;
/*
ham loc
*/
int Filter(int m)
{
  static int flag_first = 0, _buff[10], sum;
  const int _buff_max = 10;
  int i;
  
  if(flag_first == 0)
  {
    flag_first = 1;
    for(i = 0, sum = 0; i < _buff_max; i++)
    {
      _buff[i] = m;
      sum += _buff[i];
    }
    return m;
  }
  else
  {
    sum -= _buff[0];
    for(i = 0; i < (_buff_max - 1); i++)
    {
      _buff[i] = _buff[i + 1];
    }
    _buff[9] = m;
    sum += _buff[9];
    
    i = sum / 10.0;
    return i;
  }
}
int pollution_level (float x){                       // tinh gia muc o nhiem
  if (x <= 35) return 0;
  if (x <= 75) return 1;
  if (x <= 115) return 2;
  if (x <= 150) return 3;
  if (x <= 250) return 4;
  return 5;
  
  }
void setup(void)
{
  pinMode(iled, OUTPUT);                                  // cau hinh chan output
  digitalWrite(iled, LOW);                                     //tin hieu outout, o muc thap
  lcd.begin(16,2);                                                  // khai bao LCD 16x2
  Serial.begin(9600);                                         //khai bao UART , baudrate 9600  
  Serial.print("*********************************** COGE Tech Corp ***********************************\n");
}
void loop(void)
{
  /*
  get adcvalue
  */
  digitalWrite(iled, HIGH);                   //  iled high
  delayMicroseconds(280);
  adcvalue = analogRead(vout);                 // doc gia tri adc
  digitalWrite(iled, LOW);                     //   iled low
  
  adcvalue = Filter(adcvalue);                 //  loc adc
  
  /*
  chuyen muc dien ap (mv)
  */
  voltage = (SYS_VOLTAGE / 1024.0) * adcvalue * 11;
  
  /*
chuyen tu dien ap sang do bui
  */
  if(voltage >= NO_DUST_VOLTAGE)
  {
    voltage -= NO_DUST_VOLTAGE;
    
    density = voltage * COV_RATIO;
  }
  else
    density = 0;
  Serial.print("The current dust concentration is: ");
  Serial.print(density);
  Serial.print(" ug/m3\n"); 
  delay(1000);
  
  level = pollution_level (density);
  switch(level) {                 // hien thi do bui len lcd
    case 0: {                        // muc trong sach
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("Trong sach");
      break;
      }
      case 1:{                              // muc trung binh
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("Muc trung binh");
      break;
        }
      case 2:{                         // muc o nhiem nhe
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("O nhiem nhe");
        break;
        }
       case 3:{                      // muc o nhiem vua
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("O nhiem Vua");
        break;
        }
       case 4: {                    // muc o nhiem nang
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("O nhiem nang ");
         break;
        }
       case 5: {                   // muc o nhiem vo cung nghiem trong
        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("Nghiem trong");
        break;
        }
    }
    lcd.setCursor(0,1);
    lcd.print(density);
    lcd.setCursor(6,1);
    lcd.print("(ug/m3)");
}

Thứ Năm, 20 tháng 6, 2019

Phím tắt trong Altium thường dùng

Altium short key

Phím tắt trong Altium thường dùng
Khi vẽ vời, sử dụng phím tắt sẽ tăng tốc độ vẽ lên rất nhiều so với việc đi tìm kiếm công cụ cần thiết khi mà danh mục công cụ quá đồ sộ. Dưới đây liệt kê 1 số phím tắt trong Altium thường dùng (không phải tất cả) khi vẽ mạch.
Những trick nho nhỏ có sử dụng phím tắt sẽ được cập nhật ở bài viết này:

Thiết kê mạch nguyên lý (SCHEMATIC)

Phím tắtChức năng
XQuay linh kiện theo trục X (Đối xứng qua trục X).
YQuay linh kiện theo trục Y (Đối xứng qua trục Y).
SpaceXoay linh kiện 90 độ.
, SPACEĐổi màu khi dùng bút Highlight (Đánh dấu các NET cùng tên)
ALT + Click (chọn Net)Highlight những Net có cùng tên (Làm mờ toàn bộ các phần còn lại của bản vẽ SCH)
Shift + Ctrl + CClear mọi áp dụng trên SCH
Ctrl + Click và kéoDi chuyển linh kiện đi cùng với dây (Giống như trong Proteus)
Shift + SpaceXoay linh kiện 45 độ.
Shift + Left ClickCopy linh kiện.
Shift + Click và kéoKéo linh kiện ra.
Ctrl+Shift+L (hoặc A L)Căn chỉnh các linh kiện thẳng hàng dọc.
Ctrl+Shift+T (hoặc A T)Căn chỉnh các linh kiện thẳng hàng ngang.
Ctrl+Shift+H (hoặc A H)Căn chỉnh các linh kiện cách đều nhau theo hàng ngang.
Ctrl+Shift+V (hoặc A V)Căn chỉnh các linh kiện cách đều nhau theo hàng dọc.
Ctrl + MĐo khoảng cách.
C CBiên dịch Project - Kiểm tra các lỗi kết nối, port.
D BLấy linh kiện trong thư viện.
D OThay đổi thông số bản vẽ.
D UUpdate nguyên lý sang mạch in.
J CNhảy đến linh kiện.
P BVẽ đường bus.
P NĐặt tên cho đường dây.
P OLấy GND.
P TThêm Text.
P WĐể đi dây nối chân linh kiện.
P V NĐánh dấu chân không dùng.
T AMở cửa sổ quản lý đặt tên cho linh kiện.
T NĐặt tên tự động cho linh kiện.
T STìm linh kiện bên mạch in (Bạn chọn khối bạn cần đi dây bên mạch nguyên lý rồi ấn T-S, nó sẽ tự động tìm khối đấy bên mạch in cho bạn).
T WTạo linh kiện mới
TABThay đổi các thông số của mạch.
V DĐưa bản vẽ vừa trong khung màn hình.

THIẾT KẾ MẠCH IN (PCB LAYOUT)

Phím tắtChức năng
2Xem mạch in ở dạng 2D.
3Xem mạch in ở dạng 3D.
QChuyển đổi đơn vị mil --> mm và ngược lại.
P T(Place > Interactive Routing) Chế độ đi dây bằng tay.
P LĐịnh dạng lại kích thước mạch in nhấn rồi vào lớp keep out layer vẽ đường viền sau đó bôi đen toàn mạch rồi nhấn D S D.
P M (Altium 16) U M (Altium 17)Kéo nhiều dây 1 lúc (MultiRoute) (bằng cách: nhấn Shift để chọn nhiều Pad, sau đó nhấn [P M] / [U M] rồi đi dây như bình thường. Trong khi MultiRoute, bạn có thể nhấn Tab để điều chỉnh khoảng cách tương đối giữa các dây với nhau)
P GPhủ đồng.
P VLấy lỗ Via.
P RVẽ đường mạch to, khoảng cách giữa các đường mạch nhỏ.
P D DHiển thị thông tin kích thước PCB (giống như trong Cad có dạng <-- 80mm -->)
A AĐi dây tự động.
T U AXóa bỏ tất cả các đường mạch đã chạy.
T U NXóa các đường dây cùng tên.
T D RKiểm tra xem đã nối hết dây chưa sau khi hoàn thành đi dây bằng tay.
T EBo tròn đường dây gần chân linh kiện (Tea Drop - hình giọt nước cho đường mạch gần chân linh kiện).
T MXóa lỗi hiển thị trên màn hình.
D KChọn lớp vẽ. (Stack Manager)
D RĐể chỉnh các thông số trong mạch như độ rộng của đường dây (Width), khoảng cách 2 - dây (Clearance),cho phép ngắn mạch (Shortcircuit)...
D OChỉnh thông số mạch, nếu bạn không muốn các ô vuông làm ảnh hưởng đến viện vẽ mạch thì chuyển line thành dots.
D T AHiển thị tất cả các lớp.
D T SChỉ hiển thị lớp TOP + BOTTOM + MULTI...
C KMở cửa sổ chỉnh sửa đường dẫn linh kiện.
R BHiển thị thông tin mạch (kích thước, số lượng linh kiện...)
O D (Hoặc Ctrl + D)Hiện thị cửa sổ Configurations (Điều chỉnh ẩn hiện các thành phần)
V BXoay bản vẽ 180 độ.
V FHiển thị toàn bộ bản vẽ.
LKhi đang di chuyển linh kiện lật linh kiện giữa lớp Top và Bottom (Bottom và Top)
L hoặc Ctrl+LMở View Configuration để điều chỉnh hiển thị các lớp.
TABHiện cửa sổ thay đổi thông tin khi đang thao tác.
Fliped BoardLật ngược mạch in.
Ctrl G hoặc GCài đặt chế độ lưới.
Ctrl MThước đo kích thước mạch.
Shift MKính lúp hình vuông.
Shift RThay đổi các chế độ đi dây (Cắt - Không cho cắt - Đẩy dây).
Shift SChỉ cho phép hiện 1 lớp đang chọn (các lớp còn lại được ẩn).
Shift+SpaceThay đổi các chế độ đường dây (Tự do - Theo luật - Vuông 90 độ - Cong)
Ctrl+Shift+L (hoặc A L)Căn chỉnh các linh kiện thẳng hàng dọc.
Ctrl+Shift+T (hoặc A T)Căn chỉnh các linh kiện thẳng hàng ngang.
Ctrl+Shift+H (hoặc A H)Căn chỉnh các linh kiện cách đều nhau theo hàng ngang.
Ctrl+Shift+V (hoặc A V)Căn chỉnh các linh kiện cách đều nhau theo hàng dọc.
Ctrl+Shift+Cuộn chuộtChuyển qua lại giữa các lớp.

3D MODE (3D VISUALIZATION)

Phím tắtChức năng
0Xoay board mạch về hướng nhìn gốc
9Xoay board 90 độ
2Chuyển sang chế độ 2D khi trong chế độ 3D View
3Chuyển sang View 3D khi trong chế độ 2D
SHIFTĐồng thời nhần Shift và Click chuột phải, di chuyển chuột để xoay boad mạch theo các trục X Y Z
V FĐiều chỉnh board mạch vừa khít màn hình
V BLật boad mạch
Cuộn chuộtKéo lên - Kéo xuống
SHIFT + Cuộn chuộtSang trái - Sang phải
CTRL + Cuộn chuộtPhóng to - Thu nhỏ
CTRL + Di chuyển chuộtPhóng to - Thu nhỏ
CTRL + CChụp ảnh góc nhìn hiện tại của board mạch 3D vào Clipboard, để lưu thành file ảnh bạn cần sử dụng tool như Paint chẳng hạn.
T PMở cửa sổ Preferences
LMở cửa sổ Configurations - Điều chỉnh các thuộc tính hiển thị

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

Mạng LIN và CAN trong ô tô - LIN and CAN Protocol

LIN Bus Example Car Cluster Door Window CAN High Speed

LIN (Mạng kết nối cục bộ) là một giải pháp thay thế chi phí thấp cho CAN trong tự động hóa.

Ngày nay, nó được sử dụng trong tất cả các phương tiện hiện đại - và nó ngày càng phức tạp để hiểu.
Tuy nhiên, trong bài viết này, chúng tôi đề cập đến tất cả các điều cơ bản của giao thức bus LIN - incl. LIN so với CAN, các trường hợp sử dụng, cách thức hoạt động của LIN và cách ghi nhật ký dữ liệu bus LIN.

Mạng LIN - Local Interconnect Network

LIN bus vs CAN bus Signal
LIN (Mạng kết nối cục bộ) là một giao thức mạng nối tiếp được sử dụng để liên lạc giữa các thành phần trong xe. Nhu cầu về một mạng nối tiếp giá rẻ nảy sinh khi các công nghệ và phương tiện được triển khai trong xe hơi tăng lên, trong khi mạngCAN quá đắt để thực hiện cho mọi thành phần trong xe. Các nhà sản xuất ô tô châu Âu bắt đầu sử dụng các công nghệ truyền thông nối tiếp khác nhau, dẫn đến các vấn đề tương thích.

Vào cuối những năm 1990, LIN Consortium được thành lập bởi năm nhà sản xuất ô tô (BMW, Tập đoàn Volkswagen, Tập đoàn Audi, Volvo Cars, Mercedes-Benz), với các công nghệ được cung cấp (chuyên môn về mạng và phần cứng) từ Tập đoàn ô tô Volcano và Motorola. Phiên bản được triển khai đầy đủ đầu tiên của đặc tả LIN mới (phiên bản LIN 1.3) đã được xuất bản vào tháng 11 năm 2002. Vào tháng 9 năm 2003, phiên bản 2.0 đã được giới thiệu để mở rộng khả năng và cung cấp các tính năng cho các tính năng chẩn đoán bổ sung. LIN cũng có thể được sử dụng trên đường dây ắc quy của xe với bộ thu phát LIN qua đường dây điện DC (DC-LIN) đặc biệt.

Thứ Ba, 14 tháng 5, 2019

lwIP - lightweight TCP/IP là gì? Ứng dụng trong Embbed ra sao?

LwIP là một triển khai nhẹ của bộ giao thức TCP / IP ban đầu được viết bởi Adam Dunkels tại phòng thí nghiệm Computer and Networks Architectures (CNA) của Viện Khoa học Máy tính Thụy Điển nhưng hiện đang được phát triển tích cực bởi một nhóm các nhà phát triển được phân phối đứng đầu thế giới bởi Kieran Mansley.

lwIP - TCP / IP nhẹ
lwIP là một triển khai nhẹ của bộ giao thức TCP / IP ban đầu được viết bởi Adam Dunkels tại phòng thí nghiệm Computer and Networks Architectures (CNA) của Viện Khoa học Máy tính Thụy Điển nhưng hiện đang được phát triển tích cực bởi một nhóm các nhà phát triển được phân phối đứng đầu thế giới bởi Kieran Mansley.

lwIP có sẵn miễn phí (theo giấy phép kiểu BSD) ở định dạng mã nguồn C và có thể được tải xuống từ trang chủ phát triển.

Trọng tâm của việc triển khai TCP / IP lwIP là giảm mức sử dụng RAM trong khi vẫn có TCP quy mô đầy đủ. Điều này làm cho lwIP phù hợp để sử dụng trong các hệ thống nhúng với hàng chục kilobyte RAM miễn phí và có chỗ cho khoảng 40 kilobyte mã ROM.

Kể từ khi phát hành, lwIP đã thu hút rất nhiều sự quan tâm và ngày nay được sử dụng trong nhiều sản phẩm thương mại. lwIP đã được chuyển đến nhiều nền tảng và hệ điều hành và có thể được chạy có hoặc không có HĐH cơ bản.


lwIP bao gồm các giao thức và tính năng sau:


  • IP (Giao thức Internet) bao gồm chuyển tiếp gói qua nhiều giao diện mạng
  • ICMP (Giao thức tin nhắn điều khiển Internet) để bảo trì và gỡ lỗi mạng
  • IGMP (Giao thức quản lý nhóm Internet) để quản lý lưu lượng phát đa hướng
  • UDP (Giao thức gói dữ liệu người dùng) bao gồm các tiện ích mở rộng thử nghiệm UDP-lite
  • TCP (Giao thức điều khiển truyền) với điều khiển tắc nghẽn, ước tính RTT và phục hồi nhanh / truyền lại nhanh
  • API thô / gốc để tăng cường hiệu suất
  • API ổ cắm giống như Berkeley tùy chọn
  • DNS (Trình phân giải tên miền)
  • SNMP (Giao thức quản lý mạng đơn giản)
  • DHCP (Giao thức cấu hình máy chủ động)
  • AUTOIP (đối với IPv4, tuân thủ RFC 3927)
  • PPP (Giao thức điểm-điểm)
  • ARP (Giao thức phân giải địa chỉ) cho Ethernet