Импульсный режим TIG сварки

sivanko
Offline
Зарегистрирован: 25.02.2016

Добрый всем день. Я начинающий "ардуинист". Решил заменить управление на своем сварочном комбайне. В одном корпусе электрод, полуавтомат и "аргон"(в планах). 

Написал скетч, где куча меню и тд...

Возникла проблема нужно создать хитрые импульсы для импульсного режима TIG сварки.

Нужно вот такое...

Исходные переменные - частота f до 300 гц и коэфициент заполнения k от 0 до 100% -  (верхний график)

Для регулировки тока импульса и паузы - коэфициенты заполнения k1 и  k2на участках I1(t1) b I2(t2) соответсвенно.

Как организовать такой сигнал на выходе Ардуино?

 

sivanko
Offline
Зарегистрирован: 25.02.2016

Я поразмыслил и вголове созрел такой алгоритм:

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

Как это лутше организовать програмно?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а чего тему новую создал. продолжил бы в той

sivanko
Offline
Зарегистрирован: 25.02.2016

В этой меня интересуют вопросы програмирования, а в той... вопрос силовой части.

sivanko
Offline
Зарегистрирован: 25.02.2016

Вернемся к "нашим баранам"... С силовой частью вроди определился. Теперь по управлению.

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

Вот:

 int Pusk=2;
 int Out=5;
 int Freq=50; //Частота 1-300 Гц
 int Freq_PWM=40; // Заполнение 10-90%
 int Tok_I=90;  // Ток импульса 0-100% от максимума
 int Tok_P=10;  // Ток паузы 0-100% от максимума
 float t1; // длительность импульса (сек)
 float t2; // длительность пауза (сек)
 int val;
void setup() {
pinMode(Pusk, INPUT);  
}
void loop() {
 t1= Freq_PWM/Freq/100; 
 t2= (100-Freq_PWM)/Freq/100;
 val = digitalRead(Pusk); 
 while(val=HIGH){
 analogWrite(Out, int(Tok_I)*2.55);
 delay (int(t1*1000));
 analogWrite(Out, int(Tok_P)*2.55);
 delay (int(t2*1000));
 val = digitalRead(Pusk); 
 }
 analogWrite(Out,0);

}

Имеет ли он право на жизнь. Осцилографа для проверки нет. Знаю что для частоты выше 100 гц нужно с милисекунд перейти на микросекунды. Дребезг тоже не учитывается. Как я понимаю это очень топорный способ, но другого пока не знаю. 

Жду критики и ...

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Могу предложить такой вариант http://arduino.ru/forum/programmirovanie/biblioteka-dlya-tsifrovogo-vykh... пост #57

Кармазин
Offline
Зарегистрирован: 16.12.2015

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

Тема для меня очень интересна, ибо имею ТИГ инвертор и хотел в нем реализовать режим ПУЛЬС. Мой инвертор 20-200А, ток регулируется переменным резистором на 1ком. Появилась идея переменный резистор заменить на цифровой потенциометр, и управлять им с помощью ардуино. https://habrahabr.ru/post/260233/

А если дальше фантазировать, то можно реализовать голосовое управление через ГУГЛ НАУ и блютуз. Это же здорово, не снимая маску и не останавливая процесса сварки регулировать ток и менять режим.

sivanko
Offline
Зарегистрирован: 25.02.2016

Я прицепил для начала  переменные резистора на аналоговые входы, далее после победы над генерацией возможно переделаю на енкодер

Кусочек кода -стандартное считывание из аналогового входа

// считываем значение с потенциометра в переменную...
  MotorSpeed = map(analogRead(analogInPin1), 0, 1023, 0, 255); 
  Sp=map(analogRead(analogInPin1), 0, 1023, 0, 100); 
  
  
  Freq = analogRead(analogInPin2);
  Freq = map(Freq, 0, 1023, 1, 500); 
  
  Freq_PWM = analogRead(analogInPin3);
  Freq_PWM = map(Freq_PWM, 0, 1023, 5, 95);
  
  Tok_I = analogRead(analogInPin6);
  Tok_I = map(Tok_I, 0, 1023, 5, 100);
  
  Tok_P = analogRead(analogInPin7);
  Tok_P = map(Tok_P, 0, 1023, 5, 100);

