Пультоскоп на Arduino 27МГц!!!

diksen
Offline
Зарегистрирован: 11.10.2013

пин 5 соедените с A4

для того чтобы поменять пин осцила необходимо менять битовую маску в ADMUX 

Биты 3-0 MUX3, MUX2, MUX1 и MUX0. Данная группа битов определяет какой вход будет активен в качестве входа для АЦП. Для определения номера пина входного канала, необходимо данную группу сконфигурировать согласно таблице представленной ниже.
 

 

 MUX3...0   Номер пина  
 0000 ADC0
 0001 ADC1 
 0010 ADC2 
 0011 ADC3 
 0100 ADC4 
 0101 ADC5 
 0110 ADC6 
 0111 ADC7 
 1000 ADC8

 

empirevv
Offline
Зарегистрирован: 09.11.2018

Пин 5 соединил с пином А4. От них сопротивление на 10кОм далее на сигнал. Нет синусоиды.

Подаю этот же сигнал на осциллограф на компьютере - сигнал есть.

diksen
Offline
Зарегистрирован: 11.10.2013

_Пин 2 задействовал на подсветку

_Уплотнил меню осцила чтоб частоту норм показывало

https://cloud.mail.ru/public/955c/Ex3zHgJCv

 

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

Electronik83 пишет:
Ну все - теперь я не самый крутой в программировании пультоскопа:))

Всё-таки мне ваша версия 18 больше нравится. Хотя кое-что для себя поменял в ней в меру своих возможностей. Одно из главных изменений- добавил кнопку "Пауза", чтоб можно было вовремя нажать, а не через меню, ну и скоростей в Терминал добавил, для меня функция терминала востребована. И ещё по мелочам. 

Что хотелось бы, но не могу: в Терминале чтоб текст при заполнении экрана сдвигался вверх (вот здесь неплохо реализовано: 

/*
https://www.google.com.ua/url?url=https://www.mini-tech.com.ua/index.php...
СТАТЬЯ UART TTL терминал на базе Arduino Pro Mini
СКЕТЧ ИСПРАВЛЕН мной (seri0shka)2018-11-15 под Ардуино 1-6-51
 */
#include <LCD5110_Graph.h> // Подключение библиотеки LCD5110_Graph
LCD5110 myGLCD(7,6,4,2,3); // SCLK, DN(MOSI), D/C, RST, SCE
extern uint8_t TinyFont[]; // Будет использоваться внешний шрифт TinyFont
char screen[168];
int currentPosition=0;
//--------------------------------
void setup()
{
  Serial.begin(9600);
  myGLCD.InitLCD(); // Инициализация дисплея
  myGLCD.setFont(TinyFont); // Установка шрифта
  myGLCD.print("Terminal v1.1 ", CENTER, 0);
  myGLCD.print("by mini-tech.com.ua", CENTER, 6);
  myGLCD.update(); // Обновление содержимого дисплея
  delay (3000);
  myGLCD.clrScr();
}
//--------------------------------
void loop()
{
byte incomeByte;  
while (Serial.available()>0) // Если в буфере Serial порта есть доступные даные 
{
  incomeByte=Serial.read(); // Считывание байта в переменную incomeByte
  switch (incomeByte)
  {
    case 0 :
      while ((currentPosition+1)%21 != 1){
        screen[currentPosition]=' ';
        currentPosition++;}
        break; 
    case 1 : 
      while ((currentPosition+1)%21 != 1){
        currentPosition--;
        screen[currentPosition]=' ';}
        break;
    default:
      screen[currentPosition]=char(incomeByte); // Преобразование полученного байта в тип char 
      currentPosition++; // и его помещение в массив screen. Переход на след. позицию  
  //}
  if (currentPosition > 167){ // Если экран заполнен
    screenShift(); // Вызов функции сдвига экрана вверх на одну строку
    currentPosition=147;} // Перемещение в начало последней строки   
}
screenPrint(screen); // Вызов функции вывода данных на дисплей
}
}
//--------------------------------
void screenPrint(char displayMatrix[168]) // Функция вывода данных на дисплей
{
  char line[21]; // Строка экрана
  int i, j;
  for(i=0; i<8; i++){ // Цикл для строк
    for(j=0; j<21; j++){ // Цикл для символов
       line[j]=displayMatrix[i*21+j];} // Наполнение текущей строки
    myGLCD.print(line, 0, i*6); // Печать строки в буффер дисплея
    myGLCD.update();} // Обновление содержимого дисплея
}
//--------------------------------
void screenShift()// Функция сдвига содержимого дисплея на одну строку вверх
{
for (int i=0; i<147; i++){ // Каждый символ по очереди копируется на ту же 
  screen[i]=screen[i+21];} // позицию в верхней строке
for (int i=147; i<168; i++){ // Последняя строка 
  screen[i]=' ';} // заполняется пробелами
} 

А вот вместо Медленного осциллографа (или в дополнение к нему) можно было бы сделать логический анализатор на 2 цифровых канала или более. Практически 90% необходимого уже есть в Медленном осциллографе.

 

empirevv
Offline
Зарегистрирован: 09.11.2018

Что-то меню оооочень уплотнилось

 

diksen
Offline
Зарегистрирован: 11.10.2013

Adafr_gfx из последнего архива используйте

empirevv
Offline
Зарегистрирован: 09.11.2018

Да. Все из последнего архива

Nikolaj666
Offline
Зарегистрирован: 19.01.2017

приветствую. попался вот такой экранчик -  https://ru.aliexpress.com/item/128-128-1-44-SPI-TFT/32863631844.html?spm=a2g0s.8937460.0.0.4c402e0eYkHcYR  . будет работать или колдовать придётся ? вроде написано - замена 5110

diksen
Offline
Зарегистрирован: 11.10.2013

Без магии никак.

разное разрешение значит разные буфера под экран - разные библиотеки. Плюс этот "пультоскоп" очень завязан на разрешение экрана Нокии5110 . 

Nikolaj666
Offline
Зарегистрирован: 19.01.2017

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

empirevv
Offline
Зарегистрирован: 09.11.2018

diksen пишет:
Adafr_gfx из последнего архива используйте

На другом компьютере залил последний скетч с последней библиотекой - все работает.

empirevv
Offline
Зарегистрирован: 09.11.2018

Nikolaj666 пишет:

приветствую. попался вот такой экранчик -  https://ru.aliexpress.com/item/128-128-1-44-SPI-TFT/32863631844.html?spm=a2g0s.8937460.0.0.4c402e0eYkHcYR  . будет работать или колдовать придётся ? вроде написано - замена 5110

Здесь в первом десятке страниц был код пультоскопа для этого экрана.

Но он там совсем простой.

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

diksen
Offline
Зарегистрирован: 11.10.2013

проверил пультоскоп на wemos xi lgt8f328p

http://arduino.ru/forum/apparatnye-voprosy/obzor-klona-megi328-lgt8f328p

это китайский "клон" атмеги328 только в 2 раза дешевле и плюшек класных очень много особенно для этого пультоскопа

чето только стоит 32мега синтезатор(на лету переключаемся 2 командами и никаких перепаек кварца). 12 бит ацп с усилителем в 8.16.32 раза. еще один 16бит таймер.   цап - можно генерить dds не софтово а хардово.:)

