Arduino: Làm thế nào để có được loại bảng trong mã


13

Tôi muốn viết một bản phác thảo có thể được biên dịch trên các bảng Arduino khác nhau. Tôi muốn hiển thị trên PC bảng nào hiện đang được kết nối.

Điều này có nghĩa là người dùng kết nối PC qua cáp USB với bo mạch Arduino / Teensy chạy bản phác thảo của tôi và bản phác thảo của tôi cho PC biết qua Nối tiếp bảng nào được kết nối. Trên PC chạy ứng dụng C # của tôi nhận dữ liệu này và hiển thị nó.

Vì vậy, tôi cần bảng đã được chọn khi bản phác thảo đã được biên soạn:

Bộ chọn Arduino

Tôi đã tìm thấy mã trên https://github.com/backupbrain/ArduinoBoardManager nhưng nó không cho kết quả chính xác (ngoài thực tế là một số bảng bị thiếu).

Đây là một đoạn trích từ mã:

static const uint8_t BOARD_MICRO= 0x04;

....
#elif defined(__AVR_Atmega32U4__) // Yun 16Mhz, Micro, Leonardo, Esplora
  static const uint8_t BOARD = 0x04;
  static const uint8_t NUM_BITS = 8;
  static const uint16_t CPU = __AVR_Atmega32U4__;
  static const unsigned long SRAM_SIZE = 2500;
  static const unsigned long EEPROM_SIZE = 1000;
  static const unsigned long FLASH_SIZE = 32000;
#elif defined(.....

Vì vậy, mã này cho kết quả tương tự (BOARD = 0x04 = Micro) cho Yun 16MHz, Micro, Leonardo y Esplora.

Có cách nào để lấy mã C của tôi chính xác chuỗi mà người dùng có selecetd trong menu của trình biên dịch Arduino không?


2
Nếu bạn đang sử dụng IDE arduino để xây dựng chương trình cơ sở, sẽ không có điều khoản nào để chuyển #define cấp dự án cho trình biên dịch, ngoài trừ IFCPU ARDUINO và AVR_whthing . Bạn có thể cần phải nghiêm túc sử dụng tệp tạo tệp để xây dựng, thay vì arduinio IDE. Kiểm tra trang web arduino.SE, Nick và Ignatio có một số ví dụ hay.
MarkU

Tôi không thể tìm thấy bất cứ điều gì thú vị trên Arduino.SE. (Đó có phải là Thụy Điển không?)
Elmue

@Elmue arduino.StackExchange.com là Arduino SE.
Avamander

À ĐỒNG Ý. Nhưng arduino.se tồn tại!
Elmue

Bởi, tôi muốn hiển thị trên PC, bảng nào hiện đang được kết nối, bạn có nghĩa là hiển thị nó khi bản phác thảo được biên dịch và tải lên chạy hoặc hiển thị trong khi bản phác thảo đang được biên dịch hoặc trong khi IDE chỉ ngồi đó với một bản cụ thể bảng đính kèm? (Trong hai trường hợp sau, lựa chọn bảng hiển thị ở dòng thấp nhất của IDE 1.6.3, nhưng nếu bạn có IDE cũ hơn hoặc khác thì có thể không.) (Nếu trường hợp đầu tiên áp dụng, bạn có muốn nó xuất hiện trong màn hình nối tiếp không ?)
James Waldby - jwpat7 27/2/2016

Câu trả lời:


17

Nhờ sự giúp đỡ của Charlie Hanson và jantje, tôi đã tìm ra giải pháp phổ quát!

Bởi vì thật đáng tiếc khi mọi lập trình viên Arduino phải trải qua cùng một nỗi đau để tìm ra cách lấy tên bảng, tôi sẽ cung cấp mã của mình cho công chúng để mọi người có thể sao chép và dán nó.

Đây là:

