Điều khiển động cơ servo qua Wifi + Internet / 2G / 3G / 4G bằng điện thoại (App Inventer, REST API...) với công nghệ iNut Platform

Mô tả dự án: 

Hôm nay, chúng ta sẽ học cách điều khiển 02 Servo qua Internet. Vấn đề này, vừa dễ lại vừa khó, vậy nó dễ chỗ nào, khó chỗ nào, chúng ta cùng nhau tìm hiểu nhé!

Qua bài học này, bạn sẽ hiểu được cách làm thế nào để điều khiển nhiều servo bằng cách sử dụng iNut - Cảm biến. Bạn có thể tự làm app của riêng mình, mở rộng các chức năng không giới hạn!

Bạn sẽ làm được gì trong ngày hôm nay?

Bạn sẽ tự làm được một app điều khiển những chú servo thông qua Internet mà bạn chẳng cần biết gì về lập trình mạng cả!

Điều khiển từ xa qua Wifi / Internet khác với việc điều khiển qua Bluetooth ở điểm nào!

Trên đây là ý kiến cá nhân, mình tổng hợp từ kinh nghiệm của mình khi giảng dạy và triển khai các dự án IoT. Bạn có thể lướt qua và đọc phần tiếp theo. Tuy nhiên, nên đọc để lựa chọn con đường trong sự nghiệm cách mạng Công nghiệp 4.0

  Dùng Wifi Dùng Bluetooth
Năng lượng Tốn nhiều năng lượng hơn vì cơ chế cấu trúc của nó Ít tốn năng lượng hơn, vì cơ chế cấu trúc cua nó.
Phương án truyền dữ liệu Server-Client (đa số, dễ, nhiều tài liệu), Peer-to-peer (khó) Peer-to-Peer (đa số, dễ, rất nhiều tài liệu), Server-Client (khó, không dành cho newbie)
Các module thông dụng ESP8266, ESP32 HC-05, HC-06, ESP32, Vbluno
Vì sao dùng? Lập trình để có thể điều khiển nhiều thiết bị cùng một lúc. Kết nối với hàng chục thiết bị, hàm trăm,... cho tới hàng triệu thiết bị. => Scale out application Lập trình điều khiển truyền tin từ xa từ điện thoại (App Inventor) tới board mạch Arduino cực kỳ đơn giản. Prototype, Project
Điểm khó của từng nền tảng Rất khó lập trình! Vì phải hiểu biết nhiều về các phương thức mạng. Các thư viện hiện có tuy quảng cáo rất bài bản này nọ nhưng người dùng vẫn phải tự implement các loại key để bảo mật, hay treo (ngay cả production của một số hãng không tiện nói tên). Bắt lỗi từ SDK và cơ chế tự phát wifi khi không kết nối được, hay kết nối lại vào thiết bị phát wifi hay nó phát lại, chưa kể thiết bị router đổi pass wifi thì sao... Rồi, một chuyện cực kỳ quan trong nữa là... khó viết app cho newbie (dùng app inventor thì sao mà viết đây?). Chưa kể điều khiển qua Internet nữa... phải nat port, phải mua server,... tùm lum thứ. Haiza, mọi thứ rất dễ nha, nhưng mà chỉ kết nối giữa điện thoại với thiết bị điều khiển thôi. Dự án nào mà một điện thoại điều khiển nhiều thiết bị hay nhiều điện thoại điều khiển nhiều thiết bị thì em xin chào thua anh ạ! Nói vậy chứ với những board mạch hỗ trợ tính năng lập trình Bluetooth (ESP32, Vbluno) tương tự như mấy board Wifi á, thì mấy cái vấn đề ở ô bên trái lại xuất hiện và đè nặng lên tri thức của một lập trình viên.

Tôi và nhóm nghiên cứu iNut Platform đã trăn trở, đào sâu nghiên cứu, tìm kiếm phương án để giải phóng sức lao động của các lập trình viên. Vì chúng tôi muốn họ có thể tập trung phát triển chức năng vào thiết bị, từ một lập trình viên làm một dự án khoa học kỹ thuật cho kỳ thi Khoa học kỹ thuật trong trường phổ thông cho đến một lập trình viên chuyên về phần mềm, front-end, back-end,... (trừ embeded developer), ai cũng có thể biến ý tưởng về Internet of Things của mình thành hiện thực.

