Есть такая штука, как "дисплей покупателя" - это тот самый экран на кассе, где пишут сколько денег вы должны заплатить.
И есть такое народное развлечение - делать из этих экранов всякое разное - ну например, "часы или метеостанцию" (с)

Фишка тут в том, что можно приобрести их б/у за копейки, и получить при этом винтажный газоразрядный экран, приятного зеленого или синего цвета.
Пусть алфавитно-цифровой - для часов этого более чем достаточно.

Поскольку сервер времени я себе уже сделал - дай-ка, думаю, и эту штуку попробую освоить, будут часы с синхронизацией по NTP.
А еще можно приспособить их для полезного дела - показывать температуру воды в котле, например - чтобы не бегать смотреть на основные экраны "умного дома", и не хвататься за телефон.

Итак, под руку попался Wincor Nixdorf BA64-2: 2 строки по 20 символов, газоразрядный, аккуратный черный корпус.

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

У моего экземпляра был кабель для RS232, но сразу же возник вопрос: а как конкретно его подключать?
Стандартный RS232 - разьем DB25 или DB9 со штырьками, "папа", соответственно - у кабеля должен быть парный ему, "мама" - но здесь наоборот, штырьки на кабеле.
И RJ45 тоже не то, чем кажется.
Где гарантия, что распиновка разьема хоть как-то соответствует стандартам, и что дисплей не сгорит с дымом, если подключить его как положено, а не к родной кассе?
О распиновке даташит молчал, как партизан. В интернете тоже ничего не нашлось по этой модели.

Конечно, кабель можно прозвонить тестером - но кто его знает, какой провод к чему относится, раз уж тут всё не по стандарту?
Пришлось лезть внутрь - и не зря.

Разбирается он неочевидно: сначала нужно открутить всего один винт сзади, а вот потом с помощью чего-то типа пластиковых карт и стальной линейки аккуратно отжать нижнюю рамку от экрана, и приподнять "стекло".
И только когда зацепы выскочат - можно будет его снять полностью.

Дальше просто - два винта держат плату, сверху на ней стеклянный индикатор, но нам нужна нижняя сторона.

Если внимательно посмотреть - видно, что 1 пин разьема (справа, металлический корпус, сверху вниз ) идет на какой-то элемент зеленого цвета, подозрительно напоминающий предохранитель (fuze), и 4 пин - на “землю”.
Вероятно, это питание: плюс и GND. Остальные - явно сигнальные.
Вспоминаем, что дисплей может работать от USB, то есть от 5В - поэтому подаем именно 5В (хотя вроде он и 12 выдержит, для RS232).

Случилось чудо: дисплей ожил, что-то показал, и погас.
Уже хорошо, питание работает, теперь нужно подключить передачу данных.
Осциллограф показал наличие разных постоянных напряжений на разных пинах:
2 - 0,
3 - +3,
5 - 0,
6 - -5,
7 - 0,
8 - +7.

Там, где -5 и +7 - похоже на сигналы RS232, а 2 и 3 похожи на напряжения USB в состоянии покоя.
Так и оказалось: если подключиться к 2 и 3 пинам к USB - дисплей определяется в системе:

Manufacturer: Wincor Nixdorf
hid-generic 0003:0AA7:0208.002B: hiddev97,hidraw4: USB HID v1.11 Device [Wincor Nixdorf BA64-2 Customer Display] on usb-5101000.usb-1.4.3/input1
...

и тому подобное.
В устройствах появляются несколько /dev/hidrawX, с которыми теоретически уже можно работать (но непонятно как именно).

Сигналы RS232 проверить было нечем, адаптера нет, а TTL serial с таким не работает.
Но вероятно, это всё-таки они, а молчащие 5 и 7 пины - RTS/CTS.

Таким образом, распиновка разьема RJ45:

1 - + 5 VCC
2 - 0 -Data USB (white)
3 - 3 +Data USB(green)
4 - GND
5 - 0 ?
6 - -5 rs232 ?
7 - 0 ?
8 - +7 rs232 ?

Уже лучше, но надо с этим как-то работать, и желательно не через подключение проводами к компьютеру.
Смотрим на плату внимательно, и видим там такую интересную микросхему:

Это - ADM3232E, конвертор уровней TTL-RS232.
Он занимается преобразованием TTL-serial (0-3В) в RS2 32-serial (-7/+7В), причем сам питается от 3.3В, которые умножает в два раза для формирования RS232.
Но важнее тут другое: он напрямую работает с TTL-serial контроллера дисплея! А значит, не нужны ни USB, ни RS232 - можно подключиться напрямую к данным, используя всё ту же ESP8266. То есть, приделать к дисплею Wifi-интерфейс.
Тогда из проводов остается только питание, например от обычной USB-зарядки.

Для этого сначала с помощью фена аккуратно сдуваем эту микросхему.

Освободились контактные площадки: 3.3В питание, GND, RX/TX.
Строго говоря, там два комплекта RX/TX, проверить какой именно отвечает на ввод-вывод - несложно ( не очень понятно зачем второй - ну да ладно).
Рабочие выводы здесь - R2out / T2in: out идет из конвертера на контроллер, и соответственно, in из контроллера на конвертер.

Схема подключения - простейшая, поэтому все делается с помощью проводков и скотча

А, ну не забыть сначала залить прошивку: для этого подключиться к RX/TX ESP8266 через компьютер, закоротить GPIO0 на землю, подать питание и прошить средствами Ардуино.

