Arduino:Примеры/shieldtest
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Перемещение картинки на TFT-дисплее (при помощи джойстика)[1]
Это скетч для библиотеки ST7735, который при помощи платы Arduino и джойстика позволяет двигать картинку на TFT-дисплее. Для скетча потребуется вот этот TFT-модуль, оснащенный джойстиком (он представляет собой небольшую черную кнопку) и TFT-дисплеем.
Код
/***************************************************
Перемещение картинки на TFT-дисплее (при помощи джойстика)
Этот скетч предназначен для использования
с 1,8-дюймовым TFT-модулем (с джойстиком):
----> http://www.adafruit.com/products/802
Руководства и схемы подключения ищите по ссылке выше.
Этим дисплеям для коммуникации требуется SPI-интерфейс
с 4 контактами. Кроме того, для джойстика потребуется еще
один контакт, и здесь для этого используется 3-ий аналоговый.
Adafruit инвестировала время и ресурсы, создавая эту библиотеку с
открытым кодом. Пожалуйста, поддержите Adafruit и оборудование с
открытым кодом, покупая продукты Adafruit!
Библиотека написана Лимор Фрид (Limor Fried, Ladyada) для Adafruit
Industries. Весь текст выше должен быть включен при любом повторном
распространении.
****************************************************/
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SD.h>
#include <SPI.h>
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
// Коммуникация будет вестись через аппаратный SPI-интерфейс,
// и им будут пользоваться сразу два устройства: TFT-дисплей
// и SD-карта. На платах Arduino аппаратный SPI всегда находится на
// одних и тех же контактах, и переназначить их нельзя.
// На Arduino Uno, Duemilanove и т.д. за SPI отвечают следующие
// контакты: 11-ый контакт – MOSI, 12-ый контакт – MISO,
// 13-ый контакт – SCK.
#define SD_CS 4 // CS-контакт для SD-карты
#define TFT_CS 10 // CS-контакт для TFT-дисплея
#define TFT_DC 8 // DC-контакт для дисплея (для переключения между передачей данных и команд)
#define TFT_RST -1 // RESET-контакт для TFT-дисплея (или подключите к +5V)
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
#define BUTTON_NONE 0
#define BUTTON_DOWN 1
#define BUTTON_RIGHT 2
#define BUTTON_SELECT 3
#define BUTTON_UP 4
#define BUTTON_LEFT 5
void setup(void) {
Serial.begin(9600);
// инициализируем 1,8-дюймовый TFT-дисплей:
tft.initR(INITR_BLACKTAB); // инициализируем чип ST7735S, черный ярлычок
Serial.println("OK!");
tft.fillScreen(ST7735_BLACK);
}
uint8_t readButton(void) {
float a = analogRead(3);
a *= 5.0;
a /= 1024.0;
Serial.print("Button read analog = "); // "Считываем данные с аналогового джойстика = ")
Serial.println(a);
if (a < 0.2) return BUTTON_DOWN;
if (a < 1.0) return BUTTON_RIGHT;
if (a < 1.5) return BUTTON_SELECT;
if (a < 2.0) return BUTTON_UP;
if (a < 3.2) return BUTTON_LEFT;
else return BUTTON_NONE;
}
uint8_t buttonhistory = 0;
void loop() {
uint8_t b = readButton();
tft.setTextSize(3);
if (b == BUTTON_DOWN) {
tft.setTextColor(ST7735_RED);
tft.setCursor(0, 10);
tft.print("Down "); // "Вниз "
buttonhistory |= 1;
}
if (b == BUTTON_LEFT) {
tft.setTextColor(ST7735_YELLOW);
tft.setCursor(0, 35);
tft.print("Left "); // "Влево "
buttonhistory |= 2;
}
if (b == BUTTON_UP) {
tft.setTextColor(ST7735_GREEN);
tft.setCursor(0, 60);
tft.print("Up"); // "Вверх "
buttonhistory |= 4;
}
if (b == BUTTON_RIGHT) {
tft.setTextColor(ST7735_BLUE);
tft.setCursor(0, 85);
tft.print("Right"); // "Вправо "
buttonhistory |= 8;
}
if ((b == BUTTON_SELECT) && (buttonhistory == 0xF)) {
tft.setTextColor(ST7735_MAGENTA);
tft.setCursor(0, 110);
tft.print("SELECT"); // "ВЫБОР"
buttonhistory |= 8;
delay(2000);
Serial.print("Initializing SD card..."); // "Инициализация SD-карты...")
if (!SD.begin(SD_CS)) {
Serial.println("failed!"); // "не удалась!")
return;
}
bmpDraw("parrot.bmp", 0, 0);
while (1);
}
delay(100);
}
// Эта функция открывает BMP-файл и печатает его на заданных
// координатах. Ее работу можно ускорить, считывая сразу несколько
// пикселей, а не пиксель за пикселем. Для этого нужно увеличить
// размер буфера, однако это, в свою очередь, потребует ресурсов
// RAM-памяти Arduino. Разумным компромиссом будет 20 пикселей.
#define BUFFPIXEL 20
void bmpDraw(char *filename, uint8_t x, uint8_t y) {
File bmpFile;
int bmpWidth, bmpHeight; // ширина и высота в пикселях
uint8_t bmpDepth; // глубина цвета (по умолчанию должно стоять 24)
uint32_t bmpImageoffset; // место, с которого в файле начинается само изображение
uint32_t rowSize; // это значение не всегда будет равно bmpWidth; возможно, будет отступ
uint8_t sdbuffer[3*BUFFPIXEL]; // буфер для пикселей (значения R, G и B для каждого пикселя)
uint8_t buffidx = sizeof(sdbuffer); // текущая позиция в буфере для пикселей
boolean goodBmp = false; // если скетч определит нужный тип заголовка, он выставит здесь «true»
boolean flip = true; // данные BMP-файла хранятся по принципу «снизу вверх»
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if((x >= tft.width()) || (y >= tft.height())) return;
Serial.println();
Serial.print("Loading image '"); // "Загрузка изображения «"
Serial.print(filename);
Serial.println('\'');
// открываем на SD-карте запрашиваемый файл:
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print("File not found"); // "Файл не найден"
return;
}
// анализируем заголовок BMP-Файла:
if(read16(bmpFile) == 0x4D42) { // сигнатура BMP-файла
Serial.print("File size: "); // "Размер файла: "
Serial.println(read32(bmpFile));
(void)read32(bmpFile); // считываем и игнорируем байты, вписанные при создании файла
bmpImageoffset = read32(bmpFile); // место, с которого начинается в файле само изображение (смещение)
Serial.print("Image Offset: "); // "Смещение изображения: "
Serial.println(bmpImageoffset, DEC);
// считываем заголовок DIB:
Serial.print("Header size: "); // "Размер заголовка: "
Serial.println(read32(bmpFile));
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) { // количество цветовых плоскостей – должно быть «1»
bmpDepth = read16(bmpFile); // биты на пиксель
Serial.print("Bit Depth: "); // "Глубина цвета: "
Serial.println(bmpDepth);
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // «0» – это без сжатия
goodBmp = true; // поддерживаемый формат BMP – продолжаем дальше!
Serial.print("Image size: "); // "Размер изображения: "
Serial.print(bmpWidth);
Serial.print('x');
Serial.println(bmpHeight);
// если нужно, границы BMP-изображения будут иметь 4-байтный отступ:
rowSize = (bmpWidth * 3 + 3) & ~3;
// Если значение в bmpHeight отрицательное, то данные
// изображения хранятся по принципу «сверху вниз»
// Это не канон, но иногда встречается.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// загружаем обрезанную область:
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h = tft.height() - y;
// задаем адресный промежуток для границ обрезанного изображения:
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row<h; row++) { // для каждого пиксельного ряда...
// Ищем начало пиксельного ряда. Возможно, делать это для
// каждой строки – слишком трудоемко, однако эта функция
// выполняет много «грязной работы» вроде обрезки
// изображения и создания отступа для нового пиксельного
// ряда. Кроме того, этот поиск имеет место только в том
// случае, если нужно поменять позицию файла (это позволяет
// избежать кластерных расчетов в библиотеке SD).
if(flip) // данные BMP-файла хранятся по принципу «снизу вверх» (нормальный BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
else // BMP-файл хранится по принципу «сверху вниз»
pos = bmpImageoffset + row * rowSize;
if(bmpFile.position() != pos) { // нужно ли запустить поиск?
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer); // перезагружаем буфер
}
for (col=0; col<w; col++) { // для каждого пикселя...
// настало время считывать новые пиксельные данные?
if (buffidx >= sizeof(sdbuffer)) { // да!
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0; // выставляем индекс на начало
}
// конвертируем пиксели из формата BMP в формат TFT,
// а затем выводим их на дисплей:
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.pushColor(tft.Color565(r,g,b));
} // последний пиксель
} // последняя строка пикселей
Serial.print("Loaded in "); // "Картинка загрузилась за "
Serial.print(millis() - startTime);
Serial.println(" ms"); // "миллисекунд"
} // конец goodBMP
}
}
bmpFile.close();
if(!goodBmp) Serial.println("BMP format not recognized."); // "Формат BMP не обнаружен"
}
// Эти функции считывают из BMP-файла 16-битные и 32-битные данные.
// Данные BMP-файла, как и у Arduino, хранятся по принципу
// «от младшего к старшему». При портировании куда-либо этот порядок,
// возможно, придется поменять.
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // самый младший бит
((uint8_t *)&result)[1] = f.read(); // самый старший бит
return result;
}
uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // самый младший бит
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // самый старший бит
return result;
}
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
Категории:
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Пример
- Примеры
- Пример программирования Arduino
- Примеры программирования Arduino