Arduino:Примеры/BigNums

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Использование текстовых областей [1]

Этот пример показывает, как при помощи библиотеки GLCD настроить плату Arduino таким образом, чтобы показать на GLCD-панели несколько текстовых областей. Всего демонстрируется четыре разных способа задать на экране текстовую область.

Код

/*
 * Использование текстовых областей
 *
 * Этот скетч демонстрирует, как использовать текстовые области, 
 * большие шрифты и форматирующую функцию Printf().
 *
 * Примечание: Printf() использует около 1,8 Кб программной памяти. 
 * Если печатать строки, то она может быть довольно ресурсоемкой, 
 * особенно по сравнению с более простыми функциями вроде Puts() и 
 * класса Print из языка Arduino.
 * Впрочем, если использовать много форматирующих строк и выдачу в 
 * шестнадцатеричных числах, Printf() можно сделать менее громоздкой.
 *
 * Чтобы сэкономить программную память, имеет смысл не использовать 
 * в одном скетче и Printf(), и класс Print.
 * 
 * Также имейте в виду, что когда Printf() использует форматирующие 
 * строки, это требует места в RAM-памяти (обычные строки копируются 
 * в RAM, где их можно модифицировать). То же самое касается и Puts().
 * Во избежание этого нужно объявить, чтобы строки сохранялись только 
 * в программной памяти AVR при помощи макроса PSTR. Впрочем, тогда 
 * придется использовать функции Print_P() и Puts_P(). 
 *
 * Пример:
 *
 * GLCD.Printf_P(PSTR("форматирующая строка"), arg1, arg2, ...);
 * Этот метод также можно использовать для простых строк:
 * GLCD.Printf_P(PSTR("Hello world"));
 * GLCD.Puts_P(PSTR("Hello world"));
 *
 * Моноширинные шрифты – это неполные шрифты. Заголовочные файлы с 
 * этими шрифтами содержат лишь следующие символы: '+', ',', '-', '.', 
 * '/', '0', '1', '2', '3', '4', '5', '6', '7', '9'. Таким образом,
 * символы вроде 'V', 'F', 'C' напечатать не получится.
 *
 * Это сделано намеренно – чтобы была возможность печатать большие 
 * цифры, не расходуя много места во flash-памяти. Этого должно быть 
 * достаточно, чтобы показывать вещи вроде часов или цифр для 
 * счетчиков, показателей напряжения, температуры и т.д.
 *
 * 2011-04-23 Создан Биллом Перри (Bill Perry)
 */

#include "glcd.h"

/*
 * Если вы подключили файл allFonts.h, то другие шрифты отдельно 
 * подключать не нужно.
 */
//#include "fonts/fixednums15x31.h"
//#include "fonts/fixednums8x16.h"
//#include "fonts/fixednums7x15.h"
//#include "fonts/SystemFont5x7.h"

#include "fonts/allFonts.h"

void setup() {
	GLCD.Init(NON_INVERTED);
}

/*
 * Определяем текстовые области.
 * Их можно определить и в блоке setup(), и в блоке loop().
 *
 * Примечание:
 * В объект GLCD встроена текстовая область на весь GLCD-дисплей.
 * Печатающие функции есть и для объекта GLCD, и для текстовых 
 * областей, заданных самим пользователем.
 */

gText t1; // зададим эту текстовую область в блоке loop()

#if DISPLAY_HEIGHT > 32
gText t2; // эту тоже

/*
 * Задаем текстовую область t3. Она начинается в центре дисплея, 
 * но по оси X прибавлен один пиксель. Размер области – 8 столбцов и
 * 1 ряд. В качестве шрифта используется системный шрифт.
 */
gText t3 = gText(GLCD.CenterX+1, GLCD.CenterY, 8, 1, SystemFont5x7);

gText t4; // зададим эту текстовую область в блоке loop()
#endif