#if defined(TEENSYDUINO) 

    //  --------------- Teensy -----------------

    #if defined(__AVR_ATmega32U4__)
        #define BOARD "Teensy 2.0"
    #elif defined(__AVR_AT90USB1286__)       
        #define BOARD "Teensy++ 2.0"
    #elif defined(__MK20DX128__)       
        #define BOARD "Teensy 3.0"
    #elif defined(__MK20DX256__)       
        #define BOARD "Teensy 3.2" // and Teensy 3.1 (obsolete)
    #elif defined(__MKL26Z64__)       
        #define BOARD "Teensy LC"
    #elif defined(__MK64FX512__)
        #define BOARD "Teensy 3.5"
    #elif defined(__MK66FX1M0__)
        #define BOARD "Teensy 3.6"
    #else
       #error "Unknown board"
    #endif

#else // --------------- Arduino ------------------

    #if   defined(ARDUINO_AVR_ADK)       
        #define BOARD "Mega Adk"
    #elif defined(ARDUINO_AVR_BT)    // Bluetooth
        #define BOARD "Bt"
    #elif defined(ARDUINO_AVR_DUEMILANOVE)       
        #define BOARD "Duemilanove"
    #elif defined(ARDUINO_AVR_ESPLORA)       
        #define BOARD "Esplora"
    #elif defined(ARDUINO_AVR_ETHERNET)       
        #define BOARD "Ethernet"
    #elif defined(ARDUINO_AVR_FIO)       
        #define BOARD "Fio"
    #elif defined(ARDUINO_AVR_GEMMA)
        #define BOARD "Gemma"
    #elif defined(ARDUINO_AVR_LEONARDO)       
        #define BOARD "Leonardo"
    #elif defined(ARDUINO_AVR_LILYPAD)
        #define BOARD "Lilypad"
    #elif defined(ARDUINO_AVR_LILYPAD_USB)
        #define BOARD "Lilypad Usb"
    #elif defined(ARDUINO_AVR_MEGA)       
        #define BOARD "Mega"
    #elif defined(ARDUINO_AVR_MEGA2560)       
        #define BOARD "Mega 2560"
    #elif defined(ARDUINO_AVR_MICRO)       
        #define BOARD "Micro"
    #elif defined(ARDUINO_AVR_MINI)       
        #define BOARD "Mini"
    #elif defined(ARDUINO_AVR_NANO)       
        #define BOARD "Nano"
    #elif defined(ARDUINO_AVR_NG)       
        #define BOARD "NG"
    #elif defined(ARDUINO_AVR_PRO)       
        #define BOARD "Pro"
    #elif defined(ARDUINO_AVR_ROBOT_CONTROL)       
        #define BOARD "Robot Ctrl"
    #elif defined(ARDUINO_AVR_ROBOT_MOTOR)       
        #define BOARD "Robot Motor"
    #elif defined(ARDUINO_AVR_UNO)       
        #define BOARD "Uno"
    #elif defined(ARDUINO_AVR_YUN)       
        #define BOARD "Yun"

    // These boards must be installed separately:
    #elif defined(ARDUINO_SAM_DUE)       
        #define BOARD "Due"
    #elif defined(ARDUINO_SAMD_ZERO)       
        #define BOARD "Zero"
    #elif defined(ARDUINO_ARC32_TOOLS)       
        #define BOARD "101"
    #else
       #error "Unknown board"
    #endif

#endif

Bạn thậm chí có thể đặt mã này vào một tệp tiêu đề mới và #incolee nó vào dự án của bạn.

PD Nếu bạn muốn biết thêm về mô hình CPU, hãy tìm kiếm tập tin avr_castaames.h


cái khác. thay vì sử dụng "return"? ";" khi bạn không biết sử dụng tên bảng cảnh báo #pragma là không xác định
jantje

1.) Tôi đã thay thế "?" với một #error. 2.) Tôi không nghĩ rằng các chuỗi thực sự là một vấn đề. Bạn đã hiểu rằng chỉ có MỘT chuỗi sẽ được biên dịch vào cuối? Xem cập nhật của tôi giải thích điều này ở trên. Chuỗi dài nhất là 11 byte. Nếu bạn cần tối ưu hóa mã của mình đến mức bạn quan tâm đến 11 byte, tôi khuyên bạn nên xác định một enum và trả về mã đó thay vì một chuỗi. Sau đó, chức năng của bạn sẽ trả về một byte thay vì 11.
Elmue

