GAME - ST7565 - Game hứng trứng - phiên bản nâng cấp

Mô tả dự án: 

Đây là phiên bản thứ 2 của Game hứng trứng đơn giản, cùng với sự xuất hiện của cô gà mái, hi vọng đây sẽ là sản phẩm Game mang lại nhiều niềm vui trong những ngày đầu năm Đinh Dậu.laughlaugh

 

Là phiên bản nâng cấp >++

Đây là phiên bản đơn giản trước đó:cheeky

Làm game hứng trứng đơn giản - phiên bản 1

Còn ở phiên bản thứ 2 này:laugh

Một chú gà đi trên mái kèo, là một nhân vật hư cấu, chú vừa đi vừa đẻ trứng. Để trứng không bị vỡ khi rơi, 2 nhân vật Cả Mẹo và Dần Béo sẽ phải phối hợp nhịp nhàng hứng những quả trứng vào rổ.

Phân vai:

  • Cả Mẹo – có cái đầu đinh: cẩm chiếc rổ để hứng trứng.
  • Dần Béo – mập  ú và rất vụng về là sở đoản của cậu ta: tuy nhiên vì chỉ có một chiếc rỏ , cậu ấy bèn phải dùng chiếc vợt để đỡ những quả trứng đang rơi, trứng sẽ nảy lên khi rơi vào chiếc vợt đó.  

Tính Điểm:

  • Trứng rơi thẳng vào rổ: cộng 1 điểm.
  • Trứng rơi và được Dần Béo đỡ bằng vợt rồi rơi vào rổ: cộng 2 điểm.
  • Trứng rơi và được Dần Béo đỡ bằng vợt nhưng không vào rổ: trừ 2 điểm.
  • Rơi thẳng xuống đất: Trừ 1 điểm.

Điều khiển:

  • Sử dụng 2 nút di chuyển trái phải để di chuyển nhân vật.
  • Nhấn nút ”OK” để lựa chọn nhân vật.
  • Mũi tên sẽ chỉ vào nhân vật đang được chọn.

Phần cứng

Tải về thư viện đồ họa

Bạn hãy tải về thư viện tại bài viết

ST7565 | Hướng dẫn sử dụng glcd ST7565 homephone và chia sẻ thư viện

Chuẩn bị phần cứng

Nối mạch

Bạn hãy tham khảo cách nối mạch và nút bấm tại bài viết giới thiệu lcd nhé:

Quản lí đối tượng

Bạn có thể cần đọc các bài viết về quản lí đối tượng Game :

Chương trình được lập trình theo hướng thủ tục.

Có 3 loại đối tượng cần quan tâm:

Đối tượng
Chức năng, nhiệm vụ
Thuộc tính
Gà mái
Di chuyển qua lại ở phía trên màn hình. Đẻ trứng một cách ngẫu nhiên.
Tọa độ, hướng.
Dần và Mẹo.
Hứng và đỡ trứng đang rơi.
Tọa độ, hướng nhìn.
Trứng
Rơi thẳng từ trên xuống, tọa độ bắt đầu là tọa độ của gà. Bay lên theo đường parabol khi rơi xuống chiếc vợt của Dần Béo.
Sự tồn tại, tọa độ.

 

Bạn hãy đọc các bài trước về quản lí các đối tượng này nhé  !wink

Di chuyển gà

#include "ST7565_homephone.h"
// add a bitmap library of a 16x16 fruit icon
#include "bmps.h"

ST7565 lcd(3, 4, 5, 6);

const static unsigned char __attribute__((progmem)) ga_mai_16x16[] = {
    0x20, 0xD8, 0x2C, 0x0C, 0x9E, 0x72, 0x42, 0xC0, 0x40, 0x40, 0x60, 0xFC, 0xCE, 0x3B, 0x7B, 0x01,
    0x00, 0x06, 0x09, 0x10, 0x30, 0x48, 0x44, 0x4E, 0x59, 0x71, 0x39, 0x1F, 0x0E, 0x00, 0x00, 0x00
};
/* Qủa trứng (6x7) pixel
 *  */

const static unsigned char __attribute__((progmem)) trung_6x7[] = {
    0x1C, 0x22, 0x41, 0x41, 0x22, 0x1C,
};

