Страница 1 из 1

Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 02:25
Просто Плюшкин
Принесли мне как-то прожектор на ремонт. Нужно было заменить перегоревшие светодиоды. Но все уперлось в то что они на алюминиевом основании, который паяльник не берет и фен тоже. Было решено греть на обычном утюге, но т. к. утюг не догревал пришлось отключить встроенный термостат и это привело к тому что утюг перегревался и я решил сделать его термостатированным и поможет мне в этом микроконтроллер. По сути это та же немного переосмысленная паяльная станция где программно и аппаратно нет паяльника и другое переписанное по своему ПО.
Температуру можно выставить до 480 градусов.
Датчик температуры термопара К типа
Управление .энкодером
Управление нагревателем по методу ШИМ (будет мигать свет)
Проект собран в железе и успешно работает.
Изображение
сам проект https://oshwlab.com/Cricket2007/rev-1-0

Ссылка на короткое видео с ужасным качеством где я придумал еще одно применение этого девайса. https://www.youtube.com/watch?v=mN9HOS_ ... 8&index=18

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 08:50
Wladimir_TS
Схема нарисована из серии "без поллитры не поймёшь". Не совсем понятно, что за датчик - для тех температур термопара нужна - но компенсации холодного спая не видно. ПИД - это сильно - когда-то в прошлой жизни пытался сделать ПИД регулятор (на рассыпухе) - регулятор меня победил.

У самого такой столик есть - но вот только управляется обычным регулятором без обратной связи (Не СИФУ, а Безенхейма - не советую - свет тоже мигает, с СИФУ всё стабильнее - но переделывать не хочется) и китайским термодатчиком с термопарой замеряется. Давно куплен REX-C100 - но воз и ныне там. Оно и так нормально работает. Кстати на нем-же "прикатываю" платы ЛУТом.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 13:40
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 08:50
Не совсем понятно, что за датчик - для тех температур
Я писал в описании что термодатчик это термопара К типа например такая
Изображение
REX C 100 хорошая штука сам с такими на работе каждый день. Но разобрав его и увидев что в нем ОУ на LM358 стало ясно что все то же самое только прошивка покруче.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 13:50
oldmao
Хотел взглянуть на исходники - my-files.ru не пускает.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 14:51
Просто Плюшкин
oldmao писал(а):
21 фев 2023, 13:50
Хотел взглянуть на исходники

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

Код: Выделить всё

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 03.04.2020
Author  : 
Company : 
Comments: 


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/
       #define ADCMULT 0.0048828125  // разр¤дность ацп
         #define mode 2  // кол-во режимов   
#include <mega8.h>
 #include <stdio.h>
#include <delay.h>

// Alphanumeric LCD Module functions
#include <alcd.h>
          volatile   unsigned short button_count=0,button_flag=2,press_count=0,counter=0,flag_rotate_encoder=0;
            eeprom  float kP=12.0,kI=0.4,kD=60.0,dt=500.0;   //записть в энергонезависимую память 
                         int ms=0,flag=0,set_temp=40;                        
                          float out=0.0; 
                          unsigned char lcd_buff[16];                 
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                                                                    
                                int get_temp();                                     
                                 float constrain(float , float, float); 
                                    int calculateDID(float,float,float,float,float,float,int,int);
                                       void setting();
                                          void show(float,float,int);
                                            void buzzer(unsigned int delay_buzz,unsigned int count);                                
                         
                                     // out рез рассчета( выход с регул¤тора (управл¤ющий сигнал))
                                    //button_count // считает до 5 дл¤ определени¤ короткого нажати¤ и пропуска дребезга 
                                   // button_flag=0// засчитывает нажатие
                                  //press_count // счетчик нажатий  
                                 // float prevErr=0.0; //прошлые ошибки регулировани¤   
                                //float dt=0.0; // период вычислени¤ и регулировани¤ в секундах 
                               //float P=0.0; //ѕропорциональна¤ составл¤юща¤
                              // float D=0.0;  //Диференциальна¤ 
                             // float I=0.0; // интегральна¤ 
       
                                                                           
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
      if(((PIND) & (1<<PIND.3))==1)   //проверка вращения в одну сторону
   {
       
                     
        flag_rotate_encoder=1;
   
        switch(press_count)
        {
         case 0:set_temp+=1;break; //Устаноака температуры
         case 1:kP+=0.1;break;  //Установка коэффициентов
          case 2:kI+=0.01;break;
          case 3:kD+=0.1;break;
          case 4:dt+=100;break;
          case 5:set_temp+=1;break;   
        }
       
        
       if(set_temp>350)
   set_temp=40;
   
   }
   else                         //»наче в другую
   { 
   
           flag_rotate_encoder=1;
         
         switch(press_count)
        {
          case 0:set_temp-=1;break;  
          case 1:kP-=0.1;break; 
          case 2:kI-=0.01;break;
          case 3:kD-=0.1;break;
          case 4:dt-=100;break;
          case 5:set_temp-=1;break;   
        }
         if(set_temp<40)
         set_temp=350;  
}
  }
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here

}