3.) Và những gì liên quan đến khả năng bảo trì: Thật buồn khi tôi phải viết một chức năng như vậy. Đây phải là một phần của các tệp tiêu đề được cài đặt với trình biên dịch và phải được các nhà phát triển duy trì và cập nhật với mọi phiên bản mới.
Elmue

2) Tôi đã phạm sai lầm khi viết nhận xét về kích thước. Tôi đã nhận xét về điều đó 5 giờ trước. Xin lỗi vì điều đó. 3) Khả năng bảo trì là một vấn đề. Tôi đã viết mã rất giống nhau trong quá khứ. Tôi chắc chắn nhiều người khác cũng có. Đó là khả năng duy trì tại sao tôi thích "giải pháp IDE tốt hơn". Tôi khá chắc chắn rằng tất cả "IDE tốt hơn" sẽ có giải pháp tương tự như giải pháp tôi đã đề cập trong câu trả lời của mình. Xem nó như một sự bổ sung: Bạn đang vượt xa Arduino IDE.
jantje

Nếu bạn viết một bình luận sai, tốt nhất sẽ là xóa nó.
Elmue

2

lưu ý đây là mod windows, một cái gì đó tương tự phải tồn tại trên linux.

Đầu tiên là nhanh chóng và dễ dàng. Chỉ cần sửa đổi các tệp platform.txt mà bạn đang sử dụng như mô tả nelow. Mặt hạn chế của điều này là bạn sẽ cần thay đổi các tệp platform.txt với mỗi bản phát hành.

thêm -DBOARD = \ "$ {build.board} \" vào công thức. Điều này sẽ cho phép

   const char boardName[]=BOARD;

Cung cấp cho bạn chuỗi "ARDUINO_AVR_LEONARDO" (cho leonardo) trong boardName.

Cách thứ hai là chuyển sang một IDE tốt hơn (như đã được đề xuất bởi những người khác). Là người tạo ra plugin nhật thực arduino, tôi sẽ khuyên bạn nên sử dụng plugin nhật thực arduino. Trong plugin nhật thực arduino bạn thực hiện việc này như sau: Nhấp chuột phải vào dự án-> thuộc tính-> arduino-> tab "tùy chọn biên dịch" đặt

-DBOARD=\"${A.BUILD.BOARD}\" 

trong phần bổ sung vào trường C và C ++.

Điều này sẽ làm cho mã ở trên để biên dịch

Phụ lục

Tôi không biết bạn muốn "tên đẹp". Tôi không chắc điều này có thể được sửa trong platform.txt trong arduino IDE. Trong plugin nhật thực arduino thay đổi fixe ở trên trong

-DBOARD=\"${A.NAME}\"

để có được cái tên đẹp (cho leonardo "Arduino Leonardo") trong bảng xác định.


Downvoter hoặc bất cứ ai khác xin vui lòng tử tế để xác định lý do tại sao đây là câu trả lời cần downvot?
jantje

1.) Có, StackExchange sẽ buộc mọi người bỏ phiếu viết ra lời giải thích. (Đó không phải là downvote của tôi) 2.) Không cần sử dụng Eclipse để giải quyết vấn đề này. 3.) Xem câu trả lời của tôi ở đây.
Elmue

Elmue, 1) cảm ơn vì đã đồng ý :-). 2) Tôi đồng ý. Phần đầu tiên của câu trả lời là làm thế nào bạn có thể sửa lỗi này sửa đổi nền tảng txt để nó hoạt động trong Arduino IDE. Câu trả lời của bạn chi tiết hơn về cách khắc phục điều này. Không cần phải có nhật thực hoặc bất kỳ IDE nào tốt hơn cho điều đó. Giải pháp ide tốt hơn được đề cập vì ide Arduino cần phân tích các bảng.txt để có thể có thông tin này ở đâu đó và có khả năng hoạt động mà không cần sửa đổi platform.txt. Khi tôi biết rất rõ về plugin nhật thực arduino, tôi đưa ra một ví dụ về cách làm điều này với công cụ này. 3) Xem bản chỉnh sửa của tôi
jantje

Eclise cũng làm việc với Teensy? Những lợi thế khác có Exclipse?
Elmue