+ логика на 3.3 вольта по умолчанию(есть перемычка на 5в) - к экранам 3.3в как и нокиа5110 можно напрямую подсоединяться.

 

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

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

 

empirevv
Offline
Зарегистрирован: 09.11.2018

diksen пишет:

У меня почему-то на t6 при опорных 5В синусоиды почти нет. Что бы что-то увидеть приходится выставлять t1 и опорную 1.1

Что это может быть?

diksen
Offline
Зарегистрирован: 11.10.2013

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

на 1Кгц сигнале я ставил развертку 3 (t3) - это если на 16мгц (стандартном) кварце работает ардуино.

если ваш генератор выдает 5в а приходит меньше вольта значит в пути где-то теряется ;) Проверте качество пайки и соединения земляного щупа и щупа осцила. так же проверьте номинал резистора на входе A4.

Vintick
Offline
Зарегистрирован: 16.01.2018

                                            Вот накидал схему на голой AtMega328 в DIP корпусе , по версии - diksen.  Прошу проверить на ошибки!                          

smokok
smokok аватар
Offline
Зарегистрирован: 08.06.2018

diksen пишет:

((можно вообще переписать осцил чтобы он делал это автоматом - вроде у Electronika83 в одном из скетчей это было сделано))

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

Ещё как то заменил вместо 

Freq=1000000/((y-Freq1-1)*3.27)

на

Freq=1000000/((y-Freq1-1)*3.29);

и добавил flagFreq2=0;

flagFreq1=0; flagFreq2=0; flagFreq3=0;

и теперь частота в точку и не слетает когда перебераешь развёртку в ручном режиме для просмотра сигнала разной ширины. А частота отображается у меня вот (в тысячных)

display.print(count/1000.0,3);

Я не програмист, но мне интересно как оно работает))). Переделать уже свою модель не могу, так как корпус уже не разборный. Снимите кто нить видос как пашет ТТ и осцил. Собрать руки чешутся, но автоматику бросать не хочу))).

Electronik83
Offline
Зарегистрирован: 06.12.2015

Не забросили - делаем))) Можно поподробней про flagFreq2?

smokok
smokok аватар
Offline
Зарегистрирован: 08.06.2018

Было 

switch (razv) { // тут позже оптимизирую!                           ////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        case 6: Freq=1000000/((y-Freq1-1)*3.27);  break; // делитель 4
        case 5: Freq=1000000/((y-Freq1)*3.27)/2;  break; // делитель 8
        case 4: Freq=1000000/((y-Freq1)*3.27)/4;  break; // делитель 16
        case 3: Freq=1000000/((y-Freq1)*3.27)/8;  break; // делитель 32
        case 2: Freq=1000000/((y-Freq1)*3.27)/16; break; // делитель 64
        case 1: Freq=1000000/((y-Freq1)*3.27)/32; break; // делитель 128
        case 0: Freq=1000000/((y-Freq1)*500);     break; // делитель 128
      }  
      flagFreq1=0; flagFreq3=0;

Стало 

switch (razv) { // тут позже оптимизирую!                           ////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        case 6: Freq=1000000/((y-Freq1-1)*3.29);  break; // делитель 4
        case 5: Freq=1000000/((y-Freq1)*3.29)/2;  break; // делитель 8
        case 4: Freq=1000000/((y-Freq1)*3.29)/4;  break; // делитель 16
        case 3: Freq=1000000/((y-Freq1)*3.29)/8;  break; // делитель 32
        case 2: Freq=1000000/((y-Freq1)*3.29)/16; break; // делитель 64
        case 1: Freq=1000000/((y-Freq1)*3.29)/32; break; // делитель 128
        case 0: Freq=1000000/((y-Freq1)*500);     break; // делитель 128
      }  
      flagFreq1=0; flagFreq2=0; flagFreq3=0;

Видос работы залью, добавлю ниже.

empirevv
Offline
Зарегистрирован: 09.11.2018

Electronik83 пишет:
Не забросили - делаем)))

А есть версия под 1306 I2C?

Та что на главной - слишком уж кастрированная.

Electronik83
Offline
Зарегистрирован: 06.12.2015

Да есть. С гаража приеду - выложу...

smokok
smokok аватар
Offline
Зарегистрирован: 08.06.2018

Её немного потеребил для себя, работает на автомате. Пару страниц назад есть описание и видео снято. Приборчик с  этим экраном у меня выцыганили (купили), так бы ещё немного подшаманил как сейчас в 5110 например как постом выше.

Вот та  что я тут нашол версия под 1306 от Electronik83 + мод 

 https://yadi.sk/d/1fvwhbao3acrvX

sirota
Offline
Зарегистрирован: 18.08.2015

Словечко воткну (смотрю вы тут разгорячились опять). Я за интерес прожму, но к слову линк оставлю https://ru.aliexpress.com/item/DSO138mini-DIY-DSO138/32916776045.html

955,86 руб

 

Пользуюсь пару месяцев, полет нормальный. В комплекте разъем BNC (был, уже нет... у меня был BNC и клемник и проводок под простые зажимчики)

