NanoTerminal. Часть 3. OLED-дисплей на чипе SSD1306. Общее описание.

1306
Как и обещал, начинаю публиковать серию статей по работе с OLED-дисплеем на базе чипа SSD1306 разрешением 128 на 64 пикселя. Хотя практически всё нижеописанное будет относиться и к дисплеям с другим разрешением. Datasheet SSD1306 позволяет управлять через параллельный интерфейс 8080, последовательные интерфейсы I2C и SPI. Самыми дешевыми, простыми в освоении, хотя и наиболее тормозными являются версия c I2C-интерфейсом, но для использования в составе терминала — то, что нужно, если конечно мультики на экране не смотреть.

Как видно из картинки (которую я украл на просторах интернета), у рассматриваемого дисплея управление происходит по двум проводам — SDA (данные) и SCL (такт). Это самый распространенный вариант дисплея и самый демократичный — его цена около 170 рублей (2.5 — 3 $). Преимущества и недостатки кратко описаны в соответствующей табличке, но самый главный недостаток — очень хрупкое исполнение. Стекло дисплея неполностью прилегает к плате из стеклотекстолита, большой участок стекла — шириной более 5 мм (на фото —  нижняя прозрачная часть) просто «висит» в воздухе, что при малейшем надавливании приводит к излому. А излом приводит к разрыву внутренних проводников, что в свою очередь выводит из строя часть сегментов экрана.

Преимущества

Недостатки

— отличная контрастность
— невысокая цена за вариант 0.96 дюймов
— простота управления
— множество способов управления
— возможность управлять через I2C, то есть всего по двум проводам
-УЖАСНО хрупкая конструкция
-небольшие размеры, хотя иногда это можно отнести к преимуществам
-высокая цена за размеры отличные от 0.96 дюймов
-относительно невысокий FPS через I2C

Существуют модификации с одноцветными OLED-пикселями, например, белыми, голубыми, желтыми или даже зелеными. Также имеются двухцветные дисплеи, самый распространенный из который синий с желтой полоской, шириной 16 пикселей сверху.


Ну вот в целом и всё, что можно сказать о конструктиве дисплея. Самое время перейти к внутреннему устройству и основам управления. Основными составляющими SSD1306 являются:
— MCU Interface — блок взаимодействия SSD1306 с микроконтроллерами. Воспринимает команды по одному из четырех интерфейсов — параллельный, последовательные 4-wire SPI, 3-wire SPI, 2-wire I2C, транслируют их в единообразном формате в блок обработки команд — Command Decoder. Через MCU Interface также поступают данные, которые транслируются в блок памяти.
— GDDRAM — блок памяти графических данных дисплея (Graphic Display Data RAM). Собственно внутренний буфер SSD1306, в котором хранятся состояния каждого из пикселей дисплея. Путём записи данных в данный блок мы управляем картинкой на экране.
— Display Controller — блок управления экраном. Читает данные из GDDRAM и отображает эту информации на экране в режиме динамической индикации.
Есть и еще несколько блоков , полная картинка есть в datasheet‘e на странице №7.

Нас интересуют в основном два блока — GDDRAM и Command Decoder. Именно с ними происходит всё общение программиста. Причем неважно каким образом Вы направите данные в эти блоки — MCU Interface всё скушает и направит по правильному адресу. Соответственно для управления SSD1306 нужно всего лишь направлять нужные команды и нужные данные. Мы будем эти данные направлять через двухпроводной интерфейс I2C и для этого нужно две базовых функции — для данных (sendData) и для команд (sendCommand). Они практически ничем не отличаются, разница лишь в том, что перед отправкой данных мы шлем в шину I2C значение 0x40, а перед отправкой команды — 0x80, а MCU Interface распознает эти значения и решает куда направить следующий байт.  Иначе говоря, управление дисплеем сводится к отправке последовательностей двухбайтовых комбинаций по адресу SSD1306 равному 0x3C.

#include "Wire.h" 
#define SSD1306_Address               0x3C
#define SSD1306_Command_Mode          0x80
#define SSD1306_Data_Mode             0x40