// Timer2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
// Place your code here
        // срабатывает каждую миллисекунду
          ms++; 
        if(ms>dt)
        {
        flag=1;// если дотикало до уст значения
        ms=0;
         }
        
     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
              // обработка нажатий кнопок 
           if(PIND.1==1) //отпущеная кнопка  
    {                          
    
     if(button_count>=50&&button_count<1000) // если нажатие было длительностью от 50до 1000 мс это короткое нажатие  
      {                                   // провер¤ется при отжатой кнопке что бы не реарировало короткое нажатие 
        button_flag=1; // фиксируем короткое  нажатие  
        
      }
      
    button_count=0; // сбрасываем счетчик КОРОТКИХ нажатий пока не пройдет дребезг  
   
    }
    
    else
    {
      if(button_count<1001) 
      {
      button_count++;   // считаем пока пройдет дребезг 
      }
     
      
      if(button_count==1000)  // если досчитали до 1000 это длинное нажатие 
      {
       button_flag=2;  // фиксируем длинное  нажатие  
       press_count++;  // счетчик ДЛИННЫХ нажатий
      }
    }
        
}      


#define ADC_VREF_TYPE 0x40

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here
    

    
void main(void)
{
// Declare your local variables here
             
// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTB=0xFF;
DDRB=0xFF;

// Port C initialization
// Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State6=P State5=T State4=1 State3=1 State2=0 State1=1 State0=1 
PORTC=0x5B;
DDRC=0x1F;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=Out 
// State7=1 State6=1 State5=1 State4=1 State3=P State2=P State1=P State0=1 
PORTD=0xFF;
DDRD=0xF1;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Non-Inv.
// 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=0x81;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR2A
// OC2 output: Disconnected
// Timer Period: 1 ms
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (1<<CTC2) | (0<<CS22) | (1<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x7C;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(1<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=0xC0;
MCUCR=0x0A;
GIFR=0xC0;
  // External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: On
// INT1 Mode: Any change
//GICR|=(1<<INT1) | (1<<INT0);
//MCUCR=(0<<ISC11) | (1<<ISC10) | (0<<ISC01) | (1<<ISC00);
//GIFR=(1<<INTF1) | (1<<INTF0);

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

// 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 Clock frequency: 125,000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;

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

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

// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 2
// EN - PORTB Bit 3
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 16
lcd_init(16);

// Global enable interrupts
#asm("sei")
        lcd_clear();
           PORTB.2=1;   //вкл подсветку 
          buzzer(10,3); // пикнуть
while (1)
      {      
      
      
                if(flag==1) // рассчет значений в заданный промежутки времени
                       {
                       out=calculateDID(get_temp(),set_temp,kP,kI,kD,dt,0,255); // вычсление PID
                          flag=0;
                          } 
                                     
                    OCR1AL=out; // отправляем управляющий сигнал на ШИМ  
                      if(button_flag==1) // если первое короткое нажатие 
                       {
                       counter++; //Счетчик коротких нажатий 
                        button_flag=0; // что бы реагировало только на одно нажатие и на сл после отпускани¤ и снова нажати¤  
                        }
       
      /////////////////////////////////////////////////////////////////    
         
      
        if(button_flag==2&&press_count==1&&counter==1)  // Если длинное нажатие не реагировать, только на короткое 
            {
                    
                 lcd_gotoxy(7,0);    // верхняя строка 
                  lcd_putchar(0x3c);  // показать знак <
                    lcd_gotoxy(7,1);
                      lcd_puts(" ");
                
            
            }  
            
             if(button_flag==2&&press_count==2)
            {
                   
                 lcd_gotoxy(7,1);      // нижняя строка 
                  lcd_putchar(0x3c); // показать знак <
                    lcd_gotoxy(7,0);
                     lcd_puts(" ");
               
            
           }  
             
             if(button_flag==2&&press_count==3)
            {
                    
                 lcd_gotoxy(7,0);
                  lcd_putchar(0x3e);  // показать знак >
                    lcd_gotoxy(7,1);
                     lcd_puts(" ");
               
            
           }  
            
             if(button_flag==2&&press_count==4)
            {
                    
                 lcd_gotoxy(7,1);
                  lcd_putchar(0x3e);
                    lcd_gotoxy(7,0);
                   lcd_puts(" ");
                
            
           }  
              
           if(press_count==5) 
              {
               lcd_gotoxy(7,0);
                  lcd_putchar(0x3c);
                    lcd_gotoxy(7,1);
                   lcd_puts(" "); 
              
                
                
              }
              
              if( press_count==5&&counter==1) //если в режиме натроек прошли все пункты перейти на первый 
                 press_count=1;
                
                  if(press_count==0&&counter==1) // костыль стрелочки указывающей изменяемый режим
                  {
                  lcd_gotoxy(7,0);
                  lcd_puts(" ");
                    lcd_gotoxy(7,1);
                  lcd_puts(" ");
                  } 
               if(counter==1&&flag_rotate_encoder==1&&button_flag!=2)
               {
               counter=0;
               press_count=0;
               flag_rotate_encoder=0; 
                     lcd_gotoxy(13,1);
                     lcd_puts("  ");
               }    
             switch(counter)// в зависимости от кол-ва нажатий разные режимы. 
        {
         
            case 1:setting();break; // вызвать настойку коэффициентов       
            default:show(get_temp(),set_temp,out),press_count=0;break; // по умолчанию отображать текущий режим 
        }
          if(counter==mode) // Если дошли до последнего режима
          {
             counter=0;    // Сбросить счетчик коротких  нажатий
               lcd_clear(); // очистить диспрей 
              
           }
                      //пределы настроек
                      if(dt>9999.0)
                      dt=0.0;
                      else
                      if(dt<=0.0)
                      dt=9999.0;
                      if(kP<=0.0)
                      kP=0.0;
                      if(kI<=0.0)
                      kI=0.0;
                      if(kD<=0.0)
                      kD=0.0;
                 ///////////////////////////////////////     
                                                                                           
                      
                
       }
     }       
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


int get_temp()  // получить температуру
{   
     unsigned int i; // сетчик цикла 
     int m_temp[20]; //массив значений
      int g_temp=0; // временная переменная
       // int *p=m_temp;     
         for(i=0;i<20;i++)                  //усреднить температуру
          {
                   
                                  
                  m_temp[i]=read_adc(5)*ADCMULT/0.0041;                                
                                                    //перевсчитываем в температуру(1градус Цельсия=41мв)
                 
                  
                 
          }
                       
           for(i=0;i<20;i++)
           {
                   
            g_temp+=m_temp[i]; // читаем из массива и записываем  в временную переменную
               
           }
              
       return  g_temp/=20; // усредняем и возвращаем 
}
                    
int calculateDID(float c_input,float c_setpoint,float c_kP,float c_kI,float c_kD,float c_dt,int minOut, int maxOut)
{
                     // input температура из датчика
                      // set point установленна температура
                      //dt период измерени¤ в секундах  
                                    
                     static float integral=0.0, prevErr=0.0;
                      float err=0.0,D=0.0;
                        c_dt/=1000; //переводим в секунды 
                          err=c_setpoint-c_input; // ошибка регулировани¤
                            integral=constrain(integral+(float)err * c_dt * c_kI, minOut, maxOut); 
                             D=(err-prevErr)/c_dt; 
                              prevErr=err; 
             
             return constrain(err*c_kP+integral*c_kI+D*c_kD,minOut, maxOut);
}


float constrain(float in_val, float min, float max) // ограничение диапазона шим и интегральной составляющей
 {
    if(in_val< min) {
        return min;
    }
    else if(in_val>max) {
        return max;
    }
    else
        return in_val;
}

 void show(float t,float set_t,int out)
 {
           lcd_gotoxy(0,0);
             sprintf(lcd_buff,"Temp=%dC",(int)t);
              lcd_puts(lcd_buff); 
                   if(t<100)
                   {
                   lcd_gotoxy(8,0);
                   lcd_puts(" ");
                   }                 
                lcd_gotoxy(9,0); 
                if(out>0)
                {
                out=out/255.0*100.0; // перевести выходной сигнал в  0-100% в диапазоне от 0 до 255
                }                   
                 sprintf(lcd_buff,"PWM%d%%",(int)out);
                 lcd_puts(lcd_buff); 
                  if(out<100)
                    {
                     lcd_gotoxy(15,0);
                     lcd_puts(" ");
                    }
                     if(out<10)
                    {
                     lcd_gotoxy(14,0);
                     lcd_puts(" ");
                    }
                    
                 lcd_gotoxy(0,1);
                 sprintf(lcd_buff,"Set temp=%dC",(int)set_t);
                 lcd_puts(lcd_buff);
                 if(set_t<100)
                  {
                              
                 lcd_gotoxy(12,1); 
                lcd_puts(" ");
                }
               
               }
   
void setting()
{
           float tmp=0.0;                             
                  tmp=dt/1000.0;
                   lcd_gotoxy(0,0);
                    sprintf(lcd_buff,"kP%d.%02d",(int)kP,(int)(kP*100)%100);
                    lcd_puts(lcd_buff);
                         lcd_gotoxy(6,0);
                         lcd_puts(" ");
               
                  lcd_gotoxy(0,1);
                    sprintf(lcd_buff,"kI%d.%02d",(int)kI,(int)(kI*100)%100);
                    lcd_puts(lcd_buff);
                         if(kI<1||kI>=1)
                         {
                         lcd_gotoxy(6,1);
                         lcd_puts(" ");
                         
                          lcd_gotoxy(8,1);
                         lcd_puts(" ");
                         }
                     lcd_gotoxy(9,0);
                    sprintf(lcd_buff,"kD%d.%02d",(int)kD,(int)(kD*100)%100);
                    lcd_puts(lcd_buff);
               
               
                  lcd_gotoxy(9,1);
                     sprintf(lcd_buff,"dt%d.%01ds",(int)tmp,(int)(tmp*10)%10);
                    lcd_puts(lcd_buff);
               
                     if(tmp<10.0)
                     {
                     lcd_gotoxy(15,1);
                     lcd_puts(" ");
                     } 
  }
  
  
  void buzzer(unsigned int delay_buzz,unsigned int count)  // пищалка
{
     unsigned int i;
     for(i=0;i<count;i++)
     {
       PORTC.2=1;
       delay_ms(delay_buzz);
        PORTC.2=0;
       delay_ms(delay_buzz);
       
     }
}


Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 15:10
oldmao
А коэффициенты как подбирали?
Я бы, конечно, всё в целочисленной математике сделал. И код компактнее, и быстрее (хотя здесь скорость не важна, утюг - зверь инерционный).
PS Как мне кажется, дифференциальная составляющая здесь нафиг не нужна. Просто если температура меньше 50 градусов (то есть явно комнатная), тупо включаем на минуту (время уточнить экспериментально, до нагрева скажем 200 градусов), дальше - пропорционально+интегрально рулим.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 15:40
Просто Плюшкин
oldmao писал(а):
21 фев 2023, 15:10
А коэффициенты как подбирали?
Опытным путем потому что у утюга одна инерционность, а например у пищеварочного котла на 250литров другая.
Там можно коэффициенты ненужные выставить 0 и из ПИД сделать ПИ

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:10
Wladimir_TS
Просто Плюшкин писал(а):
21 фев 2023, 13:40
Я писал в описании что термодатчик это термопара К типа например такая
А где там описание ? Видимо плохо искал.
Просто Плюшкин писал(а):
21 фев 2023, 13:40
Но разобрав его и увидев что в нем ОУ на LM358 стало ясно что все то же самое только прошивка покруче.
Компенсация холодного спая там есть. А писать самому ПИД регулятор - это даааа - сурово.
oldmao писал(а):
21 фев 2023, 15:10
Я бы, конечно, всё в целочисленной математике сделал.
А можно у вас проконсультироваться ? Пишу тут одну программу - задача - максимально быстрое извлечение квадратного корня из 9ти битного числа 0-511 с получением 8ми битной целой части результата. На ассемблере Atmel AVR.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:24
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 16:10
А писать самому ПИД регулятор - это даааа - сурово
Да ничего там сурового формулу перевел на язык программирования и готово.
Wladimir_TS писал(а):
21 фев 2023, 16:10
А где там описание ?
Первый пост это и есть описание, читайте до конца. Я даже картинку прицепил.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:40
Wladimir_TS
Просто Плюшкин писал(а):
21 фев 2023, 16:24
Да ничего там сурового формулу перевел на язык программирования и готово.
Когда-то пробовал писать такой на ассемблере К580ВМ80 (контролер Электроника МС2702) - не сдюжил. Для моторного стенда - надо было притормаживая вар "небольшого" работающего ДВС удерживать его обороты постоянными. Для торможения использовалась обратная гидротурбина в режиме насоса, управлялась поворотом заслонок от отдельного привода (гибрид шагового и гидравлического двигателей). Сначала пытались сделать аналоговую систему на ОУ - что-то не получалось и я такая предложил "а давайте цифровую"....стыдно до сих пор.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:50
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 16:40
Когда-то пробовал писать такой на ассемблере
Я смотрю Вы знаете толк в извращениях. Вы бы еще виндовс12 взялись написать на ассемблере. Я на си пишу там проще, а на ассемблере даже умножить или разделить геморой, а на си умножить это * разделить /, сложение + вычитание- корень функция sqrt, лог и && или || не !
и т д

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:52
oldmao
Wladimir_TS писал(а):
21 фев 2023, 16:10
максимально быстрое извлечение квадратного корня из 9ти битного числа 0-511 с получением 8ми битной целой части результата
Увы, я корнями не занимался. Знаю, что есть приближённый метод, как раз им калькуляторы и пользуются. Но там деление нужно, а его аппаратного у AVR нет. Книжку какую-нибудь по вычислительным алгоритмам почитать надо...
Может вот тут что полезного почерпнёте.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 16:58
Wladimir_TS
Просто Плюшкин писал(а):
21 фев 2023, 16:50
Я смотрю Вы знаете толк в извращениях. Вы бы еще виндовс12 взялись написать на ассемблере.
Когда я пробовал писать, Си, может еще, и не придумали. Программа отлаживалась на Радио-86РК и записывалась на кассетный магнитофон Легенда-401, в качестве монитора был ламповый ( - полупроводниковый) ЧБ телек - Рассвет-307. Затем дамп переписывался на бумажку и на работе в ручную дамп переносился в программатор побайтно (помниться до выключения питания) и по нему прошивалась КР573РФ2.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 17:07
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 16:58
Когда я пробовал писать, Си, может еще, и не придумали.
А так это лет 100 назад было, виноват. Я начал знакомство с язиком си на VC6 в начале 2000-х потом понял что программирование под ПК не мое и перебрался на CVAVR и AVR Studio. Делать разные свистелки-перделки и прошивку для них интереснее чем на ПК кодить программу при том что аналогичных полно. Хотя делал я одну программу для жителя данного форума под ником ДедФеном, . Думаю ее сюда выложить но не могу понять в какой раздел. Программа рассчитывает эээээ забыл что но для тех кто делает ламповые УНЧ нужна.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 17:14
Wladimir_TS
После тех неудач - подвел много людей сорвал испытания я на прграммирование забил - вот сейчас решил вспомнить - пишк нал Atmel AVR еа ассемблере программу и понимаю что даже так не хватает производительности. Просто надо очень за короткое время (1 период частоты 38 кГц) довольно много вычислить. Вот думаю не создать-ли банально таблицу в 512 байт...

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 18:59
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 17:14
понимаю что даже так не хватает производительности.
Тогда STM32 в помощь там думаю уже точно хватит.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 22:51
Wladimir_TS
Я пытался просто осознать сколько переферии в этом STMе - ну это уже другой уровень. Просто мне кажется производительности не хватает не из-за процессора, а из-за программиста криворукого. Например у AVR 32 РОНа а я использую только 6, а переменных храню в ячейках памяти что приводит к лишним операциям чтения/сохранения - привычка с К580ВМ80.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 21 фев 2023, 23:18
Просто Плюшкин
Wladimir_TS писал(а):
21 фев 2023, 22:51
Я пытался просто осознать сколько переферии в этом STMе
У меня тоже от наворотов там крыша едет. Там что бы только светодиодом помигать надо написать несколько страниц инициализации)).
Или запихнуть в него целую ОС от чего думаю по вычислительной мощности это будет второе ардуино.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 05:54
oldmao
ПИД-регулятор на ассемблере вполне себе на ATtiny13 реализуется, правда без индикации, и коэффициенты на ходу не поменять: жёстко в программе задаются. Тут засада в двух моментах: математику нужно делать не на float, а с фиксированной точкой, поскольку у тинек для плавающей точки код громоздкий получается, а памяти с гулькин хрен. И второе - нет аппаратного умножения/деления. Приходится эмулировать сдвигами и сложением/вычитанием. Так что нужно сильно голову поломать, чтобы вписать в это ПИД алгоритм.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 06:10
xman
Бюджетная грелка размером 120 x 70 мм из модулей с али. Нагреватель оказался слишком мощный, поэтому пришлось запитать его через диод. Крепление термопары самодельное. Отремонтировал с её помощью уже немало алюминиевых светодиодных плат.