Trong con đường gian nan, ít người có thể chia sẻ được tầm nhìn ấy, nhóm iNut Platform đã tìm ra một con đường, tìm ra một phương án để biến một số điểm khó khăn nhất khi lập trình IoT trên Wifi trở nên giản đơn và giống hệt như module Bluetooth HC-06 hay HC-05.

Thay vì tập trung vào việc viết thư viện và đưa API (file.h) cho lập trình viên phát triển thêm trên đó, nhóm tập trung và viết ra firmware và bán nó cho các dự án sử dụng IoT. Trong đó, chi phí phát triển và mở rộng dự án, chi phí server hàng năm đã được tính vào trong một giá duy nhất. Với cách làm này, nhóm đã cho ra đời firmware iNut - Cảm biến và mạch iNut - Cảm biến cùng với đó là iNut Platform và hệ thống REST API thân thiện với mọi lập trình viên ở mọi ngôn ngữ lập trình. Ngoài ra, hệ thống iNut Platform còn hỗ trợ message broker như Socket.io và MQTT.

Bạn, một người dám nghĩ lớn, hãy để trí tưởng tượng của mình bay xa và để iNut Platform chắp cánh cho dự án IoT thành công mà bạn đã, đang và sẽ có.

Cùng khám phá xem, iNut Platform có thể làm được gì qua dự án mẫu này nhé.

Nguyên liệu cần chuẩn bị cho "món ăn" này là gì?

Thời gian nghiên cứu

  1. Nếu bạn chỉ tham khảo bài viết để đọc và xem video hướng dẫn, bạn sẽ mất khoảng: 20 phút.
  2. Bạn thử lập trình theo hướng dẫn bao gồm thời gian lắp mạch, đọc bài, nạp code: khoảng 45 phút.
  3. Bạn sáng tạo thêm thắt theo ý mình dựa vào ý tưởng mà mình gợi ý: >= 60 phút.

Bây giờ, không làm mất thời gian của bạn nữa, tiến hành thôi!

Thử lắp mạch điều khiển Servo và kết nối gửi đến iNut - Cảm biến

Bạn cần lắp mạch như sau nhé

Bạn cần nối điện cho cả board mạch Arduino Uno và board mạch iNut - Cảm biến. Nếu bạn chỉ muốn nối điện cho Arduino Uno để lập trình thôi thì bạn cần nối thêm một dây để nối VCC (của Arduino) nối vào VIN của iNut - Cảm biến nhé.

Sau đây là đoạn code lập trình cho Arduino, tôi đa chú thích trong đoạn code khá rõ ràng, bạn chỉ cần copy vào dán vào Arduino IDE thôi, một số kiến thức bạn cần tham khảo nếu chưa biết là: (các bạn có thể lướt qua đến phần code, xem đoạn nào chưa hiểu thì mới click vào danh sách này để khám phá thêm)

//Thư viện này là thư viện I2C mặc định của Arduino, bạn cần include nó
// vào mọi dự án sử dụng mạch iNut - Cảm biến
// Vì là thư viện có sẵn của Arduino nên bạn không cần cài thêm bất cứ thư viện gì nữa
#include <Wire.h>

//Thư viện này là thư viện của Servo, bạn cần include nó
// để điều khiển Servo. Đây cũng là thư viện mặc định của Arduino vì vậy bạn không cần cài thêm
// Tuy nhiên, các bạn có thể sử dụng các thư viện khác để tối ưu hóa tốc độ và độ chính xác của servo
#include <Servo.h>

