我有一个项目想要在Uno或Mega(甚至是Due)上工作,如果我不需要两个版本的软件,那就太好了。例如,在Mega上,要使用SoftwareSerial,必须使用与Uno上不同的引脚。请参阅有关软件序列号的文档。无论如何,最好检测到我正在使用Uno,所以我可以仅将针脚4和5用于TX / RX,如果我使用的是Mega,软件将检测并仅使用针脚10和11(以及当然,我必须以不同的方式进行连接,但至少软件是相同的)。
我有一个项目想要在Uno或Mega(甚至是Due)上工作,如果我不需要两个版本的软件,那就太好了。例如,在Mega上,要使用SoftwareSerial,必须使用与Uno上不同的引脚。请参阅有关软件序列号的文档。无论如何,最好检测到我正在使用Uno,所以我可以仅将针脚4和5用于TX / RX,如果我使用的是Mega,软件将检测并仅使用针脚10和11(以及当然,我必须以不同的方式进行连接,但至少软件是相同的)。
Answers:
据我所知,您无法检测到主板类型,但是可以读取ATmega设备ID。检查以下问题如何解决:在运行时可以读取ATmega或ATtiny设备签名吗?请注意,尽管使用此方法时,某些寄存器分配将发生变化,而不仅仅是引脚排列。因此,您的代码可能会变得更加复杂。优点是,如果您设法解决所有变化的寄存器分配和其他硬件相关性,则可以使用单个.hex文件直接从编程设备avrdude
。
确定板卡/控制器类型的另一种方法是在编译时。基本上,您可以根据Arduino IDE中配置的设备类型来编译部分代码或设置宏。查看以下代码片段以获取示例:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define DEBUG_CAPTURE_SIZE 7168
#define CAPTURE_SIZE 7168
#elif defined(__AVR_ATmega328P__)
#define DEBUG_CAPTURE_SIZE 1024
#define CAPTURE_SIZE 1024
#else
#define DEBUG_CAPTURE_SIZE 532
#define CAPTURE_SIZE 532
#endif
代码片段被无耻地复制自 https://github.com/gillham/logic_analyzer/wiki检查该代码是否有一些特定于设备的欺骗手段。
根据主机的操作系统,可以在以下文件中找到支持的控制器类型:
/usr/lib/avr/include/avr/io.h
...\Arduino\hardware\tools\avr\avr\include\avr\io.h
C预处理程序(用于处理上述代码)的使用可能超出此站点的范围。 http://stackoverflow.com将是解决详细问题的最佳选择。
如果您使用的是Linux,则可以通过键入以下内容轻松找到所有受支持的控制器类型:
grep 'defined (__AVR' /usr/lib/avr/include/avr/io.h | sed 's/^[^(]*(\([^)]*\))/\1/'
Tools > Get Board Info
)我希望通过串行连接进行字符串检查,因此可以在应用程序启动时自动选择正确的COM端口。因为很明显,IDE可以做到这一点,如果他们使用上述方法,您知道吗?
正如Arduino硬件规范中所述,Arduino IDE现在为boards.txt build.board
属性中定义的每个板定义了一个宏。该值将附加到该值ARDUINO_
,例如,您感兴趣的板的宏为:
ARDUINO_AVR_UNO
ARDUINO_AVR_MEGA2560
ARDUINO_SAM_DUE
如何在代码中使用这些宏的示例:
#if defined(ARDUINO_AVR_UNO)
//Uno specific code
#elif defined(ARDUINO_AVR_MEGA2560)
//Mega 2560 specific code
#elif defined(ARDUINO_SAM_DUE)
//Due specific code
#else
#error Unsupported hardware
#endif
进行板嗅探的一种简单方法是使用诸如ArduinoManager之类的库。有了这个,你可以很容易地获得板的名称和功能https://github.com/backupbrain/ArduinoBoardManager
它使用上述技术来揭示几乎每个Arduino板的大量信息,因此非常适合制作可能部署在许多不同环境中的项目。
只需下载并包含在您的Arduino项目中即可。
#include "ArduinoBoardManager.h"
ArduinoBoardManager arduino = ArduinoBoardManager(); // required if you want to know the board name and specific features
void setup() {
Serial.begin(9600);
Serial.print("Board is compatible with Arduino ");
Serial.println(arduino.BOARD_NAME);
Serial.println("Speed/SRAM/Flash: ");
Serial.print(ArduinoBoardManager::MAX_MHZ);
Serial.println(ArduinoBoardManager::SRAM_SIZE);
Serial.println(ArduinoBoardManager::FLASH_SIZE);
// Board features (multiple serial ports on Mega, for example)
if (arduino.featureExists(ArduinoBoardManager::FEATURE_MULTIPLE_SERIAL)) {
Serial.println("Your board supports multiple serial connections");
}
}
void loop() {
}
Arduino Uno上的结果输出为:
Board is compatible with Arduino UNO
Speed/SRAM/Flash:
16000000
2048
33554432
在我的博客上详细描述了使用该库(包括示例代码)来确定Arduino电路板型号和版本的过程。
适用于所有与Arduio Due兼容的主板
#if defined (__arm__) && defined (__SAM3X8E__) // Arduino Due compatible
// your Arduino Due compatible code here
#endif
(有关更多信息,请参见文件sam3.h。)
如果您只想针对Arduino Due(保留兼容板),可以使用
#if defined (_VARIANT_ARDUINO_DUE_X_)
// your Arduino Due code here
#endif
(这是在Arduino Due的variant.h文件中定义的。)
归功于Adam F /programming//a/21058963/354144
由于Arduino Due与AVR的处理器家族(ARM)不同,因此您将无法对这三个模块使用相同的可执行文件。但是你可以有相同的源代码(假设在AVR和ARM部件之间读取端口的语法相同),并且只有两个可执行文件(因为相同的文件可以在Uno和Mega上运行而无需重新编译)。
您可以在运行时确定电路板类型,而无需重新编译,方法是在任何一块电路板上选择程序尚未使用的两个数字引脚,并将其高低绑定为电路板ID。例如,如果您选择的引脚是PC1和PC3:
PC1 PC3 Board ID
0 0 Uno
0 1 Mega
1 0 Due
1 1 spare
然后,只需在加电时读取端口并在程序中设置一个变量即可。
可以使用的另一种方案仅连接一个引脚,即使用一个模拟输入引脚并使用一个电阻分压器,选择电阻器,以便获得不同的电压,例如0.25V的增量。我不仅使用该技术来指定板的类型,而且还指定同一板的板修订版(在某种意义上,这是新的板类型)。