diff --git a/GyverCore/boards.txt b/GyverCore/boards.txt index edd73cf..eef1102 100644 --- a/GyverCore/boards.txt +++ b/GyverCore/boards.txt @@ -6,7 +6,7 @@ ## GyverCore on 328 based boards ## ################################### -nano.build.extra_flags={extra_flags.timer} {extra_flags.init} +nano.build.extra_flags={extra_flags.timer} {extra_flags.init} {extra_flags.uart} ## BOARD ## nano.name=ATmega328 based @@ -126,6 +126,14 @@ nano.menu.timers.yes_millis.extra_flags.timer= nano.menu.timers.no_millis=disable nano.menu.timers.no_millis.extra_flags.timer=-D_GYVERCORE_NOMILLIS +## Serial ## +menu.serial=Serial + +nano.menu.serial.default=default Serial +nano.menu.serial.default.extra_flags.uart= +nano.menu.serial.gyverUart=GyverUART +nano.menu.serial.gyverUart.extra_flags.uart=-D_GYVERCORE_GYVERUART + ## BOD ## menu.bod=B.O.D. diff --git a/GyverCore/cores/arduino/Arduino.h b/GyverCore/cores/arduino/Arduino.h index 326c514..3c1ea86 100644 --- a/GyverCore/cores/arduino/Arduino.h +++ b/GyverCore/cores/arduino/Arduino.h @@ -215,7 +215,10 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; #include "WString.h" #include "HardwareSerial.h" #include "uart.h" -//#include "USBAPI.h" + +#ifdef _GYVERCORE_GYVERUART +#define Serial uart +#endif uint16_t makeWord(uint16_t w); uint16_t makeWord(byte h, byte l); diff --git a/GyverCore/cores/arduino/HardwareSerial.h b/GyverCore/cores/arduino/HardwareSerial.h index 929edbb..c1c81d2 100644 --- a/GyverCore/cores/arduino/HardwareSerial.h +++ b/GyverCore/cores/arduino/HardwareSerial.h @@ -24,6 +24,8 @@ #ifndef HardwareSerial_h #define HardwareSerial_h +#ifndef _GYVERCORE_GYVERUART + #include #include "Stream.h" @@ -158,4 +160,5 @@ class HardwareSerial : public Stream extern void serialEventRun(void) __attribute__((weak)); +#endif #endif \ No newline at end of file diff --git a/GyverCore/cores/arduino/main.cpp b/GyverCore/cores/arduino/main.cpp index 208f850..995009d 100644 --- a/GyverCore/cores/arduino/main.cpp +++ b/GyverCore/cores/arduino/main.cpp @@ -1,16 +1,19 @@ /* Главный цикл программы */ #pragma message "Нас тут заперли, вызовите 911!" -#pragma message "GyverCore v1.8 inside. Enjoy" +#pragma message "GyverCore v1.8.2 inside. Enjoy" #include -int main(void) { + +int main(void) { #ifndef _GYVERCORE_NOINIT init(); // инициализация таймеров и ацп #endif setup(); // функция setup for(;;) { // бесконечный цикл loop(); // функция loop +#ifndef _GYVERCORE_GYVERUART if (serialEventRun) serialEventRun(); // обслуживание serial +#endif } return 0; } \ No newline at end of file diff --git a/GyverCore/cores/arduino/uart.cpp b/GyverCore/cores/arduino/uart.cpp index 3deca71..8100d85 100644 --- a/GyverCore/cores/arduino/uart.cpp +++ b/GyverCore/cores/arduino/uart.cpp @@ -1,13 +1,12 @@ #include "uart.h" -/* Реализация облегченного Serial от AlexGyver & Egor 'Nich1con' Zaharov*/ - #define UART_RX_BUFFER_SIZE 64 static volatile char _UART_RX_BUFFER[UART_RX_BUFFER_SIZE]; static volatile uint8_t _UART_RX_BUFFER_HEAD; static volatile uint8_t _UART_RX_BUFFER_TAIL; +uint32_t _UART_TIMEOUT = 100; -// ===== INIT ===== -void uartBegin(uint32_t baudrate){ +// =========================== INIT ======================== +void GyverUart::begin(uint32_t baudrate){ uint16_t speed = (F_CPU / (8L * baudrate)) - 1; UBRR0H = highByte(speed); UBRR0L = lowByte(speed); @@ -17,11 +16,11 @@ void uartBegin(uint32_t baudrate){ _UART_RX_BUFFER_HEAD = _UART_RX_BUFFER_TAIL = 0; } -void uartEnd(){ +void GyverUart::end(){ UCSR0B = 0; } -// ===== READ ===== +// =========================== READ ============================ ISR(USART_RX_vect) { if (bit_is_set(UCSR0A, UPE0)) UDR0; // Не сохранять новые данные если parity error else { @@ -35,42 +34,42 @@ ISR(USART_RX_vect) { } } -char uartRead() { +char GyverUart::read() { if (_UART_RX_BUFFER_HEAD == _UART_RX_BUFFER_TAIL) return -1; unsigned char c = _UART_RX_BUFFER[_UART_RX_BUFFER_TAIL]; _UART_RX_BUFFER_TAIL = (_UART_RX_BUFFER_TAIL + 1) % UART_RX_BUFFER_SIZE; return c; } -char uartPeek() { +char GyverUart::peek() { //return _UART_RX_BUFFER[0]; return _UART_RX_BUFFER_HEAD != _UART_RX_BUFFER_TAIL? _UART_RX_BUFFER[_UART_RX_BUFFER_TAIL]: -1; } -uint8_t uartAvailable() { +uint8_t GyverUart::available() { return ((unsigned int)(UART_RX_BUFFER_SIZE + _UART_RX_BUFFER_HEAD - _UART_RX_BUFFER_TAIL)) % UART_RX_BUFFER_SIZE; } -boolean uartAvailableForWrite() {return 1;} +boolean GyverUart::availableForWrite() {return 1;} -void uartClear() { +void GyverUart::clear() { _UART_RX_BUFFER_HEAD = _UART_RX_BUFFER_TAIL = 0; } -uint32_t _UART_TIMEOUT = 100; -void uartSetTimeout(int timeout) { + +void GyverUart::setTimeout(int timeout) { _UART_TIMEOUT = timeout; } -int32_t uartParseInt() { +int32_t GyverUart::parseInt() { uint32_t timeoutTime = millis(); uint32_t value = 0; boolean negative = false; while (millis() - timeoutTime < _UART_TIMEOUT) { - if (uartAvailable()) { + if (available()) { timeoutTime = millis(); - char newByte = uartRead(); + char newByte = read(); if (newByte == '-') negative = true; else { value += (newByte - '0'); @@ -82,35 +81,35 @@ int32_t uartParseInt() { return (!negative) ? value : -value; } -boolean uartParsePacket(int *intArray) { - if (uartAvailable()) { +boolean GyverUart::parsePacket(int *intArray) { + if (available()) { uint32_t timeoutTime = millis(); int value = 0; byte index = 0; boolean parseStart = 0; while (millis() - timeoutTime < 100) { - if (uartAvailable()) { + if (available()) { timeoutTime = millis(); - if (uartPeek() == '$') { + if (peek() == '$') { parseStart = true; - uartRead(); + read(); continue; } if (parseStart) { - if (uartPeek() == ' ') { + if (peek() == ' ') { intArray[index] = value / 10; value = 0; index++; - uartRead(); + read(); continue; } - if (uartPeek() == ';') { + if (peek() == ';') { intArray[index] = value / 10; - uartRead(); + read(); return true; } - value += uartRead() - '0'; + value += read() - '0'; value *= 10; } } @@ -119,7 +118,7 @@ boolean uartParsePacket(int *intArray) { return false; } -float uartParseFloat() { +float GyverUart::parseFloat() { uint32_t timeoutTime = millis(); float whole = 0.0; float fract = 0.0; @@ -128,9 +127,9 @@ float uartParseFloat() { byte fractSize = 0; while (millis() - timeoutTime < 100) { - if (uartAvailable()) { + if (available()) { timeoutTime = millis(); - char newByte = uartRead(); + char newByte = read(); if (newByte == '-') { negative = true; continue; @@ -155,53 +154,77 @@ float uartParseFloat() { return (!negative) ? whole : -whole; } -String uartReadString() { +String GyverUart::readString() { uint32_t timeoutTime = millis(); String buf = ""; while (millis() - timeoutTime < _UART_TIMEOUT) { - if (uartAvailable()) { + if (available()) { timeoutTime = millis(); - buf += uartRead(); + buf += read(); } } return buf; } -// ===== WRITE ===== +String GyverUart::readStringUntil(char terminator) { + uint32_t timeoutTime = millis(); + String buf = ""; + while (millis() - timeoutTime < _UART_TIMEOUT) { + if (available()) { + if (peek() == terminator) { + clear(); + return buf; + } + timeoutTime = millis(); + buf += read(); + } + } + return buf; +} -void uartWrite(byte data){ +// ====================== WRITE =========================== + +void GyverUart::write(byte data){ while (!(UCSR0A & (1<= 0; i--) { - uartWrite(bytes[i] + '0'); + write(bytes[i] + '0'); } } -void uartPrint(double data, byte decimals) { +void GyverUart::print(double data, byte decimals) { if (data < 0) { - uartWrite(45); + write(45); data = -data; } uint32_t integer = data; printBytes(integer); - uartWrite(46); // точка + write(46); // точка data -= integer; for (byte i = 0; i < decimals; i++) { data *= 10.0; - uartPrint((byte)data); + print((byte)data); data -= (byte)data; } } -void uartPrint(double data) { - uartPrint(data, 2); -} - -void uartPrintln(double data, byte decimals) { - uartPrint(data, decimals); - uartPrintln(); +void GyverUart::println(double data, byte decimals) { + print(data, decimals); + println(); } -void uartPrint(String data) { +void GyverUart::print(String data) { byte stringSize = data.length(); for (byte i = 0; i < stringSize; i++) { - uartWrite(data[i]); + write(data[i]); } } -void uartPrintln(String data) { - uartPrint(data); - uartPrintln(); +void GyverUart::println(String data) { + print(data); + println(); } -void uartPrint(char data[]) { +void GyverUart::print(char data[]) { byte i = 0; while (data[i] != '\0') { - uartWrite(data[i]); + write(data[i]); i++; } } -void uartPrintln(char data[]) { - uartPrint(data); - uartPrintln(); +void GyverUart::println(char data[]) { + print(data); + println(); } \ No newline at end of file diff --git a/GyverCore/cores/arduino/uart.h b/GyverCore/cores/arduino/uart.h index 3a6c91f..08dd3c4 100644 --- a/GyverCore/cores/arduino/uart.h +++ b/GyverCore/cores/arduino/uart.h @@ -1,9 +1,10 @@ -/* Облегченный Serial */ +/* Облегченный Serial от AlexGyver & Egor 'Nich1con' Zaharov */ // Версия 1.2 - добавлен циклический буфер // версия 1.3 - пофикшен вывод float, добавлен вывод с базисом +// Версия 1.4 - либа собрана в класс -#ifndef uart_h -#define uart_h +#ifndef GyverUART_h +#define GyverUART_h #include "Arduino.h" #include @@ -11,47 +12,57 @@ #define DEC 10 #define HEX 16 #define OCT 8 +#define BIN 2 -void uartBegin(uint32_t baudrate = 9600); -void uartEnd(); +class GyverUart { +public: + void begin(uint32_t baudrate = 9600); + void end(); -uint8_t uartAvailable(); -boolean uartAvailableForWrite(); -char uartRead(); -char uartPeek(); -void uartClear(); + uint8_t available(); + boolean availableForWrite(); + char read(); + char peek(); + void clear(); -void uartSetTimeout(int timeout); -int32_t uartParseInt(); -float uartParseFloat(); -String uartReadString(); -boolean uartParsePacket(int *intArray); + void setTimeout(int timeout); + int32_t parseInt(); + float parseFloat(); + String readString(); + String readStringUntil(char terminator); + boolean parsePacket(int *intArray); -void uartWrite(byte data); -void uartPrintln(void); + void write(byte data); + void println(void); -void uartPrint(int8_t data, byte base = DEC); -void uartPrint(uint8_t data, byte base = DEC); -void uartPrint(int16_t data, byte base = DEC); -void uartPrint(uint16_t data, byte base = DEC); -void uartPrint(int32_t data, byte base = DEC); -void uartPrint(uint32_t data, byte base = DEC); -void uartPrint(double data, byte decimals = 2); -void uartPrint(String data); -void uartPrint(char data[]); + void print(char data); + void print(int8_t data, byte base = DEC); + void print(uint8_t data, byte base = DEC); + void print(int16_t data, byte base = DEC); + void print(uint16_t data, byte base = DEC); + void print(int32_t data, byte base = DEC); + void print(uint32_t data, byte base = DEC); + void print(double data, byte decimals = 2); + void print(String data); + void print(char data[]); -void uartPrintln(int8_t data, byte base = DEC); -void uartPrintln(uint8_t data, byte base = DEC); -void uartPrintln(int16_t data, byte base = DEC); -void uartPrintln(uint16_t data, byte base = DEC); -void uartPrintln(int32_t data, byte base = DEC); -void uartPrintln(uint32_t data, byte base = DEC); -void uartPrintln(double data, byte decimals = 2); -void uartPrintln(String data); -void uartPrintln(char data[]); + void println(char data); + void println(int8_t data, byte base = DEC); + void println(uint8_t data, byte base = DEC); + void println(int16_t data, byte base = DEC); + void println(uint16_t data, byte base = DEC); + void println(int32_t data, byte base = DEC); + void println(uint32_t data, byte base = DEC); + void println(double data, byte decimals = 2); + void println(String data); + void println(char data[]); + +private: + void printHelper(int32_t data, byte base); + void printHelper(uint32_t data, byte base); + void printBytes(uint32_t data); +}; -void printHelper(int32_t data, byte base); -void printHelper(uint32_t data, byte base); -void printBytes(uint32_t data); +extern GyverUart uart; #endif \ No newline at end of file diff --git a/GyverCore/keywords.txt b/GyverCore/keywords.txt index 796c24e..6f2330c 100644 --- a/GyverCore/keywords.txt +++ b/GyverCore/keywords.txt @@ -5,7 +5,7 @@ ####################################### # Datatypes (KEYWORD1) ####################################### - +uart KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### diff --git a/README.md b/README.md index e691b43..2d9663c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![CORE_PHOTO](https://github.com/AlexGyver/GyverCore/blob/master/gyverCoreLogo.jpg) # GyverCore for ATmega328 - **Версия 1.8 от 08.09.2019** + **Версия 1.8.2 от 11.09.2019** Быстрое и лёгкое ядро для Arduino IDE с расширенной конфигурацией. Основано на оригинальном ядре Arduino версии 1.8.9, большинство функций заменены на более быстрые и лёгкие аналоги, убрано всё лишнее и не относящееся к микроконтроллеру ATmega328p, убран почти весь Wiring-мусор, код упрощён и причёсан. Добавлено несколько функций и интересных вариантов компиляции. Разработано by Александр **AlexGyver** и Egor 'Nich1con' Zaharov @@ -20,10 +20,10 @@ - Закрой окно - Выбери плату в **Инструменты > Плата > GyverCore > ATmega328/168 based** - Готово! -- *Примечание*: файлы ядра находятся по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.8\ +- *Примечание*: файлы ядра находятся по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.8.2\ ### Ручная -- Файлы из папки GyverCore в этом репозитории положить по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.8\ +- Файлы из папки GyverCore в этом репозитории положить по пути C:\Users\Username\AppData\Local\Arduino15\packages\GyverCore\hardware\avr\1.8.2\ ## Изменения ### Облегчено и ускорено @@ -58,7 +58,7 @@ analogReference | 0 | 22 | -22 attachInterrupt | 212 | 180 | 32 detachInterrupt | 198 | 150 | 48 tone | 1410 | 740 | 670 -Serial.begin | 1028 | 166 | 862 +Serial begin | 1028 | 166 | 862 print long | 1094 | 326 | 768 print string | 2100 | 1484 | 616 print float | 2021 | 446 | 1575 @@ -98,22 +98,23 @@ parseFloat | 1070 | 246 | 824 - **64**: 56.04 мкс (частота оцифровки 17 800 кГц) - **128**: 112 мкс (частота оцифровки 8 900 Гц) - В функции **analogRead(pin)** вместо пина можно указать **INTERNAL** (получить значение внутреннего опорного напряжения) или **THERMOMETR** (получить приблизительную температуру МК). *Примечание: нужно установить предделитель 128* -- Добавлен очень быстрый и лёгкий **UART** (аналог классу Serial) - - **uartBegin()** - запустить соединение по последовательному порту со скоростью 9600 - - **uartBegin(baudrate)** - запустить соединение по последовательному порту со скоростью baudrate - - **uartEnd()** - выключить сериал - - **uartPeek()** - вернуть крайний байт из буфера, не убирая его оттуда - - **uartClear()** - очистить буфер - - **uartRead()** - вернуть крайний байт из буфера, убрав его оттуда - - **uartWrite(val)** - запись в порт - - **uartPrint(val)** - печать в порт (числа, строки, char array) - - **uartPrintln(val)** - печать в порт с переводом строки - - **uartAvailable()** - возвразает true, если в буфере что-то есть - - **uartSetTimeout(val)** - установить таймаут для функций парсинга (по умолчанию 100 мс) - - **uartParseInt()** - принять целочисленное число - - **uartReadString()** - принять строку - - **uartParseFloat()** - принять число float - - **uartParsePacket(dataArray)** - принять пакет вида **$50 60 70;** в массив dataArray (смотри пример) +- Добавлен очень быстрый и лёгкий **uart** (аналог классу Serial) + - **uart.begin()** - запустить соединение по последовательному порту со скоростью 9600 + - **uart.begin(baudrate)** - запустить соединение по последовательному порту со скоростью baudrate + - **uart.end()** - выключить сериал + - **uart.peek()** - вернуть крайний байт из буфера, не убирая его оттуда + - **uart.clear()** - очистить буфер + - **uart.read()** - вернуть крайний байт из буфера, убрав его оттуда + - **uart.write(val)** - запись в порт + - **uart.print(val)** - печать в порт (числа, строки, char array) + - **uart.println(val)** - печать в порт с переводом строки + - **uart.available()** - возвразает true, если в буфере что-то есть + - **uart.setTimeout(val)** - установить таймаут для функций парсинга (по умолчанию 100 мс) + - **uart.parseInt()** - принять целочисленное число + - **uart.readString()** - принять строку + - **uart.readStringUntil()** - принять строку по терминатору + - **uart.parseFloat()** - принять число float + - **uart.parsePacket(dataArray)** - принять пакет вида **$50 60 70;** в массив dataArray (смотри пример) ### Убарно Убраны всякие сервисные файлы и прочий хлам, не относящийся к ATmega328 (wifi, USB), почищен код. Ядро полностью совместимо с остальными библиотеками, ничего из стандартных функций не вырезано. @@ -148,6 +149,11 @@ parseFloat | 1070 | 246 | 824 - **disable** - вектор прерываний OVF таймера 0 освобождён для пользователя, delay/delayMicroseconds работают, millis/micros - нет - Примечание: при отключенном таймере 0 функции delay и delayMicroseconds автоматически заменяются на _delay_ms и _delay_us из avr/util.h, а millis и micros заменены на 0 --- +**Serial** - работа с Serial: +- **default Serial** - при работе с **Serial** работает стандартная библиотека **Serial** +- **GyverUART** - все обращения к **Serial** в коде автоматически заменяются на **uart** из библиотеки GyverUART - код становится быстрее и легче! +- Примечание: в GyverUART нет функций find, findUntil, readBytes и readBytesUntil! +--- **B.O.D.** (Brown-out detector) - reset при падении напряжения **(требует перезаписи загрузчика)**: - **disable** - отключен - **1.8V** - сброс при напряжении питания ниже 1.7-2.0V @@ -226,4 +232,7 @@ parseFloat | 1070 | 246 | 824 - Всё протестировано на всех загрузчиках (спасибо Egor!) - 1.8.1 - Пофикшен вывод float в uart - - В uart добавлен вывод с базисом числа \ No newline at end of file + - В uart добавлен вывод с базисом числа +- 1.8.2 + - uart обёрнут в класс + - Добавлена возможность заменить вызовы Serial на uart (через меню выбора платы) \ No newline at end of file diff --git a/examples/advancedPWM/advancedPWM.ino b/examples/advancedPWM/advancedPWM.ino deleted file mode 100644 index 94a537a..0000000 --- a/examples/advancedPWM/advancedPWM.ino +++ /dev/null @@ -1,22 +0,0 @@ -void setup() { - setPWM_20kHz(5); // частота шим на D5 установлена на 20 кГц - // ШИМ на выходе D6 больше не рабоатет! - // функции времени (millis/delay) теперь работают некорректно - analogWrite(5, 30); // запустить ШИМ на D5 - - setPwmFreqnuency(3, PWM_31KHZ); // частота ШИМ на пинах 3 (и на 11) установлена на 31 кГц - analogWrite(3, 30); // запустить ШИМ на D3 - analogWrite(11, 200); // запустить ШИМ на D11 - - setPWM_20kHz(9); // частота шим на D9 (и автоматичсеки на D10) установлена на 20 кГц - // разрядность по умолчанию 8 бит (0-255) - - setPWM_9_10_resolution(PWM_10BIT); // ШИМ на пинах 9 и 10 теперь 10 битный (0-1023) - analogWrite(9, 512); // ШИМ на пине 9 с 50% заполнением - analogWrite(10, 700); // ШИМ на пине 9 с заполнением 700/1023 -} - -void loop() { - - -} diff --git a/examples/parseTest/parseTest.ino b/examples/parseTest/parseTest.ino index 9d5a8b1..4058a76 100644 --- a/examples/parseTest/parseTest.ino +++ b/examples/parseTest/parseTest.ino @@ -1,21 +1,16 @@ -// пример работы с функцией uartParsePacket -// функция принимает из порта строку вида -// $10 21 458 63 8 45 875 215; -// и запихивает в массив dataArray - int dataArray[8]; void setup() { - uartBegin(); // открыть на 9600 + uart.begin(); // открыть на 9600 } void loop() { // $10 21 458 63 8 45 875 215; - if (uartParsePacket((int*)dataArray)) { + if (uart.parsePacket((int*)dataArray)) { for (byte i = 0; i < 8; i++) { - uartPrint(dataArray[i]); - uartPrint(" "); + uart.print(dataArray[i]); + uart.print(" "); } - uartPrintln(); + uart.println(); } } diff --git a/examples/printTest/printTest.ino b/examples/printTest/printTest.ino index 6be444b..4fed509 100644 --- a/examples/printTest/printTest.ino +++ b/examples/printTest/printTest.ino @@ -1,5 +1,4 @@ -// тест вывода в порт разных типов данных - +char data0 = 'b'; int8_t data1 = -50; uint8_t data2 = 125; int16_t data3 = -2000; @@ -16,20 +15,26 @@ const char *data10[] = { "CHEBUREK", }; +byte data11 = 0b11101011; +uint32_t data12 = 0xFAB666; + void setup() { - uartBegin(); - uartPrintln(data1); - uartPrintln(data2); - uartPrintln(data3); - uartPrintln(data4); - uartPrintln(data5); - uartPrintln(data6); - uartPrintln(data7); - uartPrintln(data8, 3); - uartPrintln(data9); - uartPrintln("KEK KEK"); - uartPrintln(F("KEK KEK MACRO")); - uartPrintln(data10[2]); + uart.begin(); + uart.println(data0); + uart.println(data1); + uart.println(data2); + uart.println(data3); + uart.println(data4); + uart.println(data5); + uart.println(data6); + uart.println(data7); + uart.println(data8, 3); + uart.println(data9); + uart.println("KEK KEK"); + uart.println(F("KEK KEK MACRO")); + uart.println(data10[2]); + uart.println(data11, BIN); + uart.println(data12, HEX); } void loop() { diff --git a/package_GyverCore_index.json b/package_GyverCore_index.json index df01698..7ad9e43 100644 --- a/package_GyverCore_index.json +++ b/package_GyverCore_index.json @@ -204,6 +204,20 @@ {"name": "ATmega328 based boards"} ], "toolsDependencies": [] + }, + { + "name": "GyverCore", + "architecture": "avr", + "version": "1.8.2", + "category": "Contributed", + "url": "https://github.com/AlexGyver/GyverCore/releases/download/GyverCore-1.8.2/GyverCore.zip", + "archiveFileName": "GyverCore.zip", + "checksum": "MD5:afaad60ea244aa24e7447f6eeabc684f", + "size": "115868", + "boards": [ + {"name": "ATmega328 based boards"} + ], + "toolsDependencies": [] } ], "tools": []