//đoạn code dưới đây là để khai báo số lượng luồn càm biến mà các bạn sẽ sử dụng trong iNut Platform.
// Nếu bạn đã từng nghe nói về MQTT, thì đây giống như là các topic.
// Nếu bạn đã từng nghe nói về Socket.io thì đây giống như là các room.
#define N_SENSOR 1 //Số lượng cảm biến
float sensors[N_SENSOR]; //biến lưu trữ danh sách giá trị cảm biến
//Bạn có thể tùy chỉnh số lượng cảm biến N_SENSOR từ 1 - 8,
// khi thay đổi bạn vui lòng nạp lại firmware iNut Cảm biến với số lượng cảm biến mong muốn

//Khai báo biến Servo
Servo myServo;
#define SERVO_PIN 2

void setup()
{

    //Bật Serial montior để debug - baudrate 9600
    Serial.begin(9600); //Bật Serial Montior, các bạn dùng baudrate bao nhiêu cũng được
    
    //Để giao tiếp với board iNut - Cảm biến, bạn cần chạy đoạn lệnh dưới đây
    Wire.begin(10); //Theo như yêu cầu của iNut Platform, các bạn sẽ dùng cổng I2C với địa chỉ là 10. Cách khai báo là như thế này!
    Wire.onRequest(i2cRequestEvent); //Mỗi khi iNut - Cảm biến yêu cầu thì sẽ chạy hàm này nhằm mục tiêu gửi dữ liệu lên cho iNut - Cảm biến, cứ 01 giây sẽ yêu cầu gửi 01 lần.
    //Con số 01 giây này được cài đặt trong phần mềm iNut được cài đặt trên Android và iOS. Bạn có thể thay đổi tối thiểu là 50ms.

    Serial.println("Xin chao iNut Platform");

    // Cài đặt chức năng điều khiển servo cho chân servoPin
    myServo.attach(SERVO_PIN);
}

void i2cRequestEvent()
{
    //phải có nhé, chỉ cần 02 dòng này là data đã được gửi đi
    char* data = (byte*)&sensors; //chuyển mảng float* thành mảng char * để hợp với chữ ký hàm ở dưới
    Wire.write(data, sizeof(sensors)); //chuyển đi (dưới dạng mảng char) với kích thước là số lượng float
}

void loop()
{
    //Nhiệm vụ của bạn là gán giá trị cảm biến vào các phần tử của mảng sensors
    sensors[0] = myServo.read();

    //Chương trình tự quay servo để kiểm tra việc kết nối
    quay_servo();
}

void quay_servo()
{
    static unsigned long timer = 0; //Chỉ khởi tạo một lần đầu thôi, lần sau dùng lại gí trị trước
    if (millis() - timer > 500UL) { //sau mỗi 500ms thì cho Servo quay một góc 5 độ
        timer = millis(); //cập nhập là thời điểm cuối cùng thực thi lệnh
        int pos = myServo.read();

        static int delta = 5; //Chỉ gán nó bằng 5 trong lần đầu tiên hàm này được gọi, sau đó thì không có gán, các bạn có thể xem thêm về từ khóa "static" ở http://arduino.vn/reference/static-bien-tinh
        if (pos >= 180) {
            delta = -5; //nó quay quá góc ==> cho quay lùi
        }
        else if (pos <= 0) {
            delta = 5;
        }

        myServo.write(pos + delta);
    }
}

Sau khi đã nạp code cho mạch Arduino, bạn cần cài đặt cho board mạch iNut - Cảm biến để bạn có thể dùng được mạch nó, để cài đặt, bạn có thể xem video sau:

Đăng ký tài khoản trong phần mềm iNut

Cài đặt thiết bị iNut - Cảm biến vào mạng nhà bạn.

Kết quả sau khi đã nạp code và cài đặt iNut - Cảm biến trên điện thoại iPhone

Quá dễ phải không nào, bạn đã có thể debug (kiểm tra) chương trình và việc kết nối có diễn ra đúng theo ý bạn hay không mà không cần phải lo lắng gì cả, mọi thứ đã có iNut Platform lo lắng rồi! Chỉ việc thao tác cài đặt như video trên là chúng ta đã có một đường dẫn lên Internet, điều mà trước đây chỉ là mơ ước của rất nhiều bạn trẻ. Nhưng từ đây, sức sáng tạo của toàn dân sẽ được huy động để sáng tạo các dự án, các mẫu thử trong cuộc cách mạng Công nghiệp 4.0 này. Giải phóng sức lao động và nhiệm vụ của những maker như chúng ta!