smokok
smokok аватар
Offline
Зарегистрирован: 08.06.2018

Может в нём уже прошивку поковырял?)))) Можно там что улучшить? 11.11 кУпил себе такой mini за 12.50$ по скидке/+ щуп с делителем за 3.50, вот жду чюдо)).

(видео https://youtu.be/iw0Y2Bptwyg)

скетч на всякий случай тот что в видео

//Страница проэкта  <a href="<a href="http://srukami.inf.ua/pultoscop_v25110.html" rel="nofollow">http://srukami.inf.ua/pultoscop_v25110.html</a>" rel="nofollow"><a href="http://srukami.inf.ua/pultoscop_v25110.html" rel="nofollow">http://srukami.inf.ua/pultoscop_v25110.html</a></a>
// ---------------------------------------------------------------
// От Electronik83 (mailto: <a href="mailto:gsmkillersevsk@mail.ru">gsmkillersevsk@mail.ru</a>): ver 17032017
// 1. В режиме генератора PWM в процентах в целых числах (без дробей), нарисовал график сигнала PWM
// 2. В генераторе пофиксил/оптимизировал вывод частоты (1000 герц не показывало)
// 3. Автоматическое определение схемы подключения кнопок (при включении лучше ничего не нажимать:) :
//      a). Как у автора - кнопки к питанию и резюки на массу
//      b). Как я хочу - кнопки к земле и без всяких резюков
// 4. Отправил вэйвы для DDS генератора во флэш - оперативы больше стало свободной
// 5. Реализовал перезапуск при зажатии кнопок "+" и "-" (из осцилла не работает (не знаю, как исправить!))
// 6. Убрал развертки 7 и 8 (программное растягивание) 
// 7. На DDS - генераторе видно форму выводимого сигнала, оптимизировал, сделал свои формы -  ваще клевый стал... 
// 8. Переделал меню генератора - вроде удобней стало.
// 9. В терминале можно выбирать стандартные скорости
// 10. Координально переделал некоторые куски кода, например - вывод меню....
//  От smokok, // 
// 11. Заменил терминал на меню контрастности и вкл. откл. подсветки с сохранением в EEPROM
// 12. Сломал перезагрузку кнопками + и - из за добавления EEPROM, но прошива очень шустрая однако!!!
// 13. Подсветка экрана на пине №8
// 14. Автоматическая развёртка включается с "Р" на "А"
// 15. Автоматическая синхронизация
// 15. Автоматическое автопределение делителя "5.0" "1.1" "0.2"
// 16. В планах добавить ещё звуковое предупреждение при превышении 5v на щупе // 
// 16. Переместил всю инфу в верх и подправил сетку. Теперь график ничто не закрывает
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <FreqCount.h> 
#include <PWM.h>
#include <EEPROM.h>
//#include <CyberLib.h>
// ---- UserSpace ---- //
// Подключение дисплея 
// (clk(scl, sck), din(sda, mosi), dc, ce (cs), rst)  
#define Ekran     8  //Экран/////////////////////////////////Подсвет
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 4, 3, 2); // пины к которым подключен дисплей        
//  #define contrast 52  // контрастность дисплея////////////////////////////////////////
#define key_down 11  // кнопка минус (можно любой пин)
#define key_ok   12  // кнопка ОК (можно любой пин)
#define key_up   13  // кнопка плюс (можно любой пин)
#define akb      A5  // любой свободный аналоговый пин для измерения напряжения АКБ 
#define overclock 16 // частота на которой работает Ардуино
float VCC=5.0;  // напряжение питания, меряем мультиметром
// ---- UserSpace_End ---- //
//        A3    !!   // пин подключиния входа осцилла (для отображения формы сигнала)
//        D5    !!   // пин подключиния входа осцилла (для аппаратного измерения частоты через таймер (в FreqCount.h))
#define led  9       // пин для генератора сигналов (не менять)
#define dds  10      // пин для генератора dds (не менять)

// ---- Глобальные переменные ---- //
byte contrast;
byte Set=0;       ///////////////////////Экран/////////////////////////////////
bool BL;          /////////////////////////Экран///////////////////////////////
bool avtorazv=0;      // Автоматический выбор развертки
bool flag_key;       // нужно для разных подключений кнопок
byte mode=0;         // режим работы прибора
byte menu=0;         // подменю
const char* const modeStr[] PROGMEM= { " Осциллоскоп ", "PWM-генератор", "DDS-генератор", "* * Экран * *"};

// ---- Переменые для осциллоскопа ---- //
#define BUFSIZE 700
byte adcBuf[BUFSIZE+1]; // буфер проебразований АЦП
int kdel=5;           //bulat  автопредел 1,1/0,2 вольта
byte syncLevel=0;    // уровень синхронизации 0 до 255
byte razv=4;          // развертка
bool pause=0;         // флаг режима паузы
bool opornoe=1;       // флаг опорного напряжения
int  pauseOffset=0;   // смещение графика в режиме паузы (прокрутка)
long count=0;         // для подсчета частоты сигнала
//         bool magnify=0; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// ---- Переменные для генератора ---- //
unsigned long stepFreq=0;
int PWM = 50;    // стартовое значение ШИМ от 0 до 100 для генератора        
unsigned long freq = 500; // стартовое значение частоты в Гц для генератора

void ShowMode(char m, char y) {
   display.setCursor(3, y);
   switch (m) {
      case 0: display.print(modeStr[0]); break;
      case 1: display.print(modeStr[1]); break;
      case 2: display.print(modeStr[2]); break;
      case 3: display.print(modeStr[3]); break;
    }
}
void ShowModeInv(char y) {
  display.setTextColor(WHITE, BLACK);
  display.setCursor(0, y); display.println(" "); display.setCursor(77, y); display.println(" ");  // для красоты только
  ShowMode(mode, y);
  display.setTextColor(BLACK);
}