void sendCommand(unsigned char command)
{
  Wire.beginTransmission(SSD1306_Address);
  Wire.write(SSD1306_Command_Mode);
  Wire.write(command);
  Wire.endTransmission();
}

void sendData(unsigned char Data)
{
     Wire.beginTransmission(SSD1306_Address);
     Wire.write(SSD1306_Data_Mode);
     Wire.write(Data);
     Wire.endTransmission();
}

На этом общая информация заканчивается. Далее мы рассмотрим инициализацию дисплея.

NanoTerminal. Автономный отладчик на Atmega 328 (Arduino). Часть 1.

miniterminal1
Очень часто для отлаживания программы загруженной в микроконтроллер используется последовательный интерфейс UART подключенный к реальному или виртуальному COM-порту компьютера. В частности, в Arduino IDE имеется простенький, но вполне рабочий инструмент — Монитор последовательного порта. Очень удобно отлавливая баг или просто наблюдая значение переменной написать строчку вроде Serial.println(variable); и в Монитор порта полетят цифры, буквы и прочая дребедень.

Это всё хорошо, когда мы отлаживаем изделие, которое просто лежит на столе и подключено к компьютеру. А как быть с автономными роботами, которых мёдом не корми — дай поездить, побегать, поплавать или полетать? Провода исключаются — робот ведь автономный, а значит любит свободу. Радиоканал, вроде Wi-Fi, bluetooth или что-то вроде — хорошо, но очень недалеко, а вообще желательно в пределах помещения. А самое главное надо специально переписывать программу под средства отладки по радиоканалу.

От всех этих недостатков свободен автономный терминал, представляющий собой связку микроконтроллера и дисплея. В сети лежит уже куча примеров реализации подобных устройств, бери да копируй. Но я не такой, я лёгких путей не ищу обычно, а потому решил самостоятельно разработать и реализовать NanoTerminal.
Несмотря на то, что статья датирована концом октября, данному проекту уже четыре месяца и он пережил уже три реинкарнации.

Первая версия была построена буквально за вечер, что называется «на коленках» на базе китайского клона ArduinoNano (отсюда и название NanoTerminal), с OLED-дисплеем на базе контроллера SSD1306. Всё это хозяйство было смонтировано на китайской макетной плате весьма поганого качества. Но тем не менее на этой первой версии я смог написать основной код программы.

Основные характеристики терминала на текущий момент (октябрь 2016):
1) Разрешение дисплея 128х64;
2) МК — Atmega328;
3) Расширенная память — 32 кбайта статического ОЗУ и 32 кбайта EEPROM;
4) Гибкая система меню;
5) Настраиваемая скорость приема/передачи;
6) Встроенный тестер сервоприводов;
7) Игра Тетрис;

Планируется:
1) Встроенный макроязык, аналогичный AT-командам, для управления функциями минитерминала, такими как: сохранение содержимого ОЗУ в EEPROM, чтение EEPROM, очистка памяти, включение/выключение дисплея и так далее.
2) Батарейное питание, выгрузка данных через USB на компьютер.

В серии статей об этом изделии я опишу работу с контроллером дисплея SSD1306, микросхемой EEPROM AT24C256 через интерфейс I2C, а также с микросхемой статической памяти 23К256 через интерфейс SPI.

Тестер сервоприводов своими руками

Тестер сервоприводов мне понадобился, когда я разрабатывал робота, играющего в Piano Tiles 2 на планшетном компьютере. Можно здесь глянуть на его работу. Механические «пальцы» данного робота приводятся в движения четырьмя сервоприводами. Сервопривод должен работать в узком диапазоне углов вращения (примерно 20-30 градусов) для того, чтобы движения «пальцев» точно синхронизировались с движением плиток по экрану планшета. Для точного подбора крайних значений («палец нажимает на плитку» и «палец поднят вверх»), можно было бы обойтись и подбором величин прямо в программе робота, но проще, быстрее и точнее сделать это с помощью тестера.

Для наглядности, я записал короткое видео с примером работы данного тестера.