Nếu bạn thấy chữ "Mất kết nối" trong giao diện phần mềm iNut thì là do 02 nguyên nhân sau:

  • Do bạn kết nối dây SDA, SCL với Arduino Uno chưa đúng, kiểm tra lại kết nối.
  • Mạch Arduino trong ví dụ là chỉ truyền 01 trường dữ liệu, nhưng mạch iNut - Platform mình thử nghiệm hỗ trợ 03 trường dữ liệu, nên sẽ có 02 trường sẽ bị ghi là mất kết nối.

Okay, bây giờ đã xong mạch rồi, bây giờ chúng ta đã thấy được việc kết nối với IoT đã quá dễ dàng phải không nào? Đơn giản hơn cả bluetooth đó chứ ^_^.

Lập trình điều khiển góc quay Servo qua REST API

Bluetooth thì làm gì có chuyện hỗ trợ REST API, REST API là những thứ tuyệt vời của công nghệ Wifi, và bạn sẽ được sử dụng nó đó để lập trình điều khiển Arduino. Điều này đã đủ thu hút các lập trình viên phần mềm muốn bước sang lĩnh vực phần cứng này chưa nà... Một khi đã hỗ trợ REST API thì tất cả lập trình viên ở tất cả mọi nơi đều có thể tham gia vào cuộc cách mạng công nghiệp 4.0 này.

Okay, thử code nào! Bạn nạp đoạn code sau vào Arduino nhé.

#include <Wire.h>
#include <Servo.h>

#define N_SENSOR  1
float sensors[N_SENSOR]; //biến lưu trữ danh sách cảm biến


Servo myServo;
#define SERVO_PIN 2

void setup() {
  Serial.begin(9600); //Bật Serial Montior, các bạn dùng baudrate bao nhiêu cũng được
  
  Wire.begin(10); //Theo như yêu cầu của iNut Platform, các bạn sẽ dùng cổng I2C với địa chỉ là 10.
  Wire.onReceive(receiveEvent); //Đoạn này mới nè, cái này sẽ ghi nhận yêu cầu từ iNut - Platform và lưu vào buffer để bạn có thể sử dụng để lập trình
  Wire.onRequest(i2cRequestEvent); //Mỗi khi iNut - Cảm biến yêu cầu thì sẽ chạy hàm này nhằm mục tiêu gửi dữ liệu lên cho iNut - Cảm biến, cứ 01 giây sẽ yêu cầu gửi 01 lần
  
  Serial.println("Xin chao iNut Platform");

  // Cài đặt chức năng điều khiển servo cho chân servoPin
  myServo.attach(SERVO_PIN); 
  
}

//Chỉ có thể truyền được 32 byte do giới hạn của I2C Arduino Uno, nhưng bạn có thể tăng giới hạn này, mình sẽ nói ở các bài viết sau
// Chỉ cần có 2 biến này là được bạn nhé.
volatile char buffer[33];
volatile boolean receiveFlag = false;
void receiveEvent(int howMany)
{
  Wire.readBytes((byte *)buffer, howMany);
  buffer[howMany] = 0;
  receiveFlag = true;
}

void i2cRequestEvent()
{
  //phải có nhé, chỉ cần 02 dòng này là data đã được gửi đi
  char *data = (byte*)&sensors; 
  Wire.write(data, sizeof(sensors));


  //debug
  Serial.print('.');
}


void loop() {
  //Nhiệm vụ của bạn là gán giá trị cảm biến vào các phần tử của mảng sensors
  sensors[0] = myServo.read();


  if (receiveFlag) { //khi có tín hiệu là đã nhận được lệnh
    
    String command = buffer; //chép lệnh vào biến String cho dễ xử lý
    
    
    Serial.print(command);// in ra lệnh
    Serial.print(' ');
    Serial.println(millis());//in ra thời gian theo millis tính từ lúc arduino chạy để debug
    int pos = atoi(command.c_str()); //Chuyển chuỗi command thành const char * rồi từ đó dùng atoi chuyển thành số nguyên
    
    if (command[0] == '+' || command[0] == '-') {
      pos = myServo.read() + pos;
    }
    
    Serial.println(pos);
    myServo.write(pos);

    receiveFlag = false; //đánh dấu đã xử lý xong lệnh, không cần đọc nữa
  }
}