// ==== Инициализация всего :) ==== //
void setup() {
  delay(500); // ждем, пока питание устаканится (меньше глюков чтоб потом ловить)
  
////////////////////////////Экран//////////////////////////////
//  Примечание. Экран становится темным,  решение проблемы.///////////////////////////////////////
//  EEPROM.write(0, 50);  //  Записать закрытую строку,  Обновить  и начать использовать.
  contrast = EEPROM.read(0);
  BL       = EEPROM.read(1);
  pinMode(Ekran, OUTPUT);
  digitalWrite(Ekran, BL);
  byte key_test=0;
  digitalWrite(key_up, HIGH); digitalWrite(key_down, HIGH); digitalWrite(key_ok, HIGH); 
  if (digitalRead(key_up))   key_test++; 
  if (digitalRead(key_down)) key_test++; 
  if (digitalRead(key_ok))   key_test++; 
  if (key_test>1) { 
    flag_key=0;   
  }
  else {
    digitalWrite(key_up, LOW); digitalWrite(key_down, LOW); digitalWrite(key_ok, LOW); 
    flag_key=1;
  }   
  display.begin();
  display.setContrast(contrast);  
  while(flag_key-digitalRead(key_ok))  {
    display.clearDisplay();
//////////////////////////////////////////////////////

 // автодетект кнопок
  byte key_test=0;
  //pinMode(key_up, INPUT); pinMode(key_down, INPUT); pinMode(key_ok, INPUT); 
  // подтянули кнопки к питанию
  digitalWrite(key_up, HIGH); digitalWrite(key_down, HIGH); digitalWrite(key_ok, HIGH); 
  // автодетект подключения кнопок при включении..
  if (digitalRead(key_up))   key_test++; // если подтяжка к питанию осталась (не стоят резюки на массу) - плюсуем
  if (digitalRead(key_down)) key_test++; // если подтяжка к питанию осталась (не стоят резюки на массу) - плюсуем
  if (digitalRead(key_ok))   key_test++; // если подтяжка к питанию осталась (не стоят резюки на массу) - плюсуем
  if (key_test>1) { // определили подключение кнопок на массу
    flag_key=0;   
  }
  else { // определили подключение кнопок на питание + резюки на массу
    digitalWrite(key_up, LOW); digitalWrite(key_down, LOW); digitalWrite(key_ok, LOW); // убрали подтяжку 
    flag_key=1;
  }
  // если автодетект работает неверно (менюха скачет постоянно), то нужно расскомментировать одну из следующих строчек:
  // flag_key = 0; // кнопки просто подключены к земле, резюков нету.
  // flag_key = 1; // кнопки подключены к питанию и резюки на землю
  
  while(flag_key-digitalRead(key_ok))  { // выводим меню, пока не выбран режим работы прибора  
    display.clearDisplay();              // чистим дисплей
    // выводим главное меню
    for (char i=0; i<4; i++) {
      if (i==mode) ShowModeInv(i*10); else ShowMode(i, i*10);      
    }
//    delay(50);
    display.setCursor(12,40); display.print("Бат. ");  // выводим напряжение батареи
    display.print(analogRead(akb)*VCC/1024,1);
    display.print("v");

    // перемещаемся по меню  
    if (flag_key-!digitalRead(key_up)  ) { mode++; if (mode>3)       mode=0; delay(100); }
    if (flag_key-!digitalRead(key_down)) { mode--; if (mode == 0xFF) mode=3; delay(100); }
    display.display(); // выводим все на экран
  }
  // выбран режим работы...
  if (mode==0) FreqCount.begin(1000);
  if (mode==1) { InitTimersSafe(); SetPinFrequencySafe(led, freq);   }
  if (mode==2) { InitTimersSafe(); SetPinFrequencySafe(led, 200000); }
  delay(150);
}
  } 