Изображение Изображение

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 12:25
Просто Плюшкин
oldmao писал(а):
22 фев 2023, 05:54
Приходится эмулировать сдвигами и сложением/вычитанием. Так что нужно сильно голову поломать, чтобы вписать в это ПИД алгоритм.
Для знающих толк в извращениях предлагаю взять тиньку10 ))). А если серьезно, а нафига тулить это в тинику13 если можно взять атмегу 8 и не мучаться.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 13:03
Игорь С
Понадобилось мне снять все светитки с матрицы. Разобрал утюг, подкрутил ему регулировку срабатывания и в путь. Пользуюсь редко, для моих нужд хватает. Для эстетов - у китайцев дешёвые платы термореле...

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 14:28
oldmao
Просто Плюшкин писал(а):
22 фев 2023, 12:25
а нафига тулить это в тинику13 если можно взять атмегу 8
Вот современные программисты и не задумываются об оптимизации, руководствуясь "не влезло сюда - пусть пользователь возьмёт камень пожирней". Это не только встроенной электроники касается, а и программ для компов/смартфонов, сайтостроителей...

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 15:50
Просто Плюшкин
oldmao писал(а):
22 фев 2023, 14:28
современные программисты и не задумываются об оптимизации, руководствуясь "не влезло сюда - пусть пользователь возьмёт камень пожирней".
Согласен но я понял бы если задача стоит впихнуть строго в тиньку. Это конечно не значит что для простейшей задачи надо взять 16 ядерный проц и поминать светодиодом. Я если выбираю камень то стараюсь с него снять хотя бы 90% его возможностей. А пихать невпихуемое не мое

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 22 фев 2023, 17:46
sas_75
Для быстрого извлечения квадратного корня есть алгоритм извлечения корня в столбик, по принципу деления, но с некоторыми особенностями. При переводе в булеву алгебру получается очень просто и компактно.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 06 апр 2023, 17:54
Wladimir_TS
А по подробнее можно, я не самый великий программист, что вот так все облечь в код.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 12:27
HyC
Просто Плюшкин писал(а):
21 фев 2023, 17:07
Я начал знакомство с язиком си на VC6 в начале 2000-х потом понял что программирование под ПК не мое и перебрался на CVAVR и AVR Studio.
На ассемблере зачастую писать гораздо проще и быстрее чем на C. Сложно обычно тем у кого нет практики и мышление соответствующее не натренировано.