Данный тестер состоит всего из трёх основных элементов — китайский Arduino Nano V3.0, переменный резистор, включенный по схеме потенциометра и цифровой 4-х значный дисплей, управляемый с помощью драйвера TM1637 по протоколу I2C. Всё это собрано на беспаечной макетной плате с помощью типовых проводников типа «папа-папа» (male-male).

Схема_1Для начала средний вывод потенциометра соединим с любым аналоговым входом Nano (в моем случае A0), крайние выводы потенциометра к земле (GND) и к питанию 5V. Таким образом у нас получится управляемый делитель напряжения, выдающий на среднем выводе потенциометра аналоговый сигнал от 0 до 5 Вольт, в зависимости от положения движка.

Далее, подключим модуль дисплея TM1637 к питанию, для этого нужно соединить выводы питания (5V и GND) c соответствующими выводами Arduino Nano. Управляющие лапки DIO и CLK можно цеплять на любые выводы Arduino Nano, так как будет использоваться библиотека, в которой протокол I2C реализован программно. В моем случае я соединил лапку DIO с пином D3, а CLK c пином D2.

Типовой разъем сервопривода состоит из трёх контактов, коричневый — земля (GND), красный — питание (5V) и желтый — управление (PWM). Соответственно подцепим контакты питания к одноименным контактам Arduino Nano, а желтый провод подключим к любому пину с ШИМ (PWM), в моем случае это D5. На данный пин будем выводить сигнал широтно-импульсной модуляции, управляющий сервоприводом. Угол поворота сервопривода определяется длительностью положительной части импульса и обычно лежит в пределах от 500 до 2500 микросекунд.

Теперь для проверки собранного Вами девайса, подключите Arduino Nano к компьютеру через разъем USB и прошейте простенькую программу, использующую библиотеки «Servo.h» и «TM1637.h».

#include <Servo.h>
#include "TM1637.h"

#define CLK 2 //Подключаем пины соответственно лапкам модуля
#define DIO 3
TM1637 tm1637(CLK,DIO);// создаем экземпляр класса TM1637
Servo S1; //объявляем экземпляр класса сервопривод
byte angle = 90;//переменная, которая будет хранить угол поворота сервы
byte old_angle = 91;//
int V = 0;
void setup()
{
  tm1637.init();//инициализируем дисплей, (хотя что мешало создателям библиотеки инициализировать его в конструкторе TM1637 tm1637(CLK,DIO);?)
  tm1637.set(BRIGHT_TYPICAL);//яркость дисплея
  pinMode(A0,INPUT);// объявляем пин А0 как вход, сюда будем подавать аналоговое напряжение с потенциометра
  pinMode(5,OUTPUT); 
  S1.attach (5); //прикручиваем серву к пину D5
}

void loop() {
V=analogRead(A0);//читаем напряжение с потенциометра
angle = map(V, 0, 1023, 0, 180);//преобразуем в угол
if (angle!=old_angle) // если потенциометр крутился, то...
  {
  tm1637.display(angle);// ... отображаем значение угла на дисплее
  S1.write(angle);// ... крутим сервопривод
  old_angle=angle;//... запоминаем последнее значение угла, чтобы в следующий раз не дергать серву и дисплей, если потенциометр не крутился
  }
}

Если после прошивки на экране отображается какое-либо число от 0 до 180, то значит всё собрано верно. Можно подключать сервопривод и тестировать его.

Стоимость данного тестера:
китайский клон Arduino Nano — от 120 до 200 рублей;
дисплей ТМ1637 — 85-150 рублей;
макетная плата — 100-300 рублей;
резистор — от 10 до 100 рублей;

ИТОГО: 315-715 рублей. А если учесть, что ничего не запаяно и если тестер не нужен, то его можно разобрать, то стоимость вообще падает до нуля. Обычно все эти компоненты уже имеются в арсенале любого микроконтроллерщика (ардуинщика).

Типовые роботы Лего и их микроконтроллерные аналоги. Часть 1 «Плюсы и минусы Lego Mindstrorms».

АВТОР: Чуйкин Александр. При перепечатке ссылка на сайт обязательна.

