«Магический глаз» тёплых ламповых времён — эмуляция на ардуино
 
                    
                    
                В магнитофонах и приёмниках моей юности использовались исчезнувшие ныне ламповые индикаторы уровня на лампах 6E1П или 6Е5С. Сейчас пришла пора ностальгирования по «старым временам» и на алиэкспрессе или амазоне можно купить собранные индикаторы, они почти также популярны как часы на лампах «Никси».  
Поскольку лампа требует высокого напряжения для работы, в современных устройствах это решается с помощью преобразователя напряжения на таймере 555 упроавлящим мощным полевым транзистором включенным в первичную обмотку повышающего трансформатора, и дальше вторичная обмотка подключается к умножителю напряжения из 4-5 ступеней. Этого достаточно чтобы преобразовать входные 5 вольт в 250 с током 1-2 ma.
Я хочу поделиться своим домашним проектом, суть которого в эмуляции, насколько возможно, «зелёного глаза» лампы 6E1П с помощью быстрого OLED дисплея, контролируемого платой Arduino:
Проект выполнен несколько лет назад.
Самым сложным оказалось подобрать подходящий дисплей. На рынке их огромное количество, и большинство из них легко управляется известной библиотекойAdafruit-GFX-Library. Это прекрасная универсальная библиотека, очень простая в использовании, однако при использовании обычных плат Arduino она слишком медленная и не позволяет выводить качественную анимацию. После большого количества неудач методом проб и ошибок был найден дисплей на чипе SH1106, размером 128х64 точек и с голубым свечением. Для него предлагается библиотека ардуино U8G2. Особенностью этой библиотеки является наличие страничного вывода, т.е. сначала изображение создаётся в памяти контроллера, и затем единственной командой выводится на дисплей. Это позволяет создавать простые анимации с хорошей частотой обновления. Библиотека также содержит команды для построения геометрических примитивов — прямоугольников, треугольников и окружностей. Также возможен вывод простых битмапов, однако он слишком медленный чтобы использовать для анимации. Однако битмапы могут работать как маски для вырезания части изображения, и я использовал такой битмап для придания характерной формы экрана «зеленого глаза» — вертикального прямоугольника с округлой верхней стороной.
Общий принцип построения геометрии из примитивов:
 Размеры примитивов меняются динамически в зависимости от напряжения на входе A0 платы Arduino.
Размеры примитивов меняются динамически в зависимости от напряжения на входе A0 платы Arduino.
Как я уже говорил, эмуляция вполне приблизительная. Хотя геометрию изображения я считаю довольно близкой к оригиналу, монохромность дисплея не позволила создать правильный фон, так что у меня изображение на полностью чёрном фоне, тогда как в оригинальной лампе фон всегда бледно-зелёный.
Была еще одна техническая запинка, которую мне удалось преодолеть. Дисплей этот имеет синее свечение, а мне нужно ярко-зелёное. Проблема решилась с помощью высокотемпературного скотча дюймовой ширины, это интенсивно-жёлтая полиимидная липкая лента, материал также называют «каптон». По ширине она идеально соответствует дисплею и будучи аккуратно наклееной, прекрасно превращает голубое свечение экрана в зелёное, очень близкое по цвету к «ламповому».
Для эффектности я добавил к входу Arduino сигнал с простенькой платы микрофона с усилителем от Adafruit.
Дисплей и несколько дополнительных компонент для микрофона я разместил на вырезаной под размер Arduino простенькой монтажной плате, весь монтаж выполнен проводами:

 Диаграмма соединения деталей:
Диаграмма соединения деталей:
 Для любопытствующих приведу мой код для Ардуино. Я отнюдь не считаю себя продвинутым программистом микроконтроллеров и никоим образом не претендую на совершенство стиля и кода, меня вполне устраивает что он просто работает.
Для любопытствующих приведу мой код для Ардуино. Я отнюдь не считаю себя продвинутым программистом микроконтроллеров и никоим образом не претендую на совершенство стиля и кода, меня вполне устраивает что он просто работает.
Для плавности изображения я использую усреднение по 5 замерам. Усреднение написано «руками», пытался использовать стандартную библиотеку RunningAvg, но для простенькой ArduinoUno вместе с библиотекой дисплея не хватает памяти.
Я взял себе за правило добавлять простой информативный header в свой код а также пару строчек, которые при запуске напоминают из какого файла и когда этот код был залит.
                     
    Поскольку лампа требует высокого напряжения для работы, в современных устройствах это решается с помощью преобразователя напряжения на таймере 555 упроавлящим мощным полевым транзистором включенным в первичную обмотку повышающего трансформатора, и дальше вторичная обмотка подключается к умножителю напряжения из 4-5 ступеней. Этого достаточно чтобы преобразовать входные 5 вольт в 250 с током 1-2 ma.
