Jak mogę wykryć, która płyta Arduino (lub który kontroler) w oprogramowaniu?

14

Mam projekt, w którym chcę pracować nad Uno lub Mega (lub nawet Due) i byłoby miło, gdybym nie potrzebował dwóch wersji oprogramowania. Na przykład w Mega, aby użyć SoftwareSerial, musisz użyć innych pinów niż te w Uno. Zobacz dokumentację dotyczącą oprogramowania Serial . W każdym razie miło byłoby wykryć, że używam Uno, więc mogę po prostu użyć pinów 4 i 5 dla TX / RX, a jeśli używam Mega, oprogramowanie wykryje i po prostu użyje pinów 10 i 11 (i oczywiście będę musiał to podłączyć inaczej, ale przynajmniej oprogramowanie będzie takie samo).

Tooshel
źródło

Odpowiedzi:

16

Czas pracy

Według mojej wiedzy nie można wykryć typu płytki, ale można odczytać identyfikator urządzenia ATmega. Sprawdź to pytanie, w jaki sposób można to zrobić: czy podpis urządzenia ATmega lub ATtiny można odczytać podczas działania? Zauważ, że podczas korzystania z tej metody zmieni się kilka przypisań rejestrów, a nie tylko pinout. Dlatego twój kod może stać się znacznie bardziej złożony. Zaletą jest to, że jeśli uda ci się obejść wszystkie zmieniające się przypisania rejestrów i inne zależności sprzętowe, możesz użyć jednego pliku .hex do bezpośredniego zaprogramowania urządzeń avrdude.

Czas kompilacji

Innym sposobem ustalenia typu karty / kontrolera jest czas kompilacji. Zasadniczo kompilujesz części kodu lub ustawiasz makra w zależności od typu urządzenia skonfigurowanego w Arduino IDE. Sprawdź ten fragment kodu na przykład:

#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

Fragment kodu został bezwstydnie skopiowany z https://github.com/gillham/logic_analyzer/wiki Sprawdź ten kod, aby uzyskać nieco więcej sztuczek związanych z konkretnym urządzeniem.

W zależności od systemu operacyjnego hosta obsługiwane typy kontrolerów można znaleźć w następującym pliku:

  • Linux: /usr/lib/avr/include/avr/io.h
  • Windows: ...\Arduino\hardware\tools\avr\avr\include\avr\io.h

Korzystanie z preprocesora C (przez który obsługiwany jest powyższy kod) prawdopodobnie nie wchodzi w zakres tej witryny. http://stackoverflow.com byłoby lepszym miejscem na szczegółowe pytania.

Jeśli korzystasz z systemu Linux, możesz łatwo znaleźć wszystkie obsługiwane typy kontrolerów, wpisując:

grep 'defined (__AVR' /usr/lib/avr/include/avr/io.h | sed 's/^[^(]*(\([^)]*\))/\1/'
jippie
źródło
.. \ Arduino \ hardware \ tools \ avr \ avr \ include \ avr \ io.h dla Windows
mpflaga
@mpflaga Zaktualizowałem odpowiedź. Dziękujemy za wkład.
jippie
Wszystkie predefiniowane makra specyficzne dla AVR są wymienione w dokumentacji avr-libc .
Ignacio Vazquez-Abrams
Więc w jaki sposób Arduino IDE uzyskuje informacje o płycie? ( Tools > Get Board Info) Miałem nadzieję sprawdzić ciąg znaków z połączenia szeregowego, aby właściwy port COM mógł zostać automatycznie wybrany po uruchomieniu mojej aplikacji. Ponieważ oczywiście IDE może to zrobić, masz jakiś pomysł, jeśli użyją powyższych metod?
n00dles
@ n00dles Powyżej opisane metody różnią się od tego, co chcesz. Na Arduino.SE jest to prawdopodobnie warte własnego pytania. Nie mogę sprawdzić Get Board Info, nie ma go w dostępnej wersji Arduino.
jippie
6

