├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
├── parseTest
│ └── parseTest.ino
└── printTest
│ └── printTest.ino
├── keywords.txt
├── library.properties
└── src
├── GyverUART.cpp
└── GyverUART.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 AlexGyver
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GyverUART/releases/latest/download/GyverUART.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GyverUART)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GyverUART?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # GyverUART
10 | Лёгкая библиотека для работы с последовательным портом
11 | - Практически полный аналог Serial, но гораздо легче
12 |
13 | ### Совместимость
14 | ATmega328 и прочие из этого поколения
15 |
16 | ## Содержание
17 | - [Установка](#install)
18 | - [Инициализация](#init)
19 | - [Использование](#usage)
20 | - [Пример](#example)
21 | - [Версии](#versions)
22 | - [Баги и обратная связь](#feedback)
23 |
24 |
25 | ## Установка
26 | - Библиотеку можно найти по названию **GyverUART** и установить через менеджер библиотек в:
27 | - Arduino IDE
28 | - Arduino IDE v2
29 | - PlatformIO
30 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverUART/archive/refs/heads/main.zip) .zip архивом для ручной установки:
31 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
32 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
33 | - Распаковать и положить в *Документы/Arduino/libraries/*
34 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
35 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
36 | ### Обновление
37 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
38 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
39 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
40 |
41 |
42 |
43 | ## Инициализация
44 | Нет
45 |
46 |
47 | ## Использование
48 | Как у Serial
49 |
50 |
51 | ## Пример
52 | Остальные примеры смотри в **examples**!
53 | ```cpp
54 | #include
55 |
56 | char data0 = 'b';
57 | int8_t data1 = -50;
58 | uint8_t data2 = 125;
59 | int16_t data3 = -2000;
60 | uint16_t data4 = 30000;
61 | int32_t data5 = -70000;
62 | uint32_t data6 = 4194967295;
63 | float data7 = 3681.65424;
64 | float data8 = -4375.12353;
65 | String data9 = "LOL LOL";
66 |
67 | const char *data10[] = {
68 | "LOL",
69 | "KEK",
70 | "CHEBUREK",
71 | };
72 |
73 | byte data11 = 0b11101011;
74 | uint32_t data12 = 0xFAB666;
75 |
76 | void setup() {
77 | uart.begin();
78 | uart.println(data0);
79 | uart.println(data1);
80 | uart.println(data2);
81 | uart.println(data3);
82 | uart.println(data4);
83 | uart.println(data5);
84 | uart.println(data6);
85 | uart.println(data7);
86 | uart.println(data8, 3);
87 | uart.println(data9);
88 | uart.println("KEK KEK");
89 | uart.println(F("KEK KEK MACRO"));
90 | uart.println(data10[2]);
91 | uart.println(data11, BIN);
92 | uart.println(data12, HEX);
93 | }
94 |
95 | void loop() {
96 | }
97 | ```
98 |
99 |
100 | ## Версии
101 | - v1.2 - добавлен циклический буфер
102 | - v1.3 - поправлен вывод float и добавлен вывод с базисом
103 | - v1.4 - либа собрана в класс, добавлена readStringUntil
104 | - v1.5 - добавлен буфер на отправку и flush
105 | - v1.6 - ускорена запись и чтение
106 | - v1.7 - чуть оптимизирован код
107 | - v1.8 - пофикшен write (спасибо eugenebartosh)
108 | - v1.9 - пофикшен write + оптимизация + поддержка USART0 atmega2560 (by Siliverst)
109 | - v1.10 - вывод переведён на Print.h. Размер стал чуть больше, но будет меньше при работе с другими либами на Print.h
110 |
111 |
112 | ## Баги и обратная связь
113 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
114 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
115 |
116 |
117 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
118 | - Версия библиотеки
119 | - Какой используется МК
120 | - Версия SDK (для ESP)
121 | - Версия Arduino IDE
122 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
123 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
124 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
125 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Gyveruart
4 | Light library for working with a sequential port
5 | - almost a complete analogue of Serial, but much easier
6 |
7 | ## compatibility
8 | Atmega328 and other from this generation
9 |
10 | ## Content
11 | - [installation] (# Install)
12 | - [initialization] (#init)
13 | - [use] (#usage)
14 | - [Example] (# Example)
15 | - [versions] (#varsions)
16 | - [bugs and feedback] (#fedback)
17 |
18 |
19 | ## Installation
20 | - The library can be found by the name ** gyveruart ** and installed through the library manager in:
21 | - Arduino ide
22 | - Arduino ide v2
23 | - Platformio
24 | - [download the library] (https://github.com/gyverlibs/gyvert/archive/refs/heads/main.zip). Zip archive for manual installation:
25 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
26 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
27 | - unpack and put in *documents/arduino/libraries/ *
28 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
29 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
30 | ### Update
31 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
32 | - through the IDE library manager: find the library how to install and click "update"
33 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
34 |
35 |
36 |
37 | ## initialization
38 | No
39 |
40 |
41 | ## Usage
42 | Like Serial
43 |
44 |
45 | ## Example
46 | The rest of the examples look at ** Examples **!
47 | `` `CPP
48 | #incLude
49 |
50 | char data0 = 'b';
51 | int8_t data1 = -50;
52 | Uint8_t Data2 = 125;
53 | Int16_t Data3 = -2000;
54 | Uint16_t Data4 = 30000;
55 | Int32_T DATA5 = -70000;
56 | Uint32_T DATA6 = 4194967295;
57 | Float Data7 = 3681.65424;
58 | Float Data8 = -4375.12353;
59 | String Data9 = "Lol Lol";
60 |
61 | const char *DATA10 [] = {{
62 | "Lol",
63 | "Kek",
64 | "Cheburek",
65 | };
66 |
67 | Byte data11 = 0b11101011;
68 | Uint32_T DATA12 = 0XFAB666;
69 |
70 | VOID setup () {
71 | uart.begin ();
72 | UART.PRINTLN (DATA0);
73 | urt.println (Data1);
74 | urt.println (Data2);
75 | UART.PRINTLN (DATA3);
76 | urt.println (Data4);
77 | urt.println (Data5);
78 | urt.println (Data6);
79 | urt.println (Data7);
80 | urt.println (Data8, 3);
81 | UART.PRINTLN (DATA9);
82 | urt.println ("Kek Kek");
83 | uart.println (F ("Kek Kek Macro"));
84 | urt.println (Data10 [2]);
85 | urt.println (Data11, Bin);
86 | urt.println (Data12, Hex);
87 | }
88 |
89 | VOID loop () {
90 | }
91 | `` `
92 |
93 |
94 | ## versions
95 | - V1.2 - Added cyclic buffer
96 | - V1.3 - The conclusion of Float is corrected and the conclusion with the basis has been added
97 | - V1.4 - Liba is assembled to class, added by ReadStringuntil
98 | - v1.5 - added a buffer for sending and Flush
99 | - V1.6 - Record and reading accelerated
100 | - V1.7 - The code is slightly optimized
101 | - V1.8 - Found Write (thanks to Eugenebartosh)
102 | - V1.9 - Found Write + Optimization + Support USART0 Atmega2560 (By Siliverst)
103 | - V1.10 - The conclusion was transferred to Print.h.The size has become a little larger, but it will be smaller when working with Dcranberries on Print.h
104 |
105 |
106 | ## bugs and feedback
107 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
108 | The library is open for refinement and your ** pull Request ** 'ow!
109 |
110 |
111 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
112 | - The version of the library
113 | - What is MK used
114 | - SDK version (for ESP)
115 | - version of Arduino ide
116 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
117 | - what code has been loaded, what work was expected from it and how it works in reality
118 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/parseTest/parseTest.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int dataArray[8];
4 |
5 | void setup() {
6 | uart.begin(); // открыть на 9600
7 | }
8 |
9 | void loop() {
10 | // $10 21 458 63 8 45 875 215;
11 | if (uart.parsePacket((int*)dataArray)) {
12 | for (byte i = 0; i < 8; i++) {
13 | uart.print(dataArray[i]);
14 | uart.print(" ");
15 | }
16 | uart.println();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/printTest/printTest.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | char data0 = 'b';
4 | int8_t data1 = -50;
5 | uint8_t data2 = 125;
6 | int16_t data3 = -2000;
7 | uint16_t data4 = 30000;
8 | int32_t data5 = -70000;
9 | uint32_t data6 = 4194967295;
10 | float data7 = 3681.65424;
11 | float data8 = -4375.12353;
12 | String data9 = "LOL LOL";
13 |
14 | const char *data10[] = {
15 | "LOL",
16 | "KEK",
17 | "CHEBUREK",
18 | };
19 |
20 | byte data11 = 0b11101011;
21 | uint32_t data12 = 0xFAB666;
22 |
23 | void setup() {
24 | uart.begin();
25 | uart.println(data0);
26 | uart.println(data1);
27 | uart.println(data2);
28 | uart.println(data3);
29 | uart.println(data4);
30 | uart.println(data5);
31 | uart.println(data6);
32 | uart.println(data7);
33 | uart.println(data8, 3);
34 | uart.println(data9);
35 | uart.println("KEK KEK");
36 | uart.println(F("KEK KEK MACRO"));
37 | uart.println(data10[2]);
38 | uart.println(data11, BIN);
39 | uart.println(data12, HEX);
40 | }
41 |
42 | void loop() {
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GyverUART
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 | GyverUART KEYWORD1
9 | uart KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 |
15 | begin KEYWORD2
16 | end KEYWORD2
17 | peek KEYWORD2
18 | flush KEYWORD2
19 | clear KEYWORD2
20 | read KEYWORD2
21 | write KEYWORD2
22 | print KEYWORD2
23 | println KEYWORD2
24 | available KEYWORD2
25 | setTimeout KEYWORD2
26 | parseInt KEYWORD2
27 | readString KEYWORD2
28 | parseFloat KEYWORD2
29 | parsePacket KEYWORD2
30 |
31 |
32 | #######################################
33 | # Constants (LITERAL1)
34 | #######################################
35 |
36 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverUART
2 | version=1.10.1
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Light and fast Serial library
6 | paragraph=Light and fast Serial library
7 | category=Communication
8 | url=https://github.com/GyverLibs/GyverUART
9 | architectures=avr
--------------------------------------------------------------------------------
/src/GyverUART.cpp:
--------------------------------------------------------------------------------
1 | #include "GyverUART.h"
2 |
3 | #define UART_RX_BUFFER_SIZE 64
4 | static volatile char _UART_RX_BUFFER[UART_RX_BUFFER_SIZE];
5 | static volatile uint8_t _UART_RX_BUFFER_HEAD;
6 | static volatile uint8_t _UART_RX_BUFFER_TAIL;
7 | uint32_t _UART_TIMEOUT = 100;
8 |
9 | #define UART_TX_BUFFER_SIZE 32
10 | static volatile char _UART_TX_BUFFER[UART_TX_BUFFER_SIZE];
11 | static volatile uint8_t _UART_TX_BUFFER_HEAD;
12 | static volatile uint8_t _UART_TX_BUFFER_TAIL;
13 |
14 | #if defined(__AVR_ATmega2560__)
15 | #define USARTx_RX_vect USART0_RX_vect
16 | #define USARTx_UDRE_vect USART0_UDRE_vect
17 | #else
18 | #define USARTx_RX_vect USART_RX_vect
19 | #define USARTx_UDRE_vect USART_UDRE_vect
20 | #endif
21 |
22 | // =========================== INIT ========================
23 | void GyverUart::begin(uint32_t baudrate) {
24 | uint16_t speed = (F_CPU / (8L * baudrate)) - 1;
25 | UBRR0H = highByte(speed);
26 | UBRR0L = lowByte(speed);
27 | UCSR0A = (1 << U2X0);
28 | UCSR0B = ((1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0));
29 | UCSR0C = ((1 << UCSZ01) | (1 << UCSZ00));
30 | _UART_RX_BUFFER_HEAD = _UART_RX_BUFFER_TAIL = 0;
31 | _UART_TX_BUFFER_HEAD = _UART_TX_BUFFER_TAIL = 0;
32 | }
33 |
34 | void GyverUart::end() {
35 | UCSR0B = 0;
36 | }
37 |
38 | // =========================== READ ============================
39 | ISR(USARTx_RX_vect) {
40 | uint8_t c, i;
41 | if (UCSR0A & (1 << UPE0)) {
42 | c = UDR0;
43 | } // Не сохранять новые данные если parity error
44 | else {
45 | c = UDR0;
46 | if (_UART_RX_BUFFER_HEAD + 1 == UART_RX_BUFFER_SIZE) {
47 | i = 0;
48 | } else {
49 | i = _UART_RX_BUFFER_HEAD + 1;
50 | }
51 | // Не сохранять новые данные если нет места
52 | if (i != _UART_RX_BUFFER_TAIL) {
53 | _UART_RX_BUFFER[_UART_RX_BUFFER_HEAD] = c;
54 | _UART_RX_BUFFER_HEAD = i;
55 | }
56 | }
57 | }
58 |
59 | char GyverUart::read() {
60 | if (_UART_RX_BUFFER_HEAD == _UART_RX_BUFFER_TAIL) {
61 | return -1;
62 | }
63 | uint8_t c = _UART_RX_BUFFER[_UART_RX_BUFFER_TAIL];
64 | if (++_UART_RX_BUFFER_TAIL >= UART_RX_BUFFER_SIZE) {
65 | _UART_RX_BUFFER_TAIL = 0;
66 | } // хвост двигаем
67 | return c;
68 | }
69 |
70 | char GyverUart::peek() {
71 | return _UART_RX_BUFFER_HEAD != _UART_RX_BUFFER_TAIL ? _UART_RX_BUFFER[_UART_RX_BUFFER_TAIL] : -1;
72 | }
73 |
74 | void GyverUart::flush() {
75 | while (_UART_TX_BUFFER_HEAD != _UART_TX_BUFFER_TAIL);
76 | }
77 |
78 | uint8_t GyverUart::available() {
79 | return ((uint16_t)(UART_RX_BUFFER_SIZE + _UART_RX_BUFFER_HEAD - _UART_RX_BUFFER_TAIL) % UART_RX_BUFFER_SIZE);
80 | }
81 |
82 | void GyverUart::clear() {
83 | _UART_RX_BUFFER_HEAD = _UART_RX_BUFFER_TAIL = 0;
84 | }
85 |
86 | void GyverUart::setTimeout(int timeout) {
87 | _UART_TIMEOUT = timeout;
88 | }
89 |
90 | int32_t GyverUart::parseInt() {
91 | uint32_t timeoutTime = millis();
92 | uint32_t value = 0;
93 | boolean negative = false;
94 |
95 | while (millis() - timeoutTime < _UART_TIMEOUT) {
96 | if (available()) {
97 | timeoutTime = millis();
98 | char newByte = read();
99 | if (newByte == '-') {
100 | negative = true;
101 | } else {
102 | value += (newByte - '0');
103 | value *= 10L;
104 | }
105 | }
106 | }
107 | value /= 10L;
108 | return (!negative) ? value : -value;
109 | }
110 |
111 | boolean GyverUart::parsePacket(int *intArray) {
112 | if (available()) {
113 | uint32_t timeoutTime = millis();
114 | int value = 0;
115 | byte index = 0;
116 | boolean parseStart = 0;
117 |
118 | while (millis() - timeoutTime < 100) {
119 | if (available()) {
120 | timeoutTime = millis();
121 | if (peek() == '$') {
122 | parseStart = true;
123 | read();
124 | continue;
125 | }
126 | if (parseStart) {
127 | if (peek() == ' ') {
128 | intArray[index] = value / 10;
129 | value = 0;
130 | index++;
131 | read();
132 | continue;
133 | }
134 | if (peek() == ';') {
135 | intArray[index] = value / 10;
136 | read();
137 | return true;
138 | }
139 | value += read() - '0';
140 | value *= 10;
141 | } else {
142 | clear();
143 | }
144 | }
145 | }
146 | }
147 | return false;
148 | }
149 |
150 | float GyverUart::parseFloat() {
151 | uint32_t timeoutTime = millis();
152 | float whole = 0.0;
153 | float fract = 0.0;
154 | boolean negative = false;
155 | boolean decimal = false;
156 | byte fractSize = 0;
157 |
158 | while (millis() - timeoutTime < 100) {
159 | if (available()) {
160 | timeoutTime = millis();
161 | char newByte = read();
162 | if (newByte == '-') {
163 | negative = true;
164 | continue;
165 | }
166 | if (newByte == '.') {
167 | decimal = true;
168 | continue;
169 | }
170 | if (!decimal) {
171 | whole += (newByte - '0');
172 | whole *= 10L;
173 | } else {
174 | fract += (newByte - '0');
175 | fract *= 10L;
176 | fractSize++;
177 | }
178 | }
179 | }
180 | whole /= 10L;
181 | for (byte i = 0; i <= fractSize; i++) {
182 | fract /= 10;
183 | }
184 | whole += fract;
185 | return (!negative) ? whole : -whole;
186 | }
187 |
188 | String GyverUart::readString() {
189 | uint32_t timeoutTime = millis();
190 | String buf = "";
191 | while (millis() - timeoutTime < _UART_TIMEOUT) {
192 | if (available()) {
193 | timeoutTime = millis();
194 | buf += read();
195 | }
196 | }
197 | return buf;
198 | }
199 |
200 | String GyverUart::readStringUntil(char terminator) {
201 | uint32_t timeoutTime = millis();
202 | String buf = "";
203 | while (millis() - timeoutTime < _UART_TIMEOUT) {
204 | if (available()) {
205 | if (peek() == terminator) {
206 | clear();
207 | return buf;
208 | }
209 | timeoutTime = millis();
210 | buf += read();
211 | }
212 | }
213 | return buf;
214 | }
215 |
216 | // ====================== WRITE ===========================
217 |
218 | /*
219 | // прямая запись без буфера
220 | void GyverUart::writeBuffer(byte data){
221 | while (!(UCSR0A & (1<= UART_TX_BUFFER_SIZE) {
246 | _UART_TX_BUFFER_TAIL = 0;
247 | } // хвост двигаем
248 | if (_UART_TX_BUFFER_HEAD == _UART_TX_BUFFER_TAIL) {
249 | UCSR0B &= ~(1 << UDRIE0);
250 | }
251 | }
252 |
253 | #ifdef USE_PRINT_H
254 | size_t GyverUart::write(uint8_t data) {
255 | writeBuffer(data);
256 | return 1;
257 | }
258 |
259 | #else
260 |
261 | boolean GyverUart::availableForWrite() { return 1; }
262 |
263 | void GyverUart::println(void) {
264 | writeBuffer('\r');
265 | writeBuffer('\n');
266 | }
267 |
268 | void GyverUart::print(char data) {
269 | writeBuffer(data);
270 | }
271 | void GyverUart::println(char data) {
272 | print(data);
273 | println();
274 | }
275 |
276 | void GyverUart::print(int8_t data, byte base) { printHelper((int32_t)data, base); }
277 | void GyverUart::print(uint8_t data, byte base) { printHelper((uint32_t)data, base); }
278 | void GyverUart::print(int16_t data, byte base) { printHelper((int32_t)data, base); }
279 | void GyverUart::print(uint16_t data, byte base) { printHelper((uint32_t)data, base); }
280 | void GyverUart::print(int32_t data, byte base) { printHelper((int32_t)data, base); }
281 | void GyverUart::print(uint32_t data, byte base) { printHelper((uint32_t)data, base); }
282 |
283 | void GyverUart::println(int8_t data, byte base) {
284 | printHelper((int32_t)data, base);
285 | println();
286 | }
287 | void GyverUart::println(uint8_t data, byte base) {
288 | printHelper((uint32_t)data, base);
289 | println();
290 | }
291 | void GyverUart::println(int16_t data, byte base) {
292 | printHelper((int32_t)data, base);
293 | println();
294 | }
295 | void GyverUart::println(uint16_t data, byte base) {
296 | printHelper((uint32_t)data, base);
297 | println();
298 | }
299 | void GyverUart::println(int32_t data, byte base) {
300 | printHelper((int32_t)data, base);
301 | println();
302 | }
303 | void GyverUart::println(uint32_t data, byte base) {
304 | printHelper((uint32_t)data, base);
305 | println();
306 | }
307 |
308 | void GyverUart::printHelper(int32_t data, byte base) {
309 | if (data < 0) {
310 | writeBuffer(45);
311 | data = -data;
312 | }
313 | printHelper((uint32_t)data, base);
314 | }
315 | void GyverUart::printHelper(uint32_t data, byte base) {
316 | if (base == 10) {
317 | printBytes(data);
318 | } else {
319 | char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
320 | char *str = &buf[sizeof(buf) - 1];
321 | *str = '\0';
322 | if (base < 2) base = 10;
323 | do {
324 | char c = data % base;
325 | data /= base;
326 | *--str = c < 10 ? c + '0' : c + 'A' - 10;
327 | } while (data);
328 | print(str);
329 | }
330 | }
331 |
332 | void GyverUart::printBytes(uint32_t data) {
333 | byte bytes[10];
334 | byte amount;
335 | for (byte i = 0; i < 10; i++) {
336 | bytes[i] = data % 10;
337 | data /= 10;
338 | if (data == 0) {
339 | amount = i;
340 | break;
341 | }
342 | }
343 | for (int8_t i = amount; i >= 0; i--) {
344 | writeBuffer(bytes[i] + '0');
345 | }
346 | }
347 |
348 | void GyverUart::print(double data, byte decimals) {
349 | if (data < 0) {
350 | writeBuffer(45);
351 | data = -data;
352 | }
353 | uint32_t integer = data;
354 | printBytes(integer);
355 | writeBuffer(46); // точка
356 | data -= integer;
357 | for (byte i = 0; i < decimals; i++) {
358 | data *= 10.0;
359 | print((byte)data);
360 | data -= (byte)data;
361 | }
362 | }
363 |
364 | void GyverUart::println(double data, byte decimals) {
365 | print(data, decimals);
366 | println();
367 | }
368 |
369 | void GyverUart::print(String data) {
370 | byte stringSize = data.length();
371 | for (byte i = 0; i < stringSize; i++) {
372 | print(data[i]);
373 | }
374 | }
375 | void GyverUart::println(String data) {
376 | print(data);
377 | println();
378 | }
379 |
380 | void GyverUart::print(const char data[]) {
381 | byte i = 0;
382 | while (data[i] != '\0') {
383 | print(data[i]);
384 | i++;
385 | }
386 | }
387 | void GyverUart::println(const char data[]) {
388 | print(data);
389 | println();
390 | }
391 | #endif
392 |
--------------------------------------------------------------------------------
/src/GyverUART.h:
--------------------------------------------------------------------------------
1 | /*
2 | Лёгкая библиотека для работы с последовательным портом
3 | Документация: https://alexgyver.ru/gyveruart/
4 | GitHub: https://github.com/GyverLibs/GyverUART
5 | Возможности:
6 | - Практически полный аналог Serial, но гораздо легче
7 | - Данная версия встроена в ядро GyverCore!
8 |
9 | AlexGyver & Egor 'Nich1con' Zaharov, alex@alexgyver.ru
10 | https://alexgyver.ru/
11 | MIT License
12 |
13 | Версии:
14 | v1.2 - добавлен циклический буфер
15 | v1.3 - поправлен вывод float и добавлен вывод с базисом
16 | v1.4 - либа собрана в класс, добавлена readStringUntil
17 | v1.5 - добавлен буфер на отправку и flush
18 | v1.6 - ускорена запись и чтение
19 | v1.7 - чуть оптимизирован код
20 | v1.8 - пофикшен write (спасибо eugenebartosh)
21 | v1.9 - пофикшен write + оптимизация + поддержка USART0 atmega2560 (by Siliverst)
22 | v1.10 - вывод переведён на Print.h. Размер стал чуть больше, но будет меньше при работе с другими либами на Print.h
23 | */
24 |
25 | #define USE_PRINT_H // закомментируй, чтобы использовать gyver-вывод
26 |
27 | #ifndef GyverUART_h
28 | #define GyverUART_h
29 | #include
30 |
31 | #include "Arduino.h"
32 |
33 | #ifdef USE_PRINT_H
34 | #include "Print.h"
35 | class GyverUart : public Print {
36 | #else
37 |
38 | #define DEC 10
39 | #define HEX 16
40 | #define OCT 8
41 | #define BIN 2
42 |
43 | class GyverUart {
44 | #endif
45 | public:
46 | void begin(uint32_t baudrate = 9600);
47 | void end();
48 |
49 | uint8_t available();
50 | char read();
51 | char peek();
52 | void clear();
53 | void flush();
54 |
55 | void setTimeout(int timeout);
56 | int32_t parseInt();
57 | float parseFloat();
58 | String readString();
59 | String readStringUntil(char terminator);
60 | boolean parsePacket(int *intArray);
61 |
62 | #ifdef USE_PRINT_H
63 | virtual size_t write(uint8_t);
64 | #else
65 | boolean availableForWrite();
66 | void write(byte data);
67 | void println();
68 |
69 | void print(char data);
70 | void print(int8_t data, byte base = DEC);
71 | void print(uint8_t data, byte base = DEC);
72 | void print(int16_t data, byte base = DEC);
73 | void print(uint16_t data, byte base = DEC);
74 | void print(int32_t data, byte base = DEC);
75 | void print(uint32_t data, byte base = DEC);
76 | void print(double data, byte decimals = 2);
77 | void print(String data);
78 | void print(const char data[]);
79 |
80 | void println(char data);
81 | void println(int8_t data, byte base = DEC);
82 | void println(uint8_t data, byte base = DEC);
83 | void println(int16_t data, byte base = DEC);
84 | void println(uint16_t data, byte base = DEC);
85 | void println(int32_t data, byte base = DEC);
86 | void println(uint32_t data, byte base = DEC);
87 | void println(double data, byte decimals = 2);
88 | void println(String data);
89 | void println(const char data[]);
90 | #endif
91 | private:
92 | void writeBuffer(byte data);
93 | #ifndef USE_PRINT_H
94 | void printHelper(int32_t data, byte base);
95 | void printHelper(uint32_t data, byte base);
96 | void printBytes(uint32_t data);
97 | #endif
98 | };
99 |
100 | extern GyverUart uart;
101 | #endif
--------------------------------------------------------------------------------