В настоящий момент конструкторы Lego серий Mindstorms EV3 и NXT стали стандартом де-факто в сфере обучения детей основам робототехники. Это произошло, в первую очередь, благодаря широкой маркетинговой поддержке фирмы Lego своего детища, ну и конечно благодаря несомненным его преимуществам. Конструкторы просты в освоении, снабжены отличными инструкциями и позволяют в очень короткие сроки увидеть результат своего труда.
Перечислим основные плюсы и минусы данных конструкторов:


ПЛЮСЫ

МИНУСЫ

сразу 17 конструкций!!! Эта игрушка займет ребенка надолго. В коробке лежит одна скромная инструкция, но зато на сайте Lego еще целых 16 разнообразных поделок.

подробные пошаговые инструкции по сборке — позволят быстро добиться желаемого результата, выглядят очень красиво и футуристично. Гениальные создатели, как самих поделок, так и инструкций по сборке, сделали всё чтобы ребенок чувствовал себя приобщенным к хайтеку, робототехнике и технологиям будущего

куча дополнений, датчиков, ресурсных наборов — существенно увеличивают количество роботов и прочий конструкций, которые можно собрать. Кроме того, каждый новый датчик знакомит ребенка с каким-либо физическим явлением (звуковыми волнами, инфракрасным излучением, температурой воздуха и т.д.). Роботы могут автономно принимать решения основываясь на показаниях того или иного датчика.

возможность обучения основам алгоритмического программирования — поможет развить логическое мышление и в целом приблизит ребенка к пониманию сути програмиирования.

легкость освоения — для большинства детей не составит проблем собрать любую конструкцию

поддержка со стороны производителя и пользователей — новые конструкции с подробнейшими инструкциями постоянно появляются и обновляются. Сторонние производители выпускают множество Lego-совместимых деталей и модулей.

широкая распространенность — найти в сети Интернет Lego-робота на любой вкус можно за минуту. А еще за пару минут пошаговую инструкцию по его изготовлению и (если надо) программированию.

самый большой минус — цена. Стоимость базового набора на начало лета 2016 составляет от 22000 до 31000 рублей. Зарядное устройство, цена которому 200 рублей в базарный день, продают за 2000 р.

ограниченный набор датчиков — в базовую комплектацию входит всего 2 датчика (датчик цвета, датчик касания). А в продвинутую версию Education еще 2 (гироскоп и ультразвуковой датчик расстояния). Это сильно ограничивает Вашу свободу творчества, так как собранный робот, будет иметь очень ограниченную автономность и по сути все собранные роботы будут отличаться только механикой. Но если Вы готовы выложить от 3000 рублей за каждый новый датчик, то тогда конечно ограничения снимаются. В общем, это тот же минус, что и предыдуший.

урезанные возможности программирования — программированием это можно назвать с большой натяжкой. Раскладка блоков на экране позволяет выполнять некоторые простые задачи, но только в рамках того функционала, что заложен в Lego производителем. Продвинутые пользователи конечно могут возразить, что для Lego созданы куча компиляторов разных языков, но разве тот, кто способен программировать на Си и Ассемблере станет всерьез заниматься Lego?

скромное количество портов ввода и вывода — к одному микрокомпьютеру Lego можно подключить всего 4 датчика и 4 исполнительных устройства (двигатели или сервомоторы, как правило). Хотите подключить больше? Будьте готовы заплатить еще 20000 рублей за еще один блок.

 

Подытоживая, можно сказать, что в Lego Mindstorms несомненно больше плюсов чем минусов. Назвать минусом невозможность полноценного программирования скорее всего нельзя. Производитель не ставил задачи создать инструмент для обучения программированию. Нельзя забывать, что Lego Mindstorms — это всё же игрушка. Применяемый алгоритмический способ программирования вполне подходит для решения определенного круга задач. И этого достаточно.
Главный минус один: цена. Функциональные аналоги роботов на Arduino или других микроконтроллерных платформах обходятся пользователю на порядки дешевле. В дальнейших статьях мы рассмотрим стандартных роботов Lego и их микроконтроллерные аналоги.