Регулировка четырех переменных, основная частота и заполнение, и потом заполнение импульса и паузы

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

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

//Вместо
//Freq_PWM = analogRead(analogInPin3);
//Freq_PWM = map(Freq_PWM, 0, 1023, 5, 95);
//пишем функцию getVal()

//Пример вызова функции
Sp = getVal(analogInPin1, 0, 1023, 0, 100);
Freq_PWM = getVal(analogInPin3, 0, 1023, 5, 95);
Tok_I = getVal(analogInPin6, 0, 1023, 5, 100);
Tok_P = getVal(analogInPin7, 0, 1023, 5, 100);

int getVal(byte analogIn, int minIn, int maxIn, int minOut, int MaxOut)
{
  int val = map(analogRead(analogIn), minIn, maxIn, minOut, maxOut);
  return val;
}

Можно добавить

#define getFreq getVal(analogInPin3,0,1023,5,95)
//тогда можно будет писать 
Freq_PWM = getFreq;

 

sivanko
Offline
Зарегистрирован: 25.02.2016

Спасибо за науку. Я этому еще не обучен, учусь потихоноку между основной работой.  Я подозревал что такое есть. Мне пока так проще.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Можно чуть подправить

int getVal(byte analogIn, int minOut, int maxOut)
{
  int val = map(analogRead(analogIn), 0, 1023, minOut, maxOut);
  return val;
}

тогда вызов соответственно

Freq_PWM = getVal(analogInPin3, 5, 95);

 

sivanko
Offline
Зарегистрирован: 25.02.2016

Спасибо. Получилось. По количеству строк если писать так :

Sp=map(analogRead(analogInPin1), 0, 1023, 1, 100); 

то получается тоже самое. Только через пользовательскую функцию правильнее, и еще большой плюс - научился функции писать...

sivanko
Offline
Зарегистрирован: 25.02.2016

Сегодня блуждая на просторах интернета наткнулся на такое устройство 12ти битный ЦАП с управлением по I2S

http://mini-tech.com.ua/download/datasheet/chips/mcp4725.pdf

Вот видео работы 

И возникла идея для создания тока нужной формы

или такой 

Записью в устройсво  по I2S целого числа до 4095 изменяется напряжение на выходе. Очень простая реализация нарастания и спада напряжения через цикл. Да и импульсы сотворить не сложно. На выход баян из МОСФЕТов и возможно победа.

Хочу услышать мнения специалистов. Из минусов вижу большой нагрев транзисторов, но с этим можно бороться.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Записью в аналоговый выход в "Ардуино" целого числа до 255 тоже изменяеться напряжение на выходе, только шаг больше (1:16) против внешнего ЦАП. Вам же не музыку играть.

sivanko
Offline
Зарегистрирован: 25.02.2016

Напрямую с ардуинки идет ШИМ сигнал, а так чистый аналог. Я пока обдумываю варианты и впитываю информацию.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

sivanko пишет:

Напрямую с ардуинки идет ШИМ сигнал, а так чистый аналог. Я пока обдумываю варианты и впитываю информацию.

Необходимо только отфильтровать несущую ,но Вам то это ни к чему (возможно писк будет при работе от несущей частоты)

А транзисторы при работе в ключевом режиме (от PWM) меньше греються и КПД намного выше.

Интересно узнать длитильность режимов по второму графику.

Например.

1. нажали кнопку - подача газа до сварки 100мс

2. выдаем стартовый ток - 100мс

3. увеличиваем ток до наминального - 100мс

4. в течении периуда (200мс) выдаем рабочий ток - 100мс, затем ток паузы - 100мс (продолжаем пока не отпустим кнопку повторять пункт 4)

и т.д. ...

sivanko
Offline
Зарегистрирован: 25.02.2016

За фильтрацию ШИМа я в курсе. Вот только проблема в том что частота ШИма грубо 500Гц, а при частоте импульса 200 -300 Гц там и фильтровть особо нечего. Гдето на форуме видел тему о повышении частоты ШИМа, но пока не вникал...

Вот примерные режимы работы (за исключением импульсов обратной полярности)