// безконечный цикл - по сути прыгаем в подпрограммы
void loop() {
  if (mode==0) Oscill();       // "выпадаем" в осцилл
  if (mode==1) Generator();    // "выпадаем" в генератор 
  if (mode==2) DdsGenerator(); // "выпадаем" в DDS генератор
  if (mode==3) Menu_ekrana();  // "выпадаем" в Menu Экрана
}
// читаем с АЦП данные и помещаем их в буфер...   
void ReadAdc() {
  if (razv>0) { // (razv>0)           // если развертка без задержек всяких
    ADCSRA = 0b11100000 | (8-(razv%10)); // (8-razv); // установили делитель (/2 - не работает, так что начинаем с /4)
    for(int i=0; i<BUFSIZE; i++) {  // цикл для чтения  
      while ((ADCSRA & 0x10)==0);   // ждем готовность АЦП
      ADCSRA|=0x10;                 // запускаем следующее преобразование
      adcBuf[i]=ADCH;               // записываем данные в массив
    }
  } else {                          // развертка с задержками (delay)
    ADCSRA = 0b11100111;            // делитель на /128
    for(int i=0; i<BUFSIZE; i++) {  // цикл для чтения
      while ((ADCSRA & 0x10)==0);   // ждем готовность АЦП
      ADCSRA|=0x10;                 // запускаем следующее преобразование
      delayMicroseconds(500);       // делаем задержку 
      adcBuf[i]=ADCH;               // записываем данные в массив
    }
  }
}
//////////////////////////////// РЕЖИМ ОСЦИЛЛОСКОПА//////////////////////////////
void Oscill() {  
  if(opornoe) ADMUX = 0b01100011; // выбор внешнего опорного
         else ADMUX = 0b11100011; // выбор внутреннего опорного 1,1В
 label_ReadAdc:
         
  delay(100);
  if(!pause) ReadAdc(); // если паузы нет, то считываем сигнал в буфер
  // определение точки синхронизации
  bool flagSync=0;    // флаг, когда сигнал ниже уровня синхронизации
  int syncOffset=0;   // смещение для вывода с синхронизацией

    // считаем смещение графика по уровню синхронизации
  for(int y=0; y<BUFSIZE-80; y++) {
    if(adcBuf[y]<syncLevel) flagSync=1;
    if(flagSync && adcBuf[y]>syncLevel) { syncOffset = y; break; } 
    }
  // считаем максимальное и минимальное значение сигнала (для вывода на экран)
  byte Vmax=0, Vmin=255; // тут будем хранить максимальное и минимальное напряжение 
  for(int y=0; y<BUFSIZE; y++) { if(Vmin>adcBuf[y]) Vmin=adcBuf[y]; if(Vmax<adcBuf[y]) Vmax=adcBuf[y]; }
  syncLevel = (Vmax-Vmin) / 2 + Vmin; // /////////////// Авто синхронизация 
  
  //bulat если зашкаливает включаем предел 5 в  
  if (Vmax==255){
    if (opornoe==0)
       {
        opornoe=1;
       ADMUX = 0b01100011;// выбор внутреннего опорного 5.0 В
           goto   label_ReadAdc;
     }
  }
//bulat если  5 в  и уровень менее 1,1 в то вкл предел 1,1 в
  if (Vmax<=55){
    if (opornoe==1)
       {
        opornoe=0;
        ADMUX = 0b11100011;// выбор внутреннего опорного 1,1В
        goto   label_ReadAdc;
     }
  }
  //bulat здесь автопредел 1,1/0,22 в,программный
  kdel=5;
  if (Vmax<=55){
    if (opornoe==0)
       {
       kdel=1;
     }
  }
  // отрисовка графика 
  display.clearDisplay(); // чистим дисплей
  byte x=2; // задаем смещение графика немного вправо
  if(pause) { // если в режиме паузы, то рисуем с прокруткой...
    display.drawLine(pauseOffset/0,8,84,8, BLACK); //линия прокрутки
    display.drawLine(pauseOffset/8,10,pauseOffset/8+6,10, BLACK); //шкала прокрутки
    display.drawLine(pauseOffset/8,11,pauseOffset/8+6,11, BLACK); //шкала прокрутки
    display.drawLine(pauseOffset/8,12,pauseOffset/8+6,12, BLACK); //шкала прокрутки
    
    for(int y=pauseOffset; y<pauseOffset+80; y++) { // рисуем форму сигнала
      display.drawLine(++x, 47-adcBuf[y]/kdel/1.7, x, 47-adcBuf[y+1]/kdel/1.7, BLACK);   //линия сигнала/////////
    }
  }
    else   {// если паузы нет, то рисуем немного по другому))..  
    for(int y=syncOffset; y<syncOffset+80; y++) {  // рисуем форму сигнала
      display.drawLine(++x, 47-adcBuf[y]/kdel/1.7, x, 47-adcBuf[y+1]/kdel/1.7, BLACK);   //линия сигнала/////////
    }
    syncOffset=0;
  }
  // отрисовка полосочек слева
  for(byte i=17;i>6;i+=6) { display.drawPixel(0, i, BLACK); display.drawPixel(1, i, BLACK); display.drawPixel(2, i, BLACK); }
  // сетка вертикаль
  for(byte i=17;i>5;i+=4) { display.drawPixel(21,i, BLACK); display.drawPixel(41,i, BLACK); display.drawPixel(61,i, BLACK); display.drawPixel(81,i, BLACK); }
  // сетка горизонт
  for(byte i=1;i<84;i+=4) { display.drawPixel(i,41, BLACK); display.drawPixel(i,29, BLACK); display.drawPixel(i,17, BLACK); }
    ///////////////авто razv
  if (avtorazv)
  #define PER 1.3                               
  if (count > 3823.3*PER) razv = 6; else
  if (count > 1934.5*PER) razv = 5; else
  if (count > 0969.3*PER) razv = 4; else
  if (count > 0486.8*PER) razv = 3; else
  if (count > 0245.8*PER) razv = 2; else
  if (count > 0120.1*PER) razv = 1; else
  razv = 0;
   //////////////// 
  // отрисовка menu

  if (menu==0) {
      display.setCursor(21,8); 
  if (opornoe) display.print(Vmax*VCC/255,2); else display.print(Vmax*1.1/255,2);
    display.print("v");
    display.setCursor(66,8);
    if(opornoe) 
       {
        display.print(VCC,1);
        }
        else 
        { 
        if(kdel==5)display.print("1.1"); else display.print("0.2");
        }
    display.setCursor(0,0);
    if(flag_key-!digitalRead(key_down)) { razv--; if(razv==255) razv=6; }
    if(flag_key-!digitalRead(key_up)  ) { razv++; if(razv==7)   razv=0; }
    else display.setTextColor(WHITE, BLACK);
    display.print(" "); display.print(razv);
    display.setTextColor(BLACK);
    if(flag_key-!digitalRead(key_down) || flag_key-!digitalRead(key_up));
    display.setCursor(0,8);
    display.print(" "); display.print(avtorazv?'A':'P');
  }  
if (menu==1) {
    display.setCursor(21,8); 
  if (opornoe) display.print(Vmax*VCC/255,2); else display.print(Vmax*1.1/255,2);
   display.print("v");
   display.setCursor(66,8);
    if(opornoe) 
       {
        display.print(VCC,1);
        }
        else 
        { 
        if(kdel==5)display.print("1.1"); else display.print("0.2");
        }
   display.setCursor(0,8);
    if(flag_key-!digitalRead(key_down) || flag_key-!digitalRead(key_up)) avtorazv = !avtorazv;
    else display.setTextColor(WHITE, BLACK);
    display.print(" "); display.print(avtorazv?'A':'P');
    display.setTextColor(BLACK);
    display.setCursor(0,0);
    display.print(" "); display.print(razv);
  }  
  if (menu==2) { 
    pause=1;
   display.setCursor(0,0);
    if(flag_key-!digitalRead(key_down)) { pauseOffset-=27; if(pauseOffset<0)   pauseOffset=0;   }
    if(flag_key-!digitalRead(key_up)  ) { pauseOffset+=27; if(pauseOffset>(BUFSIZE-84)) pauseOffset=BUFSIZE-84; }    
    else display.setTextColor(WHITE, BLACK);
    display.print(" П~");
    display.setTextColor(BLACK);
  }

  if (flag_key-!digitalRead(key_ok)) { menu++; if(menu==3) { menu=0; pause=0; }}

  // забираем частоту сигнала, полученную аппаратно (через таймер)
  if (FreqCount.available()) count = FreqCount.read(); // забираем по готовности счетчика
    
  // считаем программно частоту сигнала
  byte Freq1=0;
  long Freq=0;
  bool flagFreq1=0, flagFreq2=0, flagFreq3=0;
  for(int y=1; y<255; y++) {
    if(!flagFreq1 && adcBuf[y]<syncLevel) flagFreq2=1; // тут можно че то оптимизировать, тока не могу понять, что [El83]   
    if(!flagFreq1 && flagFreq2 && adcBuf[y]>syncLevel) { flagFreq1=1; Freq1=y; }    
    if( flagFreq1 && adcBuf[y]<syncLevel) flagFreq3=1;    
    if( flagFreq3 && adcBuf[y]>syncLevel) {      
      switch (razv) { // тут позже оптимизирую!                           ////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        case 6: Freq=1000000/((y-Freq1-1)*3.29);  break; // делитель 4
        case 5: Freq=1000000/((y-Freq1)*3.29)/2;  break; // делитель 8
        case 4: Freq=1000000/((y-Freq1)*3.29)/4;  break; // делитель 16
        case 3: Freq=1000000/((y-Freq1)*3.29)/8;  break; // делитель 32
        case 2: Freq=1000000/((y-Freq1)*3.29)/16; break; // делитель 64
        case 1: Freq=1000000/((y-Freq1)*3.29)/32; break; // делитель 128
        case 0: Freq=1000000/((y-Freq1)*500);     break; // делитель 128
      }  
      flagFreq1=0; flagFreq2=0; flagFreq3=0;
    }
  }
  // отрисовка частоты сигнала
  display.setCursor(15,0);
  if (opornoe && ((Vmax*VCC/255)>2.5)) count=count*(overclock/16.0); 
                                  else count=Freq *(overclock/16.0);
  if (Vmax*VCC/255<0.29) count = 0;
  if (count<1000) { display.print(" "); display.print(count); display.print("Hz"); }
             else { display.print(" "); display.print(count/1000.0,3); display.print("KHz"); }
  display.setCursor(78,0);           
  if(opornoe && ((Vmax*VCC/255)>2.5)) display.print('*'); // если меряем частоту аппаратно, рисуем звездочку

//  delay(150);  
  display.display(); // вываливаем все на экран
}