Okay, bây giờ đã cài đặt xong rồi, bây giờ chúng ta cần sử dụng REST API để có thể truyền lệnh từ xa từ Internet đến board mạch Arduino thôi. Tài liệu về REST API của iNut Platform được chia sẻ miễn phí và rộng rãi ở https://inutapi.docs.apiary.io/

Hiện tại, vào thời điểm viết bài này, iNut Platform đang hỗ trợ 5 đường dẫn cú pháp cho các bạn. Để có thể lập trình giao tiếp truyền dữ liệu, các bạn chỉ cần dùng 02 API như hình là được.

Okay, bây giờ chúng ta sẽ cùng Xem thử API đầu tiên, Xem trạng thái thông tin của thiết bị và cảm biến. Đây là API của nó.

Để lấy được uuid, node_id và token của thiết bị iNut - Cảm biến, bạn xem video hướng dẫn sau:

Bạn mở app iNut vào "Cài đặt" > Thiết bị mà bạn có > Dành cho nhà phát triển > Kéo xuống dưới chọn Copy vào bộ nhớ đệm > Gửi mã đó qua Email, Zalo hay Facebook Messenger.

Phần mềm trong video là Postman, phần mềm này dùng để thử nghiệp API một cách dễ dàng nhất. Tuy nhiên, bạn cũng có thể sử dụng Console có sẵn trong trang tài liệu của iNut Platform để thử nghiệm API.

Đây là một ví dụ 

Kết quả trả về có dạng như thế này:

{
    "status": 0,
    "count": 3,
    "devices": [
        {
            "node_id": "BJg3q5Yrz",
            "id": 0,
            "state": "93.00",
            "type": "SENSOR"
        },
        {
            "node_id": "BJg3q5Yrz",
            "id": 1,
            "state": "NOT_CONNECTED",
            "type": "SENSOR"
        },
        {
            "node_id": "BJg3q5Yrz",
            "id": 1,
            "state": "NOT_CONNECTED",
            "type": "SENSOR"
        }
    ]
}

Trong đó, status = 0 tức là request thành công, bạn đã nhập đúng bộ 3 mã uuid, node_id và token. Tiếp theo là count: số lượng node cảm biến / thiết bị, tiếp theo là devices là danh sách các trường dữ liệu cảm biến nhận được. Do mình dùng iNut Cảm biến loại 3 cảm biến và chỉ mới dùng 1 bộ cảm biến nên sẽ có 02 bộ cảm biến báo state là NOT_CONNECTED.

Okay, đã thử lấy được thông tin cảm biến rồi, bây giờ chúng ta sẽ thử gửi liệu (POST) vào API để nó thay đổi góc của servo nhé.

Cùng xem lại đoạn code trên Arduino mà ta vừa nạp lại vừa rồi:

if (receiveFlag) { //khi có tín hiệu là đã nhận được lệnh
        
    String command = buffer; //chép lệnh vào biến String cho dễ xử lý
    
    
    Serial.print(command);// in ra lệnh
    Serial.print(' ');
    Serial.println(millis());//in ra thời gian theo millis tính từ lúc arduino chạy để debug
    int pos = atoi(command.c_str()); //Chuyển chuỗi command thành const char * rồi từ đó dùng atoi chuyển thành số nguyên
    
    if (command[0] == '+' || command[0] == '-') {
        pos = myServo.read() + pos;
    }
    
    Serial.println(pos);
    myServo.write(pos);

    receiveFlag = false; //đánh dấu đã xử lý xong lệnh, không cần đọc nữa
}

Cú pháp lệnh:

<số nguyên>: kêu servo quay đến góc cố định. Ví dụ: 0 => Đến góc 0 độ, 180: đến góc 180 độ, 90: đến góc 90 độ.

+<số nguyên: kêu servo quay thêm một góc nữa để tăng độ hiện thời. Ví dụ: +5. Quay thêm độ về phía dương.

-<số nguyên>: Kêu servo quay giảm một góc. Ví dụ: -5. Quay thêm độ về phía âm.

Từ đó, đoạn code trên là để giải quyết cú pháp lệnh này:

  1. Trong đó, từ buffer lệnh, ta chuyển thành chuỗi String command để dễ dàng xử lý.
  2. Sau đó thì in lệnh ra để debug.
  3. Chuyển lệnh thành số nguyên để tính toán.
  4. Kiểm tra phần tử đầu tiên của lệnh. Nó nó có dấu + hoặc dấu - thì thay đổi góc quay theo góc hiện thời.
  5. In ra tọa độ mới của servo đó (để debug).
  6. Điều khiển servo đến một vị trí đã được tính toán.
  7. Đánh dấu là đã xử lý xong lệnh, không cần đọc nữa.

Với việc cài đặt đoạn chương trình trên, bạn đã bước chân vào thế giới IoT mà không cần biết một chút kiến thức gì về lập trình mạng (trong khi lĩnh vực này rất khó để có một bộ thiết bị hoàn thiện và ổn định). Okay, bây giờ ta sẽ thử gửi dữ liệu từ thế giới bên ngoài xuống Arduino nhé.

Bạn cũng có thể thử nghiệm ngay trên tài liệu của iNut Platform.

Bạn thử sửa command thành 0, 180, 90, +5, -5 để xem hiệu ứng trên Servo nhé ^_^.

iNut Platform kết hợp với App Inventor

Yeah, cuối cùng cũng đã đến phần hay nhất rồi! Bây giờ, chúng ta cùng nhau xem lại kịch bản kết nối nhé:

  • Để kết nối đến thiết bị iNut Cảm biến, chúng ta cần 3 khóa: node_id, uuid và token.
  • 3 khóa đõ được đặt trong một mã QRcode trong app iNut.
  • Sau khi đã có 3 khóa đó, ta có thể dùng thiết bị của mình ở mọi nơi trên thế giới!

Như vậy, ta sẽ viết một app Internet có thể quét được mã QRcode gửi được REST API. Thế là xong! Quá dễ đi à.

Đoạn code dùng để giao tiếp REST API để gửi lệnh xuống Servo.

Mình đã nén code App Inventor và chương trình APK. Các bạn có thể tải về ở https://drive.google.com/open?id=1_84mJUG5w5l2oZEVKvpT-bXah2Ah1lPo 

Một số video demo thử nghiệm hiệu năng với việc gửi yêu cầu điều khiển liên tục

Thử với code 2 servo

Trước tiên, ta cần định nghĩa là tập lệnh một xíu, vì tập lệnh hiện tại chỉ cho phép ta điều khiển 01 con servo. 

Ta sẽ thêm một ký tự cuối cùng ở phía sau để định danh servo. Chữ A => tức là servo 1, chữ B => tức là servo 2.

Ví dụ: 180A => Servo 1 quay qua góc 180 độ; +5B => Servo 2 quay thêm 5 độ về hướng dương.

Đoạn code Arduino sẽ thành:

#include <Wire.h>
#include <Servo.h>

#define N_SENSOR  2
float sensors[N_SENSOR]; //biến lưu trữ danh sách cảm biến


Servo myServo;
Servo myServo2;
#define SERVO_PIN 2
#define SERVO_PIN_2 3

void setup() {
  Serial.begin(9600); //Bật Serial Montior, các bạn dùng baudrate bao nhiêu cũng được
  
  Wire.begin(10); //Theo như yêu cầu của iNut Platform, các bạn sẽ dùng cổng I2C với địa chỉ là 10.
  Wire.onReceive(receiveEvent); 
  Wire.onRequest(i2cRequestEvent); //Mỗi khi iNut - Cảm biến yêu cầu thì sẽ chạy hàm này nhằm mục tiêu gửi dữ liệu lên cho iNut - Cảm biến, cứ 01 giây sẽ yêu cầu gửi 01 lần
  
  Serial.println("Xin chao iNut Platform");

  // Cài đặt chức năng điều khiển servo cho chân servoPin
  myServo.attach(SERVO_PIN); 
  myServo2.attach(SERVO_PIN_2);
  
}