Я хочу поделиться своим домашним проектом, суть которого в эмуляции, насколько возможно, «зелёного глаза» лампы 6E1П с помощью быстрого OLED дисплея, контролируемого платой Arduino:
Проект выполнен несколько лет назад.
Самым сложным оказалось подобрать подходящий дисплей. На рынке их огромное количество, и большинство из них легко управляется известной библиотекойAdafruit-GFX-Library. Это прекрасная универсальная библиотека, очень простая в использовании, однако при использовании обычных плат Arduino она слишком медленная и не позволяет выводить качественную анимацию. После большого количества неудач методом проб и ошибок был найден дисплей на чипе SH1106, размером 128х64 точек и с голубым свечением. Для него предлагается библиотека ардуино U8G2. Особенностью этой библиотеки является наличие страничного вывода, т.е. сначала изображение создаётся в памяти контроллера, и затем единственной командой выводится на дисплей. Это позволяет создавать простые анимации с хорошей частотой обновления. Библиотека также содержит команды для построения геометрических примитивов — прямоугольников, треугольников и окружностей. Также возможен вывод простых битмапов, однако он слишком медленный чтобы использовать для анимации. Однако битмапы могут работать как маски для вырезания части изображения, и я использовал такой битмап для придания характерной формы экрана «зеленого глаза» — вертикального прямоугольника с округлой верхней стороной.
Общий принцип построения геометрии из примитивов:
 Размеры примитивов меняются динамически в зависимости от напряжения на входе A0 платы Arduino.
Размеры примитивов меняются динамически в зависимости от напряжения на входе A0 платы Arduino.Как я уже говорил, эмуляция вполне приблизительная. Хотя геометрию изображения я считаю довольно близкой к оригиналу, монохромность дисплея не позволила создать правильный фон, так что у меня изображение на полностью чёрном фоне, тогда как в оригинальной лампе фон всегда бледно-зелёный.
Была еще одна техническая запинка, которую мне удалось преодолеть. Дисплей этот имеет синее свечение, а мне нужно ярко-зелёное. Проблема решилась с помощью высокотемпературного скотча дюймовой ширины, это интенсивно-жёлтая полиимидная липкая лента, материал также называют «каптон». По ширине она идеально соответствует дисплею и будучи аккуратно наклееной, прекрасно превращает голубое свечение экрана в зелёное, очень близкое по цвету к «ламповому».
Для эффектности я добавил к входу Arduino сигнал с простенькой платы микрофона с усилителем от Adafruit.
Дисплей и несколько дополнительных компонент для микрофона я разместил на вырезаной под размер Arduino простенькой монтажной плате, весь монтаж выполнен проводами:

 Диаграмма соединения деталей:
Диаграмма соединения деталей: Для любопытствующих приведу мой код для Ардуино. Я отнюдь не считаю себя продвинутым программистом микроконтроллеров и никоим образом не претендую на совершенство стиля и кода, меня вполне устраивает что он просто работает.
Для любопытствующих приведу мой код для Ардуино. Я отнюдь не считаю себя продвинутым программистом микроконтроллеров и никоим образом не претендую на совершенство стиля и кода, меня вполне устраивает что он просто работает.Для плавности изображения я использую усреднение по 5 замерам. Усреднение написано «руками», пытался использовать стандартную библиотеку RunningAvg, но для простенькой ArduinoUno вместе с библиотекой дисплея не хватает памяти.
Я взял себе за правило добавлять простой информативный header в свой код а также пару строчек, которые при запуске напоминают из какого файла и когда этот код был залит.
/************************************************************
* WHEN: 07-SEP-2022
* WHAT: Magic eye emulator with OLED 1.3″ 128×64 I2C Blue Display I2C address 0x3C
* https://protosupplies.com/product/oled-1-3-128x64-i2c-blue-display/
* Uses Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
* DETAILS:  
* without RunningAvg library as per
* https://www.powertronika.com/2020/04/reducing-noise-from-sensor-data.html 
* bitmap for central triangle, side with circle and rectangle
* On Mega2056 SDA A20, SCL A21
* On UNO SDA A4, SCL A5
* Use analogReference() for signal 1-2.5 v
* Analog input on A0
* Works on direct input from radio receiver
/************************************************************/
#include <Arduino.h>
#include <U8g2lib.h>
#define ARR_SIZE 5
// U8g2 Contructor List (Frame Buffer)
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R1, /* reset=*/ U8X8_PIN_NONE);
U8G2_SSD1327_WS_128X128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
int sum, a, y_max, delta_side,delta_y; //delta_side,delta_y - for small side triangles when a>32; y_max - maximum height
float p,p_avg,myRA[ARR_SIZE];
byte index;
#define owl_width 64
#define owl_height 36
static const unsigned char owl_bits[] U8X8_PROGMEM  = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
   0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
   0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
   0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
   0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
   0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x03, 0x00, 0x00,
   0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff,
   0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x1f, 0x00, 0x00,
   0x00, 0x00, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
   0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00,
   0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xe0, 0xff, 0xff,
   0xff, 0xff, 0x1f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
   0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff };
void setup(void) {
  Serial.begin(115200);
  u8g2.begin();
  Serial.print("Sketch:   ");   Serial.println(__FILE__);
  Serial.print("Uploaded: ");   Serial.println(__DATE__);
// #if defined(__AVR_ATmega2560__)
//    analogReference(INTERNAL1V1); 
    //analogReference(INTERNAL2V56);
 //#else
 //   analogReference(INTERNAL);
// #endif
 delta_side=12;
 delta_y=40;
 y_max=100;
 sum=0;
 index=0;
 u8g2.setFont(u8g2_font_timR10_tr);
 u8g2.setFontDirection(2);
}
void loop(void) {
  p=analogRead(A0);
    //averaging
    sum=sum-myRA[index];
    myRA[index]=p;
    sum+=p;
    index=(index+1)%ARR_SIZE;
    p_avg=sum/ARR_SIZE;
  //myRA.addValue(p);
  //p_avg=myRA.getAverage();
  a=min(map(p_avg,1,60,1,32),80);
  //drawScreen(a,p_avg,1);  //print amplitude
  drawScreen(a,p_avg,0);  //don't print amplitude
}
void drawScreen(int a, int vu, boolean printVU) {
  int16_t delta, a_x,a_y,a1,r,r1;
  u8g2.clearBuffer();
  delta=min(32,a);
  a1=min(a,72);
  a_y=min(map(a,4,32,18,32),50);//70
  a_x=map(delta,4,32,16,10);
  r=map(delta,4,32,11,8);
  r1=map(delta,4,32,6,0);
  if (a<6) u8g2.drawBox(29,0,7,y_max);
  //central triangle
   else u8g2.drawTriangle(32,0,32-delta,y_max,32+delta,y_max);
  if (a1>32) {
    u8g2.drawTriangle(32-delta_side, delta_y,0,y_max,0,y_max-(a1-32));
    u8g2.drawTriangle(32+delta_side, delta_y,64,y_max,64,y_max-(a1-32));
  }
  //side triangles    
  u8g2.drawTriangle(28,10,a_x,a_y,a_x,10);
  u8g2.drawBox(0,10,a_x,a_y-10);
  u8g2.drawDisc(r1+1,a_y-r1-2,r,U8G2_DRAW_LOWER_RIGHT|U8G2_DRAW_LOWER_LEFT);
  u8g2.drawTriangle(36,10,64-a_x,a_y,64-a_x,10);
  u8g2.drawBox(64-a_x,10,a_x,a_y-10);
   u8g2.drawDisc(64-r1-1,a_y-r1-2,r,U8G2_DRAW_LOWER_RIGHT|U8G2_DRAW_LOWER_LEFT);
  u8g2.setDrawColor(0);
  u8g2.drawBox(0,0,64,14);
u8g2.setBitmapMode(1);
u8g2.setDrawColor(0);
u8g2.drawXBMP(0,64,owl_width, owl_height, owl_bits);
u8g2.setDrawColor(1);
  if (printVU) {
    u8g2.setCursor(40, 110);
    u8g2.print(vu);
  }  
    u8g2.sendBuffer();    
} 
        Самые обсуждаемые обзоры
    
    | +29 | 
                                3027
                                59
                             | 
| +95 | 
                                3052
                                51
                             | 
 
    







PS: Лампы продаются, стоит у меня в Ригонде mysku.club/blog/diy/76018.html
Вот такая вот у меня «ностальжи» по старой технике…
Другое дело газоразрядные, с живой, оранжевой плазмой! Вот такие, на Ин-13:
Да для меня в детстве ИН-13 был эталоном мечты! Это потому что про ИН-33 и не знал.
главное отличие у них конечно в контрастности пикселей и их количеству!
Сегменты кстати на нем как и на Маяке по два сделаны, немного не честно но заметно не сильно.
upd: О, кстати с принципом управления я из статьи познакомился где Skiffrusspb ссылался на вас. На коте тоже все эти темы перечитывал по неск. раз на сколько это возможно с тамошней организацией форума:)
В свете событий последних лет эти индикаторы конечно становятся коллекционными.
Но живое дыхание ИН-13, это совсем другое… Жаль что они уходят в историю.
PS SLvik с РадиоКота это не я, просто тёзка.
палатысмотреть).www.youtube.com/watch?v=jcfLcW5KpgE
Да и не плоская она
Коробка DSG всем хороша, но не видит дорогу
Приходится иногда помогать — руками сбрасывать на передачу ниже. Ибо затяжной подъём на 1200 оборотах — оно такое себе. Хотя двиг и может
Но
На дачной дороге есть уклон градусов 15-20 с ухабами и колдобинами. Так вот на этой горке на принудительной первой ползёт вниз 5 км/ч. Дизель крутится под 3 тыс
Но опять же есть нюанс — классический автомат работает через гидромуфту (когда-то бывшей гидротрансформатором), DSG (aka Робот) — на «обычном» сцеплении. Здесь связь жёстче.