byte Xmin, Ymin, Xmax, Ymax; //biên
// mảng cho 2 đối tượng gà(0) và trứng(1)
byte object[2][4];
//object[i][0]: tồn tại hay không
//object[i][1]: tọa độ x
//object[i][2]: tọa độ y
//object[i][3]: hướng (1 phải, 2 trên , 3 trái, 4 dưới)
//
// Chương trình chạy 1 lần
void setup()
{
    lcd.ON();
    lcd.SET(23, 0, 0, 0, 4);

    Xmin = 0;
    Xmax = 125;
    Ymin = 0;
    Ymax = 63;
}
void ve_ga_di()
{
    byte x_cu, y_cu, huong_cu;
    byte x_moi;
    x_cu = object[0][1];
    y_cu = object[0][2];
    huong_cu = object[0][3];
    //lấy thông tin

    if (huong_cu == 1) { //gà quay về bên phải
        x_moi = x_cu + 1;
        lcd.Plus_Bitmap(x_moi, y_cu, 16, 16, ga_mai_16x16, 0, MIRROR, BLACK);
        // xoay bitmap (mirror)
        //
    }

    if (huong_cu == 3) { //gà quay về bên trái
        x_moi = x_cu - 1;
        lcd.Plus_Bitmap(x_moi, y_cu, 16, 16, ga_mai_16x16, 0, NO_MIRROR, BLACK);
        // không xoay (non mirror)
    }
    //ghi lại thông tin
    object[0][1] = x_moi;
    lcd.display();

} //vẽ gà
void xoa_ga(byte x, byte y)
{
    lcd.FillRect(x, y, 16, 16, DELETE); //
    lcd.display();
} //xóa gà
void ga_di_va_de_trung()
{ // gà đi và đẻ trứng
    //////////// XỬ LÍ GÀ////////////
    //b1: cấp giấy khai sinh
    if (object[0][0] == 0) {
        // nếu không tồn tại gà thì phải tạo gà
        // cấp thuộc tính cho đối tượng gà
        object[0][1] = Xmin + 5; //hoành độ ban đầu
        object[0][2] = Ymin; // tung độ ban đầu
        object[0][3] = 1; //hướng sang bên phải
        object[0][0] = 1; //cấp quyền tồn tại
    }
    //b2: gà đi và quay đầu
    //lấy thông tin;
    if (object[0][1] <= Xmin) {
        // nếu gà đến biên trái thì phải quay đầu về bên phải
        object[0][3] = 1;
        //ghi lại thông tin
    }

    if (object[0][1] >= Xmax) {
        // nếu gà đến biên phải thì phải quay đầu về bên trái
        object[0][3] = 3;
        //ghi lại thông tin
    }
    ///////////GÀ ĐANG ĐI/////////
    // lấy tt

    xoa_ga(object[0][1], object[0][2]); //xóa ảnh cũ
    ve_ga_di(); // vẽ ảnh mới
}
void loop()
{

    ga_di_va_de_trung();
    delay(100);
}

Kết quả chạy thử

Di chuyển gà và đẻ trứng

#include "ST7565_homephone.h"
// add a bitmap library of a 16x16 fruit icon
#include "bmps.h"

ST7565 lcd(3, 4, 5, 6);

const static unsigned char __attribute__((progmem)) ga_mai_16x16[] = {
    0x20, 0xD8, 0x2C, 0x0C, 0x9E, 0x72, 0x42, 0xC0, 0x40, 0x40, 0x60, 0xFC, 0xCE, 0x3B, 0x7B, 0x01,
    0x00, 0x06, 0x09, 0x10, 0x30, 0x48, 0x44, 0x4E, 0x59, 0x71, 0x39, 0x1F, 0x0E, 0x00, 0x00, 0x00
};
/* Qủa trứng (6x7) pixel
 *  */

const static unsigned char __attribute__((progmem)) trung_6x7[] = {
    0x1C, 0x22, 0x41, 0x41, 0x22, 0x1C,
};