//////////////////////////////// РЕЖИМ ГЕНЕРАТОРА//////////////////////////////
void Generator() {
  // обработка кнопок и отрисовка одновременно
  display.clearDisplay();
  ShowModeInv(0);  
  if(flag_key-!digitalRead(key_ok)) { if(menu++==7) menu=0; delay(200); } // переходим по разрядам / меняем ШИМ
  if (menu==7) { // меняем ШИМ
    if(flag_key-!digitalRead(key_down)) { PWM--; if(PWM<0)   PWM=100; delay(200); }
    if(flag_key-!digitalRead(key_up))   { PWM++; if(PWM>100) PWM=0;   delay(200); }
    pwmWrite(led, PWM*2.55); // задали ШИМ
    display.setTextColor(WHITE, BLACK); // если меняем шим, то рисуем его инверсным
    display.drawLine(15, 39, 68+(PWM==100?6:0)+(PWM<10?-6:0), 39, BLACK); // сверху полоска для большей инверсности
  } else { // меняем частоту
    if(flag_key-!digitalRead(key_down)) {
      if (freq>stepFreq)  freq-=stepFreq;              // не даем выйти за допустимый диаппазон
      SetPinFrequencySafe(led, freq/(overclock/16.0)); // задали частоту
      delay(150); // задержка для кнопок 
    }
    if(flag_key-!digitalRead(key_up))   {
      if ((freq+stepFreq)<10000000) freq+=stepFreq;    // не даем выйти за допустимый диаппазон
      SetPinFrequencySafe(led, freq/(overclock/16.0)); // задали частоту
      delay(150); // задержка для кнопок 
    }  
    display.setTextColor(BLACK); // если ШИМ не меняем, то выбираем обычный текст
    #define XFREQ 12 // ======== // и, выделяем декаду частоты полосочками
    stepFreq=pow(10, (byte)menu); if (menu>1) stepFreq++; // устраняем глючность pow, почему 10 в степени 2 = 99?
    byte menu_t = menu; if (menu>2) menu_t++; if (menu==6) menu_t++; // делаем табуляцию частоты
    menu_t = 54 - menu_t * 6; // считаем положение полосочек
    display.drawLine(menu_t, XFREQ-2, menu_t+4, XFREQ-2, BLACK); // рисуем полоски
    display.drawLine(menu_t, XFREQ-3, menu_t+4, XFREQ-3, BLACK);
    display.drawLine(menu_t, XFREQ+8, menu_t+4, XFREQ+8, BLACK);          
    display.drawLine(menu_t, XFREQ+9, menu_t+4, XFREQ+9, BLACK);
  }
  // рисуем уровень ШИМ (инверсия текста задана ранее)
  display.setCursor(15, 40); // ставим курсор))
  display.print(" PWM=");  display.print(PWM);  display.print("% "); // выводим уровень ШИМ
  display.setTextColor(BLACK); // убираем инверсию при выводе частоты
  // рисуем частоту с табуляцией  
  display.setCursor(6, XFREQ);
  for (unsigned long freq_t = 1000000; freq_t>0; freq_t/=10) {
  if (freq>=freq_t) {
    display.print((freq/freq_t)%10); if (freq_t==1000000 || freq_t==1000) display.print("'"); }  else { 
    display.print("_");              if (freq_t==1000000 || freq_t==1000) display.print(" "); }
  }
  display.print(" Hz");  
  // отрисовка графика PWM
  for (char x=17; x<67; ) {
    if (PWM!=0)             display.drawLine(x, 25, x+PWM/4, 25, BLACK); x+=PWM/4;       // верх 
    if (PWM!=0 && PWM!=100) display.drawLine(x, 25, x, 36, BLACK);                       // спад
    if (PWM!=100)           display.drawLine(x, 36, x+25-PWM/4, 36, BLACK); x+=25-PWM/4; // низ
    if (PWM!=0 && PWM!=100 && x<43) display.drawLine( x, 36, x, 25, BLACK);              // подъем
  }
  display.display(); // вываливаем буфер на дисплей
}