Я на ассемблер (даже пишучи на сях или на паскале) перехожу много и часто. Просто на ассемблере многие вещи получаются проще и при этом нагляднее. А компилятор ассемблер здорового человека (например турбо-ассемблер) поддерживает ООП и там вполне есть и инкапсуляция и наследование и полиморфизм и контроль типов.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 13:52
Wladimir_TS
А нужно вычислить квадратный корень из 8ми разрядного числа....

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 14:01
Просто Плюшкин
HyC писал(а):
07 апр 2023, 12:27
На ассемблере зачастую писать гораздо проще и быстрее чем на C
Пример в студию плиз. Мне проще написать (например out+=2;) чем на ассемблере. И это что надо под каждый контроллер свой ассемблер учить? Точнее помнить отличия. Нее я так в дурку попаду. Мне нужно так что бы я мог логику работы описывать английскими словами
например if else while for тогда мне самому будет понятно что я делаю что я написал и что оно делает иначе я сильно запутаюсь.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 16:44
HyC
Просто Плюшкин писал(а):
07 апр 2023, 14:01
Пример в студию плиз. Мне проще написать (например out+=2;) чем на ассемблере. И это что надо под каждый контроллер свой ассемблер учить? Точнее помнить отличия. Нее я так в дурку попаду. Мне нужно так что бы я мог логику работы описывать английскими словами
например if else while for тогда мне самому будет понятно что я делаю что я написал и что оно делает иначе я сильно запутаюсь.
Вы пример неудачный с out+=2 привели. Вы усложните его чуть-чуть до out = a+++b и попытайтесь угадать что получится.

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

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

