Несколько TFT не отображаются

Я пытаюсь подключить около 5 TFT к моему Arduino Uno, и мне удалось подключить два из них без каких-либо проблем. Однако после загрузки кода они перестали работать. Затем я извлек весь код и протестировал каждый по отдельности, и они все еще работают. Однако вместе только один из них отображает данные. Я использую TFT ST7789v2, найденный здесь. https://www.waveshare.com/wiki/1.69inch_LCD_Module#Hardware_Connection_3

Я подключил их по схеме со словами «все»; контакты являются общими, за исключением контакта CS. У каждого дисплея свой.

Код выглядит следующим образом;

#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>

#define TFT_CS1 10
#define TFT_CS2 3

#define TFT_RST        8 // Общие экраны
#define TFT_DC         7 // Общие экраны
#define TFT_BACKLIGHT  9 // Подсветка для всех экранов

Adafruit_ST7789 tftHour1 = Adafruit_ST7789(TFT_CS1, TFT_DC, TFT_RST);
Adafruit_ST7789 tftHour2 = Adafruit_ST7789(TFT_CS2, TFT_DC, TFT_RST);

Adafruit_ST7789 setupScreen (Adafruit_ST7789 tft){
  tft.init(240, 280);
  tft.fillScreen(ST77XX_BLACK);
  return tft;
}

void setup(void) {
  tftHour1 = setupScreen(tftHour1);
  tftHour2 = setupScreen(tftHour2);
}

void loop(){
  tftHour1.print("1");
  tftHour2.print("2");
}

Когда это выполняется, на дисплее 2 отображаются выходные данные, а на дисплее 1 — нет. Как ни странно, если я возьму CS с дисплея 1 и вставлю его в ту же строку на макете, что и CS2, а затем верну его в исходное положение, дисплеи 1 и 2, похоже, будут работать. Но только до следующего включения или загрузки.

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

Если я прокомментирую код tftHour2, то tftHour1 начнет отображать текст. Если я поменяю код настройки на ftfHour1 и tftHour2, то дисплей, который инициализируется последним, будет отображать текст, а другой останется пустым.

Как я уже сказал, у меня все это работало, а затем я просто загрузил изменение шрифта, и все перестало работать.

Любая помощь в этом вопросе очень ценится.

Должен отметить, что я программист и очень новичок в электронике, поэтому, пожалуйста, будьте проще.

#Обновление. Если у меня есть отдельные контакты RST, это работает. Но мне нужно 5 экранов, и в этом случае у меня кончатся контакты. Есть ли способ обойти это?

, 👍2

Обсуждение

ваш код противоречив... существует определение двух имен объектов tftHour1 и tftHour2, а затем вы добавляете имя объекта tft, @jsotola

так что это внутри функции, где я могу отправить ему tft-объект, инициализировать его и вернуться. Имя объекта внутри функции — tft. это для возможности повторного использования и сокращения количества кода и, следовательно, пространства, @griegs

Не по теме: ваша функция setupScreen() принимает в качестве аргумента Adafruit_ST7789, что идеально подходит для использования того же кода. Но, во-первых, почему функция должна возвращать этот аргумент? И во-вторых, почему вы перезаписываете существующие объекты в tftHour1 и tftHour2 сами собой?, @the busybee

Сначала я сделал это, потому что не был совсем уверен, считает ли Arduino IDE переданный контекст объекта локальным или нет. Однако не имеет значения, верну ли я объект и перезапишу глобальный или нет., @griegs

@thebusybee ему, вероятно, это нужно, потому что он передает его как копию оригинала, поэтому это не влияет на исходный объект без повторного копирования в него :D Подсказка: ему следует использовать передачу по ссылке (или указателю, но ссылка более проста ) void setupScreen (Adafruit_ST7789 & tft) { // теперь изменения в tft будут также изменять исходный объект, @KIIV


1 ответ


Лучший ответ:

1

Согласно спецификации, сигнал RST принимается без активной CS, поэтому при передаче этого сигнала все дисплеи сбрасываются, если вы инициализируете хотя бы один из них. Это объясняет поведение, которое вы наблюдаете.

Вы нашли решение: не используйте общий сигнал RST во всех экземплярах Adafruit_ST7789.


Теперь вы беспокоитесь о необходимом количестве контактов, и это действительно проблема.

Одним из возможных решений является использование декодера, который принимает n входных данных для активации 1 из 2n выходных данных, например:

schematic

Для управления 5 линиями RST вам понадобится всего 3 контакта. Используйте двоичное значение, чтобы выбрать один из неиспользуемых выходов для деактивации всех линий RST.

То же самое относится и к линиям CS.

Однако используемая библиотека не поддерживает такой тип управления. Поэтому боюсь, что вам стоит рассмотреть другую модель Arduino с большим количеством контактов.


В качестве обходного пути вы можете попробовать следующий вариант:

Назначьте один и тот же вывод Arduino всем экземплярам Adafruit_ST7789, как в первой попытке. Но не подключайте его к RST-входам дисплеев. Оставьте вывод Arduino неподключенным.

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

Или попробуйте подключить входы RST всех дисплеев к VCC, так как они могут нормально работать без явного аппаратного сброса.


В комментарии вы высказали идею использования мультиплексора.

Без каких-либо других изменений вам потребуются сигналы выбора в качестве дополнительных контактов к нескольким контактам CS, в вашем случае еще 3.

Вместо этого вы также можете поделиться сигналом CS таким же образом:

schematic

Очень важно использовать мультиплексоры, выводящие неактивный уровень, требуемый дисплеями, на невыбранные выходы!

Даже сейчас вам следует создать столько экземпляров Adafruit_ST7789, сколько у вас есть дисплеев, поскольку каждый экземпляр, скорее всего, хранит внутреннюю информацию, необходимую для его правильной работы. Но вы можете использовать одни и те же контакты для всех из них.

Прежде чем вызывать какой-либо метод экземпляра, переключите мультиплексоры на соответствующий дисплей.

Чтобы быть уверенным, что все данные переданы полностью, вам может потребоваться небольшая задержка после вызванного метода. Возможно, вызываемый метод уже блокируется до полной передачи всех данных. Вы можете попробовать прочитать исходный код библиотеки, чтобы узнать больше.

,

Назначение одного контакта. Я попробую это, потому что я могу просто сбрасывать их через определенные промежутки времени, когда меняется значение, например, когда меняется минута. Что, если я воспользуюсь мультиплексором? Могу ли я тогда подключить к нему RST и CS? Не знаю, как это может сработать, @griegs

@griegs Если код библиотеки не установит CS перед выполнением сброса, он у вас не сработает. И вопрос в том, смогут ли TTF обрабатывать CS во время RST. Возможно, попробуйте NOT_A_PIN (или как он называется) для RST, передаваемого в объекты tft, и самостоятельно на некоторое время переключите реальный вывод RST, прежде чем переходить к функциям инициализации TFT., @KIIV

@griegs Необходимо ли сбрасывать дисплей, прежде чем он сможет отображать новый контент? Я так не думаю, это было бы довольно странно. -- Что касается идеи мультиплексора, я расширю свой ответ., @the busybee

@griegs добавьте пару вентилей, чтобы RST мог быть подтвержден только тогда, когда подтвержден CS ... таким образом вам понадобится только один вывод для управления линией RST, @jsotola

@thebusybee, я почти уверен, что экран не требует перезагрузки для отображения нового контента. Я «мог» выполнить сброс один раз в день и просто затемнить область, в которую хочу написать, перед любой записью. Затем в 2 часа ночи сделайте сброс, чтобы очистить кеш., @griegs