По крайней мере к этому нужно стремится... Хотя тут в примере частота импульса до 10 Гц, в основном в таких сварочниках верхний порог 200-500 Гц

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Можно собрать генератор http://radiopolyus.ru/-ne555/137-generator-pryamougolnyx-impulsov-na-ne5... а его выход комутировать через транзистор управляемый ардуиной

sivanko
Offline
Зарегистрирован: 25.02.2016

Я думал и о таком варианте. Но... Много вопросов по регулировкам и комутации. Получается нужно 2 генератора с ШИмами для импульса и паузы, и их включать по очереди для получения необходимого сигнала.

Babaiko
Offline
Зарегистрирован: 18.12.2011

Экспериментирую с подобной системой.

реализовал режим пульса и режим прихваток. 

пульс в основном использую низкочастотный 1-3 пульса в секунду. Высокочастотный  нормально проверить не удаётся  но вроде работает.

Всё сделал через разъём  педали.

педаль полностью подключена к ардуине контакта с аппаратом нет.

Ардуина шлёт pwm сигнал в аппарат ну и включает релюху. вобщемто и всё.

JVS
Offline
Зарегистрирован: 22.12.2016

Babaiko пишет:

реализовал режим пульса и режим прихваток. 

А какой у Вас сварочник?

solzan
Offline
Зарегистрирован: 21.09.2017

Привет! Получилось ли задуманное? Сам сейчас на перепутье, купить новый аргонник или доработать то что есть.

Shibakoff_fab
Offline
Зарегистрирован: 11.01.2020

Всем привет
Купил тифровой тиг Аврора Система AC/DC Пульс
Подключил педаль с аналогового тига,внутри нее переменный резистор 10 кОм.Все работает но есть запаздывание в сигнале,не плавная работа и рывки. https://youtu.be/C_AUZPwWQKc
Видел несколько педалей с новых машин везде аналоговые резисторы.
В радио электронике почти полный 0,но начал понимать, что током аппарата управляет не сам резистор и напряжение а код по которому прописан этот резистор.Пожалуйста посоветуйте пути решения проблемы,с официалами ругаться устал ,они просто продают сырой китай и им все по фигу.
Думаю что могла бы помочь ардуина с грамотным кодом.
Топик стартеру посоветовал бы в циклограмме добавить базовый ток 1 и базовый ток 2,так сделано у топовых брендов типа фрониуса. А вообще думал что можно было бы управлять основным током как функция ток - время линейно для многократных операций например на вращателе.Не ток спада который горит фиксированной величины определенное время,а именно падающий ток по времени,работа педалью ,но програмно.Надеюсь мысль понятна.Можно реализовать программы по расходу газа если найти пневмоклапан расходомер,ведь для нержавейки и алюминия нужен разный расход например.И ячеек памяти надо больше 10 это точно.
Так же проситься дисплей типа evospark .
А вообще сварочный аппарат как открытый проект на arduino это великолепно!

,

ВН
Offline
Зарегистрирован: 25.02.2016

Shibakoff_fab пишет:
Подключил педаль с аналогового тига,внутри нее переменный резистор 10 кОм.Все работает но есть запаздывание в сигнале,не плавная работа и рывки.

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

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

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

Только сначала вам придется разобраться с типами характеристик переменных резисторов А,В,С , выяснить какой у вас и купить аналогичный тип и номинал. 

Желательно бы еще выяснить, подается в педаль питание или там цепь делителя.   

-NMi-
Offline
Зарегистрирован: 20.08.2018

Подпишусь для почитать-посмотреть.

bwn: Коллеги-модераторы, а зачем подписки скрывать, ведь человек хотел чтобы извещения приходили. Поправил. ИМХО.

Vadim_V
Offline
Зарегистрирован: 12.01.2020

Доброго времени суток.

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

Цитата из https://forum.grainwine.info:

 

Теория:

 

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

 

20180130125515.png20180130125525.png

 

Мы видим из схемы, что резистор просто выступает делителем напряжения. И на выходе переменного резистора напряжение изменяется от 0 до 5 вольт. В некоторых моделях инверторов изменяется до 12 вольт, но суть та же. Возможно существуют инверторы где ток регулируется, как то по другому, но будем пока тренироваться, как на схеме. Вся резистивная обвязка переменника это защита сварочного аппарата от белого дыма. Обрыв в переменнике, забыли его подключить к плате... но при этом всегда на в точке крепления средней ноги переменника должно быть напряжение от 0 до 5 вольт, что и делает обвязка.

 