Jak podano w specyfikacji sprzętowej Arduino , Arduino IDE definiuje teraz makro dla każdej płytki, zgodnie z definicją we build.boardwłaściwości boards.txt . Ta wartość jest dołączana do, ARDUINO_więc na przykład makra dla tablic, którymi jesteś zainteresowany, to:

  • ONZ: ARDUINO_AVR_UNO
  • Mega 2560: ARDUINO_AVR_MEGA2560
  • Z powodu: ARDUINO_SAM_DUE

Przykład wykorzystania makr w kodzie:

#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
na1234
źródło
Powiedziałbym, że jest to najprostsza i najprostsza odpowiedź na pytanie. Chciałbym, żeby to był przyjęty.
Erutan409
4

Łatwym sposobem na wąchanie tablicy jest użycie biblioteki takiej jak ArduinoManager. Dzięki temu możesz bardzo łatwo uzyskać nazwę płyty i funkcje https://github.com/backupbrain/ArduinoBoardManager

Wykorzystuje opisaną powyżej technikę, aby ujawnić wiele informacji o prawie każdej płycie Arduino, więc świetnie nadaje się do tworzenia projektów, które mogą zostać wdrożone w wielu różnych środowiskach.

Wystarczy pobrać i dołączyć do swojego projektu 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() {
}

Wynikowy wynik w Arduino Uno to:

Board is compatible with Arduino UNO

Speed/SRAM/Flash: 
16000000
2048
33554432

Proces tworzenia tej biblioteki (w tym przykładowego kodu) w celu ustalenia modelu i wersji płyty Arduino jest szczegółowo opisany na moim blogu.

Adonis Gaitatzis
źródło
Twoje Arduino Właściwe uznanie w ArduinoBoardManager.h może być niepoprawne, zobacz ten post .
Ulrich Stern
Proszę wskazać licencję w swoim projekcie.
arun
2

Do wszystkich płyt kompatybilnych z Arduio Due

#if defined (__arm__) && defined (__SAM3X8E__) // Arduino Due compatible
// your Arduino Due compatible code here
#endif

(Aby uzyskać więcej informacji, zobacz plik sam3.h. )

Jeśli chcesz po prostu wycelować w Arduino Due (pomijając kompatybilne płyty), możesz użyć

#if defined (_VARIANT_ARDUINO_DUE_X_)
// your Arduino Due code here
#endif

(Jest to zdefiniowane w pliku variant.h Arduino Due .)

Podziękowania dla Adama F. /programming//a/21058963/354144

nialsh
źródło
1

Ponieważ Arduino Due to inna rodzina procesorów (ARM) niż AVR, nie będziesz mógł używać tego samego pliku wykonywalnego dla wszystkich trzech. Ale możesz mieć ten sam kod źródłowy (zakładając, że składnia odczytu portu jest taka sama dla obu części AVR i ARM) i tylko dwa pliki wykonywalne (ponieważ ten sam będzie działał zarówno na Uno, jak i Mega bez ponownej kompilacji).

Możesz określić typ płytki w czasie wykonywania bez konieczności ponownej kompilacji, wybierając dwa cyfrowe piny, które nie są jeszcze używane przez program na żadnej z kart, i przypisz je jako wysokie lub niskie jako identyfikator karty. Na przykład jeśli wybrane piny to PC1 i PC3:

 PC1   PC3   Board ID
  0     0      Uno
  0     1      Mega
  1     0      Due
  1     1      spare

Następnie po prostu przeczytaj port po włączeniu zasilania i ustaw zmienną w swoim programie.

Innym schematem, który można zastosować, który wiąże tylko jeden pin, jest użycie analogowego pinu wejściowego i użycie dzielnika rezystora, wybierając rezystory tak, aby uzyskać różne napięcia, powiedzmy, co 0,25 V. Użyłem tej techniki, aby określić nie tylko typ planszy, ale także wersję planszy dla tej samej planszy (która w pewnym sensie jest nowym typem planszy).

tcrosley
źródło