Я выучив когда-то давно PDP11 не имел никаких проблем с Z80 и i8080, после чего не имел проблем с x86, позже с PIC еще позже с AVR. Когда надо было покопаться в ARM прошивке я документацию на процессор уже не открывал.

Реально проще под другой контроллер перенести программу на ассемблере (особенно учитывая прокачаный механизм макросов), так как там подавляющее большинство движняков можно сделать просто в редакторе контекстным поиском и заменой и вручную обрулить только аппаратно зависимые вещи, но они обычно небольшие и простые, чем выяснять почему то что у меня keil51 компилировалось и работало а gcc под stm32 этот же код компилирует но не работает нихрена. И все равно берешь отладчик и лезешь в ассемблерный листинг.

На сях писать хорошо чтоб не думать что как и во что компилируется, платформу не меняешь и по ресурсам можно шагать широко.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 17:56
oldmao
HyC писал(а):
07 апр 2023, 16:44
Я выучив когда-то давно PDP11 не имел никаких проблем с Z80 и i8080
Я асм начал с БК0010-01, это PDP-10. Когда столкнулся с i386, сильно плевался, гораздо нелогичнее система команд.
Сейчас асм только для AVR и PIC знаю, самопал на них делаю. Упоминал уже где-то на этом сайте, что оптимизация кода (не использовать float и умножения/деления) позволяет запихать в килобайт кода такое, что на сях и не снилось. Например, часы, обработку BMP-280, два DS18B20 и всё это вывести на матричный светодиодный индикатор (два 74hc595) в динамике - в ATtiny13A.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 18:54
Просто Плюшкин
HyC писал(а):
07 апр 2023, 16:44
Вы усложните его чуть-чуть до out = a+++b и попытайтесь угадать что получится
Я читал что на си "ответственность" за написанное в основном на том кто пишет поэтому во всех книгах написано что старайтесь избегать выражений с неопределенным результатом, всегда обнуляйте переменные особенно глобальные и т. д.
Я согласен только в том что в одном компиляторе "принято " писать например так PORTB.5=1; а в другом только так PORTB|=(1<<5); И это напрягает но по моему это чисто дело привычки. Я сижу только на атмеловских МК(мне их за глаза). Купил с дуру STM32 но когда увидел что там что б помигать светодиодом 3 листа инициализации надо написать что б они провалились. А сложную прошивку для STM32 на ассемблере слабо?

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 19:23
oldmao
Просто Плюшкин писал(а):
07 апр 2023, 18:54
писать например так PORTB.5=1; а в другом только так PORTB|=(1<<5)
Это рожает совершенно разный код! Вот второй вариант (с сдвигами) не каждый компилятор превратит в одну команду асма SBIT (выставить один бит в порту). Если нет оптимизации - он захреначит процессору загрузить 0b01 в регистр и цикл с командами ROL (логический сдвиг влево). Встречался, к сожалению...

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 19:54
Просто Плюшкин
oldmao писал(а):
07 апр 2023, 19:23
Это рожает совершенно разный код!
Да пусть он там что хочет делает мне главное что б мое устройство работало )) Мне единственное что на данный момент не понятно это какого AVRStudio и 4 и 6 во время отладки иногда открывает лист с дизассемблированным кодом. И как я понимаю показывает мне что код зациклился хотя циклов нет в этой части кода. Наверное это от корявого написания.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 19:59
oldmao
Просто Плюшкин писал(а):
07 апр 2023, 19:54
это какого AVRStudio и 4 и 6 во время отладки иногда открывает лист с дизассемблированным кодом.
ВОТ!!! На ваши ошибки указывает, которые сам компилятор разрулить не смог. Именно поэтому знать ассемблер надо, чтобы ошибки компиляторов ловить.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 07 апр 2023, 20:09
Просто Плюшкин
oldmao писал(а):
07 апр 2023, 19:59
Именно поэтому знать ассемблер надо, чтобы ошибки компиляторов ловить.
Думаю надо лучше учить си и не писать кривой код. А ассемблер я пытался учить но как я понял сначала надо выучить устройство МК(и понять) а потом уже ассемблер. А может сразу 010101111 ? для меня супер сложно и первое и второе. А си хоть и со скрипом потихоньку там хоть о железе не думаешь точнее почти не думаешь.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 08 апр 2023, 06:51
HyC
Просто Плюшкин писал(а):
07 апр 2023, 20:09
Думаю надо лучше учить си и не писать кривой код. А ассемблер я пытался учить но как я понял сначала надо выучить устройство МК(и понять) а потом уже ассемблер. А может сразу 010101111 ? для меня супер сложно и первое и второе. А си хоть и со скрипом потихоньку там хоть о железе не думаешь точнее почти не думаешь.
Нельзя писать не кривой код если не понимаешь 1) как работает железо и 2) во что твой код компилируется. А когда "о железе почти не думаешь" и рожаются гигабайты и гигагерцы на решение тривиальных задач. Когда-то телефон с АОН работал на 4 мегагерца тактовой и влазил в 8 килобайт. Сегодня не думающие о железе специалисты вряд-ли бы реализовали это на STM32, просто негде размахнуться бы было.