Как же можно изменить сварочный ток? Можно пытаться, каким то образом изменять напряжение на средней ноге переменника. Я же предлагаю (а впрочем так я и сделал себе и другим советовал) изменять напряжение где на схеме стрелочка вверх и написано +5,1В. Если выкрутить Ток на максимум то при 5,1В будет максимум на выходе, а если вместо 5,1В подать 2,5В то ток упадет в два раза.

 

От теории к практике:

 

Отрываем к херам провод который на схеме стрелочка вверх 5,1В и подключаем к нему свой источник напряжения. Т.е. подаем "свое" напряжение на резисторы R34 R35 R37, но в допустимых пределах от 0 до 5 вольт. При этом резистор "Ток" в макс положении. Изменяя в процессе сварки "свое" напряжение, мы будем изменять выходной Ток.

 

 

Project : TIG pulse
Version : 1.7
Date    : 19.08.2015
Author  : Vladimir Kulikov
Company : KULIKOV TECHNOLOGY
Comments: 


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 14,745600 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>

 #include <delay.h>
// Standard Input/Output functions
 #include <stdio.h>
// #include <math.h>

#define SYM             PORTB.1
#define SPK             PORTD.2
#define on             0
#define off            1
#define Amp_Delta      0      // Поправка если при максимальном токе не выдает 12 Вольт или выдает более  от 0 и выше

#define pulse 1
#define base  0

#define adc_cycles    28         // norm 100 или 28

#define free 0b00111100

#define ADC_VREF_TYPE 0xC0

// Declare your global variables here
unsigned char duty_cycle; // скважность
int freq ; // частота
// unsigned char amp; // Базовый ток
unsigned char pulse_on=off; // Включение режима Pulse
unsigned char ocr_p, ocr_b; // скважность для изменения напряжения  =0 максимальное заполнение, наибольший ток
unsigned char HI, LOW; // макс и мин ток 

unsigned char Fd; // шаг изменения частоты 

long int T; // период в микросекундах
int Tbase, Tpulse;

unsigned int delay=0;

unsigned char menu=0, menu_bsp=0;


unsigned char video_RAM[4][2];  // область видеопамяти
unsigned char video_inc=0;      // глобальный счетчик позиции вывода
unsigned char push=0;           // нажатая кнопка

// Array memory <<HI, LOW, Freq*10, Duty, PostGas, Empty>>   Частота в Герцах * 10
eeprom unsigned char TIG_MEMO[16][6] = { {180,15,10,57,7,0}, {50,25,11,50,7,0}, {60,30,12,50,7,0}, {70,35,13,50,7,0}, 
                                        {80,40,14,50,7,0}, {90,45,15,50,7,0}, {100,50,16,50,7,0}, {120,60,17,50,7,0},
                                         {60,15,10,57,7,0}, {50,25,11,50,7,0}, {60,30,12,50,7,0}, {70,35,13,50,7,0}, 
                                        {55,40,14,50,7,0}, {75,45,15,50,7,0}, {75,50,16,50,7,0}, {65,60,17,50,7,0}
                                         }; 

eeprom unsigned char mode_eep = 180; // два режима 180 Ампер и 75 Ампер 
unsigned char mode = 75, arr=0;
float mode_k = 1.416; 

flash unsigned char PB_symb[] = {
            0b00110100,         // 0
            0b00000100,         // 1
            0b00110001,         // 2
            0b00010101,         // 3
            0b00000101,
            0b00010101,
            0b00110101,
            0b00000100,
            0b00110101,        // 8
            0b00010101,        // 9
            0b00000000,        // 10 - темный символ
            0b00110101,        // 11 буква о
            0b00100000,        // 12  i       
            0b00110101,        //13 d
            0b00100001,        //14 F
            0b00100101,        //15 H
            0b00110000,         //16 L
            0b00100001,         //17 P
            0b00010101,         //18 S
            0b00110100,         //19 U
            0b00110101,         //20 b
            0b00110001,         //21 E
            0b00100101          //22 A
            };
            
            
