Nick Chung gửi vào
- 21361 lượt xem
Đã có nhiều bài viết về cách làm rada hiển thị lên màn hình máy tính. Tương tự, mình cũng sẽ làm một chiếc rada cảnh báo hiển thị lên một vài LCD thông dụng hiện nay.
Chuẩn bị
Mình viết cho 2 loại lcd là ST7565 (homephone) và PCB8540 (nokia5110).
- Hiển thị: 1 lcd st7565 hoặc nokia5110
- Điều khiển: arduino uno r3
- Cảm biến đo khoảng cách: 1 cảm biến siêu âm SHF04 hoặc HRF05
- Cổ xoay: 1 động cơ servo
- Thiết lập người dùng: 2 nút ấn.
- Cảnh báo: led + trở 220 ohm hoặc còi báo.
Ráp mạch
Với màn hình lcd nokia 5110
Arduino pin to..
|
Nokia5510
|
(3,4,5,6)
|
Lcd nokia (Rst,DC,Din,Clk), trên lcd còn chân CS bạn nối xuống 0v.
|
7
|
Còi báo hoặc đèn báo
|
8
|
Nút A
|
9
|
Nút B
|
11
|
Servo
|
12
|
Echo của cảm biến siêu âm
|
13
|
Trigger của cảm biến siêu âm
|
Bạn nào sử dụng module siêu âm SRF05 như của mình thì để hở chân “OUT”.
Lcd nokia 5110 sử dụng thư viện : PCD8544_hoangsa.h
Bạn hãy cài thư viện theo bài viết này:
Với màn hình lcd st7565 homephone
Arduino pin to..
|
LCD ST7565
|
(3,4,5,6)
|
Lcd ST7565 (RST,D/C, Din,CLK), trên lcd còn chân CS bạn nối xuống 0v.
|
7
|
Còi báo hoặc đèn báo
|
8
|
Nút A
|
9
|
Nút B
|
11
|
Servo
|
12
|
Echo của cảm biến siêu âm
|
13
|
Trigger của cảm biến siêu âm
|
Bạn nào sử dụng module siêu âm SRF05 như của mình thì để hở chân “OUT”.
LCD ST7565 sử dụng thư viện : st7565_homephone.h
Bạn hãy cài thư viện theo bài viết này:
ST7565 | Hướng dẫn sử dụng glcd ST7565 homephone và chia sẻ thư viện
Hiện cả hai thư viện đều đã được nâng cấp phiên bản V3.0 và V2.0 (16/12/2016) với nhiều tính năng mới.
Để cho hình đỡ rối, mình đã bỏ qua điện trở giảm áp cho lcd, các bạn hãy đọc 2 bài viết trên để có cách nối đúng hơn (nối như trên vẫn chạy).
CODE
LCD nokia5110
// Tác giả: Thái Sơn.<Nick_chung> // code đăng lên arduino.vn . ngày 18/12/2016. // phiên bản rada dành cho lcd nokia 5110 //CÁCH dùng: // b1: sử dụng nút B để chọn cách vẽ vật cản,sau đó nhấn nút A để vào chương trình // b2: sử dụng nút B để giảm khoảng cách phát hiện, nút A để tăng khoảng cách phát hiện // đơn vị hiển thị là : cm. #include "PCD8544_HOANGSA.h" PCD8544 lcd(3, 4, 5, 6); //RST,D/C, Din,CLK /* #include <ST7565_homephone.h> ST7565 lcd(3, 4, 5, 6); //RST, SCLK, A0, SID */ #ifdef __AVR__ #include <avr/io.h> #include <avr/pgmspace.h> #endif const static unsigned char __attribute__ ((progmem)) logo_84x14[] = { // 84, // width // 14, // height /* page 0 (lines 0-7) */ 0x0, 0xfe, 0xfe, 0xfe, 0xc6, 0xc6, 0xc6, 0xfe, 0x7e, 0x7c, 0x0, 0x0, 0x0, 0xc0, 0xf0, 0xfe, 0x1e, 0xe, 0xfe, 0xfc, 0xf0, 0xc0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0x6, 0x6, 0x6, 0x6, 0xe, 0xfe, 0xfc, 0xf8, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0x7e, 0xfc, 0xf8, 0xc0, 0x0, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0xf8, 0xfc, 0xfe, 0xe, 0x6, 0x6, 0x6, 0x6, 0x6, 0xfe, 0xfe, 0xfc, 0xf8, /* page 1 (lines 8-15) */ 0x0, 0x3f, 0x3f, 0x1f, 0x1, 0x1, 0x3, 0x3f, 0x3f, 0x3c, 0x38, 0x20, 0x3c, 0x3f, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xf, 0x3f, 0x3c, 0x30, 0x0, 0x3f, 0x3f, 0x3f, 0x38, 0x38, 0x38, 0x38, 0x1c, 0x1f, 0xf, 0x7, 0x0, 0x0, 0x7, 0xf, 0x1f, 0x3f, 0x38, 0x38, 0x38, 0x38, 0x3f, 0x1f, 0xf, 0x7, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x3f, 0x0, 0x0, 0x7, 0xf, 0x1f, 0x3f, 0x3f, 0x3f, 0x0, 0x0, 0x7, 0xf, 0x1f, 0x3c, 0x38, 0x38, 0x38, 0x38, 0x3c, 0x1f, 0xf, 0x7, 0x3, }; #include <Servo.h> #define CONST 58 #define loc_nhieu 1 // lọc nhiễu: đơn vị cm, thể hiện sự sai lệch 2 lần đo trước và sau // nếu sai lệch <= loc_nhieu thì kết luận đó là vật cản // loc_nhieu cầng nhỏ thì độ tin cậy kết luận có vật cản càng cao+ #define trig 13 // chân trig của HC-SR04 #define echo 12 // chân echo của HC-SR04 # define cong_xa 8 #define tru_xa 9 #define loa 7 #define tam_xa_max 250 #define Width_lcd 84 #define Height_lcd 48 const byte x0 = Width_lcd / 2; const byte y0 = Height_lcd - 1 ; const byte r_max = Width_lcd / 2; // tâm và bán kính hình tròn int giao_dien = 0; // // lựa chọn giao diện Servo servo; // create servo object to control a servo void setup() { Serial.begin(9600); // giao tiếp Serial với baudrate 9600 pinMode(trig, OUTPUT); // chân trig sẽ phát tín hiệu pinMode(echo, INPUT); // chân echo sẽ nhận tín hiệu pinMode(cong_xa, INPUT_PULLUP); // Tăng khoảng cách pinMode(tru_xa, INPUT_PULLUP); // giam khoảng cách pinMode(loa, OUTPUT); servo.attach(11); // attaches the servo on pin 9 to the servo object lcd.ON(); lcd.SET(23, 0, 0, 0, 4); Serial.begin(9600); cai_giao_dien(); } void cai_giao_dien() { bool state = digitalRead(tru_xa); int plus = 0; lcd.clear(); lcd.bitmap(0, 20, 84, 14, logo_84x14, BLACK); lcd.display(); delay(5000); lcd.clear(); lcd.uni_string( 0, 0, uni(u"V\x1EBD v\x1EADt \x63\x1EA3n"), BLACK); lcd.display(); while (digitalRead(cong_xa) == 1) { if ((state != digitalRead(tru_xa)) && (digitalRead(tru_xa) == 0)) { // khi mà nút nhấn là thấp plus++; giao_dien = plus % 3; if (giao_dien > 2) { giao_dien = 2; } if (giao_dien < 0) { giao_dien = 0; } state == digitalRead(tru_xa); // bip bip digitalWrite(loa, HIGH); delay(30); digitalWrite(loa, LOW); //vẽ lcd.fillrect( 0, 15, 100, 30, DELETE); lcd.number_long(0, 15, giao_dien, STYLE_NUMBER , BLACK); switch (giao_dien) { case 0: lcd.uni_string( 20, 19, uni(u"\x110\x1B0\x1EDDng"), BLACK); break; case 1: lcd.uni_string( 20, 19, uni(u"H tr\xF2n"), BLACK); break; case 2: lcd.uni_string( 20, 19, uni(u"H vu\xF4ng"), BLACK); break; } lcd.display(); delay(250);// làm trễ chống nhiễu } } lcd.clear(); } int k_cach(int tam_xa) { /* Tốc độ của âm thanh trong không khí là 340 m/s (hằng số vật lý), tương đương với 29,412 microSeconds/cm (106 / (340*100)). Khi đã tính được thời gian, ta sẽ chia cho 29,412 để nhận được khoảng cách. */ unsigned long duration; // Đo độ rộng xung HIGH ở chân echo. int distance; // biến lưu khoảng cách PORTB = PORTB & (~(1 << PB5)); //delayMicroseconds(4); /* Phát xung từ chân trig */ PORTB = PORTB | (1 << PB5); delayMicroseconds(10); // xung có độ dài 10 microSeconds PORTB = PORTB & (~(1 << PB5)); /* Tính toán thời gian */ duration = pulseIn(echo, HIGH); // Tính rồi trả về khoảng cách đến vật. distance = int(duration / CONST); distance = constrain(distance, 0, tam_xa); //delay(20); return distance; } int quet_k_cach( int goc, int tam_xa) { servo.write(goc); // quay servo; //delay(10);// đợi cho servo quay xong return k_cach(tam_xa); } void in_distance( int distance) { lcd.fillrect(Width_lcd - 19, 0, 19, 8, WHITE); // xóa ảnh cũ lcd.number_long(Width_lcd - 19, 1, distance, ASCII_NUMBER, BLACK); } void in_tam_xa( int tam_xa) { lcd.fillrect(0, 0, 19, 8, WHITE); // xóa ảnh cũ lcd.number_long(1, 1, tam_xa, ASCII_NUMBER, BLACK); } void ve_vat_can(int x, int y, byte chon_giao_dien) { switch ( chon_giao_dien) { case 0: //cách 1: lcd.drawline(x0, y0, x, y, BLACK); // vẽ vật cản lcd.drawline(x0 - 1, y0, x + 1, y, BLACK); // vẽ vật cản lcd.drawline(x0 + 1, y0, x - 1, y, BLACK); // vẽ vật cản break; case 1: //cách 2; lcd.fillcircle(x, y, 2, BLACK); break; case 2: lcd.rect( x - 2, y - 2, 4, 4, BLACK); // hình vuông break; default: // mặc định lcd.rect( x - 2, y - 2, 4, 4, BLACK); // hình vuông break; } /* */ //cách 3: /* */ } void loop() { int distance; // biến lưu khoảng cách int goc_quet;// góc quét: 0->180 int tam_xa = 50; // 50cm in_tam_xa(tam_xa); // tâm O(x0,y0) int xB, yB; // điểm A(xA,yA), B(xB,Yb); int x_cu, xA, y_cu, yA; // p1(x_cu,y_cu), p2(xA,yA); int distance_cu, distance_moi; // khi p1 sát p2 thì mới vẽ, p1 là điểm quét tước, p2 là điểm quét sau(điểm hiện tại) int analog; byte r = 250; int distance_tb[3];// khoảng cách trung bình while (1) { for ( unsigned long goc = 0; goc < 361; goc++) { //180 quét đi + 180 quét về // quay được 10 độ thì kiểm tra button 1 lần if (digitalRead(cong_xa) == 0) { tam_xa += 2; if (tam_xa > tam_xa_max) { tam_xa = tam_xa_max; // giới hạn cộng } in_tam_xa(tam_xa); } if (digitalRead(tru_xa) == 0) { tam_xa -= 2; if (tam_xa < 0) { tam_xa = 0; //giới hạn trừ } in_tam_xa(tam_xa); } if ((goc < 181) && (goc >= 0)) { goc_quet = goc; //quay thuận 0->180 } else if (goc < 361) { goc_quet = 360 - goc; // quay ngược 180->0 } //tìm điểm B if (goc < 180) { lcd.Find_XY_Elip(x0, y0, r_max, r_max, goc_quet + 10); } else { lcd.Find_XY_Elip(x0, y0, r_max, r_max, goc_quet - 10); } xB = lcd.X_Elip(); yB = lcd.Y_Elip(); lcd.drawline(x0, y0, xB, yB, BLACK); //vẽ thanh quét lcd.display(); digitalWrite(loa, 0); // tắt loa //////////////////////////// for (byte i = 0; i < 3; i++) { distance_tb[i] = quet_k_cach(goc_quet, tam_xa); // delay(50);// đợi } if ((abs(distance_tb[0] - distance_tb[1]) <= loc_nhieu) & (abs(distance_tb[1] - distance_tb[2]) <= loc_nhieu) & (abs(distance_tb[0] - distance_tb[2]) <= loc_nhieu)) { distance_moi = (distance_tb[0] + distance_tb[1] + distance_tb[2]) / 3; r = (r_max * distance_moi) / tam_xa; //tìm Pmới (p2) lcd.Find_XY_Elip(x0, y0, r, r, goc_quet); xA = lcd.X_Elip(); yA = lcd.Y_Elip(); //delay(10); //dừng khung hình if (distance_moi < tam_xa) { if (goc < 180) { ve_vat_can(xA, yA, giao_dien); in_distance(distance_moi); digitalWrite(loa, 1); } else { ve_vat_can(xA, yA, giao_dien); in_distance(distance_moi); digitalWrite(loa, 1); } }//if(distance<tam_xa) } lcd.drawline(x0, y0, xB, yB, DELETE); // xóa thanh quét lcd.drawline(x0 + 1, y0, xB - 1, yB, DELETE); //vẽ thanh quét lcd.drawline(x0 - 1, y0, xB + 1, yB, DELETE); //vẽ thanh quét lcd.display(); }//for }//while }
ST7565-HOMEPHONE
// Tác giả: Thái Sơn.<Nick_chung> // code đăng lên arduino.vn . ngày 18/12/2016. // phiên bản rada dành cho lcd st7565 homephone 128x64 //CÁCH dùng: // b1: sử dụng nút B để chọn cách vẽ vật cản,sau đó nhấn nút A để vào chương trình // b2: sử dụng nút B để giảm khoảng cách phát hiện, nút A để tăng khoảng cách phát hiện // đơn vị hiển thị là : cm. /* #include "PCD8544_HOANGSA.h" PCD8544 lcd(3,4,5,6);//RST,D/C, Din,CLK */ #include <ST7565_homephone.h> ST7565 lcd(3, 4, 5, 6); //RST, SCLK, A0, SID #ifdef __AVR__ #include <avr/io.h> #include <avr/pgmspace.h> #endif // file bitmap const static unsigned char __attribute__ ((progmem)) logo_114x20[] = { // 114, // width // 20, // height /* page 0 (lines 0-7) */ 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0xe, 0xe, 0xe, 0xe, 0xbe, 0xfc, 0xfc, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xf8, 0xfe, 0x7e, 0x1e, 0xfe, 0xfe, 0xf8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x1e, 0x3c, 0xfc, 0xf8, 0xf0, 0xc0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xfc, 0xfe, 0xfe, 0xfe, 0x7e, 0xfc, 0xf8, 0xe0, 0x80, 0x0, 0x0, 0x0, 0xfe, 0xfe, 0xfe, 0x0, 0x0, 0x0, 0x80, 0xf0, 0xf8, 0xfc, 0x3c, 0x1e, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x3e, 0xfc, 0xfc, 0xf8, 0xe0, 0x0, /* page 1 (lines 8-15) */ 0x0, 0xff, 0xff, 0xff, 0xff, 0xe, 0xe, 0xe, 0x3f, 0xff, 0xfb, 0xf3, 0xc1, 0x0, 0x0, 0x0, 0x80, 0xf0, 0xfe, 0xff, 0x7f, 0x73, 0x70, 0x70, 0x70, 0x77, 0x7f, 0xff, 0xfe, 0xf0, 0xc0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, 0x7, 0x1f, 0x7f, 0xfe, 0xf8, 0xe0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xc0, 0xff, 0xff, 0xff, 0x3f, 0x0, /* page 2 (lines 16-23) */ 0x0, 0x7, 0x7, 0x7, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x7, 0x7, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x7, 0x7, 0x7, 0x6, 0x0, 0x0, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x3, 0x3, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x3, 0x3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x7, 0x7, 0x0, 0x0, 0x0, 0x0, 0x7, 0x7, 0x7, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0x7, 0x7, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x3, 0x3, 0x1, 0x0, 0x0, 0x0, }; #include <Servo.h> #define CONST 58 #define loc_nhieu 1 // lọc nhiễu: đơn vị cm, thể hiện sự sai lệch 2 lần đo trước và sau // nếu sai lệch <= loc_nhieu thì kết luận đó là vật cản // loc_nhieu cầng nhỏ thì độ tin cậy kết luận có vật cản càng cao+ #define trig 13 // chân trig của HC-SR04 #define echo 12 // chân echo của HC-SR04 # define cong_xa 8 #define tru_xa 9 #define loa 7 #define tam_xa_max 250 #define Width_lcd 128 #define Height_lcd 64 const byte x0 = Width_lcd / 2; const byte y0 = Height_lcd - 1 ; const byte r_max = Width_lcd / 2; // tâm và bán kính hình tròn int giao_dien = 0; // // lựa chọn giao diện Servo servo; // create servo object to control a servo void setup() { Serial.begin(9600); // giao tiếp Serial với baudrate 9600 pinMode(trig, OUTPUT); // chân trig sẽ phát tín hiệu pinMode(echo, INPUT); // chân echo sẽ nhận tín hiệu pinMode(cong_xa, INPUT_PULLUP); // Tăng khoảng cách pinMode(tru_xa, INPUT_PULLUP); // giam khoảng cách pinMode(loa, OUTPUT); servo.attach(11); // attaches the servo on pin 9 to the servo object lcd.ON(); lcd.SET(23, 0, 0, 0, 4); Serial.begin(9600); cai_giao_dien(); } void cai_giao_dien() { bool state = digitalRead(tru_xa); int plus = 0; lcd.clear(); lcd.bitmap(10, 20, 114, 20, logo_114x20, BLACK); lcd.display(); delay(5000); lcd.clear(); lcd.uni_string( 0, 0, uni(u"V\x1EBD v\x1EADt \x63\x1EA3n"), BLACK); lcd.display(); while (digitalRead(cong_xa) == 1) { if ((state != digitalRead(tru_xa)) && (digitalRead(tru_xa) == 0)) { // khi mà nút nhấn là thấp plus++; giao_dien = plus % 3; if (giao_dien > 2) { giao_dien = 2; } if (giao_dien < 0) { giao_dien = 0; } state == digitalRead(tru_xa); // bip bip digitalWrite(loa, HIGH); delay(30); digitalWrite(loa, LOW); //vẽ lcd.fillrect( 0, 15, 100, 30, DELETE); lcd.number_long(0, 15, giao_dien, STYLE_NUMBER , BLACK); switch (giao_dien) { case 0: lcd.uni_string( 20, 19, uni(u"\x110\x1B0\x1EDDng th\x1EB3ng"), BLACK); break; case 1: lcd.uni_string( 20, 19, uni(u"H\xECnh tr\xF2n"), BLACK); break; case 2: lcd.uni_string( 20, 19, uni(u"H\xECnh vu\xF4ng"), BLACK); break; } lcd.display(); delay(250);// làm trễ chống nhiễu } } lcd.clear(); } int k_cach(int tam_xa) { /* Tốc độ của âm thanh trong không khí là 340 m/s (hằng số vật lý), tương đương với 29,412 microSeconds/cm (106 / (340*100)). Khi đã tính được thời gian, ta sẽ chia cho 29,412 để nhận được khoảng cách. */ unsigned long duration; // Đo độ rộng xung HIGH ở chân echo. int distance; // biến lưu khoảng cách PORTB = PORTB & (~(1 << PB5)); //delayMicroseconds(4); /* Phát xung từ chân trig */ PORTB = PORTB | (1 << PB5); delayMicroseconds(10); // xung có độ dài 10 microSeconds PORTB = PORTB & (~(1 << PB5)); /* Tính toán thời gian */ duration = pulseIn(echo, HIGH); // Tính rồi trả về khoảng cách đến vật. distance = int(duration / CONST); distance = constrain(distance, 0, tam_xa); //delay(20); return distance; } int quet_k_cach( int goc, int tam_xa) { servo.write(goc); // quay servo; //delay(10);// đợi cho servo quay xong return k_cach(tam_xa); } void in_distance( int distance) { lcd.fillrect(Width_lcd - 19, 0, 19, 8, WHITE); // xóa ảnh cũ lcd.number_long(Width_lcd - 19, 1, distance, ASCII_NUMBER, BLACK); } void in_tam_xa( int tam_xa) { lcd.fillrect(0, 0, 19, 8, WHITE); // xóa ảnh cũ lcd.number_long(1, 1, tam_xa, ASCII_NUMBER, BLACK); } void ve_vat_can(int x, int y, byte chon_giao_dien) { switch ( chon_giao_dien) { case 0: //cách 1: lcd.drawline(x0, y0, x, y, BLACK); // vẽ vật cản lcd.drawline(x0 - 1, y0, x + 1, y, BLACK); // vẽ vật cản lcd.drawline(x0 + 1, y0, x - 1, y, BLACK); // vẽ vật cản break; case 1: //cách 2; lcd.fillcircle(x, y, 2, BLACK); break; case 2: lcd.rect( x - 2, y - 2, 4, 4, BLACK); // hình vuông break; default: // mặc định lcd.rect( x - 2, y - 2, 4, 4, BLACK); // hình vuông break; } /* */ //cách 3: /* */ } void loop() { int distance; // biến lưu khoảng cách int goc_quet;// góc quét: 0->180 int tam_xa = 50; // 50cm in_tam_xa(tam_xa); // tâm O(x0,y0) int xB, yB; // điểm A(xA,yA), B(xB,Yb); int x_cu, xA, y_cu, yA; // p1(x_cu,y_cu), p2(xA,yA); int distance_cu, distance_moi; // khi p1 sát p2 thì mới vẽ, p1 là điểm quét tước, p2 là điểm quét sau(điểm hiện tại) int analog; byte r = 250; int distance_tb[3];// khoảng cách trung bình while (1) { for ( unsigned long goc = 0; goc < 361; goc++) { //180 quét đi + 180 quét về // quay được 10 độ thì kiểm tra button 1 lần if (digitalRead(cong_xa) == 0) { tam_xa += 2; if (tam_xa > tam_xa_max) { tam_xa = tam_xa_max; // giới hạn cộng } in_tam_xa(tam_xa); } if (digitalRead(tru_xa) == 0) { tam_xa -= 2; if (tam_xa < 0) { tam_xa = 0; //giới hạn trừ } in_tam_xa(tam_xa); } if ((goc < 181) && (goc >= 0)) { goc_quet = goc; //quay thuận 0->180 } else if (goc < 361) { goc_quet = 360 - goc; // quay ngược 180->0 } //tìm điểm B if (goc < 180) { lcd.Find_XY_Elip(x0, y0, r_max, r_max, goc_quet + 10); } else { lcd.Find_XY_Elip(x0, y0, r_max, r_max, goc_quet - 10); } xB = lcd.X_Elip(); yB = lcd.Y_Elip(); lcd.drawline(x0, y0, xB, yB, BLACK); //vẽ thanh quét lcd.display(); digitalWrite(loa, 0); // tắt loa //////////////////////////// for (byte i = 0; i < 3; i++) { distance_tb[i] = quet_k_cach(goc_quet, tam_xa); // delay(50);// đợi } if ((abs(distance_tb[0] - distance_tb[1]) <= loc_nhieu) & (abs(distance_tb[1] - distance_tb[2]) <= loc_nhieu) & (abs(distance_tb[0] - distance_tb[2]) <= loc_nhieu)) { distance_moi = (distance_tb[0] + distance_tb[1] + distance_tb[2]) / 3; r = (r_max * distance_moi) / tam_xa; //tìm Pmới (p2) lcd.Find_XY_Elip(x0, y0, r, r, goc_quet); xA = lcd.X_Elip(); yA = lcd.Y_Elip(); //delay(10); //dừng khung hình if (distance_moi < tam_xa) { if (goc < 180) { ve_vat_can(xA, yA, giao_dien); in_distance(distance_moi); digitalWrite(loa, 1); } else { ve_vat_can(xA, yA, giao_dien); in_distance(distance_moi); digitalWrite(loa, 1); } }//if(distance<tam_xa) } lcd.drawline(x0, y0, xB, yB, DELETE); // xóa thanh quét lcd.drawline(x0 + 1, y0, xB - 1, yB, DELETE); //vẽ thanh quét lcd.drawline(x0 - 1, y0, xB + 1, yB, DELETE); //vẽ thanh quét lcd.display(); }//for }//while }
Cách sử dụng
- B1: sử dụng nút B để chọn cách vẽ vật cản, sau đó nhấn nút A để vào chương trình
- B2: sử dụng nút B để giảm khoảng cách phát hiện, nút A để tăng khoảng cách phát hiện
- Đơn vị hiển thị là: cm.
- Số bên góc trái màn hình hiển thị tầm quét xa nhất của rada.
- Số bên phải hiển thị khoảng cách của vật cản tới cảm biến.
- Bề mặt vật cản cần phải có tính phản xạ âm thanh tốt, mặt phản xạ song song với mặt cảm biến thì khả năng phát hiện ở đầu thu là cao nhất.
Tạm kết.
Phần khó nhất vẫn là khâu vẽ, khó thứ hai là lọc nhiễu… cứ luẩn quẩn mãi..
OK. Chúc mọi người có tuần làm việc mới hiệu quả.
Tác giả: Thái Sơn.