//////////////////////////////// DDS генератор//////////////////////////////
void DdsGenerator() {
  static const byte ddsWave[][32] PROGMEM = {
    1,6,15,29,48,69,92,117,143,168,191,212,229,243,251,255,254,248,237,222,203,181,156,131,106,81,59,39,22,10,3,1,    // El83_sinNew    
    1,18,35,52,69,86,103,120,137,154,171,188,205,222,239,255,239,223,207,191,175,159,143,127,111,95,79,63,47,31,15,1,  // El83_treugNew    
    1,9,17,25,33,41,49,57,65,73,81,89,97,105,113,121,129,137,145,153,161,169,177,185,193,201,209,217,225,235,245,255,   // El83_pilaNew
    250,246,238,230,222,214,206,198,190,182,174,166,158,150,142,134,126,118,110,102,94,86,78,70,62,54,41,33,25,17,9,1 }; // El83_pilaObrNew
  const char* const ddsStr[] PROGMEM = { "    Синус", " Треугольник", "    Пила", "Обратная пила"};
  byte ddsCount=0;
  // Рисуем DDS-генератор
  display.clearDisplay();  
  ShowModeInv(0);  
    for (byte i=0; i<84;) display.drawLine(i, 37-pgm_read_byte(&ddsWave[menu][i%32])/9, i, 37-pgm_read_byte(&ddsWave[menu][(i++)%32])/9, BLACK);
  display.setCursor(3, 40);  display.print(ddsStr[menu]);  display.display(); // отрисовали все
  // выводим выбранный сигнал, пока не нажали кнопку
  while(flag_key-digitalRead(key_up) && flag_key-digitalRead(key_down) && flag_key-digitalRead(key_ok)) {
    pwmWrite(dds, pgm_read_byte(&ddsWave[menu][(ddsCount++)&0x1F]));
  }
  if (++menu==4) menu = 0; // нажали кнопку - переключаем режим
  delay(150); // чтоб кнопки нормально нажимались
}

//////////////////////////////Экран/////////////////////////////////
void Menu_ekrana() {
  Set=0;delay(200);
  while (flag_key-digitalRead(key_ok)){
    display.clearDisplay();
    if (Set == 0) display.setTextColor(WHITE, BLACK); else display.setTextColor(BLACK);
    display.setCursor(0 , 0); display.println("Контраст:"); display.setTextColor(BLACK);
    display.setCursor(60 , 0); display.println(contrast);
    display.setCursor(0 , 10); display.println("Подсветк:"); display.setTextColor(BLACK);
    if (BL == 1) { display.setCursor(60 , 10); display.println("Вкл");} else
                 { display.setCursor(60 , 10); display.println("Отк");} display.display();
    if (flag_key-!digitalRead(key_up))   contrast++;
    if (flag_key-!digitalRead(key_down)) contrast--;
    if (contrast<30) contrast=30;
    if (contrast>70) contrast=70;
    display.setContrast(contrast); 
    delay(150);
  }
  Set=1; delay(200);
  while (flag_key-digitalRead(key_ok)){
    display.clearDisplay();
    display.setCursor(0 , 0); display.println("Контраст:");
    display.setCursor(60 , 0); display.println(contrast);
    if (Set == 1) display.setTextColor(WHITE, BLACK); else display.setTextColor(BLACK);
    display.setCursor(0 , 10); display.println("Подсветк:"); display.setTextColor(BLACK);
    if (BL == 1) { display.setCursor(60 , 10); display.println("Вкл"); digitalWrite(Ekran, BL); } else
                 { display.setCursor(60 , 10); display.println("Отк"); digitalWrite(Ekran, BL);  }
    if (flag_key-!digitalRead(key_up))   BL=1;
    if (flag_key-!digitalRead(key_down)) BL=0;
    display.display();
    delay(150);
  }
  display.display();
  display.clearDisplay();
  EEPROM.write(0, contrast);
  EEPROM.write(1, BL);
  setup();
}

 

Electronik83
Offline
Зарегистрирован: 06.12.2015

Для SSD1306 моя версия. Вроде самая стабильная, но старая....:

https://yadi.sk/d/4Gvs0l3ur9ynHw

Electronik83
Offline
Зарегистрирован: 06.12.2015

У кого-нибудь аппаратный замер частоты работает адекватно при не подключении ко входу ничего, кроме наводок сети (типа как антена на 50 гц)? У меня показывает то 71, то 75, то много разных неправильных герц...

smokok
smokok аватар
Offline
Зарегистрирован: 08.06.2018

У меня по нулям, а когда через кандёр (режим АС) то прыгает  45, 50, 55 и то нужно щупы расположить (типо найти волну) и подождать пока полоса графика немного поднимется если повезёт, но в ословном всегда ноль показывает. Смотри может хреновый вильтр по питанию если работает от повышалки. Он может давать хорошие помехи. В режиме На 0.2 вольта + увеличение сигнала (magnify)  отлично помехи вычисляли. 

sirota
Offline
Зарегистрирован: 18.08.2015

smokok пишет:

Может в нём уже прошивку поковырял?)))) Можно там что улучшить? 11.11 кУпил себе такой mini за 12.50$ по скидке/+ щуп с делителем за 3.50, вот жду чюдо)).

Не. Сорцов я не видел вообще ) Точнее не парился. На сайте смотрел только готовый бинарник, там версия старее чем у меня зашита.

Сам брал без 11.11 за 800 рублей ) Щупы рублей 500 отдавал, но очень и очень давно, когда долляр за 70 рублей был.

Пару раз уже пригодился (смотрел сигнал с шим контроллера). Вроде ни чего. На генераторе не проверял. Обзоров в инете не видел именно на него. 

tig-rrr
Offline
Зарегистрирован: 26.08.2018

Vintick,  а цепочка R21 -C7 в режиме транзистор-тестера мешать не будет!?

empirevv
Offline
Зарегистрирован: 09.11.2018

Почему-то видно только половину синуса. Есть возможность увидеть всю кривую?

Evg-Chugunov
Evg-Chugunov аватар
Offline
Зарегистрирован: 22.08.2015

Если сделать входную цепь как в сообщении 3866, то можно.

volodya198024
Offline
Зарегистрирован: 26.12.2016

Я перед контроллером устонавливал опирационник на него подовал смещщение минусом  и просматривал полную картинку. Питание ОУ тоже  0..+5в. Может кому пригодится, минус я брал из этой-же схемы.  В схеме 3866 будет влияние на входной сигнал.