flash unsigned char PD_symb[] = {
            0b11100000,
            0b10000000,
            0b10100000,
            0b10100000,
            0b11000000,
            0b01100000,
            0b01100000,
            0b10100000,
            0b11100000,
            0b11100000,
            0b00000000,
            0b00000000,
            0b00000000,
            0b10000000,   // d
            0b01100000,   // F
            0b11000000,   // H
            0b01000000,    // L 
            0b11100000,    // P
            0b01100000,    // S
            0b11000000,    // U  
            0b01000000, // b
            0b01100000,  // E
            0b11100000   //A
            };        
            
  
unsigned char PC_pos[] = {
            0b00001111,      // выходы PC0, PC1, PC2, PC3 высокие, низкий выбран сегмент дисплея
            0b00000111,      // первый символ дисплея
            0b00001101,      // второй символ дисплея
            0b00001011,      // третий символ дисплея
            0b00001110,      // четвертый символ дисплея
            0b00001111 };    // выбор опроса клавиатуры           
unsigned char PD_pos[] = {
            0b00010000,
            0b00010000,
            0b00010000,
            0b00010000,
            0b00010000,
            0b00000000 };     // выбор опроса клавиатуры       
                          





// Вывод на дисплей
// Timer0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{
// Reinitialize Timer0 value
TCNT0=0xB0; // 0xB0; // A0 normal
// Place your code here
static unsigned char key;
static unsigned char key1;
static unsigned char k, tmp_pw;
static int fltime;
static char symlt=1, tm ;
// Опрос клавиатуры
  // RESET POSITION
    #asm   
      
         cbi 0x15,0  // port C.0
         cbi 0x15,1
         cbi 0x15,2
         cbi 0x15,3 
         cbi 0x12,4  // port D.4
    #endasm  
    
PORTC |= PC_pos[5];
PORTD |= PD_pos[5];     

tmp_pw = PORTB&0b00000010;
PORTB = 0b00110001|tmp_pw;
DDRB  = 0b00000010;

delay = delay + 1;

key = PINB&0b00110001;

if ((key!=0b00110001) && (key==key1))
                                    {
                                        k=k+1;
                                        if (k>=25)     // задержка антидребезга        18
                                                {
                                                    push=key;
                                                    k=0;
                                                }    
                                    }
                                    else
                                    {
                                        key1=key;
                                        k=0;
                                    } 
            
#asm   
nop
#endasm       
 PORTB=tmp_pw;
 DDRB= 0x3F;         
       

// Выводим на дисплей
 // RESET POSITION
    #asm   
        // cbi 0x12,4  // port D.4
        // cbi 0x15,0  // port C.0
        // cbi 0x15,1   
       
         cbi 0x15,0  // port C.0
         cbi 0x15,1
         cbi 0x15,2
         cbi 0x15,3  
         cbi 0x12,4  // port D.4
    #endasm  
        
        // RESET SYMBOL
    #asm   
        cbi 0x18,0     // PORTB 
        cbi 0x18,2
        cbi 0x18,3
        cbi 0x18,4
        cbi 0x18,5   
       // cbr 0x18,61
        cbi 0x12,5     // PORTD         
        cbi 0x12,6
        cbi 0x12,7
    #endasm   
        
                
fltime++;  
if (fltime>=80) {if (symlt==1) symlt=0; else symlt=1; fltime=0;} 
   
       tm = video_RAM[video_inc][1]&1;
       if (symlt==1 || tm==0 ) 
       {
       PORTB |= PB_symb[video_RAM[video_inc][0]];
       PORTD |= PD_symb[video_RAM[video_inc][0]];
       } 
       tm = video_RAM[video_inc][1]&6; 
       if ((symlt==1 && tm==2) || tm==4) PORTB |= 0b00001000;
        
       PORTC |= PC_pos[video_inc+1];
       PORTD |= PD_pos[video_inc+1]; 

video_inc = video_inc + 1;
if (video_inc >= 4) video_inc=0;

}

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
static int Tmb = 0, Tmp = 0;
// Place your code here
if (Tmb==0 && Tmp==0) { Tmb = Tbase; Tmp = Tpulse; OCR1AH=0x00; OCR1AL= ocr_b ; }
if (Tmb==0 && Tmp==Tpulse) { OCR1AH=0x00; OCR1AL= ocr_p ; }