Có, teeny được hỗ trợ bởi plugin nhật thực arduino nhưng bạn sẽ phải sửa đổi platform.txt (nên được sửa trong youthyduino 1.28)
jantje

0

Tên chính xác trong menu đến từ tệp bảng.txt trong Arduino IDE của bạn (Arduino \ phần cứng \ arduino \ avr \ bảng.txt). Tôi nghĩ rằng bạn sẽ phải phân tích tệp một mình và tìm bảng được phát hiện ở đó.


Phân tích tệp ?? Và làm thế nào để tôi biết cái nào là selecetd trong menu?
Elmue

0

Tôi đã hỏi một câu hỏi liên quan một lúc trước.

Một tệp * .h bên trong tồn tại được tạo bởi IDE và chứa trong đó loại bảng đã được chọn. Danh sách các tùy chọn có thể được đưa ra trong câu hỏi được liên kết, nhưng chỉ dành cho các bảng AVR. Tôi tin rằng danh sách không phải là ngắn hơn nhiều.

Nó chỉ đơn giản là vấn đề thêm một số tuyên bố có điều kiện để gửi cho PC thông tin chính xác. Một ví dụ đơn giản:

//...within your code, perhaps during setup()...
#ifdef ARDUINO_AVR_UNO
    serial.println("UNO");
#endif
#ifdef ARDUINO_AVR_LEONARDO
    serial.println("LEONARDO");
#endif
// etc...

Nếu bạn cần tham khảo loại bảng nhiều lần trong bản phác thảo, hãy sử dụng định dạng sau:

//...BEFORE setup(), or otherwise in the global namespace...
#ifdef ARDUINO_AVR_UNO
    #define __BOARD_TYPE "UNO"
#endif
#ifdef ARDUINO_AVR_LEONARDO
    #define __BOARD_TYPE "LEONARDO"
#endif
// etc...

// within your code, wherever necessary:
serial.println(__BOARD_TYPE);

Cái sau gọn gàng hơn nhiều, ngay cả khi bạn chỉ cần __BOARD_TYPEmột lần, vì nó loại bỏ phần rườm rà #ifdefkhỏi các chức năng của bạn.

Tất nhiên, bạn sẽ phải viết một bảng cho mỗi bảng mà bạn mong muốn người dùng cuối của bạn có thể có, và bạn có thể sẽ cần phải cập nhật danh sách này khi các mô hình mới xuất hiện.


Cảm ơn câu trả lời của bạn. Nó giúp tôi rất nhiều. (Xem câu trả lời của tôi ở đây) Nhưng có một lỗi trong mã của bạn. Thay vì AVR_UNO, nó phải là ARDUINO_AVR_UNO.
Elmue

Bạn có thể muốn xóa dấu chấm phẩy ở cuối #defines của bạn; chúng không phải là câu lệnh C và không cần dấu phân cách; trong thực tế, các dấu phân cách sẽ được chèn vào nơi các macro được sử dụng, liên kết bên trong các parens của hàm println (). (Nếu dấu chấm phẩy bị xóa, bình luận này sẽ không có ý nghĩa với những người đọc sau này).
Zeph

0

Câu trả lời ban đầu đã hết hạn vì bảng mới đã được thêm vào. Bài kiểm tra cơ bản là chính xác, nhưng không rõ danh sách các bảng đến từ đâu.

Nếu bạn định vị boards.txttệp và xem qua nó (ví dụ: ~\Library\Arduino\hardware\arduino\avr\boards.txttrên máy Mac), mỗi bảng sẽ có một mục dọc theo dòng <BOARD>.build.board=<NAME>, vì vậy, ví dụ, MKR1000 sẽ có một dòng:

mkr1000.build.board=SAMD_MKR1000

Các #define tương ứng có thể được tạo ra bằng cách đặt trước các <NAME>bằng ARDUINO_như vậy trong ví dụ này, các mã sau đây sẽ báo lỗi cho một bảng MKR1000 ...

#if defined(ARDUINO_SAMD_MKR1000) #error


Câu trả lời này chỉ là bla bla. Tại sao bạn không chỉ cần đăng một danh sách đầy đủ của tất cả các bảng mới với tất cả các định nghĩa?
Elmue
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.