byte Xmin, Ymin, Xmax, Ymax; //biên
// mảng cho 2 đối tượng 1 gà(0) và 3 trứng(1,2.3)
byte object[1 + 3][4];
//object[i][0]: tồn tại hay không
//object[i][1]: tọa độ x
//object[i][2]: tọa độ y
//object[i][3]: hướng (1 phải, 2 trên , 3 trái, 4 dưới)
//
// Chương trình chạy 1 lần
void setup()
{
    lcd.ON();
    lcd.SET(23, 0, 0, 0, 4);

    Xmin = 0;
    Xmax = 125;
    Ymin = 0;
    Ymax = 63;
}
//===========================================================
////////////////DI CHUYỂN GÀ////////////////////
void di_chuyen_ga()
{
    byte x_cu, y_cu, huong_cu;
    byte x_moi;
    x_cu = object[0][1];
    y_cu = object[0][2];
    huong_cu = object[0][3];
    //lấy thông tin

    if (huong_cu == 1) { //gà quay về bên phải
        x_moi = x_cu + 1;
        lcd.Plus_Bitmap(x_moi, y_cu, 16, 16, ga_mai_16x16, 0, MIRROR, BLACK);
        // xoay bitmap (mirror)
        //
    }

    if (huong_cu == 3) { //gà quay về bên trái
        x_moi = x_cu - 1;
        lcd.Plus_Bitmap(x_moi, y_cu, 16, 16, ga_mai_16x16, 0, NO_MIRROR, BLACK);
        // không xoay (non mirror)
    }
    //ghi lại thông tin
    object[0][1] = x_moi;
    lcd.display();

} //vẽ gà
void xoa_ga(byte x, byte y)
{
    lcd.fillrect(x, y, 18, 18, DELETE);
    lcd.display();
} //xóa gà
void ga_di_va_de_trung()
{ // gà đi và đẻ trứng
    //////////// XỬ LÍ GÀ////////////
    //b1: cấp giấy khai sinh
    if (object[0][0] == 0) {
        // nếu không tồn tại gà thì phải tạo gà
        // cấp thuộc tính cho đối tượng gà
        object[0][1] = Xmin + 5; //hoành độ ban đầu
        object[0][2] = Ymin; // tung độ ban đầu
        object[0][3] = 1; //hướng sang bên phải
        object[0][0] = 1; //cấp quyền tồn tại
    }
    //b2: gà đi và quay đầu
    //lấy thông tin;
    if (object[0][1] <= Xmin) {
        // nếu gà đến biên trái thì phải quay đầu về bên phải
        object[0][3] = 1;
        //ghi lại thông tin
    }

    if (object[0][1] >= Xmax) {
        // nếu gà đến biên phải thì phải quay đầu về bên trái
        object[0][3] = 3;
        //ghi lại thông tin
    }
    ///////////GÀ ĐANG ĐI/////////
    // lấy tt

    xoa_ga(object[0][1], object[0][2]); //xóa ảnh cũ
    di_chuyen_ga(); // vẽ ảnh mới
}
//===============================================================
////////////////////TRỨNG RƠI//////////////////////
void ve_trung(byte x, byte y)
{
    lcd.bitmap(x, y, 6, 7, trung_6x7, BLACK);
    lcd.display();
}
void xoa_trung(byte x, byte y)
{
    //xóa = hình chữ nhật màu trắng
    lcd.fillrect(x, y, 7, 7, DELETE);
    lcd.display();
}
void di_chuyen_trung(byte huong_cu, byte i)
{
    byte x_cu, y_cu, x_moi, y_moi, ton_tai, huong_moi;
    //lây tt
    x_cu = object[i][1];
    y_cu = object[i][2];
    ton_tai = object[i][0];
    if ((huong_cu == 4) && (ton_tai == 1)) {
        //trứng rơi xuống dưới;
        y_moi = y_cu + 1;
        x_moi = x_cu;
        huong_moi = huong_cu;
        ve_trung(x_moi, y_moi);
    }
    //ghi tt
    object[i][1] = x_moi;
    object[i][2] = y_moi;
    object[i][3] = huong_moi;
}
void ve_trung_roi()
{
    for (byte i = 1; i <= 3; i++) { // xét lần lượt 3 quả trứng

        /*   
if((object[i][3]==3)||(object[i][3]==1)){
// nếu trứng i này đang bay theo parabol
//thì phải nhảy sang trứng khác
*/

        //vẽ trứng rơi
        if (object[i][0] == 0) {

            // nếu không tồn tại trứng thì phải tạo trứng
            //b1: chuẩn bị sẵn tọa độ  bằng random
            randomSeed(millis() % 5000);
            byte X_random;
            X_random = random(Xmin, Xmax);
            // lưu thông tin
            object[i][1] = X_random;
            //chương trình chỉ chạy 1 lần mà thôi
        }
        //khi gà đi đến vị trí chuẩn bị sẵn này, trứng bắt đầu được tạo và rơi
        if (object[i][1] == object[0][1]) { // thỏa mãn trùng tọa độ
            //b2: cấp giấy khai sinh
            // cấp thuộc tính cho đối tượng trứng
            //(nên nhớ đã có hoành độ Random)
            object[i][2] = Ymin + 10; // tung độ ban đầu
            object[i][3] = 4; //hướng xuống dưới
            object[i][0] = 1; //cấp quyền tồn tại
        }
        //b2 : trứng roi
        //lấy thông tin

        xoa_trung(object[i][1], object[i][2]); //xóa ảnh cũ
        di_chuyen_trung(object[i][3], i); // vẽ ảnh mới
        //b3: Trứng chạm đất và vỡ
        // hàm test nếu tung độ quá biên thì mất quả trứng đó
        if (object[i][2] >= Ymax) {
            object[i][0] = 0; // xóa quyền tồn tại
        }
    } //for
}
//========================================================