volatile char buffer[33];
volatile boolean receiveFlag = false;

void receiveEvent(int howMany)
{
  Wire.readBytes((byte *)buffer, howMany);
  buffer[howMany] = 0;
  receiveFlag = true;
}

void i2cRequestEvent()
{
  //phải có nhé, chỉ cần 02 dòng này là data đã được gửi đi
  char *data = (byte*)&sensors; 
  Wire.write(data, sizeof(sensors));


  //debug
  Serial.print('.');
}


void loop() {
  //Nhiệm vụ của bạn là gán giá trị cảm biến vào các phần tử của mảng sensors
  sensors[0] = myServo.read();
  sensors[1] = myServo2.read();


  if (receiveFlag) { //khi có tín hiệu là đã nhận được lệnh
    receiveFlag = false; //đánh dấu đã xử lý xong lệnh, không cần đọc nữa
    String command = buffer; //chép lệnh vào biến String cho dễ xử lý
    
    
    Serial.print(command);// in ra lệnh
    Serial.print(' ');
    Serial.println(millis());//in ra thời gian theo millis tính từ lúc arduino chạy để debug
    int pos = atoi(command.c_str()); //Chuyển chuỗi command thành const char * rồi từ đó dùng atoi chuyển thành số nguyên


    Servo servo;
    char lastCharacter = command[command.length() - 1];
    if (lastCharacter == 'A') {
      servo = myServo;
    } else if (lastCharacter == 'B') {
      servo = myServo2;
    } else //kết thúc
      return;
    
    
    char firstCharacter = command[0];
    if (firstCharacter == '+' || firstCharacter == '-') {
      pos = servo.read() + pos;
    }
    
    Serial.println(pos);
    servo.write(pos);

    
  }
}

Và chương trình App Inventor cho các bạn cũng đã được đóng gói và tải lên ở đây https://drive.google.com/open?id=1_84mJUG5w5l2oZEVKvpT-bXah2Ah1lPo

Cùng xem video thành quả của chúng ta, bạn nhé:

Yeah, xong rồi bạn ơi!

Lời kết

Các bạn hãy sáng tạo thêm nữa nhé, thêm điều khiển LED, trạng thái của nó,.. sử dụng bitmath để lưu trữ nhiều dữ liệu hơn,... lập trình một mạng cảm biến, mạng servo, điều khiển vị trí,... có rất nhiều điều mà bạn có thể tiếp tục sáng tạo và khám phá với iNut Platform bằng board mạch iNut - Cảm biến.

Chúc các bạn sáng tạo thành công và biến những ý tưởng của mình thành hiện thực.

lên
9 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

Select any filter and click on Apply to see results

Các bài viết cùng tác giả

HackadayPrize 2017 - Cuộc thi sáng tạo hàng đầu thế giới - Trị giá lên đến 250.000 Mỹ cành

Bạn muốn thử sức mình ở một cuộc thi tầm cỡ thế giới với giải thưởng lên đến 250.000 USD? Bạn muốn đưa ý tưởng của mình tiếp cận những quỹ đầu tư mạo hiểm về công nghệ? Hãy tham gia cuộc thi HackdayPrize 2017. Đây là một cuộc thi sẽ biến ý tưởng của bạn thành những làn sóng công nghệ quét qua hành tình trái đất. Tìm hiểu hoy.

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

static - biến tĩnh

Biến tĩnh là biến sẽ được tạo ra duy nhất một lần khi gọi hàm lần đầu tiên và nó sẽ không bị xóa đi để tạo lại khi gọi lại hàm ấy. Đây là sự khác biệt giữa biến tĩnh và biến cục bộ.

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