после прошивки освободить GPIO0.
И всегда оставлять для себя возможность перепрошивки по OTA.

Простейшая тестовая прошивка - принимает по MQTT строку байт и пишет ее в порт.
Единственно что - пришлось добавить небольшую задержку записи, дисплей не успевает за ESP, приходится писать побайтно:

...
bool outs = false;
void outString(char * buf, int length){
  if(outs) return;
  outs = true;
  for(int i=0; i< length; i++){
    Serial.write(buf[i]);
    delay(4);
  }
  outs = false;
}

...

void msg_callback(char* topic, byte* payload, unsigned int length){

  ...

  if(!strncmp((char *)payload, "test ", 5) && length > 5){
    outString((char*)&payload[6], length - 6);
  }
  
  ...

}

Отправка команд из консоли по MQTT (список команд есть в даташите на дисплей):

printf "\x1B[2J\x1B[1;0HHello world!" | mqtt-simple -h mosqit -p command/ba64

Что ж, всё работает.
Теперь добавляем, наконец, часы. Синхронизация - по NTP, с тем самым сервером точного времени:

#define CLEAR_SCREEN "\x1B[2J"
#define CLEAR_EOL "\x1B[0K"
#define UTF8_MODE "\x1B[1u"

time_t  olddtm = 0;
bool clock_mode = true;
char * wdays[] = { "Воскресение", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббот
а", "Воскресение"};

#include <RTClib.h>
....

void drawClock(){

  time_t dtm = time(nullptr);
  dtm += (3 * 3600);
  if(dtm != olddtm){

    DateTime now = DateTime(dtm);

    olddtm = dtm;

    char buf[21];

    int year = now.year();
    int month = now.month();
    int day = now.day();
    int wday = now.dayOfTheWeek();

    uint8_t h = now.hour();
    uint8_t m = now.minute();
    uint8_t s = now.second();

    sprintf(buf,"\x1B[1;%dH%02d.%02d.%04d  %02d:%02d:%02d", 0 ,day,month,year,h,m,s);
    outString(buf,strlen(buf));
    sprintf(buf,"\x1B[2;%dH%s\x1B[0K", 0 ,wdays[wday]);
    outString(buf,strlen(buf));

  }

}
...
#include <time.h>

void TimeSetup(){

  configTime(0, 0, "ntpserver.home");
  int cnt = 4;
  while (!time(nullptr) && cnt > 0) {
    delay(1000);
    cnt --;
  }

}


void setup(){

  Serial.begin(9600);

  WifiSetup();

  MqttSetup();

  TimeSetup();
  ...



  pinMode(IND,OUTPUT);
  digitalWrite(IND,HIGH);

  outString(CLEAR_SCREEN,strlen(CLEAR_SCREEN));
  outString(CLEAR_SCREEN,strlen(CLEAR_SCREEN));
  outString(UTF8_MODE,strlen(UTF8_MODE));

  olddtm = 0;

}

void loop() {

  WifiLoop();

  MqttLoop();

  ...

  drawClock();

  ...

  delay(100);

}

Но просто часы - это не особо интересно. Добавим возможность показа принятого по MQTT текста (уже почти есть) и автоматическое возвращение к показу часов через 60 секунд.

...
#define UTF8_MODE "\x1B[1u"
#define LINE1_0 "\x1B[1;0H"
#define LINE2_0 "\x1B[2;0H"

bool clock_mode = true;
#define INFO_PERIOD 60000
unsigned long info_timer = 0;

...

void msg_callback(char* topic, byte* payload, unsigned int length){

  if(!strncmp((char *)payload, "reset", length)){
    ESP.reset();
  }
  if(!strncmp((char *)payload, "clock", length)){
    clock_mode = true;
    olddtm = 0;
    outString(CLEAR_SCREEN,strlen(CLEAR_SCREEN));
  }
  if(!strncmp((char *)payload, "line1 ", 5) && length > 5){
    clock_mode = false;
    info_timer = millis();
    outString(LINE1_0,strlen(LINE1_0));
    outString((char*)&payload[6], length - 6);
    outString(CLEAR_EOL,strlen(CLEAR_EOL));
  }
  if(!strncmp((char *)payload, "line2 ", 5) && length > 5){
    clock_mode = false;
    info_timer = millis();
    outString(LINE2_0,strlen(LINE2_0));
    outString((char*)&payload[6], length - 6);
    outString(CLEAR_EOL,strlen(CLEAR_EOL));
  }
  
} 

void setup(){
  ...

  olddtm = 0;
  clock_mode = true;
  info_timer = 0;

}


void loop(){
  ...


  if(clock_mode){
    drawClock();
  }else{
    if(( millis() - info_timer ) > INFO_PERIOD){
      clock_mode = true;
      olddtm = 0;
      outString(CLEAR_SCREEN,strlen(CLEAR_SCREEN));
    }
  }
  
  ...
}

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

‘line1 котел 63.28/55.43\xC2\xB0C’ -> “котел 63.28/55.43°C”
'line2 ’ -> " "

Можно конечно было бы просто подписать сам дисплей на сообщения от датчика температуры - но по принятой у меня системе рассылкой информации занимаются скрипты на сервере. Вдруг потребуется выводить что-то еще и по-другому? Дисплей получается универсальный, и их может быть несколько.

А вот дальше я подумаю, что именно туда выводить, и где еще можно это использовать…
Да, это как раз было сделано из чисто академического интереса.