void loop()
{

    ga_di_va_de_trung();
    ve_trung_roi();
    delay(100);
}

 

Kết quả test thử

Di chuyển nhân vật

#include "ST7565_homephone.h"
// add a bitmap library of a 16x16 fruit icon
#include "bmps.h"
ST7565 lcd(3, 4, 5, 6);

#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#endif
/** Nhân vật Cả Mẹo (22x18)pixel
*/
const static unsigned char __attribute__((progmem)) ca_meo_22x18[] = {
    0x60, 0x9C, 0x62, 0x01, 0x01, 0xC1, 0x26, 0x29, 0x29, 0x4B, 0x4E, 0x48, 0x70, 0x00, 0xC0, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x00, 0x00, 0x01, 0x01, 0x02, 0xE4, 0xFF, 0xFE, 0xFE, 0xFE,
    0xFC, 0x1C, 0x0E, 0x06, 0x1F, 0x21, 0x52, 0x44, 0x48, 0x52, 0x21, 0x1F, 0x00, 0x00, 0x64, 0x70,
    0x2F,

};
/** Nhân vật Dần Béo (23x19)pixel
*/
const static unsigned char __attribute__((progmem)) dan_beo_23x19[] = {
    0x00, 0x00, 0x80, 0x43, 0xB2, 0x0F, 0x86, 0x44, 0x5C, 0xA2, 0xA6, 0x5C, 0x50, 0xB0, 0x40, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xE3, 0xF4, 0xFA, 0xF0, 0xF7, 0x28, 0x78,
    0xD8, 0xA8, 0xA8, 0xA4, 0x90, 0x58, 0x3E, 0x0A, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04, 0x07, 0x07,
    0x06, 0x06, 0x05, 0x07, 0x07, 0x04,
};
/* mũi tên
 *  
 */
const static unsigned char __attribute__((progmem)) mui_ten_5x4[] = {

    0x01, 0x07, 0x0F, 0x07, 0x01,

};
// mảng cho 2 nhân vật Cả mẹo(0) và Dần béo(1)
byte object2[2][4] = { 0 };
//object[i][0]: tồn tại hay không
//object[i][1]: tọa độ x
//object[i][2]: tọa độ y
//object[i][3]: hướng (1 phải, 2 trên , 3 trái, 4 dưới)
//
byte chon_nv_A;
byte chon_nv_B;
//lựa chọn nhân vật, mặc định A được chọn trước
byte Xmin, Ymin, Xmax, Ymax; //biên
//cài đặt chân input
#define fight_b A5
#define select_b A4
#define right_b A3
#define up_b A2
#define left_b A1
#define down_b A0
// Chương trình chạy 1 lần
void setup()
{
    Serial.begin(9600);
    lcd.ON();
    lcd.SET(23, 0, 0, 0, 4);

    pinMode(left_b, INPUT_PULLUP);
    pinMode(down_b, INPUT_PULLUP);
    pinMode(right_b, INPUT_PULLUP);
    pinMode(up_b, INPUT_PULLUP);
    pinMode(fight_b, INPUT_PULLUP);
    pinMode(select_b, INPUT_PULLUP);

    Xmin = 0;
    Xmax = 125;
    Ymin = 0;
    Ymax = 63;
    chon_nv_A = 1;
    chon_nv_B = 0;
}