if (Tmb > 255) {TCNT2 = 0; Tmb = Tmb-255; } else if (Tmb > 0) {TCNT2 = 255 - Tmb; Tmb = 0;} else
if (Tmp > 255) {TCNT2 = 0; Tmp = Tmp-255;}  else if (Tmp > 0) {TCNT2 = 255 - Tmp; Tmp = 0;}
                                    
}

void cls_disp(void)
{
// Place your code here
video_RAM[0][1] = 0;
video_RAM[1][1] = 0;
video_RAM[2][1] = 0;
video_RAM[3][1] = 0;   
        
video_RAM[0][0] = 10;                                         
video_RAM[1][0] = 10;
video_RAM[2][0] = 10;
video_RAM[3][0] = 10;
}

void load_mem(char i)
{
// Загружаем параметры из памяти
HI          = TIG_MEMO [i + arr][0];
LOW         = TIG_MEMO [i + arr][1];
freq        = TIG_MEMO [i + arr][2];
duty_cycle  = TIG_MEMO [i + arr][3];
}

void save_mem(char i)
{
// Сохраняем параметры в память
TIG_MEMO [i + arr][0] =   HI ;
TIG_MEMO [i + arr][1] =   LOW ;
TIG_MEMO [i + arr][2] =   freq ;
TIG_MEMO [i + arr][3] =   duty_cycle ;
}

void digital (int x)         //456
{
static int c[]= {9,90,900};
static char d[]={1,10,100};
// static char z[3];
signed char j;
char b, pos;
static int i;


pos = 1;
j = 2;

while (j>=0)
            {
                i=c[j];
                b=9;
                while (x<i)
                            {
                                i = i - d[j];
                                b=b-1;
                            }  
            // z[j] = b;
            video_RAM[pos][0] = b;
            x = x - i;
            j = j - 1;
            pos = pos + 1;                
            }
}

void rst_btn(void)
{
    push = 0b00110001; 
}

void ocr_lh (char l, char h)
{
        ocr_b = 255 - mode_k*l+Amp_Delta ;     
        ocr_p = 255 - mode_k*h+Amp_Delta ;   
}

//====================================================================
//                           MAIN
//====================================================================

