Na drodze nauki każdego amatora elektroniki i programowania przychodzi czas na napisanie własnej biblioteki. Czynność ta może być spowodowana chęcią oczyszczenia kodu z niepotrzebnych funkcji oraz ułatwienia prac z nim lub chęcią podzielenia się swoim „dziełem” z innymi.
Najbardziej przydatne biblioteki to te, które ułatwiają współpracę Arduino z zewnętrznymi komponentami.
Zanim przystąpisz do pisania swojej biblioteki sprawdź czy już nie ma podobnej lub takiej samej.
Pisząc bibliotekę na Arduino możesz korzystać z klas oraz metod.
Ułatwia to bardzo proces tworzenia, ponieważ w późniejszym czasie osoba pisząca szkic będzie komunikować się z biblioteką przy użyciu metod publicznych a metody prywatne nie będą wykorzystywane, będą przechowywane wewnątrz biblioteki. Co uniemożliwi zmianę ich wartości z poziomu kodu Arduino. Jest to bardzo przydatna funkcja. Przekonasz się o tym pisząc swoją pierwszą bibliotekę.
Podstawowe kroki tworzenia biblioteki to
1. Określenie interfejsu programistycznego
2. Napisanie pliku nagłówkowego
3. Napisanie pliku implementacji
4. Napisanie pliku ze słowami kluczowymi
5. Stworzenie kilku przykładów.
Każda biblioteka to folder. Nazwa tego folderu powinna być taka sama jak nazwa klasy biblioteki. W folderze powinien znajdować się podfolder examples (przykłady) oraz plik keywords.txt czyli dokument tekstowy zawierający słowa kluczowe.
Określ interfejs programistyczny
Biblioteki mogą być obsługiwane przez użytkowników na dwa sposoby.
Biblioteki proste, w których wystarczy dodać bibliotekę do szkicu a następnie uzyskać dostęp do jej metod
1 2 3 |
#include <Narcoleptic.h> […] Narcoleptic.delay(500); |
W ten sposób używa się bibliotek przeznaczonych do tylko jednego urządzenia.
Jeżeli istnieje możliwość obsługi kilku urządzeń(na przykład biblioteka IR ma możliwość obsługi wielu typów pilotów) należy z niej korzystać w trochę inny sposób.
1 2 |
#include <SoftwareSerial.h> SoftwareSerial mySerial(10, 11); |
gdy póżniej chcesz skorzystać z portu szeregowego musisz użyć nazwy
1 2 |
mySerial.begin(9600); mySerial.println(„hello”); |
Utwórz plik nagłówkowy
Plik nagłówkowy jest to plik z rozszerzeniem .h w pliku tym definiujemy nazwy klas i metod w bibliotece
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
#ifndef Firmata_h #define Firmata_h #include "Boards.h" #define FIRMATA_PROTOCOL_MAJOR_VERSION 2 // for non-compatible changes #define FIRMATA_PROTOCOL_MINOR_VERSION 5 // for backwards compatible changes #define FIRMATA_PROTOCOL_BUGFIX_VERSION 1 // for bugfix releases #define FIRMATA_FIRMWARE_MAJOR_VERSION 2 #define FIRMATA_FIRMWARE_MINOR_VERSION 5 #define FIRMATA_FIRMWARE_BUGFIX_VERSION 2 #define FIRMATA_MAJOR_VERSION 2 // same as FIRMATA_PROTOCOL_MAJOR_VERSION #define FIRMATA_MINOR_VERSION 5 // same as FIRMATA_PROTOCOL_MINOR_VERSION #define FIRMATA_BUGFIX_VERSION 1 // same as FIRMATA_PROTOCOL_BUGFIX_VERSION #define MAX_DATA_BYTES 64 // max number of data bytes in incoming messages #ifdef SET_PIN_MODE #undef SET_PIN_MODE #endif // message command bytes (128-255/0x80-0xFF) #define DIGITAL_MESSAGE 0x90 // send data for a digital port (collection of 8 pins) #define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM) #define REPORT_ANALOG 0xC0 // enable analog input by pin # #define REPORT_DIGITAL 0xD0 // enable digital input by port pair // #define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc #define SET_DIGITAL_PIN_VALUE 0xF5 // set value of an individual digital pin // #define REPORT_VERSION 0xF9 // report protocol version #define SYSTEM_RESET 0xFF // reset from MIDI // #define START_SYSEX 0xF0 // start a MIDI Sysex message #define END_SYSEX 0xF7 // end a MIDI Sysex message // extended command set using sysex (0-127/0x00-0x7F) /* 0x00-0x0F reserved for user-defined commands */ #define SERIAL_MESSAGE 0x60 // communicate with serial devices, including other boards #define ENCODER_DATA 0x61 // reply with encoders current positions #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq #define STRING_DATA 0x71 // a string message with 14-bits per char #define STEPPER_DATA 0x72 // control a stepper motor #define ONEWIRE_DATA 0x73 // send an OneWire read/write/reset/select/skip/search request #define SHIFT_DATA 0x75 // a bitstream to/from a shift register #define I2C_REQUEST 0x76 // send an I2C read/write request #define I2C_REPLY 0x77 // a reply to an I2C read request #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value #define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins #define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution #define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers #define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info #define REPORT_FIRMWARE 0x79 // report name and version of the firmware #define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop #define SCHEDULER_DATA 0x7B // send a createtask/deletetask/addtotask/schedule/querytasks/querytask request to the scheduler #define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages #define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages // these are DEPRECATED to make the naming more consistent #define FIRMATA_STRING 0x71 // same as STRING_DATA #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL |
polecenie #ifndef chroni przed kilkukrotnym zaimportowaniem biblioteki
Kolejnym plikiem w bibliotece jest plik implementacyjny .cpp
W typ pliku implementujemy funkcje zdefiniowane w pliku nagłówkowym
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#include "Firmata.h" #include "HardwareSerial.h" extern "C" { #include <string.h> #include <stdlib.h> } void FirmataClass::sendValueAsTwo7bitBytes(int value) { FirmataStream->write(value & B01111111); // LSB FirmataStream->write(value >> 7 & B01111111); // MSB } void FirmataClass::startSysex(void) { FirmataStream->write(START_SYSEX); } void FirmataClass::endSysex(void) { FirmataStream->write(END_SYSEX); } FirmataClass::FirmataClass() { firmwareVersionCount = 0; firmwareVersionVector = 0; systemReset(); } void FirmataClass::begin(void) { begin(57600); } void FirmataClass::begin(long speed) { Serial.begin(speed); FirmataStream = &Serial; blinkVersion(); printVersion(); // send the protocol version printFirmwareVersion(); // send the firmware name and version } void FirmataClass::begin(Stream &s) { FirmataStream = &s; // do not call blinkVersion() here because some hardware such as the // Ethernet shield use pin 13 printVersion(); printFirmwareVersion(); } |
Plik ze słowami kluczowymi nie jest konieczny jednak jest bardzo przydatny.
Umożliwia on środowisku programistycznemy oznaczanie kolorem fragmentów kodu, które są słowami kluczowymi biblioteki
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
####################################### # Syntax Coloring Map For Firmata ####################################### ####################################### # Datatypes (KEYWORD1) ####################################### Firmata KEYWORD1 Firmata callbackFunction KEYWORD1 callbackFunction systemResetCallbackFunction KEYWORD1 systemResetCallbackFunction stringCallbackFunction KEYWORD1 stringCallbackFunction sysexCallbackFunction KEYWORD1 sysexCallbackFunction ####################################### # Methods and Functions (KEYWORD2) ####################################### begin KEYWORD2 printVersion KEYWORD2 blinkVersion KEYWORD2 printFirmwareVersion KEYWORD2 setFirmwareVersion KEYWORD2 setFirmwareNameAndVersion KEYWORD2 available KEYWORD2 processInput KEYWORD2 isParsingMessage KEYWORD2 parse KEYWORD2 sendAnalog KEYWORD2 sendDigital KEYWORD2 sendDigitalPort KEYWORD2 sendString KEYWORD2 sendSysex KEYWORD2 getPinMode KEYWORD2 setPinMode KEYWORD2 getPinState KEYWORD2 setPinState KEYWORD2 attach KEYWORD2 detach KEYWORD2 write KEYWORD2 sendValueAsTwo7bitBytes KEYWORD2 startSysex KEYWORD2 endSysex KEYWORD2 writePort KEYWORD2 readPort KEYWORD2 disableBlinkVersion KEYWORD2 ####################################### # Constants (LITERAL1) ####################################### FIRMATA_MAJOR_VERSION LITERAL1 FIRMATA_MINOR_VERSION LITERAL1 FIRMATA_BUGFIX_VERSION LITERAL1 MAX_DATA_BYTES LITERAL1 DIGITAL_MESSAGE LITERAL1 ANALOG_MESSAGE LITERAL1 REPORT_ANALOG LITERAL1 REPORT_DIGITAL LITERAL1 REPORT_VERSION LITERAL1 SET_PIN_MODE LITERAL1 SET_DIGITAL_PIN_VALUE LITERAL1 SYSTEM_RESET LITERAL1 START_SYSEX LITERAL1 END_SYSEX LITERAL1 REPORT_FIRMWARE LITERAL1 STRING_DATA LITERAL1 PIN_MODE_ANALOG LITERAL1 PIN_MODE_PWM LITERAL1 PIN_MODE_SERVO LITERAL1 PIN_MODE_SHIFT LITERAL1 PIN_MODE_I2C LITERAL1 PIN_MODE_ONEWIRE LITERAL1 PIN_MODE_STEPPER LITERAL1 PIN_MODE_ENCODER LITERAL1 PIN_MODE_SERIAL LITERAL1 PIN_MODE_PULLUP LITERAL1 PIN_MODE_IGNORE LITERAL1 TOTAL_PINS LITERAL1 TOTAL_ANALOG_PINS LITERAL1 TOTAL_DIGITAL_PINS LITERAL1 TOTAL_PIN_MODES LITERAL1 TOTAL_PORTS LITERAL1 ANALOG_PORT LITERAL1 MAX_SERVOS LITERAL1 |
Folder z przykładami także nie jest konieczny jednak jeżeli udostępnisz swoją bibliotekę w internecie może okazać się on bardzo przydatny dla osób korzystających z twojej biblioreki
Jeżeli chcesz udostępnić bibliotekę osobom z zewnątrz najlepiej dodaj jej do listy arduino lub udostępnij na serwisie GitHub/Google Code lub innym
Dzięki udostępnieniu biblioteki innym ludziom twoja biblioteka może zostać poprawiona oraz mogą zostać wyłapane błędy przez zewnętrznych użytkowników
Jeżeli stworzyłeś jakąś bibliotekę podziel się nią w komentarzu 😀