////////ĐIỀU KHIỂN 2 NHÂN VẬT//////////////////////
void ve_nhan_vat(byte x, byte y, byte huong, byte i)
{
    switch (i) {

    case 0:
        // vẽ Cả Mẹo
        if (huong == 1) {
            //quay về bên phải
            lcd.Plus_Bitmap(x, y, 22, 18, ca_meo_22x18, 0, NO_MIRROR, BLACK);
        }
        if (huong == 3) {
            //quay về bên trái
            lcd.Plus_Bitmap(x, y, 22, 18, ca_meo_22x18, 0, MIRROR, BLACK);
        }
        lcd.display();
        break;
    case 1:

        if (huong == 1) {
            //quay về bên phải
            lcd.Plus_Bitmap(x, y, 23, 19, dan_beo_23x19, 0, NO_MIRROR, BLACK);
        }
        if (huong == 3) {
            //quay về bên trái
            lcd.Plus_Bitmap(x, y, 23, 19, dan_beo_23x19, 0, MIRROR, BLACK);
        }

        lcd.display();
        //vẽ Dần Béo
        break;
    default:
        break;
    } //switch

} // ve nhân vật
void xoa_nhan_vat(byte x, byte y)
{
    lcd.fillrect(x, y - 7, 24, 19 + 7, DELETE);
    lcd.display();

} // xóa nhân vật
void ve_mui_ten(byte x, byte y)
{
    // mũi tên sẽ chỉ vào nhân vật i
    lcd.bitmap(x, y, 5, 4, mui_ten_5x4, BLACK);
    lcd.display();

} // vẽ mũi tên
void xoa_mui_ten(byte i)
{
    lcd.fillrect(object2[i][1] - 5, object2[i][2] - 7, 20, 5, DELETE);
    lcd.display();
} //xóa mũi tên

void di_chuyen_nhan_vat(byte i)
{
    byte x_cu, y_cu, huong_cu;
    byte x_moi;
    //lấy thông tin
    x_cu = object2[i][1];
    y_cu = object2[i][2];
    huong_cu = object2[i][3];
    if (huong_cu == 1) {
        //đi về bên phải
        x_moi = x_cu + 4;
        ve_nhan_vat(x_moi, y_cu, huong_cu, i);
        ve_mui_ten(x_cu + 5, y_cu - 7);
    }

    if (huong_cu == 3) {
        //đi về bên trái

        if (x_cu >= Xmin + 4 * 2) {
            //chống quá biên
            x_moi = x_cu - 4;
        }
        else {
            x_moi = x_cu;
        }
        ve_nhan_vat(x_moi, y_cu, huong_cu, i);

        ve_mui_ten(x_cu + 5, y_cu - 7);
    }
    //lưu thông tin

    object2[i][1] = x_moi;

} //di chuyển nhân vật
void xu_li_nhan_vat()
{
    //b0: điều khiển lựa chọn nhân vật
    if (digitalRead(fight_b) == 0) { //fight được nhấn
        if (chon_nv_A == chon_nv_B) { // đề phòng A bằng B
            chon_nv_A = 1;
            chon_nv_B = 0;
        }
        if (chon_nv_A != chon_nv_B) { //để dảm bảo A khác B
            chon_nv_A = !chon_nv_A;
            chon_nv_B = !chon_nv_B;
            //đổi
        }
    } //if
    //b1: chọn nhân vật
    byte i = 0;
    if ((chon_nv_A == 1) && (chon_nv_B == 0)) {
        i = 0; // nhân vật Cả Mẹo
    }
    if ((chon_nv_A == 0) && (chon_nv_B == 1)) {
        i = 1; // nhân vật Dần Béo
    }
    if (digitalRead(fight_b) == 0) { //fight được nhấn

        xoa_mui_ten(!i);
        ve_mui_ten(object2[i][1] + 5, object2[i][2] - 7);
    }

    //b2: cấp giấy khai sinh (chỉ dùng khi start game)
    if (object2[i][0] == 0) {
        // nếu không tồn tại gà thì phải tạo gà
        // cấp thuộc tính cho đối tượng gà
        object2[i][1] = Xmin + 50 * i; //hoành độ ban đầu
        object2[i][2] = Ymax - 19; // tung độ ban đầu
        object2[i][3] = 1; //hướng về bên phải
        object2[i][0] = 1; //cấp quyền tồn tại
    }

    //b4: vẽ 2 nhân vật

    for (byte j = 0; j <= 1; j++) {

        ve_nhan_vat(object2[j][1], object2[j][2], object2[j][3], j);
    }
    //b5: điều khiển hướng nhân vật i
    byte read_button;
    read_button = lcd.Pullup_4(right_b, up_b, left_b, down_b);
    if (read_button == 1) { // nút right
        //ghi lại tt hướng
        object2[i][3] = 1;
        xoa_mui_ten(!i);

        xoa_nhan_vat(object2[i][1], object2[i][2]); //xóa ảnh cũ
        //lấy thông tin tọa độ để xóa

        di_chuyen_nhan_vat(i); // vẽ ảnh mới
    }

    if (read_button == 3) { // nút left
        object2[i][3] = 3;
        xoa_mui_ten(!i);
        xoa_nhan_vat(object2[i][1], object2[i][2]); //xóa ảnh cũ
        //lấy thông tin tọa độ để xóa

        di_chuyen_nhan_vat(i); // vẽ ảnh mới
    }

} //xử lí nhân vật
//==================================================
void loop()
{
    xu_li_nhan_vat();
    delay(50);
}