diksen
Offline
Зарегистрирован: 11.10.2013

volodya198024 пишет:

Я перед контроллером устонавливал опирационник на него подовал смещщение минусом  и просматривал полную картинку. Питание ОУ тоже  0..+5в. Может кому пригодится, минус я брал из этой-же схемы.  В схеме 3866 будет влияние на входной сигнал.

А можно схемку хоть от руки, а то я совсем не бу-бу:?

empirevv
Offline
Зарегистрирован: 09.11.2018

volodya198024 пишет:

Я перед контроллером устонавливал опирационник на него подовал смещщение минусом  и просматривал полную картинку. Питание ОУ тоже  0..+5в. Может кому пригодится, минус я брал из этой-же схемы.  В схеме 3866 будет влияние на входной сигнал.

А подробней можно?

 

volodya198024
Offline
Зарегистрирован: 26.12.2016

На сегодня прибор  разобрал. Но работал он хорошо. Соберу заново. Источник минуса это два ярких светодиода и два фотодиода по парно в термоусадке.  Схема примерно такая.  ОУ  AD8032, но наверное и другой пойдёт.

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

Беспроигрышный вариант: просто, надёжно, не влияет на источник сигнала, амплитуда от -2,5 вольт до +2,5 вольт (то есть амплитуда 5 вольт)

Vintick
Offline
Зарегистрирован: 16.01.2018

 

Изменил схему в соответствии с рекомендацией - seri0shka.
ОУ - для пробника, считаю, слишком "жирно".
На счёт R21 и C7 - не знаю. Ещё не пробовал.
seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

 

Вопрос к старожилам на форуме (прочитать все 80 сраниц пока не успел). Никто не поднимал тему изготовления логического анализатора на базе пультоскопа? Достаточно вместо аналоговых измерений читать состояние порта РС (входы А0...А5 или А0...А7) максимально быстро, и затем отобразить состояние в каждый момент времени. К сожалению, моих познаний и времени для реализации катастрофически не хватает. А вот анализатор очень бы пригодился, причём в первую очередь для конструкций на ардуино. Вход А3 при этом может использоваться для аналогового чтения в режиме осциллографа, а в режиме анализатора все 4...8 входов порта как цифровые. В прошивке №18 от Electronik83 эти входы доступны, а режим анализатора установить вместо "медленного осциллографа" (разумеется, первый вариант тоже может быть нужен кому-то).

Не проходите мимо, напишите своё мнение по поводу:
1. Возможна ли реализация?
2. Какая максимальная частота (или минимальная длительность импульса) доступна для измерений?
3. Насколько востребован такой режим?

На фото не реализация, а только макет примерного вида

Electronik83
Offline
Зарегистрирован: 06.12.2015

Подумаю... кода не видел...

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

Vintick, к 11 ноге неплохо два защитных диода подключить, они спасут контроллер в случае неправильного подключения к высокому напряжению, даже 220 вольт. Хотя R13 погибнет во имя спасения.)

А вместо VD1...VD3 поставить красный светодиод- падение напряжения 1,7 вольт, остаётся 3,3 , как раз это и надо. Будет попутно индицировать включение.  Осторожно, сейчас бывают красные светодиоды с бóльшим падением напряжения, это не опасно, но дисплей может не работать.

Vintick
Offline
Зарегистрирован: 16.01.2018

Спасибо, seri0shka, изменил, только диодов будет мало.

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

Диодов достаточно, а если хотите стабилитроны, то оставить VD5. 

VD6 включён неправильно. 

Диоды желательно высокочастотные, напряжение любое.

Electronik83
Offline
Зарегистрирован: 06.12.2015

seri0shka, сколько каналов нужно?

Тут скорей всего вопрос - а сколько можно комфортно разглядеть на этом экране?

Прикинул в пэинтбраше: думаю, что пять каналов - самое то:)

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

Так до давно хотел сделать, даже тема тут поднималась....

Можно же читать целиком весь порт (все 8 бит)...

empirevv
Offline
Зарегистрирован: 09.11.2018

seri0shka пишет:

Диодов достаточно, а если хотите стабилитроны, то оставить VD5. 

VD6 включён неправильно. 

Диоды желательно высокочастотные, напряжение любое.

А какую роль здесь играют диоды? Для чего они?

Сделал без них - все работает.

 

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

seri0shka, сколько каналов нужно?

Поскольку сигнал цифровой, то можно хоть все 8 разместить на экране без проблем. Вопрос только, повлияет ли увеличение количества на максимальную доступную частоту. Хотя оптимально действительно 5.

Обязательно нужно оставить прокрутку (в паузе), делитель частоты, и индикатор паузы. Уровень синхронизации и опорное напряжение теряют смысл. Номеровать каналы тоже не стóит, 5 каналов неплохо различаются визуально, а терять драгоценное место на цифры не хочется.

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

[/quote]

А какую роль здесь играют диоды? Для чего они?

Сделал без них - все работает.

[/quote]

empirevv

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

empirevv
Offline
Зарегистрирован: 09.11.2018

О нет, я не настолько в себе уверен )

Спасибо, поставлю.

empirevv
Offline
Зарегистрирован: 09.11.2018

Дубль

Electronik83
Offline
Зарегистрирован: 06.12.2015

Только что увидел на дисплейчике 5 каналов - для меня - дак мелковато. Думаю, что 4 - самое то!

Ещеж нужно куда то впихнуть полоску прокрутки для паузы.... Так что 4 канала... А хотя.....

Влазит и пять, так то..... И для полоски прокрутки места - более чем...

Дак четыре или пять? А, seri0shka?

seri0shka
seri0shka аватар
Offline
Зарегистрирован: 19.11.2018

Мыслить нужно глобально! Обидно будет, если одного не хватит (это как зарплата: сколько ни есть- всегда мало). Сделать выбор или при прошивке (то есть 2 варианта прошивки), или при выборе режима. Более читаемый для меня верхний вариант. И прошивать себе буду однозначно с 5 каналами.

На фото уже действующая заготовка?

Кстати, уже даже вспомнил про один терзающий вопрос, там мне как раз 5 нужно, чтоб понять процесс.