void loop()
{
int hr, min, sec;
int counter = 0;;

	/*
	 * Разными способами создаем 4 текстовые области 
	 * (в демонстрационных целях). 
	 *
	 * Функция DefineArea() позволяет объявить текстовые области 
	 * несколькими способами:
	 * - при помощи заранее определенных областей;
	 * - x1, y1, столбцы, ряды;
	 * - от x1,y1 к x2,y2. 
	 *
	 */

	/*
	 * Задаем текстовую область t1 исходя из заранее определенной 
	 * области размером во весь дисплей.
	 */

	t1.DefineArea(textAreaTOP);
	t1.SelectFont(fixednums15x31);

#if DISPLAY_HEIGHT > 32
	/*
 	 * Задаем t2. Исходная точка середина левой стороны экрана. 
	 * Размер – 8 столбцов и 2 ряда.
	 */
	t2.DefineArea(0, GLCD.CenterY, 8, 2, fixednums7x15);

	/*
	 * В демонстрационных целях делаем цвет шрифта белым и очищаем 
	 * всю текстовую область, чтобы сделать ее видимой.
	 */
	t2.SetFontColor(WHITE); // задаем цвет шрифта 
	t2.ClearArea(); // очищаем всю текстовую область, чтобы видеть ее границы

	/*
 	 * Область t3 была задана в блоке setup().
	 */

	/*
	 * Задаем t4. Это текстовая область с 8 столбцами и 1 рядом. 
	 * Она начинается в середине экрана на высоте в 3/4 дисплея.
 	 */

	t4.DefineArea(GLCD.CenterX, GLCD.Height * 3/4, 8, 1, fixednums7x15);
#endif

	hr = 0;
	min = 0;
	sec = 0;
	while(1)
	{

#if DISPLAY_WIDTH > 127
		t1.CursorToXY(0,0); // Координаты (столбец, ряд) 
                               // относительно текстовой области
		/* 
		 * используем форматирующую строку, но находящуюся 
		 * во FLASH/(программной памяти), а не в RAM.
		 */ 
		t1.Printf_P(PSTR("%02d:%02d.%02d"), hr, min, sec);

#if DISPLAY_HEIGHT > 32
		t2.CursorTo(0,0); // Координаты (столбец, ряд) относительно 
                             // текстовой области
		t2.Printf("%02d:%02d.%02d", hr, min, sec);

		/*
		 * Поскольку размер области t3 – 8х1 (в символах), и мы 
		 * будем печатать ее очень часто, нет нужды очищать область 
		 * и указывать конкретную позицию. Новый текст будет 
		 * вытеснять собой старый текст.
		 */
		t3.Printf("%02d:%02d.%02d", hr, min, sec);

		/*
		 * Вы также можете пользоваться классом Print 
		 * из языка Arduino. Если использовать printIn(), 
		 * библиотека будет отсрочивать печать новой строки до 
		 * появления нового символа. Таким образом, если вы 
		 * используете однолинейную текстовую область, то при печати 
		 * нового символа она будет автоматически очищаться.
		 */

		/*
		 * Здесь создается такая же форматирующая строка, как и при 
		 * помощи функции printf(), но с использованием класса Print 
		 * из языка Arduino.
		 */
		if(hr < 9)
			t4.print(0);
		t4.print(hr);
		t4.print(":");
		if(min < 9)
			t4.print(0);
		t4.print(min);
		t4.print(".");
		if(sec < 9)
			t4.print(0);
		t4.println(sec);
#endif
		sec++; // не совсем секунды, но для демонстрационных целей – то, что нужно
		if(sec > 59)
		{
			sec = 0;
			min++;
			if(min>59)
			{
				min = 0;
				hr++;
				if(hr>11)
					hr = 0;
			}
		}
#else
		/*
		 * Печатаем простой счетчик с «0» (для маленьких дисплеев).
 		 */
		t1.CursorTo(0,0);
		t1.Printf("%04d", counter);
		counter++;
		delay(100);
#endif
	}
}

См.также

Внешние ссылки