void main(void)
{
// Declare your local variables here
int char_disp;
int  tmp_mem=0;
signed char i_mem=0;
char sav = 0, n_mem;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=T State6=T State5= 0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTB=0x00;
DDRB=0x3F;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out 
// State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 
PORTC=0x00;
// DDRC=0x03;
DDRC=0b00001111;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=Out Func1=In Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=T State2=0 State1=T State0=0 
PORTD=0x00;
DDRD=0b11110101; // F0;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 14,400 kHz
TCCR0=0x05;                       //   TCCR0=0x00;
TCNT0=0x07;                       //   TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 14745,600 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Inverted
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xC1;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0xFF;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 14,400 kHz
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x07;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x41;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;



// DELETE????
Tbase = 0;
Tpulse = 0;


// Global enable interrupts
#asm("sei")


menu = 5;         // По умолчанию при старте показывает выходное напряжение.
n_mem=0;          // При загрузке напряжение из 0 ячейки памяти



// определяем режим работы 180А или 75А если нажата кнопка 1 при включении то меняем режим и запоминаем его.

mode = mode_eep;

// Ждем нажатия секретной кнопки


delay_ms(200); 
if (push==0b00010001)// Жамкаем первую кнопку
{
        
        if (mode == 180 ) mode = 75; else mode = 180;
        mode_eep = mode;       
}
delay_ms(500);
if (mode == 180 ) { arr = 0; mode_k = 1.416; } else { arr = 8; mode_k = 3.4; }

// Загружаем параметры из памяти
load_mem(n_mem);
ocr_lh (LOW,HI);
cls_disp();        
        

while (1)
      {
      // Place your code here  
      //    #asm("nop")
            
      if (push==0b00010001)  // Первая кнопка листает настройки вниз, одна за другой
                                                                    {  //push = 0b00111100;
                                                                    
                                                                       cls_disp();
                                                                       if (menu!=10) { rst_btn(); menu = menu + 1;}
                                                                       delay = 0;
                                                                    }  
      if (push==0b00100001 && menu==0)  // Кнопка работы с памятью сохраненых значений
                                                                    { rst_btn();
                                                                      cls_disp();
                                                                      menu = 10;
                                                                      i_mem = n_mem; 
                                                                      tmp_mem = TIG_MEMO [i_mem + arr][0];
                                                                      menu_bsp = 5;
                                                                      sav = 0;
                                                                      delay = 0;
                                                                    }                                                                
     
      switch (menu)
            {
                case 0: 
                        { 
                        menu_bsp = 0; 
                        
                        
                        if (push==0b00101100)
                                                                    {
                                                                      //                                         
                        
                                                                    }                                            
                        if ((push==0b00110000))
                                                                    {  
                                                                     if (pulse_on==on) pulse_on=off; else pulse_on=on;
                                                                     ocr_lh (LOW,HI);
                                                                      rst_btn();
                                                                    }  
                        if (pulse_on==on)
                                     {
                                        video_RAM[0][0] = 17;          // PULS                               
                                        video_RAM[1][0] = 19;
                                        video_RAM[2][0] = 16;
                                        video_RAM[3][0] = 18;
                                       // ocr_b = 10; ocr_p = 254;
                                                                    }   else
                                      {
                                        video_RAM[0][0] = 20;        // bASE                                 
                                        video_RAM[1][0] = 22;
                                        video_RAM[2][0] = 18;
                                        video_RAM[3][0] = 21; 
                                        ocr_b = ocr_p ; // = 254;
                                                                    } 
                                                                                                                                           
                        char_disp = 0;
                        }
                        break;
                
               case 1:    // Hi Amper 
                        {  
                         menu_bsp = 5; 
                                                                                      
                        if ((push==0b00100001))           // минус
                                                                    { 
                                                                      HI = HI - 1;
                                                                      if (HI<=10) HI=10;
                                                                      delay=0; 
                                                                       rst_btn();
                                                                    } 
                                                                    
                        if ((push==0b00110000))           // плюс
                                                                    { 
                                                                       HI = HI + 1;
                                                                       if (HI>= mode) HI= mode;
                                                                      delay=0;  
                                                                       rst_btn();
                                                                    }                                                                                        
                         
                        
                                                                                    
                        
                        digital (HI);     
                        video_RAM[0][0] = 15;
                          
                        }
                        break; 
                        
                        case 2:    // Setup LOW Amper  
                        {  
                         menu_bsp = 5;
                                                                                             
                        if ((push==0b00100001))           // минус
                                                                    { 
                                                                      LOW = LOW - 1;
                                                                      if (LOW<=10) LOW=10;
                                                                      delay=0; 
                                                                       rst_btn();
                                                                    } 
                                                                    
                        if ((push==0b00110000))           // плюс
                                                                    { 
                                                                       LOW = LOW + 1;
                                                                       if (LOW>= mode) LOW=mode;
                                                                      delay=0;  
                                                                       rst_btn();
                                                                    }                                                                                        
                         
                        
                                                                                    
                        // char_disp = LOW; 
                        digital (LOW);    
                        video_RAM[0][0] = 16;
                        // delay = 0;   
                        }
                        break;
                 
                 case 3:    // Показывает частоту импульса и реагирует на кнопки +-
                        {  
                         menu_bsp = 5;
                        
                         if (push==0b00101100)
                                                                    { 
                                                                     //   
                                                                    }
                                                                                                                                            
                        if ((push==0b00100001))           // минус
                                                                    { 
                                                                      if (freq<=30) Fd = 1; else if (freq<=100) Fd=10; else Fd=100;
                                                                      freq = freq - Fd; 
                                                                      if (freq<=3) freq=3;
                                                                      delay=0;
                                                                       rst_btn(); 
                                                                    } 
                                                                    
                        if ((push==0b00110000))           // плюс
                                                                    { 
                                                                      if (freq>=100) Fd = 100; else if (freq>=30) Fd=10; else Fd=1;  
                                                                      freq = freq + Fd;
                                                                      if (freq>=4000) freq=4000;
                                                                      delay=0;   
                                                                       rst_btn();
                                                                    }                                                                                        
                         
                        
                        if (freq<=29)
                                        {   video_RAM[2][1] = 10;                                                                   
                                            digital (freq) ;}
                                         else
                                         {  video_RAM[2][1] = 0;                                                                   
                                            digital (freq/10) ;}     
                        video_RAM[0][0] = 14;
                        // delay = 0;   
                        }
                        break;
                        
                        case 4:    // Duty cycle    значение заполнения основным током в %
                        {  
                         menu_bsp = 5;
                        
                         if (push==0b00101100)
                                                                    { 
                                                                        // push = 0b00111100;
                                                                    }                                                                        
                        if ((push==0b00100001))           // минус
                                                                    { 
                                                                      duty_cycle = duty_cycle - 1;
                                                                      if (duty_cycle<=10) duty_cycle=10;
                                                                      delay=0;  
                                                                       rst_btn();
                                                                    } 
                                                                    
                        if ((push==0b00110000))           // плюс
                                                                    { 
                                                                       duty_cycle = duty_cycle + 1;
                                                                       if (duty_cycle>=90) duty_cycle=90;
                                                                      delay=0; 
                                                                       rst_btn();
                                                                    }                                                                                        
                         
                        
                                                                                    
                        digital (duty_cycle);     
                        video_RAM[0][0] = 13;
                        // delay = 0;   
                        }
                        break;  
                        case 5:    // Перерасчет параметров    // запретить прерывания до конца вычислений
                        {   
                        
                            cls_disp();
                            ocr_lh (LOW,HI);
                            
                            T = 10000000/freq;
                            T = T/64; // Для кварца 16 МГц 
                            // T = T/69.5; // Для кварца 14745,6  кГц
                            Tbase = T*duty_cycle/100;
                            Tpulse = T - Tbase;
                         //   ib = Tbase/255; jb = Tbase - 255*ib ;   
                         //   ip = Tpulse/255; jp = Tpulse - 255*ip ;
                             
                          //  OCR1AH=0x00;
                          //  OCR1AL= ocr_p ;
                            
                            menu=0;
                            menu_bsp = 0;
                        }
                        break;
                        
                        case 10:   // Работа с сохранёными значениями
                        {   
                            
                            if (push==0b00010001)
                                                                    { // push = 0b00111100;
                                                                       // menu = 0;
                                                                       // menu_bsp = 0;  
                                                                       rst_btn();
                                                                       video_RAM[0][1] = 1; 
                                                                       tmp_mem = HI;
                                                                       sav = 1; 
                                                                       delay=0;  
                                                                       
                                                                        
                                                                    } 
                            if (push==0b00100001)
                                                                    { // push = 0b00111100; 
                                                                       rst_btn();
                                                                       menu = menu_bsp;
                                                                       if (sav == 1) {sav = 0; save_mem(i_mem);} 
                                                                       else {load_mem(i_mem);}
                                                                       n_mem = i_mem;
                                                                       delay=870;
                                                                    }                                        
                            if (push==0b00110000)
                                                                    { // push = 0b00111100; 
                                                                       rst_btn();
                                                                       i_mem++;
                                                                       sav = 0;
                                                                       if (i_mem>7) i_mem = 0; 
                                                                       tmp_mem = TIG_MEMO [i_mem + arr][0];
                                                                       delay=0; 
                                                                       video_RAM[0][1] = 0; 
                                                                    }                                                                                
                        video_RAM[0][0] = i_mem;
                        digital (tmp_mem);                                            
                        }
                        break; 
                           
                default: menu = 0; break;
            }   
      
    
     if (delay>=1000) { cls_disp(); menu= menu_bsp; delay=0; }     
      
    
     }
        
        
      
}

 

Спасибо Владимиру Куликову за рабочий проект.

Может кто-то, хотя в рамках риторики данного форума вероятность стремится к 0.1%, соблаговолит портировать на ардуино и 1602, что более удобно. ПредГаз, постГаз, заварку кратера, 2Т-4Т и управление энкодером, я думаю, заинтересованные будут "грызть" сами. Как и портировать на 328.

Хотя ...