А что кстати в STM32 на асемблере сложного ? На древнюю моторолу 68k очень сильно похоже. Там 3 листа инициализации писать по крайней мере не надо, инициализируешь только то чем пользуешься, а не все что тебе в системную библиотеку натолкали.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 08 апр 2023, 12:41
Просто Плюшкин
HyC писал(а):
08 апр 2023, 06:51
А когда "о железе почти не думаешь" и рожаются гигабайты и гигагерцы на решение тривиальных задач. Когда-то телефон с АОН работал на 4 мегагерца тактовой и влазил в 8 килобайт. Сегодня не думающие о железе специалисты вряд-ли бы реализовали это на STM32, просто негде размахнуться бы было.
Все правильно программы все больше и больше, железо все мощнее и мощнее. Потому так и живем.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 08 апр 2023, 13:09
HyC
Весьма мрачно мне было только в ассемблер 6502 процессора. Из-за того что процессор упрощен настолько что имеет только 8-битные регистры (кроме PC) при 16-битной шине адреса и вся гинекология 256-байтную "выхлопную трубу"-окно делается. Причем регистров общего назначения там ровно один, и два индексных (если не считать стек, флаговый и указатель адреса) поэтому там одевания трусов через голову очень много. Зато там есть прям ассемблерные инструкции обращения к памяти с пред- и пост-инкрементом индексного регистра. Но все равно вот там на ассемблере прям реально больно, потому-что сразу нужно очень много рамок в голове держать.

Re: Нижний подогрев из утюга с ПИД регулированием.

Добавлено: 08 апр 2023, 13:40
Просто Плюшкин
HyC писал(а):
08 апр 2023, 13:09
Но все равно вот там на ассемблере прям реально больно, потому-что сразу нужно очень много рамок в голове держать.
Это надо на собеседовании тестовое ТЗ на таком проце давать.