Kết quả

Xử lí nảy trứng

Giải phương trình quỹ đạo bay Parabol.

Trong đoạn code này

byte X0; // tọa độ đỉnh parabol
f_y_moi = 1.0 + sq((float(X0) - float(x_moi)) / 4.0); //phương trình

Với quy ước màn hình, trục tung hệ tọa độ có chiều hướng xuống dưới. Kết quả ta được phương trình của chuyển động ném xiên. 

Bay từ trái sang phải

#include "ST7565_homephone.h"
ST7565 lcd(3, 4, 5, 6); //RST, SCLK, A0, SID
void setup()
{
    lcd.ON();
    lcd.SET(23, 0, 0, 0, 4);
}
void loop()
{
    float y;
    byte X0 = 60; // hoành độ đỉnh parabol
    for (byte x = 30; x < 100; x += 1) {
        y = 1.0 + sq((float(X0) - float(x)) / 4.0); //phương trình
        lcd.FillCircle(x, byte(y), 4, BLACK);
        lcd.Display();
        delay(1);
        lcd.Clear(); // xóa toàn màn hình
    }
}

Bay từ phải sang trái

#include "ST7565_homephone.h"
ST7565 lcd(3, 4, 5, 6); //RST, SCLK, A0, SID
void setup()
{
    lcd.ON();
    lcd.SET(23, 0, 0, 0, 4);
}
void loop()
{
    float y;
    byte X0 = 60; // hoành độ đỉnh parabol
    for (byte x = 100; x > 30; x -= 1) {
        y = 1.0 + sq((float(X0) - float(x)) / 4.0); //phương trình
        lcd.FillCircle(x, byte(y), 4, BLACK);
        lcd.Display();
        delay(1);
        lcd.Clear(); // xóa toàn màn hình
    }
}

Kết

Code đã dài, sau khi kết hợp các module với nhau, ta được Game hoàn chỉnh :

https://drive.google.com/file/d/0BzMEcyRK_uUFU2EyWWF0dmpaZlk/view?usp=sharing (mirror)

Chúc bạn có hứng khởi cùng các dự án về Game. Hẹn gặp lại ở các project game khác.

< Thái Sơn >

lên
8 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Điều khiển 8 đèn LED qua wifi, sử dụng Arduino và ESP8266

Với mục đích giúp các bạn tiếp cận với các thiết bị IOT gần hơn. Hôm nay mình sẽ hướng dẫn các bạn viết chương trình điều khiển 8 LED qua mạng wifi. Và hơn thế nữa, nếu kết hợp với VPN hoặc mở port thì chúng ta có thể làm hơn thế nữa!

lên
43 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

Làm robot tự học lệnh đơn giản.

Robot arm, robot nhện, robot múa.. hay các robot mini có sử dụng động cơ servo đều là những sản phẩm gây ấn tượng với những chuyển động đẹp mắt. Đúng như tiêu chí của ARDUINO, mình sẽ làm một dự án ROBOT tự học lệnh cực kì COOL.  

lên
18 thành viên đã đánh giá bài viết này hữu ích.

NOKIA5110 | Hướng dẫn sử dụng và chia sẻ thư viện HOÀNG SA

Xin chào các bạn, bộ thư viện ST7565 homephone có nhiều tính năng nổi bật, để sánh ngang tầm ưu việt, giờ đây lcd 84x48 NOKIA5110 đã có một phiên bản giống hệt như vậy. Cùng khám phá nào !!  

lên
16 thành viên đã đánh giá bài viết này hữu ích.