Авторизация
Регистрация

Напомнить пароль

Высокотемпературный электронный термометр на ATTiny13, MAX6675 и TM1637

Решил сделать свою паяльную станцию и возник вопрос о её калибровке. Покупать на Али высокотемпературный точный измеритель температуры просто жаба задавила. Дома были в наличии простенькие микроконтроллеры ATTiny13 и четырёхразрядный дисплей на TM1637. А также завалялась пара аккумуляторов от электронных сигарет и термопара от мультиметра.
Поэтому решил сделать свой высокотемпературный электронный термометр, используя специализированную микросхему преобразователь для термопар K-типа.
Самая простая, которая была на Али, это MAX6675.

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

В качестве термопары используется хорошо знакомая версия для мультиметров. Цена на Али меньше трёх долларов за пару. Там именно термопара типа К, которая нужна для MAX6675.
На Али были куплены три микросхемы MAX6675 за четыре доллара. Там же был куплен пластиковый корпус размером 73 X 43 X 23 mm за доллар.
Микросхема MAX6675 имеет компенсацию холодного спая, что снимает эту проблему при измерениях с помощью термопары и даёт хороший по точности результат.

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

В результате получилась такая схема:

На схеме также указана распиновка Arduino Nano и её пины, к которым подключалась схема при тестировании кода с Arduino Nano вместо ATTiny13.

Код писался в Arduino IDE 1.8.19.
Размер скетча при компиляции получился 362 байта. Так что желающие могут попробовать нарастить функционал. Например, фиксация максимального напряжения. Или запись температуры в память по кнопке, которые поддерживаются TM1637, и индикация по вызову сохранённых значений. Звуковая индикация разных событий (тоже через TM1637) и т.д…

В качестве программатора использовал Arduino Nano, прошитый под ISP программатор. При попытке прошивки иногда выдавалась ошибка. Устранялась повторным запуском процесса прошивки. Два раза подряд ошибка ни разу не выскакивала.
Ядро использовалось MicroCore.

Настройки Arduino IDE при прошивке вот такие:
Проверил написанный код с этой схемой в Proteus. Всё ОК.
Спаял, прошил – не работает. ((

Заменил ATTiny13 на Arduino Nano. Прошил тем же кодом. Всё работает.
Путём проб и ошибок и с помощью осциллографа выяснил, что вся проблема в величине пауз между сигналами на входе TM1637. При слишком коротких паузах, TM1637 не успевает отрабатывать команды СТАРТ, СТОП и ЗАПИСЬ БАЙТА.

Подобрал правильные паузы. Заработало.

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

Внёс поправку в код скетча на минус три градуса. Стал показывать точно 100 при окунании в кипящую воду, 36 градусов в качестве медицинского термометра и при сравнении с комнатной температурой по обычному термометру разбежность ушла. Вроде нормально, учитывая паспортную погрешность MAX6675.

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

Потом решил сэкономить ещё чуток памяти контроллера и заменил паузы между сменами уровней на выходе контроллера просто повторными выдачами команд на установку нужного уровня сигнала на выходах контроллера, идущих к TM1637.
Получилось. Работает.

Теперь, с учётом этих нюансов, можно пробовать сделать паяльную станцию с дисплеем TM1637 на базе ATTiny13.

С монтажом решил не заморачиваться.
Всё паялось навесным монтажом с использованием переходников для микросхем контроллера и MAX6675.

Внутри корпуса всё крепилось на горячий клей.

Фото результата:

1. Температура в комнате

2. Вид внутри

3. Заряжаем от USBmicro

4. Моя температура тела

Код скетча прилагается:

// Точный термометр до 1000 градусов на ATTiny13 с MAX6675 и TM1637
// есть отображение значка градусов в 4-ом разряде
// 
// Скетч использует 362 байт (35%) памяти устройства. Всего доступно 1024 байт.
// Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.
// Обновление данных 1 раз в секунду.
// Усреднение по четырём замерам
// Значёк градуса в правом разряде дисплея
// В коде поправка на -3 градуса - при этом точность температуры в комнате, температуры тела и температуры кипения воды - до одного градуса


#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

// Определить пины для кодключения к МАХ6675
#define miso     PB0                            // MAX6675  MISO - 5 ножка ATtiny13        
#define cs       PB1                            // MAX6675  CS - выбор микросхемы - 6 ножка ATtiny13 
#define clk      PB2                            // MAX6675  CLK - 7 ножка ATtiny13 


// Определить состояние пинов для кодключения к TM1637
#define DIO_H()    (PORTB |=  _BV(PB4))
#define DIO_L()    (PORTB &= ~_BV(PB4))
#define DIO_OUT()  (DDRB  |=  _BV(PB4))
#define DIO_IN()   (DDRB  &= ~_BV(PB4))
#define DIO_RD()   (((PINB  & _BV(PB4)) > 0) ? 1 : 0)
#define CLK_H()    (PORTB |=  _BV(PB3))
#define CLK_L()    (PORTB &= ~_BV(PB3))


//------------- ¤ркость свечени¤ индикатора TM1637 ----------
#define Bright0 0x88
#define Bright1 0x89
#define Bright2 0x8A
#define Bright3 0x8B
#define Bright4 0x8C
#define Bright5 0x8D
#define Bright6 0x8E
#define Bright7 0x8F
#define SetBright Bright5                       //сюда прописать ¤ркость от 0 до 7. По умолчанию 5.
//------------------------------------------------------------------

// Коды цифр 0-9, пусто и значка градуса для сегментов (A-B-C-D-E-F-G)
const uint8_t digits[] PROGMEM = 
{
// Соответствие разрядов и сегментов  
  0x3F, // 0 - B00111111
  0x06, // 1 - B00000110
  0x5B, // 2 - B01011011
  0x4F, // 3 - B01001111
  0x66, // 4 - B01100110            _1_
  0x6D, // 5 - B01101101         6 |   | 2
  0x7D, // 6 - B01111101           |_7_|
  0x07, // 7 - B00000111         5 |   | 3
  0x7F, // 8 - B01111111           |_4_|
  0x6F, // 9 - B01101111
  0x00, // пусто - B00000000
  0x63  // градус - B001100011
};

//********************************************************************************************************
//***************************  SETUP   *****************************************************************
int main(void) 
{
  //=================== Инициализация дисплея ===================
    DDRB |= (_BV(PB4)|_BV(PB3));                // Настройка PB3 и PB4 на выход
    PORTB &= ~(_BV(PB4)|_BV(PB3));              // Установка PB3 и PB4 в ноль
  
  
    delay_msTK(100);

    #if F_CPU != 9600000UL
    #error "Частота в коде не совпадает с настройками IDE!"
    #endif
    
    //********************************************************************************************************
    //*********************  ОСНОВНОЙ ЦИКЛ  ******************************************************************
    while(1) 
    {
        int t = getSmoothTemp();            	//Читаем усреднённые данные из модуля термопары MAX6675 и ...
        if (t > 3)								// ... вычитаем поправку (у меня выдавал без поправки на три градуса больше)
			t = t  - 3;
		byte ks = 0;
        byte kd = 0;
        while (t>=100)
            {
                t-=100;
                ks++;
            } 
        while (t>=10)
            {
                t-=10;
                kd++;
            }

    //************ Выводим число на индикатор *******************
        if (ks==0)
            ks=10;
        // 1. Команда установки данных (0x40 - автоинкремент адреса)
        start();
        writeByte(0x40);
        stop();

        // 2. Установка адреса начала (0xC0) и передача 4 цифр
        start();
        writeByte(0xC0); 
        writeByte(pgm_read_byte(&digits[ks])); 	// Первая цифра
        writeByte(pgm_read_byte(&digits[kd])); 	// Вторая
        writeByte(pgm_read_byte(&digits[t])); 	// Третья
        writeByte(pgm_read_byte(&digits[11])); 	// Четвертая
        stop();

        // 3. Установка яркости (0x88 - включено, средняя яркость)
        start();
        writeByte(SetBright); 
        stop();
        
        delay_msTK(100);                        //  задержка   
    }
}


//*********************  КОНЕЦ MAIN  ******************************************************************              
//*****************************************************************************************************


//*****************************************************************************************************
//*****************************************************************************************************
//*********************  ФУНКЦИИ  *********************************************************************  

//------------------------------------------------------
//---------  Функция отправки одного байта  ------------
void writeByte(uint8_t value) 
{
    uint8_t i;
    for (i = 0; i < 8; ++i) 
    {
        CLK_L(); 
        if (value & 0x01) 
            DIO_H();
        else 
            DIO_L();
		value >>= 1;
        CLK_H(); 
    }
    CLK_L();
    DIO_IN();
	DIO_IN();
    CLK_H(); 
    DIO_OUT();
}


//------------------ Команда СТАРТ --------------------
void start() 
{
    DIO_H();
    CLK_H(); 
    CLK_H();
	CLK_H();
    DIO_L();
}


//------------------ Команда СТОП ---------------------
void stop() 
{
    CLK_L(); 
    DIO_L();
    DIO_L(); 
    DIO_L(); 
    CLK_H(); 
    DIO_H();
}


//=== Своя функция задержки в мс   ====================
void delay_msTK(uint8_t ms) 
{
    while(ms--) 
        _delay_ms(1);
}


//******************** Усреднение по 4 замерам для стабильности показаний  ***********************
int getSmoothTemp() 
{
  int sum = 0;
  for (int i = 0; i < 4; i++) 					// В цикле суммируем показания 8 опросов ...
  {
    sum += spiRead() ;							// ... в переменную sum
    delay_msTK(240); 							// Делаем паузу между опросами - MAX6675 нужно время на преобразование 170 - 220 мс
  }
  
  return (sum >>= 2);							// Делим показания на 4 - получаем усреднённое значение
}


//*************************** Чтение данных из модуля термопары  MAX6675 ******************************
//https://arduinodiy.wordpress.com/2019/12/06/using-a-max6675-temperature-sensor-without-a-library/

int spiRead() 
{
    DDRB = DDRB | 0B00000110;
    int rawTmp = 0;
    PORTB &= ~(1<<cs);                          //  cs,LOW
    delay_msTK(2);                              //  задержка 2 миллисекунды
    PORTB |= (1<<cs);                           //  cs,HIGH
    delay_msTK(200);                            //  задержка 200 миллисекунд
    PORTB &= ~(1<<cs);                          //  cs,LOW Опускаем CS для старта преобразования

    //Считываем 11 из 14 бит из MAX6675  и сохраняем в rawTmp
    //(больше не нужно - 11 бит это целая часть температуры без точнсти 0,25 градусов)

    for (int i=10; i>=0; i--) 
    {
        PORTB |= (1<<clk);                      // clk,HIGH

        byte r=0;
        if(PINB & (1<<miso))                    // Чтение пина MISO - если на ножке MISO 1, то ... 
            r=1;                                // ... фиксируем единичку
        
        rawTmp +=r << i;                        // Сохраняем считанный бит в переменную температуры
        PORTB &= ~(1<<clk);                     // clk,LOW
    }
    
    PORTB |= (1<<cs);                           //  cs,HIGH
    return rawTmp;
}

//=========================================================================================================

P.S.
Спасибо комментаторам — заметили, что на схеме не указано соединение отрицательного провода термодатчика с минусом питания. На фото внутренностей это соединение видно, а на схеме забыл дорисовать. Сейчас уже поправил.
И также отметили, что в тексте не указано, что MAX6675 имеет компенсацию холодного спая.
Тоже добавил в тексте.

Добавить в избранное
+91 +122
свернутьразвернуть
Комментарии (266)
RSS
+
avatar
+14
Это ж сколько жвачки ушло при сборке. )))
+
avatar
+12
И всю её запихнули по ошибке в коробочку для хранения электронных компонентов… Теперь замучаешься отчищать! ))

Автору, конечно респект, но вид, конечно… Строго 18+!!!
+
avatar
+7
  • trykov
  • 04 мая 2026, 16:43
Какая жвачка! Это самый модный розовый термоклей. ))
+
avatar
+4
По способу крепления напоминает «сопли» чужих из одноимённого кинофильма.
+
avatar
+5
  • trykov
  • 04 мая 2026, 22:51
Главное, чтобы крепко держали. ))
+
avatar
+8
А просто дешевый китайский тестер с термопарой не подойдет для этого? Они очень дешевые есть )
+
avatar
+5
Этож хобби. Кто то рыбу ловит в снаряжении на килограм так 100 палтуса, кто-то в футбол, в бутсах, как пару ящиков водки.

Плюс програмирование, хорошая зарядка для мозга. У меня дед до старости задачки решал и пазлы складывал.
+
avatar
+1
Ну я так понял что здесь не хобби было (это я бы понял), а необходимость.
+
avatar
+6
  • trykov
  • 04 мая 2026, 18:33
Тут сразу несколько факторов.
— была в наличии часть комплектующих
— нужен был прибор для калибровки
— нужно было проверить, сколько кода займёт обмен с TM1637 для дальнейшего применения такого индикатора с этим контроллером в паяльной станции
+
avatar
0
Давно пользую термометр на этой микросхеме. Собран в корпусе брелка на PIC контроллере. Есть вывод «сырых» данных по UART для лог.анализатора. Очень удобно. Усреднение по 40 выборкам, с десятичным знаком. Реакция на уровне ртутного термометра. Пробовал разные фильтры, медианный в том числе. Лучшим оказался гистерезис ± 0,5 шага, шустро и младший разряд не мельтешит.
+
avatar
+3
  • trykov
  • 04 мая 2026, 16:41
А Вы им пробовали измерять температуру? Вот на той же самой термопаре мой мультиметр показывает вместо 24 в комнате — 18, температуру тела вместо 36 — 28.\Ничего не смущает?
+
avatar
+2
Просто нет компенсации холодного спая.

И так пойдёт. У нас тут куча адептов, что датчик температуры в ручке паяльника (для компенсации холодного спая) не нужен. :)
+
avatar
+2
  • trykov
  • 04 мая 2026, 18:36
Ну, вместо датчика температуры в ручке для компенсации холодного спая достаточно принять поправку в 20 градусов в качестве температуры холодного спая.
Комнатная температура не сильно отклоняется от этого значения.
+
avatar
+1
В паяльнике «холодный спай» у вас на контактах жала (если говорим о Т12 и подобных)
И корректировать нужно не на температуру в комнате, а на температуру ручки. Когда много паял, моя нагревалась заметно (теплее чем ладонь)
+
avatar
0
  • trykov
  • 06 мая 2026, 07:39
А как в паяльных станциях на С245 учитывается холодный спай? Там в ручке нет термодатчика.
+
avatar
+4
  • matis
  • 04 мая 2026, 19:14
Просто нет компенсации холодного спая.
Она и тут под вопросом, учитывая MAX6675 с алика ))
+
avatar
+4
Пробовал — у меня градус в градус показывает, ну и компенсация есть даже в дешёвых мультиметрах, а если нет — оно решается одним сопротивлением, нет?

Ну и на синем сайте 624р:
+
avatar
+4
  • trykov
  • 04 мая 2026, 18:42
Ну так на вкус и цвет все фломастеры разные. ))
Мне мой обошелся дешевле.
Он меньше по размерам.
Нет проблемы со считыванием информации при пониженой освещённости.
Работает от аккумулятора и подзаряжается обычной телефонной зарядкой.
Есть возможность доработки программы под дополнительные хотелки.
В отличие от приведённого на Вашем фото, может использоваться не только для замера температуры жала паяльника.
+
avatar
+6
А термопара здесь специально перепутана выводами? ))
+
avatar
-1
  • trykov
  • 05 мая 2026, 13:59
Где перепутана?
+
avatar
+3
На фотографии.
+
avatar
0
Меряет очень точно. Я термостат делал на этом модуле, только микроконтроллер взял PIC16f630. Точность в один градус. В мультиметре измерение реализовано по другому.
+
avatar
+7
В качестве термопары используется хорошо знакомая версия для мультиметров.
А чего бы её в мультиметр и не вставить?
+
avatar
+3
Жвачку в мультиметр жалко.
+
avatar
+2
  • trykov
  • 04 мая 2026, 16:42
Вставлял конечно. Температуру тела показывает 28. Температуру в комнате 18 вместо 24. Мне не нравится такая точность. А Вам?
+
avatar
0
Жала калибровать ± 10 градусов нормально.
+
avatar
0
  • trykov
  • 05 мая 2026, 14:05
Ну, в общем-то, да. Но всегда приятнее, если можно точнее сделать. ))
Ну и точный, компактный высокотемпературный термометр в хозяйстве всегда пригодится. ))
Учитывая остаток свободного места у ATTiny13, можно доработать до высокотемпературного терморегулятора или сигнализатора высокой температуры.
+
avatar
+2
  • trykov
  • 04 мая 2026, 18:44
А Вы им пробовали измерять температуру? Вот на той же самой термопаре мой мультиметр показывает вместо 24 в комнате — 18, температуру тела вместо 36 — 28.\Ничего не смущает?
+
avatar
+3
  • vlo
  • 04 мая 2026, 18:53
вам не повезло, возможно это особо дешевый современный 830ый. никаких других выводов из этого сделать нельзя.
+
avatar
0
  • trykov
  • 04 мая 2026, 20:03
Вы хотите сказать, что в Вашем мультиметре есть отдельная микросхема для работы с термопарой?
Или там обычное измерение микровольт?
+
avatar
0
  • vlo
  • 04 мая 2026, 22:41
хочу сказать что в куче мультиметров начиная с тех самых 830х что у меня есть, проблем подобного рода не наблюдается.
а отдельная микросхема — нафига? это она калечному ацп тиньки нужна, а не специализированным для мультиметров.
+
avatar
0
  • trykov
  • 04 мая 2026, 22:53
А можете показать, как Ваш 830-й точно измеряет, например, температуру тела или температуру в комнате — поставьте рядом с электронным комнатным термометром.
+
avatar
0
  • vlo
  • 04 мая 2026, 23:20
mastech m9508 — тот же 830ый в большом корпусе.
+
avatar
0
  • trykov
  • 04 мая 2026, 23:39
Ну вот — больше градуса уже есть.
Дальше будет хуже из-за нелинейности термопары. А-ля 830-е не умеют учитывать нелинейность термопар. ))
+
avatar
0
  • yup2
  • 05 мая 2026, 00:47
В мультиметрах обычно есть два подстроечника, предназначенные для настройки работы с термопарой. Но на заводе-изготовителе точным их выставлением никто не озабочивается, покупатели тоже крутить их не лезут, а в процессе перемещения мультиметра туда-сюда первоначально выставленные сопротивления куда-то да изменятся.

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

(Мне тут впервые за тридцать лет понадобилось измерять температуру более-менее точно, и именно мультиметром. А он десять лет назад делал это нормально, а сейчас, как оказалось, врёт безбожно. Вот и сижу, смотрю на его плату и чешу затылок — как же, не имея второго мультиметра, найти именно те два подстроечника, которые за термопару отвечают.)
+
avatar
+3
  • vlo
  • 05 мая 2026, 03:33
тут неизвестно у кого из них больше градуса. но такого требования и не стояло. описанных выше безобразий тут явно нет, этого достаточно.
+
avatar
0
  • icenet
  • 04 мая 2026, 19:39
Было горы мультиметров, и дома и на работе, все всегда показывают правильную температуру. Тем более, в тех диапазонах, которые все могут проверить, аля температура тела или кипения воды. Кабы они лгали, то считай каждый мог бы сходу выбивать с али компенсацию с каждого купленого мультиметра
+
avatar
0
  • trykov
  • 04 мая 2026, 20:05
А можете своим мультиметром свою температуру измерить и фотку выложить*
+
avatar
+4
  • icenet
  • 04 мая 2026, 20:33
Детский сад какой-то. Ну выложу я фотку, а вы скажете, что это я предварительно нагрел/остудил термопару и сфоткал в нужный момент.
+
avatar
+1
  • trykov
  • 04 мая 2026, 20:43
Ну вот — Вы же сами видите — больше полутора градусов разницы. И вариантов компенсации этого расхождения у Вас в мультиметре нет. А у меня есть. ))
И добавить какой-то ещё функционал в свой прибор я могу (например сохранение нескольких контрольных замеров по дополнительной кнопке или вывод показаний по Фаренгейту, или Кельвину, или превратить его в терморегулятор и т.д.), а Вы в свой мультиметр не сможете.
+
avatar
0
  • icenet
  • 04 мая 2026, 20:56
Да я против вашего измерителя ничего против не имею. Захотели + сделали, всё ок. Просто резануло глаз ваше утверждение, что мультиметры типа вообще температуру на Марсе показывают.
+
avatar
-1
  • trykov
  • 04 мая 2026, 23:01
Большинство дешевых так и показывают — плюс минус несколько градусов.
К тому же мультиметры без микроконтроллеров, с обычными вариантами а-ля ICL7106 не учитывают нелинейность характеристики термопары.
А она там есть. Вот для справки.
«Термопара имеет нелинейную характеристику. Зависимость между температурой рабочего спая и напряжением (термо-ЭДС), которое вырабатывает термопара, не является прямой линией (напряжение растет не пропорционально температуре).Ключевые особенности нелинейности: Большинство промышленных термопар (типы K, S, J, L и др.) имеют выраженную нелинейность, которая меняется в зависимости от измеряемого диапазона температур.
Причина: Эффект Зеебека сам по себе нелинеен, и величина термо-ЭДС зависит от разности температур горячего и холодного спаев. Как это учитывается: Для точных измерений приборы (вторичные преобразователи, контроллеры) используют специальные алгоритмы линеаризации, таблицы или полиномы для преобразования нелинейного напряжения в точную температуру.»
+
avatar
+2
  • kvarkk
  • 05 мая 2026, 14:03
Можно подумать, MAX6675 учитывает нелинейность. Вот что сказано в даташите:
Получается, что микросхема использует линейную зависимость. Это дает погрешность +-2 градуса. Единственное, что MAX6675 реально компенсирует, так это температуру холодного спая.
+
avatar
-1
  • trykov
  • 05 мая 2026, 15:14
Там, вроде, написано про то, что характеристика ТЕРМОПАРЫ типа К ПРИБЛИЖАЕТСЯ к линейному уравнению, приведённому ниже.
А где написано, что MAX не обрабатывает данные термопары для повышения точности?
+
avatar
0
  • kvarkk
  • 05 мая 2026, 16:28
В общем, да, прямо не сказано, что MAX6675 все считает по линейному закону. Однако нигде в даташите нет и упоминания о том, что она компенсирует нелинейность. Так что вопрос открытый пока.
Вот что говорит Алиса:
Точность работы MAX6675 указана как 8 LSB для температур от 0°C до +700°C, что подразумевает учёт погрешностей, включая нелинейность.
Qwen того же мнения:
В характеристиках указана точность:
«Thermocouple Accuracy: ±3°C (typ), ±5°C (max)» в диапазоне 0…+700 °C
www.datasheetall.com
.
Эта точность достижима только при учёте нелинейности характеристики К-типа. Если бы использовалась простая линейная аппроксимация (41
мкВ/°C), погрешность на краях диапазона (особенно ближе к 700–1000 °C) превышала бы десятки градусов.
+
avatar
+2
Я вот как раз болею, попробовал: 36° на мультиметре, 36.6° на ртутном, держал вместе подмышкой. Ура, вернулась в норму, ещё бы голос восстановился.

+
avatar
+1
  • trykov
  • 04 мая 2026, 20:48
Поздравляю — у Вас хороший прибор!
Ну и цена у него не слабая.
У меня такого нет.
Поэтому мне проще сделать свой прибор за недорого с такой же точностью. ))
+
avatar
+1
  • dkom
  • 04 мая 2026, 20:53
Нормальный мультиметр без подключенной термопары показывает комнатную температуру. Сравниваем с обычным домашним градусником. Далее подключаем термопару соблюдая полярность. Показания остаются такими же плюс-минус градус, т.к обычно у мультиметра нет десятых и он округляет. Узнаем давление на уровне квартиры. Вычисляем температуру кипения воды, сравниваем с показанием термопары. Если не живете в горах можно принять 99-100 в принципе грубо оценить хватит.
Если показания не совпадают — либо поддельная термопара, что встречается при покупке ее отдельно когда родную от мультиметра сломали или потеряли, либо «игрушечный» некалиброванный мультиметр
+
avatar
+2
А Вы им пробовали измерять температуру?
Измерял температуру термопарой в мультиметре еще до того, как это стало мейнстримом. Ни разу не сталкивался с такой большой погрешностью, как у вас. А тот же OWON даже десятые доли градуса на низкой температуре показывает. Погрешность где-то в пределах полградуса.

P.S. Ничего не имею против DIY, отвечаю лишь на сообщение о невозможности нормально измерять температуру мультиметром.
+
avatar
0
  • trykov
  • 05 мая 2026, 21:12
Ну тут, наверное, вопрос в том, каокго уровня мультиметр.
Те, что не на контроллерах, а на простых АЦП типа 7106, не отличаются точностью.
+
avatar
0
на простых АЦП типа 7106
Кажется, у меня первым ММ с термопарой был VC9805, не знаю, на чем он, но показывал тогда нормально.
+
avatar
+1
покупать на Али высокотемпературный точный измеритель температуры просто жаба задавила
а сколько они стоят?
+
avatar
+2
  • aliex
  • 04 мая 2026, 16:33
5 баксов простой — https://www.aliexpress.com/item/33006280425.html
10 — клон Хакко и пяток датчиков в комплекте — www.aliexpress.com/ssr/300000512/BundleDeals2?productIds=1005012013884820%3A12000057287106823

Пределы там, правда, 600 и 700 градусов заявлены, но для паяльной станции — с головой

Edit: теперь оно меня ими спамит… Вот за 3.45: https://www.aliexpress.com/item/1005008703344868.html — и всё это именно для паяльника, с соответствующим креплением датчика.
+
avatar
0
  • trykov
  • 04 мая 2026, 16:45
Вы внимательно смотрели на свои же ссылки? Там не 5, а 14 баксов.
+
avatar
0
мне показывает 8.7 бакса. Это адекватно совершенно имхо
+
avatar
+1
  • aliex
  • 04 мая 2026, 17:22
Смотрите сами
+
avatar
+2
У вас опция «только 20 датчиков», с прибором будет уже не 5 ;)
+
avatar
+3
  • aliex
  • 04 мая 2026, 18:24
Ааа! Подловил меня Али, думал, уже не попадаюсь на это. Тьфу.
Само устройство 12.31
+
avatar
0
ну нормальные цены
+
avatar
+2
  • trykov
  • 04 мая 2026, 18:48
у меня уже была в наличии часть комплектующих — я покупал только MAX6675 и корпус
+
avatar
+3
  • Detail
  • 04 мая 2026, 16:07
Проделанную работу оценил, отлично.

Неясна конечная цель.

Тм-902С решает задачу по приемлемой стоимости

Чтобы ТХА работала до 1200°С, ее нужно как-то упаковать — это главная проблема, с чем я, например, бился лично ) стандартные термопары типа К упакованы в нерж футляр из 304, который и ограничивает Т применения на уровне градусов 800°С.
+
avatar
-1
  • trykov
  • 04 мая 2026, 18:21
Ну это кому что нравится.
Мне мой обошелся дешевле.
Он меньше по размерам.
Нет проблемы со считыванием информации при пониженой освещённости.
Работает от аккумулятора и подзаряжается обычной телефонной зарядкой.
Есть возможность доработки программы под дополнительные хотелки.
+
avatar
0
Нужно ТПР ставить.
+
avatar
0
  • Detail
  • 05 мая 2026, 13:21
Это да, но стоимость ТПР против ТХА?

При том, что платина-родий для моих применений очевидно избыточна. Плюс, если правильно припоминаю — платинородиевым же нужен газовый поддув нейтральным газом, чтобы не происходило отравления и выгорания? Это не для бытового применения.
+
avatar
0
но стоимость ТПР против ТХА?
А температуры использования?
+
avatar
0
  • Detail
  • 06 мая 2026, 12:35
900°C..1100°C
+
avatar
0
Плюс, если правильно припоминаю — платинородиевым же нужен газовый поддув нейтральным газом, чтобы не происходило отравления и выгорания?<\code>

Платиновые сплавы выгорят очень нескоро.
+
avatar
0
  • kvarkk
  • 05 мая 2026, 14:05
Можно просто платиновый терморезистор поставить, цена вопроса — 100...200 рублей.
+
avatar
+6
Простите за глупый вопрос, вы с линий даты TM1637 выкусывали конденсаторы? Из-за них очень сильно фронты заваливает и приходится снижать скорость ногодрыга.

Сам когда писал либу под MAX31855 — github.com/enjoyneering/MAX31855. Меня тогда очень просили добавить линеаризацию термопары. Внезапно микруха этого сама не умеет. Вобщем вам есть еще чего добавить, чтобы вообще шик-блеск.

Кстати для усреднения очень хорошо работает медианный фильтр на 3 измерения. Пример тут — github.com/enjoyneering/HCSR04
+
avatar
0
  • trykov
  • 04 мая 2026, 18:23
Нет, конденсаторы не убирал.
Одна дополнительная команда в коде решила проблему неустойчивого обмена данными.
+
avatar
0
Я никогда не снимаю ни конденсаторы, ни резисторы с модуля ТМ1637. Все работает нормально. «Недодрыг» на индикации не «дрыгает».
+
avatar
0
У вас видимо медленный ногодрыг. Мне жалко тратить циклы процессора на лишние delay, поэтому выкусываю.

Эти конденсаторы нужны при работе с устройствами создающие большие помехи, типа коллекторных двигателей и тд.
+
avatar
0
  • rem1
  • 04 мая 2026, 17:37
по деталям выходит у меня 600 рублей, Так то всё нечего, но вот со слов аватар, жаба задушила. Не понять.
За див конечно плюс
+
avatar
0
  • trykov
  • 04 мая 2026, 18:27
У меня уже были и термопара, и контролер, и индикатор, и аккумулятор, и плата заряда аккумулятора.
Докупались только корпус и MAX 6675.
Итого 2,5 бакса затрат.
+
avatar
+3
А теперь подушним. :)))) Температура 100С у кипящей воды только при 760мм рт. столба. Для калибровки по воде сначала надо озадачиться барометром. Соленостью, наверное, можно и пренебречь.
+
avatar
+1
  • trykov
  • 04 мая 2026, 18:30
При атмосферном давлении 770 мм рт. ст. и 750 мм рт. ст. температура кипения воды составляет:
При 770 мм рт. ст.: примерно \(100,37^\circ\text{C}\).
При 750 мм рт. ст.: примерно \(99,63^\circ\text{C}\).
Как видно из этих данных, изменение давления на каждые 10 мм рт. ст. от нормального (760 мм рт. ст.) меняет точку кипения примерно на \(0,37^\circ\text{C}\) в соответствующую сторону.
+
avatar
+3
А вы на какой высоте над уровнем моря? :)
Вот, например, для Москвы сегодня давление 742 мм рт.ст., моя квартира примерно на 40-50 метров выше базовой погодной станции, если верить навигации, карте высот и яндексу. Т.е у меня должно быть примерно 738 мм рт.ст., что даёт около 99.16 градусов кипения воды. Ближе к 99, чем к 100.

Хотя при точности МАХ в 2 градуса толку от такой калибровки мало. Но… Когда-то я пытался по воде откалибровать свою схему тоже, поверенный прибор показывал 99.2-99.4 температуру кипящего чайника. Вот и вспомнилось к случаю. :)
+
avatar
0
  • trykov
  • 04 мая 2026, 20:14
257 метров
+
avatar
+1
Даже выше, чем у меня. Вполне вероятно, что кипит и при 99-99.1 С.
Но это я так, подушнить в качестве развлекательного чтения.
+
avatar
0
  • trykov
  • 04 мая 2026, 23:18
Вблизи земной поверхности атмосферное давление падает примерно на 10 мм рт. ст. на каждые 100 метров подъема (или около \(1\) мм рт. ст. на каждые \(10-12\) метров).
Давление бортовой компьютер машины показывает 992 мбар. Это 744 мм.
+
avatar
+2
https://www.ozon.ru/product/termometr-tester-5-bessvintsovyh-datchikov-0-700-c-3506674761

613 рублей в Озоне… И тут мне вспомнился пошлый анекдот про размеры и форму огурчиков… «Мне без разницы форма и размеры — мне их в окрошечку»… Сколько времени у меня уйдет на ожидание комплектухи, поиски всякой всячины для комплекта, пайку, программирование… Я за час зарабатываю больше, чем стОит готовый прибор! Я лучше потрачу свободное время на более полезные дела, с теми же Ардуинками более интересные и нужные проекты…
+
avatar
+2
  • trykov
  • 04 мая 2026, 20:18
Так на вкус и цвет все фломастеры разные.))
Каждый тратит свободное время как хочет.
Меня мой вариант времяпрепровождения вполне устраивает. ))
+
avatar
+8
У нас был микроконтроллер Attiny, какая-то термопара, светодиодный дисплей, аккумулятор от электронной сигареты с платой зарядки, микросхема преобразования, и целое море рассыпухи, корпусов и термоклея, а так же компьютер и среда разработки для Ардуино, светодиод и куча свободного времени. Не то, чтобы всё это было категорически необходимо для измерения температуры, но если уж начал электронничать, то к делу надо подходить серьёзно. ©
+
avatar
0
  • trykov
  • 05 мая 2026, 14:20
Не, ну согласитесь, что про МОРЕ рассыпухи в виде трёх СМД резисторов и кнопки Вы погорячились. ))
+
avatar
+1
  • kvarkk
  • 05 мая 2026, 14:08
Купил такой прибор, завышает температуру градусов на 10-20. И вот что теперь с ним делать? Калибровать его вроде нельзя.
+
avatar
0
  • trykov
  • 05 мая 2026, 14:21
О, вот и ещё одно преимущество самодельного решения выплыло. ))
+
avatar
0
  • kvarkk
  • 05 мая 2026, 14:30
Тут согласен. Видимо, буду этот покупной прибор переделывать, оставив только корпус. Но там хотя бы удобный держатель термопары, это плюс.
+
avatar
0
  • trykov
  • 05 мая 2026, 15:31
Ну это держатель для измерения температуры жала удобный. А если что-то измерять выносным датчиком, то уже вопрос.
+
avatar
+9
  • sfs
  • 04 мая 2026, 21:01
Как-многовато хейта в комментариях. «Дешевле купить», «нечего было время тратить»… Ну автору виднее куда и зачем ему тратить время и деньги, это же DIY. Повторять же никто не заставляет. Хотя проект вполне себе неплохой: мелкий МК, компактный код. И Си в Ардуино ИДЕ это не стандартно. Так что проект еще и неплохой пример для начинающих ембеддеров, желающих выйти за ограничения/экстенсивность Wiring. По-моему автор заслуживает похвалы за разработку, а он почему-то вынужден оправдываться… Лично я прочитал с интересом, спасибо!
+
avatar
+2
  • vlo
  • 04 мая 2026, 22:45
И Си в Ардуино ИДЕ это не стандартно.
в смысле?

По-моему автор заслуживает похвалы за разработку, а он почему-то вынужден оправдываться…
ну так его аргументация критики не выдерживает.
но зачем она вообще нужна — непонятно, захотел — сделал.
+
avatar
0
  • trykov
  • 04 мая 2026, 23:08
А какая вам нужна аргументация? ))
У меня при разработке была такая:
— была в наличии часть комплектующих
— покупать готовый было дороже
— готовое решение невозможно доработать, при необходимости
— нужен был прибор для калибровки
— нужно было проверить, сколько кода займёт обмен с TM1637 для дальнейшего применения такого индикатора с этим контроллером в паяльной станции
+
avatar
+4
  • vlo
  • 04 мая 2026, 23:12
да вроде ясно написал — никакая.

но если так хочется поспорить, то во1ых готовый таки дешевле, во2ых сама идея калибровки паяльника практического смысла не имеет, равно как и изобретения велосипеда в этой (ейный контроллер) области — тоже, ибо их полно готовых и тоже — дешевле.
+
avatar
0
  • trykov
  • 04 мая 2026, 23:35
С какого это счастья покупной дешевле?
Ссылочку дадите на покупной за 4 доллара?
Ссылочку на паяльную станцию с цифровым дисплеем и ценой до 10 долларов дадите?
А если Вам не нравится точное отображение температуры жала на дисплее, то это только Выша личная проблема. Не нужно за всех делать подобные заявления. ))
Мне достаточно было примера, когда паяльная станция GVM T12-XS за сорок долларов, свежепривезённая из магазина, врала более, чем на 30 градусов.
+
avatar
+1
  • vlo
  • 05 мая 2026, 03:30
с такого что дешевле. вот например 220р:
https://www.ozon.ru/product/tm-902c-portativnyy-udobnyy-izmeritel-temperatury-k-tip-zhk-tsifrovoy-termometr-termopara-zond-1300-4108968321

контроллер — 600р:
https://www.ozon.ru/product/youlort-payalnik-75-vt-keramicheskiy-nagrevatel-1281909521

мне на него пофиг, а с подобного бессмысленного перфекционизма — смешно.
+
avatar
0
  • trykov
  • 05 мая 2026, 10:17
Я не в РФ. А на алике дешевле 6 долларов не вижу такого прибора.
И контроллера паяльной станции дешевле 10 долларов там тоже нет.
А на тиньке и TM1637 контроллер обойдётся в пять баксов. Так что Ваш пример с Озона всё равно дороже — 8 у.е.
Ну, а если Вас не смущает ошибка паяльной станции более 30 градусов, то я же не настаиваю — работайте и такой.
Я предпочитаю поточнее.
+
avatar
+1
И Си в Ардуино ИДЕ это не стандартно.
А что непонятного-то? Arduino IDE живёт поверх парадигмы wiring — надстройки над C++.

Программировать в среде Wiring на «чистом C» — своеобразное эстетство. Сам порой балуюсь.

«Потому что могу».

Очень красивый проект.
+
avatar
+1
  • vlo
  • 05 мая 2026, 03:31
ну и что может мешать в рамках cpp писать на чистом c?
смысл правда сильно не очевиден, ибо в плюсах безотносительно всякого обьектного есть удобные конструкции.
+
avatar
0
  • sfs
  • 05 мая 2026, 08:57
Ну если не очевиден, тогда действительно любые аргументы автора в дискуссии бесполезны.
+
avatar
0
  • vlo
  • 05 мая 2026, 15:37
причем тут автор? это вас чем-то зацепило.
у автора странное только про цены.
+
avatar
0
Программировать в среде Wiring на «чистом C» — своеобразное эстетство. Сам порой балуюсь.
Если взять С++ код, половина его строк будут полностью совместимы с С. Если уж говорить об эстетстве, то для АВР это ассемблер)
+
avatar
+1
  • trykov
  • 05 мая 2026, 21:25
Ой, не — что-то душа не лежит на ассемблере с АВР сражаться. Может возраст уже не тот. ))
Хотя в молодости и в кодах 580-го процессора напрямую приходилось кодить. ))
+
avatar
0
на ассемблере с АВР сражаться
У АВР очень простой ассемблер и много регистров) Писать на нем — удовольствие, особенно, когда надо какой-то интересный алгоритм в минимум тактов уложить. Но, конечно, тут каждому своё.
+
avatar
+1
  • trykov
  • 06 мая 2026, 00:17
ОК. Уговорили. Попробую. ))
+
avatar
+3
  • IWRY
  • 06 мая 2026, 12:16
в кодах 580-го процессора напрямую приходилось кодить
Когда деревья были ещё большими, переводил узел электронной почты с UUCP на сендмейл по SMTP, а поскольку до этого на 8080 и Z80 писал почти исключительно на Ассемблере, то и тут биллинг (почта была платной для клиентов) через обработку логов сендмейла написал на нём же, только на 8086, разница невелика.
Со всей математикой, с выводом в текстовую таблицу для бухгалтерии, все дела…
Это, видимо, моё личный рекорд несоответствия инструмента задаче )))
+
avatar
+1
  • trykov
  • 06 мая 2026, 12:22
))
Да уж — были времена.
И всё это без помощи ИИ. ))
+
avatar
0
несоответствия инструмента задаче
Не факт, что несоответствия — в те времена компиляторы оптимизировали плохо, например, паскалевский код выполнялся примерно в 10 раз медленнее ассемблерного. Про сишный не помню, но, думаю, раза в три разница была.

Единственное, поддерживать такой продукт труднее.
+
avatar
+1
  • IWRY
  • 07 мая 2026, 07:35
в те времена
на юниксах компиляторы работали замечательно.
Если Вы (вдруг) не в курсе, типичная процедура инсталляции FreeBSD заключается в формировании конфигурационного файла и последующей компиляции ВСЕЙ системы под конкретную машину прямо на ней же.
Но тут сама задача и не требовала компиляции вовсе, можно было писать хоть на Бейсике.
Надо всего лишь отпарсить текстовый лог-файл сендмейла за месяц, выбрать из него нужные данные, разложить по юзерам, пересчитать в объёмы, перемножить на цены и выдать табличку для бухгалтерии, будет оно при этом считаться 5 секунд или два часа — не имеет значения.
Буквально парой лет позже намного более сложный биллинг реального времени для карточного дайлапа я написал на перле, который для этих целей подходит просто идеально, и система успешно работала много лет, до физической кончины дайла у этого ИСП.
+
avatar
0
на юниксах компиляторы работали замечательно.
Работать они могли как угодно, но выдаваемый ими код был хуже ассемблерного. Несколько лет назад я тестировал Visual Studio 2017 и она всё еще генерировала плохой код, значительно хуже IAR. GCC генерирует отвратительный код под AVR. Создание хорошо оптимизирующих компиляторов — задача, еще находящаяся в процессе решения. А 25 лет назад ситуация была еще хуже.
я написал на перле, который для этих целей подходит просто идеально
Когда в нашем городке частные компании начали переходит с дайлапа на постоянные подключения, безлимита поначалу не было и платили за объем. У нас в компании (где я тогда работал) решили разрешить сотрудникам доступ к интернету, но брать с них деньги за скачанный объем, поэтому возникла задача создать инструмент, который бы этот объем считал. Я также написал на перле анализатор логов WinGate, что задачу решило. Однако подсчет логов за месяц занимал несколько минут, из-за чего я не мог выложить это решение в публичный доступ и разрешить всем сотрудникам самостоятельно смотреть, сколько они потратили. Тогда я переписал анализатор на С++ используя memory mapped file и оптимизированный подсчет, что сократило время его работы до 10-15 секунд!
+
avatar
0
А ничего, что Перл — интерпретируемый язык? Давайте тогда уж сравнивать с Бейсиком. Тоже можно писать анализаторы журналов. Хотя Перл, разумеется, изначально был заточен именно под такие задачи.
+
avatar
0
А ничего, что Перл — интерпретируемый язык?
Вообще-то перл компилируется в некий «байт-код» при запуске скрипта, так что полностью интерпретируемым его считать нельзя.
+
avatar
0
… как и Питон.
+
avatar
0
  • yup2
  • 08 мая 2026, 12:16
Можно ещё и Javascript вспомнить. Причём это будет самый поучительный пример: язык возник как чисто интерпретируемый, а сейчас компилируется непосредственно в процессорный код (та самая JIT-компиляция). И все остальные названные и не названные выше интерпретируемые языки, в принципе, можно с помощью JIT в код превращать.

Но при этом такие откомпилированные программы всё равно будут менее производительны, чем программы, написанные на нормальных компилируемых языках, из-за больших накладных расходов, вызванных изначальным наличием в исходных языках особенностей, характерных для интепретируемых языков.
+
avatar
0
  • IWRY
  • 08 мая 2026, 08:33
перл компилируется в некий «байт-код»
Так и Бейсик — в тех версиях, где я его копал — тоже не в плейн-тексте программы исполняет))
+
avatar
0
  • IWRY
  • 08 мая 2026, 08:36
Перл — интерпретируемый язык? Давайте тогда уж сравнивать с Бейсиком
Это несравнимо)
На что перлу достаточна одна строка, в бейсике потребует пару станиц.
+
avatar
+2
  • IWRY
  • 08 мая 2026, 08:28
подсчет логов за месяц занимал несколько минут
Даже не представляю, что это за предприятие такое, — там половина России работала, что ли? ))
Я писал тот биллинг на коленке и сам, один. Собсна, и весь узел собирал сам))
Раз в минуту один перловый скрипт через rlogin опрашивал поочерёдно все модемные пулы, сделанные на роутерах Cisco 3640, — «кто сейчас на линии», складывал в файловый буфер, всего было около 200 модемов, подключенных потоками ISDN PRI.
Другой скрипт брал из буфера, парсил, и для каждого активного юзера проверял в базе на мыскле его тарифный план, вычитал из остатка его баланса стоимость минуты в соответствии с временем суток по тарифному плану, и если вдруг остался ноль или появился административный запрет (оператор отключил юзера) — ставил на него флаг третьему скрипту, который заходил через rlogin на нужную киску и отключал юзера.
При подключении юзера киска запрашивала доступ для него у радиуса, который адресовался к четвёртому скрипту, тот проверял в той же базе на мыскле, есть ли такой юзер, не запрещён ли административно, хватит ли у него денег на балансе хотя бы на минуту работы в соответствии с его тарифным планом и временем, и выдавал или не выдавал разрешение радиусу, а тот — модемному пулу.
Там же крутились два простеньких веб-интерфейса на том же перле, один административный, для ввода/удаления/пополнения баланса операторами, другой — юзерский, для текущего контроля.
Карты вводились в базу пачками по 100 штук, были и индивидуальные аккаунты по договорам, вводились, понятно, по одному.
Всё это работало на двух самосборных p266, на одном — мыскль и радиус, на другом — собственно биллинг и веб-морды.
На каком-то из них крутились ещё и сендмейл для всех желающих, и МРТГ (а он тоже на перле) для рисования в рил-тайме красивых графиков загрузки модемных пулов, каналов и пр.
Всё — под FreeBSD.
И замечательно, с огромным запасом хватало производительности этих двух дохлых петухов на ежеминутный, напоминаю, контроль, вообще никакой потребности что-то переписывать более оптимально не возникало.
А, ещё примерно на такой же железке отдельно был собран BGP-роутер с брендмауэром и шейпером, тоже под фрями, я ж честно получил в райпе под этот узел AS и блок IP-адресов ))
+
avatar
0
Даже не представляю, что это за предприятие такое, — там половина России работала, что ли? ))
Логов вингейта набиралось несколько сотен мегабайт. Перлу было сложно парсить их регулярками, вот он и тормозил.
киску
Сиску :) Как бы это по-русски не звучало двусмысленно, но произносится именно так.
+
avatar
+1
  • IWRY
  • 12 мая 2026, 07:17
Логов вингейта набиралось несколько сотен мегабайт.
Хз как это в вингейте, но в норме лог — линейный тестовый файл, парсится построчно по ходу чтения, так же по ходу чтения выполняется вся математика, нет никакой надобности его читать в память целиком и там ворочать.
И начиная, как минимум, с тех же P266 обработка любого лога построчно выполняется быстрее, чем его чтение с диска — хоть на ассемблере, хоть на перле.
В моём опыте это так.
Сиску :)
Хыыы… полагаете, я не в курсе? )))))
+
avatar
0
И начиная, как минимум, с тех же P266 обработка любого лога построчно выполняется быстрее, чем его чтение с диска — хоть на ассемблере, хоть на перле.
Совсем нет. Во времена Р2 266, насколько я помню, был уже стандарт Ultra DMA 66, то есть, дисковый интерфейс на 66 МБ/сек. Диски при этом давали емнип 50 МБ/сек линейного чтения. Лог, конечно, не обязан располагаться на диске линейно, но, думаю, 25 МБ/сек он читаться мог. Отсюда чтение лога на 200 МБ — всего 8 секунд. А вот его обработка занимала пару минут.

И не забывайте, что перл силен регулярными выражениями, которые легко обрабатывают логи, но тяжело даются процессору, это и объясняет скорость обработки.
Хыыы… полагаете, я не в курсе? )))))
Полагаю, вы же пишете иначе )
+
avatar
0
  • IWRY
  • 13 мая 2026, 08:06
25 МБ/сек он читаться мог
Обычные десктопные харды того времени плюс-минус умещались в производительность 100Мбод сетевого адаптера.
тяжело даются процессору
На перле тоже можно писать очень по-разному. Я, повторю, не замечал проблем со скоростью обработки логов. Вообще. И никогда такого не было, чтобы результата приходилось ждать «несколько минут».
вы же пишете иначе )
Пишу так, как в ту пору принято было их называть среди посвящённых ))
+
avatar
0
На перле тоже можно писать очень по-разному. Я, повторю, не замечал проблем со скоростью обработки логов.
Писать по-разному можно везде. Но обычно на перле все текстовые данные обрабатываются с помощью регулярок, ведь в этом и есть его сила. А регулярки работают достаточно медленно в сравнении с обычным поиском. Да, если бы я логи парсил по аналогии с С++, где я точно не использовал регулярки, скорее всего, перл бы не проиграл в 10 раз. Но только какой смысл тогда вообще на перле изначально писать? Читать файлы я и на С++ неплохо умею.
Пишу так, как в ту пору принято было их называть среди посвящённых ))
Посвященных во что? В незнание английского? ) В ту пору их называли, в основном, «Циско», что еще можно понять, т.к. английская С во многих сокращениях по какой-то причине произносилась как Ц. Например, MSVC (Microsoft Visual C) — «МСВЦ». Также была еще одна легенда, что Cisco — это окончание San-Francisco, а раз у нас это произносится как «Сан-Франциско», значит, и Cisco надо читать «Циско».

А вот произношение «Киска» считалось мерзко-издевательским, когда маршрутизаторы пытались сравнивать с теми самыми «мокрыми кисками», которых можно было тогда полно найти в интернете. Неужели именно эту предметную область вы и назвали «для посвященных»? ))
+
avatar
+1
  • IWRY
  • 14 мая 2026, 07:36
Но обычно на перле все текстовые данные обрабатываются с помощью регулярок, ведь в этом и есть его сила.
Так и регулярки можно написать очень и очень по-разному.
А регулярки работают достаточно медленно в сравнении с обычным поиском.
Пишите регулярки удобно для транслятора — и не будет великой разницы.
А вот произношение «Киска» считалось мерзко-издевательским, когда маршрутизаторы пытались сравнивать с теми самыми «мокрыми кисками»,
Ничоси, Вас понесло )))
Киска — скорее, снисходительно-уменьшительно-ласкательное, как к симпатичной, но вредной и взбалмошной любимой девушке.
Про «незнание английского», а заодно и прямых указаний Создателя, расскажете тем, кто пишет «линуХ» )))
+
avatar
0
Про «незнание английского», а заодно и прямых указаний Создателя, расскажете тем, кто пишет «линуХ» )))
Это вы указали на касту каких-то «посвященных», я и предположил, что посвящены они в незнание английского, т.к. с перед i и e читается как «эс». А вот если английский не знать, можно читать и как «к».

Что касается линуха — это прижившийся жаргон (к сожалению?). Также как «лухури», например.

То есть, разница тут в том, что в одном случае человек ошибся и прочитал неправильно, а в другом — исказил намеренно.
+
avatar
0
  • IWRY
  • 15 мая 2026, 07:07
в одном случае человек ошибся и прочитал неправильно, а в другом — исказил намеренно
Нет разницы, киски называли кисками не по ошибке, а именно намеренно.
Среди тех айтишников /и названия-то такого ещё не было/, с кем я тогда активно общался и кого назвал «посвящёнными» /ибо очень мало нас тогда ещё было, и общались преимущественно, не поверите, — в фидонете )))/ это был ровно такой же типовой жаргон, как сейчас «линуХ».
Хотя, справедливости ради, были и поборники «чистоты языка», ага, и версию про Сан-Франциско тоже видел.
Между прочим, были несколько случаев, когда экспаты, — и нативные американцы, и всякие разные другие, — с которыми приходилось общаться на эту тему, замечательно понимали, о чём идёт речь, если по привычке говорил «киска» )))
+
avatar
0
замечательно понимали, о чём идёт речь, если по привычке говорил «киска»
Когда общение идет с иностранцами, главная цель — понять собеседника, что не всегда бывает тривиально. Вопросы произношения уходят на второй план, поэтому если ты понимаешь примерно, о чем речь и можешь додумать остальное, то на ошибки стараешься не обращать внимание. Я работал с американцами, они вообще никогда нас не поправляли, даже если мы говорили откровенно неправильно. Например, у нас один человек из команды target всегда произносил «тарджет» (правильно — «таргет»), его ни разу никто не поправил.

Касательно сиски, в наших краях её повсеместно звали «циска». «киска» я слышал только от тех, кто не умел правильно читать название, либо когда был намек на неиллюзорные половые отношения с её конфигурацией в виде длительного и мучительного пердолинга последней. И, предположительно, второй вариант использования пошел от первых — кто-то неправильно прочитал, другим понравилось.
+
avatar
0
  • IWRY
  • 18 мая 2026, 13:42
Я работал с американцами, они вообще никогда нас не поправляли
Разные бывали случаи ))
неиллюзорные половые отношения с её конфигурацией в виде длительного и мучительного пердолинга последней
Это какая-то местная специфика, похоже.
Да и чего там пердолить?
Мне они вообще с первого взгляда вкатили — всем, кроме цены )))
Документация у них с самого начала была очень грамотная и качественная, да и альтернативы во многих случаях в те времена не было в принципе.
Помню, как восхитился идеей интерливинга, — когда году в 1997, если не путаю, мы пытались в один обычный телефонный спутниковый серийный линк на 64 кбод вструмить 4 канала VoIP и параллельно передачу данных, чтобы на дальнем объекте организовать электронную почту впридачу к телефону, и это удалось))
И называли их не только кисками, но и кошками, и вовсе не было в этом негативной коннотации — какой вообще может быть негатив к кошкам?
+
avatar
0
  • yup2
  • 14 мая 2026, 12:23
Чё-то меня в сторону потянуло…

Посвященных во что? В незнание английского? )
маршрутизаторы пытались сравнивать с теми самыми «мокрыми кисками»
Те самые «мокрые киски» сами по себе результат незнания английского, ибо «pussy» означает совсем не «кошечка».

Что интересно, как минимум в восьмидесятые в народе употреблялся именно правильный перевод этого слова. Но, наверное, никто не подозревал, что это перевод, потому что очень уж по-русски оно звучало.
+
avatar
0
Те самые «мокрые киски» сами по себе результат незнания английского, ибо «pussy» означает совсем не «кошечка».
Откуда, откуда берется столько самоуверенности у тех, кто не знает? ) Ну вы хоть погуглите сначала, перед тем как писать. Pussy произошло от puss, вед так даже сейчас там подзывают кошек. У нас «кис-кис-кис», у них «puss-puss-puss».
+
avatar
0
  • yup2
  • 14 мая 2026, 16:52
Откуда, откуда берется столько самоуверенности у тех, кто не знает? ) Ну вы хоть погуглите сначала, перед тем как писать.
И тем не менее, даже по той ссылке написано (с примерами), что слово это означает не только кошку, но и «anything soft and furry».

Соответственно, в описаниях порнофильмов для «pussy» гораздо более уместным и точным переводом, чем «киска», является «мохнатка».
А для многих прочих случаев — «пушистик».
+
avatar
+1
  • IWRY
  • 08 мая 2026, 08:42
выдаваемый ими код был хуже ассемблерного
Сильно зависит от.
Хороший умный программист, разумеется, на ассемблере сделает лучше, чем сможет компилятор.
Но много ли может сделать один хороший умный программист?
А при масштабном производстве, когда задачу приходится разбивать на множество частей для множества разных людей с разными навыками и мозгами, использование компилятора легко может дать лучший результат.
+
avatar
+2
  • yup2
  • 08 мая 2026, 13:19
Хороший умный программист, разумеется, на ассемблере сделает лучше, чем сможет компилятор.
С тех пор, как у процессоров появились конвейер, параллельное и опережающее (спекулятивное) исполнение, компиляторы, потенциально, способны порождать более эффективный код, чем человек. Потому что человек не сможет учесть нюансы растактовки параллельного исполнения команд.
+
avatar
0
Но много ли может сделать один хороший умный программист?
В одном из первых сообщений я написал:
Единственное, поддерживать такой продукт труднее.
Но есть места, оптимизация которых дает огромный прирост. Например, мы решали одну задачу где нам надо было выводить масштабированный растр. Мой коллега сделал это по пикселям — цикл, цикл, вычисление адреса пикселя, вывод. Код был простой и понятный, но давал практически два кадра в секунду. Тогда пришел я, переписал это на ассемблер х86, добавил MMX для коррекции растра на лету, подняв производительность до сотни (емнип) кадров в секунду.
Кстати, не вижу здесь связи, даже если так.
Связь простая — 50 пользователей по 2 минуты — это уже 100 минут. Каждый пользователь дергал сервис раза 3 в день, это 5 часов пустой работы процессора. А сервер должен был еще другие задачи выполнять, интернет он раздавал «постольку поскольку». Ну, и если сразу 2-3 человека ткнут в сервис, результата вообще никто не получал, отваливалось по таймауту.
Или сделать запуск по крону раз в час с расчётом для всех, а по запросу юзера выдавать ему его цифру с точностью до последнего часа, «по состоянию на 13.00».
Позже я так и сделал, когда нагрузка даже от сишного кода стала мешать основным функциям сервера. Но я же здесь не архитектуру обсуждаю, а сравнение быстродействия перла и си.
+
avatar
+1
  • IWRY
  • 12 мая 2026, 07:23
если сразу 2-3 человека ткнут в сервис, результата вообще никто не получал, отваливалось по таймауту
Вы под виндами всё это делали чоли?
Виндовый перл — тот ещё перл, форки какие-то липовые, пайпы вообще нерабочие, да и в целом всё через ж.
Как минимум, так было четверть века назад )))))
+
avatar
0
Вы под виндами всё это делали чоли?
Да. У нас никто в то время линух не умел админить, да и не надо было, по сути. Потому что многие серверные раздавалки лицензий умели работать только под виндой. Ну, и как бы название «ВИНгейт» на это намекает ))
Как минимум, так было четверть века назад )))))
А вот о быстродействии перла тех лет сказать ничего не могу, не помню. Использовали, кажется, ActiveState Perl 5. Но, правда, ни форков, ни пайпов при обработке логов не было.
+
avatar
0
  • IWRY
  • 13 мая 2026, 08:20
никто в то время линух не умел
Я и до сих пор толком не умею линух /заметьте, Вы тоже пишете не по канону)))/, хотя есть пара VPS на Дебиане для ВПН, рутеры все везде под РоутерОС от Микротика (типа, тоже разновидность линуха) и смарты под Андроидом (как бы тоже).
Работу строил на FreeBSD, это вообще другая система, другая команда (название как бы намекает на Berkeley Software Distribution) и другая история, намного более древняя и фундаментальная, чем линух.
В 2000 году линух был ещё довольно сырой наколенной поделкой /на мой взгляд, канеш/, а BSD — серьёзной системой с серьёзным бэкграундом.
о быстродействии перла тех лет сказать ничего не могу
Я могу, сравнивал всяко-разно, отстой был полный на виндах.
+
avatar
0
/заметьте, Вы тоже пишете не по канону
Что вы имеете в виду?
BSD — серьёзной системой с серьёзным бэкграундом.
Так её тоже никто у нас тогда не умел ни то что админить, даже просто установить) Но и, справедливости ради, задач под неё не было.
+
avatar
0
  • IWRY
  • 14 мая 2026, 07:21
Что вы имеете в виду?
Ну, Вы до меня докопались за «киска» вместо «сиска», но при этом пишете «линух» вместо «линукс», как завещал лично Автор.
Так её тоже никто у нас тогда не умел
«Если вы в чём-то не разбираетесь, но хотите разбираться, начните разбираться — и разберётесь» )))
+
avatar
0
как завещал лично Автор.
Вряд ли г-н Торвальдс что-то завещал на русском языке ) Он вообще нас не любит.
«Если вы в чём-то не разбираетесь, но хотите разбираться, начните разбираться — и разберётесь» )))
Так не надо было, я ж два раза сказал) Изначально сервер создали даже не из-за сетевой шары, а из-за менеджера лицензий какого-то софта, который проверял аппаратный ключ и раздавал лицензии по сети. А уже потом сделали шару, подключили принтер, научили раздавать интернет и т.п.

Так вот, менеджер лицензий этот был только под винду, т.к. сам софт был тоже только под винду.

Ну, и даже если бы сервер подняли на FreeBSD, разбираться с её админством заняло бы гораздо больше времени. То есть, было бы экономически невыгодно для организации.
+
avatar
0
  • IWRY
  • 15 мая 2026, 07:02
Вряд ли г-н Торвальдс что-то завещал на русском языке )
Он завещал это устно, вслух, и русскими буквами это никак невозможно написать как «линуХ» )))
Вот:
Создатель операционной системы Линус Торвальдс записал аудиофайл, который стал историческим стандартом. В нем он на английском языке говорит: «Hello, this is Linus Torvalds, and I pronounce Linux as Linux».
Буква «i» произносится как краткий звук «и», а не «ай».
Буква «u» звучит близко к русскому «у» (хотя в шведском и финском языках, родных для Линуса, этот звук находится посередине между «у» и «о»).
Уверен, что при желании Вы легко найдёте и саму эту аудиозапись.
было бы экономически невыгодно для организации
А для себя?
А чисто из инженерного любопытства?
Просто чтобы быть в курсе и саморазвития для.
+
avatar
0
Вот:
А, так это было потому, что его начали произносить «лайнукс» )
А чисто из инженерного любопытства?
Не было его) Тогда настроить раздачу интернета — уже был успех. Интерес к линуксу (уже линуксу) у меня появился сильно позже, году в 2013, когда мы с товарищем подняли на собственном сервере небольшой сайт со скриптами и БД с нуля. Позже, по собственной инициативе, я перевел сайт компании с платного хостинга (такая услуга) на VPS.
+
avatar
0
  • IWRY
  • 08 мая 2026, 09:19
подсчет логов за месяц занимал несколько минут, из-за чего я не мог выложить это решение в публичный доступ
Кстати, не вижу здесь связи, даже если так.
Нажал юзер кнопочку «посчитать» на веб-морде, через «несколько минут» получил в почту файлик с итогом, в чём проблема?
Или сделать запуск по крону раз в час с расчётом для всех, а по запросу юзера выдавать ему его цифру с точностью до последнего часа, «по состоянию на 13.00».
+
avatar
0
Надо только припомнить, что паскаль вообще создавался Виртом как «компилируемая замена Бейсику» — изначально был «языком для обучения программированию».

Да, первые компиляторы Паскаля были ох и ах. Однако среда ТурбоПаскаль сделала язык столь популярным, что гиганты просто не могли пройти мимо поля непаханного. Дальше от версии к версии компиляторы становились сильно умнее.

Си — изначально «надстройка над ассемблером». Он НЕ МОГ работать медленнее. Вот не всегда экстремально идеально — да, матёрый ассемблерщик всегда мог выкроить пару килобайт или сотню тактов, переписав на ассемблере. Поэтому Кёрниган с первой минуты имел в линии языка обязательную поддержку инлайн-вставок инструкций ассемблера. С первых же минут, с нулевой версии.
+
avatar
0
Он НЕ МОГ работать медленнее.
Вот сейчас ерунду написали) Он, как надстройка, не мог работать быстрее ассемблера, а медленнее — вполне работал.

Вы смотрели код, который выдает компилятор? Я смотрел. Во всех компиляторах и под все платформы, с которыми работал. И впечатлил меня только IAR под ARM — вот он реально генерировал крутой код, который было тяжело побить ассемблером. Но, тем не менее, свое демонстративное Radix-4 FFT компания ST (производитель STM) написала на ассемблере.
+
avatar
0
Он, как надстройка, не мог работать быстрее ассемблера
Вот сейчас ерунду написали. Потому что «надстройкой» он является исключительно с точки зрения лингвистики. И первые же компиляторы Си имели нехилые оптимизаторы. Выдававшие ассемблерный код более качественный, чем студенческие потуги начинающих ассемблерщиков.

Да, я всегда смотрю код. На всех платформах. И меня, например, притно удивил код, который компилируется из C++ под AVR.
+
avatar
+1
  • yup2
  • 08 мая 2026, 12:57
И первые же компиляторы Си имели нехилые оптимизаторы.
Язык C вырастал постепенно из макроассемблера для DEC-овских процессоров. И специфика системы команд этих процессоров торчит у него изо всех щелей. При том, что у процессоров других фирм аналогичных особенностей нет, и для них эти языковые извраты нафиг не нужны.

У первых компиляторов C никакой оптимизации не было. Хотя бы потому, что компиляторы эти писали те самые люди, которые этот язык сочиняли. А у них для этого не было времени — их производственным заданием было написать («быстренько склепать») операционную систему для компьютера, создаваемого в это время той фирмой, в которой они трудились.

С точки зрения возможности получения эффективного кода между Pascal и C нет никакой разницы. Вообще никакой. (Если, конечно, исключить из рассмотрения компиляцию для DEC-овских процессоров ;-) )

Сейчас уже мало кто помнит, но у некогда у Microsoft были компиляторы с Fortran, Pascal и С. А фактически это был один и тот же трёхпроходный компилятор, потому что второй (оптимизация) и третий (кодогенерация) проходы у них были общие, различался только первый проход (синтаксический разбор).
+
avatar
0
Вот сейчас ерунду написали. Потому что «надстройкой» он является исключительно с точки зрения лингвистики.
Нет. Процессор понимает только машинные коды, которые соотносятся 1-к-1 с ассемблером. Си он не понимает, ему в этом помогает компилятор. Значит, си — надстройка над ассемблером.
Выдававшие ассемблерный код более качественный, чем студенческие потуги начинающих ассемблерщиков.
Возможно, у нас разное понимание качества ассемблерного кода, потому что я начинал программировать с ассемблера Z80, потом был ассебмлер х86 и только потом паскаль и си. И я всегда обращал внимание, насколько плохой код выдавали компиляторы и всегда понимал, как его можно сделать лучше.
И меня, например, притно удивил код, который компилируется из C++ под AVR.
Это лишь подтверждает предыдущий абзац, потому что я еще не видел, чтобы компилятор генерировал хороший код для АВР. А уж на АВР у меня много ассемблерных проектов.
+
avatar
+1
  • yup2
  • 08 мая 2026, 13:27
Процессор понимает только машинные коды, которые соотносятся 1-к-1 с ассемблером.
Значит, си — надстройка над ассемблером.
Чтобы на пустом месте не возникало срача, давайте аккуратно относится к терминологии.

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

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

Дальше есть компилятор Си, он берет на вход текстовые файлы, а на выходе выдает (условно) машинные коды. И как бы он не старался, он не сможет выдать решение более оптимальное, чем А, потому как А является самым оптимальным решением. А вот хуже выдать вполне может. То есть высказывание:
Си — изначально «надстройка над ассемблером». Он НЕ МОГ работать медленнее.
Ложное.
+
avatar
+1
  • yup2
  • 08 мая 2026, 19:32
И как бы он не старался, он не сможет выдать решение более оптимальное, чем А, потому как А является самым оптимальным решением.
Как я уже написал выше, на сложных современных процессорах и человек далеко не всегда выдаст А. Причём его решение запросто может оказаться дальше от А, чем то, что породил компилятор.

Представьте, что есть две машинные команды: X и Y — абсолютно друг от друга не зависящие (в том смысле, что результат не зависит от порядка их исполнения). Но в том конкретном месте конкретной программы, где они оказались рядом, из-за загруженности конвейера предшествующими командами, последовательность «X; Y;» будет исполнена медленнее, чем «Y; X;». Сможет человек это учесть?
(Причём в каком-то другом месте более быстрым окажется применение «X; Y;».)

В итоге и решение человека, и решение компилятора будут уступать А, но компиляторное окажется лучше человеческого.
(Битву за шахматы человек уже проиграл.)
+
avatar
0
на сложных современных процессорах и человек далеко не всегда выдаст А
Да, вполне. Но я, например, последний раз писал ассебмлерный код х86 лет 10 назад, и он работал быстрее компилятора. Потому что кроме учета аппаратных особенностей исполнения команд (которые, кстати, несколько различаются на разных процессорах) еще есть программные особенности алгоритма. И вот если первые компилятор знает и просчитывает хорошо, то вторые ему зачастую даются хуже, чем человеку.

А еще на современных процессорах многие алгоритмы упираются в производительность памяти, и тогда взаимное расположение команд уходит на второй план, потому что процессор всё равно тратит такты в ожидании данных.
но компиляторное окажется лучше человеческого.
(Битву за шахматы человек уже проиграл.)
Выполнение команд процессором намного проще шахмат, поэтому всегда будут люди, которые будут писать ассемблерный код лучше компиляторов. Ведь процессоры создают тоже люди, а уж создание процессора значительно более сложная задача, чем написание под него кода.
+
avatar
+1
  • yup2
  • 11 мая 2026, 14:09
последний раз писал ассебмлерный код х86 лет 10 назад, и он работал быстрее компилятора.
Тут ещё есть очень большая зависимость от языка программирования. Потому что нынешние языки (все без исключения) настолько чудовищные, что получить от них эффективный код невозможно в принципе — слишком много «не заказанных» процессорных операций приходится выполнять исключительно из-за особенностей самого языка. У тех же Perl или Python операция «2 + 3» это совсем не то же самое, что она же у C или Pascal. И классы у объектно-ориентированных языков тоже столько дерьма с собой тащат, что… (причём ради того, чтобы вместо f(x) писать x.f()).
Потому что кроме учета аппаратных особенностей исполнения команд еще есть программные особенности алгоритма. И вот если первые компилятор знает и просчитывает хорошо, то вторые ему зачастую даются хуже, чем человеку.
Алгоритм в любом случае создаёт человек. На долю творчества компилятора остаётся только оптимальное распихивание по регистрам (и памяти) результатов промежуточных вычислений. И с некоторых пор — выбор порядка выполнения некоторых операций.
особенностей исполнения команд (которые, кстати, несколько различаются на разных процессорах)
Да. Компиляторы же стараются делать кроссплатформенными (как по части операционок, так и по части архитектур процессоров), и поэтому они не умеют выжимать максимум из каждой конкретной архитектуры. Но когда производитель процессоров делает компилятор, заточенный под конкретно его процессоры, то результат бывает куда лучше.
А еще на современных процессорах многие алгоритмы упираются в производительность памяти, и тогда взаимное расположение команд уходит на второй план, потому что процессор всё равно тратит такты в ожидании данных.
В том-то и дело, что в подобных случаях человек пишет по наитию, а специализированный на конкретном процессоре компилятор держит в себе информацию о внутренних подробностях исполнения команд процессором и может подобрать действительно наилучшую их последовательность, чтобы минимизировать ожидание. (В конце-концов, сами команды ведь тоже вычитываются из памяти.)
Выполнение команд процессором намного проще шахмат, поэтому всегда будут люди, которые будут писать ассемблерный код лучше компиляторов.
Оптимизирующий компилятор, как и в шахматах, берёт «грубой силой» — он в процессе работы способен оперировать гораздо большим объёмом информации и осуществлять полный перебор вариантов.
Ведь процессоры создают тоже люди, а уж создание процессора значительно более сложная задача, чем написание под него кода.
Многие процессоры сейчас чуть ли не студенты собирают из готовых библиотечных модулей как из блоков конструктора «Лего». И даже создание новых архитектур без использования типовых библиотек не обходится.

А с другой стороны, для VLIW-процессоров («Эльбрус» и др.) писать эффективные программы на ассемблере никто даже не пытается — настолько это дохлый номер.
+
avatar
0
И классы у объектно-ориентированных языков тоже столько дерьма с собой тащат, что… (причём ради того, чтобы вместо f(x) писать x.f()).
Не все так однозначно. Если вы понимаете, как внутри устроены классы и другие особенности языка, вы сможете и с ними писать эффективный код, который будет работать весьма быстро. Например, если взять тот же MSVS 32 бит, то там this передается в регистре ECX, то есть, вызов x.f() произойдет вообще без записи в память (стек), а вот f(x) потребует пуша аргумента.
Алгоритм в любом случае создаёт человек. На долю творчества компилятора остаётся только оптимальное распихивание по регистрам (и памяти) результатов промежуточных вычислений. И с некоторых пор — выбор порядка выполнения некоторых операций.
Хороший прирост производительности можно получить, если выполнять операции параллельно используя MMX, SSE, SSE2, SSE3 и т.д. И как мне объяснить компилятору, что вот тут можно так сделать? Например, я решал задачу поиска пересечений линии с объектом, там надо выполнять одинаковые операции с разными данными, компилятор сам этого понять не смог, хоть и флаг использования SSE был включен.

А еще в Си прекрасный пример — это умножение. На интеле результат умножения имеет удвоенную разрядность, но Си это категорически не поддерживает. В результате приходится кастить аргументы к более широкому типу, после чего производить умножение. И даже вот тут не всякий компилятор понимает, что из 4-х команд умножения надо оставить лишь одну.
А с другой стороны, для VLIW-процессоров («Эльбрус» и др.) писать эффективные программы на ассемблере никто даже не пытается
Да, не для любой системы команд человеку просто писать ассемблерный код. Но это не значит, что человек вообще не сможет написать лучше компилятора, это лишь означает, что всё меньшее число людей успешно с этим справятся. Но тот же x86/64 или AVR очень просты с точки зрения команд, поэтому в большинстве задач под них писать эффективный код относительно несложно.
+
avatar
+1
  • yup2
  • 12 мая 2026, 21:48
Если вы понимаете, как внутри устроены классы и другие особенности языка, вы сможете и с ними писать эффективный код
Но косвенная адресация, которая используется для вызова методов вместо прямой, при этом никуда не денется. И расход памяти на все эти таблицы экземпляров объектов — тоже.
там this передается в регистре ECX, то есть, вызов x.f() произойдет вообще без записи в память (стек), а вот f(x) потребует пуша аргумента.
Даже древние версии TurboPascal умели передавать параметры в функции через регистры. А мой любимый компилятор тех же времён позволял вручную для каждого параметра указывать, в какой именно регистр его засовывать.
Хороший прирост производительности можно получить, если выполнять операции параллельно используя MMX, SSE, SSE2, SSE3 и т.д. И как мне объяснить компилятору, что вот тут можно так сделать?
А вот это и есть тот недостаток многоплатформенных компиляторов, который я упоминал. Алгоритмы оптимизации у таких компиляторов более-менее общие для всех поддерживаемых платформ, поэтому использование всяких уникальных особенностей идёт по принципу «как шмогла». Но, например, ISPC, заточенный сугубо на Intel, обещает кратный прирост производительности на таких задачах.
Но тот же x86/64 или AVR очень просты с точки зрения команд
С тех пор, как в Интеловских процессорах появилось опережающее исполнение, простота команд стала обманчивой. Выше я это описывал. Человек реально не в состоянии учитывать особенности прохождения последовательности команд по конвейеру.
это лишь означает, что всё меньшее число людей успешно с этим справятся.
Да. Если на весь мир какая-то пара сотен человек знакома с внутренней кухней конвейера и может писать программы с учётом её, то это то же самое, что сказать: «Никто не может».
А если есть компилятор, который это автоматом учитывает, то круг успешных программистов расширяется в тысячи раз.
+
avatar
0
Но косвенная адресация, которая используется для вызова методов вместо прямой, при этом никуда не денется
Какая еще косвенная адресация? Вызов обычного метода ничем не отличается от вызова обычной функции, они оба имеют постоянный адрес в памяти. Вы с виртуальными путаете, похоже. Но виртуальными методы делать без особой необходимости не стоит.
И расход памяти на все эти таблицы экземпляров объектов — тоже.
Опять же, какой памяти? Вы снова про виртуальные методы? Ну, так не делайте, они не всегда нужны.
Даже древние версии TurboPascal умели передавать параметры в функции через регистры.
Можно использовать __fastcall и С++ тоже будет передавать через регистры. Только регистров в х86 мало.
простота команд стала обманчивой
Опережающее исполнение появилось, емнип, еще во времена вторых пентиумов. Но только примерно в 2013-2015 годах я еще вполне успешно писал для х86 программы на асме, которые работали в полтора раза быстрее компилятора (MSVS).
+
avatar
0
  • yup2
  • 13 мая 2026, 14:03
Вызов обычного метода ничем не отличается от вызова обычной функции, они оба имеют постоянный адрес в памяти. Вы с виртуальными путаете, похоже.
Не путаю. Виртуальные методы — тоже методы. А я просто поленился длинное слово набирать.
Но виртуальными методы делать без особой необходимости не стоит.
А без них большинство «гениальных идей» ООП становится невозможным реализовать, и остаётся, по сути, один только изменённый синтаксис исходников.
И расход памяти на все эти таблицы экземпляров объектов — тоже.
Опять же, какой памяти?
В терминах того языка, на котором я предпочитаю писать, объект представляет из себя запись (RECORD), полями которой являются все его свойства, указатели на виртуальные методы и всякая разная служебная информация компилятора.

Каждый раз, когда порождается экземпляр класса, в памяти размещается вся эта запись, даже если реально в программе от всего «богатого внутреннего мира» объекта требуется только один метод, не имеющий параметров и не доступающийся к прочим свойствам объекта. А никакого иного способа вызвать данную «обычную функцию, имеющую постоянный адрес в памяти» у меня нет.
Даже древние версии TurboPascal умели передавать параметры в функции через регистры.
Можно использовать __fastcall и С++ тоже будет передавать через регистры.
Да. Но я же написал это в связи с:
если взять тот же MSVS 32 бит, то там this передается в регистре ECX, то есть, вызов x.f() произойдет вообще без записи в память (стек), а вот f(x) потребует пуша аргумента.
— чтобы напомнить, что использование регистров для передачи параметров в функции не является чем-то уникальным, присущим только работе с объектами.
Опережающее исполнение появилось, емнип, еще во времена вторых пентиумов. Но только примерно в 2013-2015 годах я еще вполне успешно писал для х86 программы на асме, которые работали в полтора раза быстрее компилятора (MSVS).
Ничего удивительного. Я уже писал, что для выбора наилучшей последовательности машинных команд компилятор должен иметь информацию об особенностях исполнения каждой команды внутри процессора. Такой компилятор могут сделать только люди, хорошо знакомые с «внутренней кухней» процессора, и это будет компилятор, заточенный именно под этот процессор. Инженеры Intel способны на такое. Отдельные энтузиасты, глубоко зарывшиеся в документацию по процессору, тоже. Но создатели MSVC??? У них несколько другой вектор приложения усилий — не генерация максимально эффективного кода, а «громадьё библиотек».
+
avatar
0
А я просто поленился длинное слово набирать.
Вы пишете сообщение на весь экран высотой и поленились набрать одно слово? )) Извините, но не верю)
А без них большинство «гениальных идей» ООП становится невозможным реализовать
Ничего подобного. ООП — это, прежде всего, инкапсуляция, когда объекты представляют собой «черные ящики». Для такого виртуальные методы нужны далеко не везде.
Каждый раз, когда порождается экземпляр класса, в памяти размещается вся эта запись, даже если реально в программе от всего «богатого внутреннего мира» объекта требуется только один метод, не имеющий параметров и не доступающийся к прочим свойствам объекта.
Если для вызова метода не нужен доступ к свойствам объекта, такой метод следует делать статическим. И если такого разработчики библиотеки по какой-то причине не сделали, это значит всего-лишь, что дураки они, а не ООП в целом.
А никакого иного способа вызвать данную «обычную функцию, имеющую постоянный адрес в памяти» у меня нет.
Есть. Если это ваш код, просто перепишите, чтобы метод был статическим. Если это библиотечный код, посмотрите исходники, убедитесь, что метод реально не нуждается в данных. Затем просто вызовите его с нулевым указателем. Делов-то.
чтобы напомнить, что использование регистров для передачи параметров в функции не является чем-то уникальным, присущим только работе с объектами.
Компилятор можно настроить под себя, под проект и под его цели. Моя мысль была в том, что если компилятор не настраивать и перейти от f(x) к x.f(), то код станет даже быстрее, так что ООП само по себе еще совсем не означает снижение скорости.
Инженеры Intel способны на такое
Ну и кто будет пользоваться этим компилятором? Сейчас миллионы проектов собираются «универсальным» gcc, которому такая оптимизация и не снилась, поэтому ассемблерный код я сравниваю именно с ним.
+
avatar
0
  • yup2
  • 13 мая 2026, 17:24
Вы пишете сообщение на весь экран высотой
И это ещё после того, как часть написанного удаляю…
и поленились набрать одно слово?
Да, конкретно в этом случае сначала хотел написать, но потом подумал: «Всё равно ж удалю, когда перегруженный текст сокращать буду».
ООП — это, прежде всего, инкапсуляция, когда объекты представляют собой «черные ящики».
Это разве что для потомков С, где вся программа с точки зрения компилятора является одним сплошным текстом, собираемым из отдельных файлов с помощью препроцессорного #include. Но есть же ж куча других языков, в которых объектов нет и близко, а инкапсуляция — вот она, в полный рост. Чтобы далеко не ходить — тот же TurboPascal с его Unit-ами.
Если для вызова метода не нужен доступ к свойствам объекта, такой метод следует делать статическим.
Не во всех языках есть такая концепция. В TCL, например, нет.

Но сам пример был выбран таким просто ради его максимального упрощения.
Давайте возьмём чуть более сложный и заглянем встроенным в браузер отладчиком в потроха любой веб-странички. Там мы быстро обнаружим, что у любого элемента странички есть сотни свойств и методов, не имеющих для данного объекта никакого смысла. Особенно это касается его CSS-свойств. Например, у любой картинки обязательно имеется несколько десятков свойств, имеющих смысл только для текста. Но память эти поля жрут.

А почему так? Потому что ООП с его наследованием. А при наследовании потомок получает от предка всё, что у того было. Потомку можно ещё добавить то, чего у предка не было, но нельзя при наследовании взять только часть имеющегося и отказаться от того, что заведомо не нужно.
Если это библиотечный код, посмотрите исходники, убедитесь, что метод реально не нуждается в данных. Затем просто вызовите его с нулевым указателем.
Как его вызвать, если в языке даже нет понятия «указатель» (адрес переменной или функции)?
Ну и кто будет пользоваться этим компилятором?
Вы же хотели эффективное использование MMX/SSEx/… Значит, можете предпочесть именно тот компилятор, который это обеспечивает.
А кому-то может быть нужно выжимать максимум скорости из обычных команд.
Вон, тот же Intel компилятор не только с C делает, но и с Fortran. Значит, людЯм надо.
(И я не удивлюсь, если где-то там внутри себя они для своих нужд и PL/M (не путать с PL/1!) до сих пор тянут.)
+
avatar
+1
вся программа с точки зрения компилятора является одним сплошным текстом
Ну снова не так — в Си куча юнитов трансляции (*.с и *.срр файлов), через инклюд подключаются лишь заголовки. А файлы трансляции полностью независимы и потом собираются линковщиком.
А почему так? Потому что ООП с его наследованием.
Нет. ООП предоставляет механизм наследования, но не заставляет вас его использовать. Если конкретно в js было решено унаследовать какой-то объект от какого-то, в этом виновато не ООП и наследование, а разработчики, которые так решили. Не нужны вам часть свойств базового класса — разбейте базовый на два, унаследовав один от другого. А теперь наследуйте свой класс от первого и он не получит «лишние» свойства второго. Как видите, любой вопрос в программировании решаем.
Как его вызвать, если в языке даже нет понятия «указатель» (адрес переменной или функции)?
Когда мне начинают говорить про скорость и всякие оверхеды, единственные языки, которые я представляю — это С и С++. Остальные языки не про быстродействие в первую очередь, а про что-то еще — memory safety и т.п. Компиляторы в них тоже бывают неплохими (тот же Го неплохо оптимизирует), но у них на первое место поставлены другие цели. И это не всегда плохо — к примеру, на джаве пишется куча бэкендов, где 99% времени выполнения, в конечном счете, потратится на запросы в БД. Так какая разница, выполнится оставшийся 1% медленно или быстро, всё равно это практически никак не скажется на системе в целом. А вот писать безопасный код на джаве явно проще. Да и юнит-тесты по-настоящему раскрываются только с DI.
+
avatar
0
  • yup2
  • 14 мая 2026, 14:34
Ну снова не так — в Си куча юнитов трансляции (*.с и *.срр файлов), через инклюд подключаются лишь заголовки.
Но если в программе написано:
#include "file1.h"
#include "file2.h"
то в file2.h доступно всё то, что определено в file1.h

Если же «пустить в зачёт» тот факт, что содержимое комплектного file1.с извне таки недоступно, то это обесценит утверждение:
ООП — это, прежде всего, инкапсуляция, когда объекты представляют собой «черные ящики».
потому что file1.с — точно такой же «чёрный ящик» без всякого ООП.
Если конкретно в js было решено унаследовать какой-то объект от какого-то, в этом виновато не ООП и наследование, а разработчики, которые так решили.
И ООП тоже. Потому что без ООП в используемой чужой библиотеке будут переменные и функции, и использовать в своём коде можно только те из них, которые нужны.
А при ООП в чужой библиотеке будет класс, в который помещены все эти переменные и функции, и импортировать их выборочно возможности нет никакой.

Если же тот огромный класс из примера раздробить на кучу мелких, то потом, когда понадобится добавить что-то всем или многим из них (а наследуют ведь ради добавления), то проделать это придётся для каждого из мелких классов. (Да, есть двадцать мелких классов, в которые нужно добавить один и тот же метод, значит его двадцать раз и придётся добавить).
Поэтому авторам проще «так не делать», а держать всё в одном монстре.

А при классическом программировании и в самом деле достаточно будет добавить только одну функцию. Причём причина такой разницы — всего лишь синтаксис исходников.
Как его вызвать, если в языке даже нет понятия «указатель» (адрес переменной или функции)?
Когда мне начинают говорить про скорость и всякие оверхеды, единственные языки, которые я представляю — это С и С++.
А как в C++ сделать то, что Вы написали:
Если это библиотечный код, посмотрите исходники, убедитесь, что метод реально не нуждается в данных. Затем просто вызовите его с нулевым указателем.
У меня такое получается только для метода объекта. Но целью-то было вызвать (статический) метод класса, не создавая объекта. А для класса у меня получить адрес метода не выходит, компилятор ругается. И на попытку вызвать его как MyClass.a() тоже ругается.
+
avatar
0
Если же «пустить в зачёт» тот факт, что содержимое комплектного file1.с извне таки недоступно, то это обесценит утверждение:
Вы какую-то ерунду сейчас пишете. h-файл — это заголовок, в нем находится то, что объект о себе рассказывает другим. Это общедоступная информация, её знают все, поэтому то, что в файле 2 будет доступна эта информация из файла 1 никакой проблемы не представляет. А вот реализация находится в с/срр файлах, и она уже скрыта от прямого включения.
Потому что без ООП в используемой чужой библиотеке будут переменные и функции
Может тогда сразу надо и от компьютеров отказаться? Глупо обвинять инструмент в плохом результате.
А при ООП в чужой библиотеке будет класс, в который помещены все эти переменные и функции, и импортировать их выборочно возможности нет никакой.
Переменные и функции всё так же можно использовать отдельно, потому что в классе — методы и свойства. Выборочный импорт методов и свойств — бред, т.к. импортированный методы может использовать то свойство, которое вы импортировать забыли.
Да, есть двадцать мелких классов, в которые нужно добавить один и тот же метод, значит его двадцать раз и придётся добавить
Опять какая-то фигня. Если у этих 20 мелких классов нет общего предка, добавьте этот предок, и добавьте его в родителей 20 классов.
А при классическом программировании и в самом деле достаточно будет добавить только одну функцию.
И снова ерунда. Какой тип параметра будет принимать эта функция, если у вас есть 20 независимых мелких структур?
Причём причина такой разницы — всего лишь синтаксис исходников.
Ничего личного, но я смотрю на ваши сообщения и понимаю, что у вас достаточно много пробелов в знаниях в программировании (по крайней мере, в С/С++). Отсюда и ваш негатив в сторону ООП, потому что фактически f(x) и x.f() даже после компиляции будет практически одним и тем же. Вы или явно передаете параметр, или неявно передаете его как this.
Но целью-то было вызвать (статический) метод класса, не создавая объекта.
Статический метод вызывает без создания экземпляра штатно: Class::Method().

Обычный метод можно вызвать так:
class A
{
    ...
    void SomeMethod();
}

void main()
{
    A* a = reinterpret_cast<A*>(nullptr);
    a->SomeMethod();
}
Но это если только вы точно уверены, что методу не нужны свойства класса и другие свойствозависимые методы.
+
avatar
0
  • yup2
  • 14 мая 2026, 19:53
h-файл — это заголовок, в нем находится то, что объект о себе рассказывает другим. Это общедоступная информация, её знают все, поэтому то, что в файле 2 будет доступна эта информация из файла 1 никакой проблемы не представляет.
Не представляет? Представьте, что file1 и file2 — из разных библиотек, ничего не знающих друг о друге, но при этом в них (так уж вышло) встречаются одинаковые имена (типов, классов, констант, переменных). Как это разруливать?

Пример может показаться надуманным и редковстречающимся, но реальность даже печальнее, чем то, что в нём предложено. Мне не раз приходилось писать на C для Windows с использованием одного только Windows SDK. Это одна библиотека, в которой, по идее, всё должно быть согласовано. Но стоит только начать, и поехало:

— «Тип А неизвестен»
Находим .h, в котором есть нужное определение, подключаем через #include.
— «Тип B неизвестен»
Находим .h, в котором есть нужное определение, подключаем через #include.
— «Тип С неизвестен»
Находим .h, в котором есть нужное определение, подключаем через #include.
— «Повторное определение типа А»

Всё, приплыли. Убираешь любой из #include — возвращается ошибка, что что-то не определено. Все #include присутствуют — «Повторное определение...»

Полдня мучаешься, пытаясь найти тот волшебный h-файл, подключение которого позволит обойтись без одного из «нехороших» #include — ничего не выходит. В конце-концов нервы не выдерживают, и просто копируешь нужные фрагменты в свой самодельный .h. Но эти фрагменты немедленно тянут за собой что-то ещё, и ещё, и ещё…
В результате у меня уже практически свой собственный вариант Windows SDK образовался. И ещё вариант его же, но уже на нормальном языке программирования, в котором определения в заголовочных файлах действительно изолированы друг от друга и поэтому подобных проблем в принципе быть не может.
А вот реализация находится в с/срр файлах, и она уже скрыта от прямого включения.
Поэтому я и сказал, что инкапсуляция вполне возможна без ООП.
И теперь хочется спросить: Вам лично чем ООП в C++ помогает? Все виденные примеры, где от него хоть какой-то толк имеется, касались довольно узкого круга задач, с которым не очень много людей сталкивается. А в тех реальных чужих исходниках, с которыми мне иметь дело приходилось, пользы от него не было вообще, одна только головная боль от переусложнённого текста.
Глупо обвинять инструмент в плохом результате.
А использовать инструмент не по назначению?
Переменные и функции всё так же можно использовать отдельно, потому что в классе — методы и свойства.
Но это же просто другое название для того же самого. Однако функцию можно задать одну и засовывать в неё всякое разное, а новый метод разным классам придётся прописывать индивидуально. И хорошо ещё, что в C++ саму функцию можно один раз задать и N раз прописать, а не N копий тела функции вставлять. (Да и то не факт. Вдруг классы в разных файлах описаны?..)
Если у этих 20 мелких классов нет общего предка, добавьте этот предок, и добавьте его в родителей 20 классов.
Ага. Огромный класс раздробили на 100 простых, происходящих от одного предка. Потом 20 из них понадобилось расширить. Задали для них нового (промежуточного) предка, в который и добавили новый метод.
А чуть позже понадобилось расширить ещё 20 классов — десять из этих двадцати и ещё десять из оставшихся девяноста…
Наверное, найдётся способ выкрутиться с помощью ещё какого-то нового класса. Но каждый раз, когда понадобится расширяться, придётся добавлять новые промежуточные классы, связь между которыми быстро станет невероятно запутанной. С печальными результатами мне сталкиваться приходилось. Не помогало даже заботливо построенное авторами графическое дерево связей между классами — в этом мелком кружеве линий отследить что-либо было совершенно невозможно.
Какой тип параметра будет принимать эта функция, если у вас есть 20 независимых мелких структур?
Зависит от того, за что боремся — за память или за скорость. И от языка программирования. Поскольку здесь я стараюсь оперировать названиями известных языков, то в Pascal (и TurboPascal) это, скорее всего, будет «запись с вариантами». А может и просто записью (в С это struct) обойтись удастся. Но это уже от конкретной ситуации зависит.
смотрю на ваши сообщения и понимаю, что у вас достаточно много пробелов в знаниях в программировании (по крайней мере, в С/С++).
С C у меня проблем нет, а вот с C++ отношения — да, очень напряжённые, хотя он и был создан, когда я уже весьма активно программировал, и вся его эволюция происходила на моих глазах. Просто, глядя на эту его эволюцию, я достаточно быстро пришёл к двум выводам:

1. С++ — воняющее кладбище чьих-то гениальных идей.
2. От языков, новые версии которых появляются чуть ли не каждый год, лучше держаться подальше.

Наблюдение за некоторыми другими языками пункт 2 полностью подтвердило.
фактически f(x) и x.f() даже после компиляции будет практически одним и тем же.
Кроме случаев, когда x не нужен (а именно об этом случае и был вопрос). Для вызова функции можно написать f(), а для вызова метода придётся поизвращаться указанным Вами способом.

Кстати, на Ваш пример компилятор ругается:
error: invalid cast from type 'std::nullptr_t' to type 'A*'
   A* a = reinterpret_cast<A*>(nullptr);
И, пользуясь случаем, спрошу: что могло быть причиной того, что во многих местах одной из моих C++-ных программ прекрасно работали примерно такие последовательности:
y = x.a().b().c().d().e();
z = y.f().g().h().i().j();
и они же не работали, будучи объединены в один оператор:
z = x.a().b().c().d().e().f().g().h().i().j();
Программа тихо валилась, хотя и памяти, и стека было более чем достаточно.
+
avatar
0
встречаются одинаковые имена (типов, классов, констант, переменных). Как это разруливать?
Ситуация достаточно редкая, на самом деле, потому что сейчас практически все библиотеки используют неймспейсы. Если нет, то разруливать так — если доступны исходники, обернуть в неймспейс. Если исходников нет, написать враппер для одной из библиотек, который будет динамически её загружать (статически не слинкуется) и экспортировать сущности с другими именами.
для Windows с использованием одного только Windows SDK
Написал именно так достаточно много приложений, ни разу не столкнулся с подобным. Да есть там WIN32_LEAN_AND_MEAN, если его отключить, могут быть конфликты, но они решаются весьма легко.
В результате у меня уже практически свой собственный вариант Windows SDK образовался.
Проблема в том, что Win SDK обновляется.
инкапсуляция вполне возможна без ООП.
Нет. Без ООП у вас будет полностью открытая структура и функции. Никаких private переменных. Конечно, можно сделать две структуры — публичную и личную, вторую определить уже в С файле, но с ООП это гораздо проще.
Вам лично чем ООП в C++ помогает?
Прежде всего, виртуальными функциями. Например, я описываю интерфейс, добавляю реализацию, код работает. А завтра я добавляю вторую реализацию, и без какого-либо труда подключаю её в свой проект. Более того, я еще пользователю могу выбор дать, какую реализацию использовать. Конечно, я мог бы и на plain-c реализовать такое, можно же адрес функции в структуру загнать, но на ООП это в разы удобней.
А использовать инструмент не по назначению?
А это уже не проблема инструмента.
Однако функцию можно задать одну и засовывать в неё всякое разное
В С/С++ — нет. У вас есть функция, она принимает строго определенный тип. С другим (если он не потомок первого) работать не будет. А если потомок, то это ведь то же самое наследование.
Ага. Огромный класс раздробили на 100 простых, происходящих от одного предка. Потом 20 из них понадобилось расширить. Задали для них нового (промежуточного) предка, в который и добавили новый метод.
А чуть позже понадобилось расширить ещё 20 классов
Мне кажется, наигранный сценарий. Но, в любом случае, это возможно. А еще есть множественное наследование, и хоть есть много рекомендаций его не использовать, иногда оно может решить как раз вашу задачу более элегантно.
А может и просто записью (в С это struct) обойтись удастся
Не сможет одна функция работать с разными данными. Чисто физически, на уровне машинного кода. Единственное исключение — шаблоны. Но там для каждого типа генерируется своя функция.
1. С++ — воняющее кладбище чьих-то гениальных идей.
С++ — великолепный язык, сочетающий в себе простоту и близость к процессору языка С с высокоуровневыми конструкциями типа шаблонов и ООП. Правда сейчас он развивается несколько не в ту сторону, но сейчас времена другие — на первое место начинает выходить memory safety, а не быстродействие.
Кроме случаев, когда x не нужен
Если х не нужен, функция должна быть статической! Если это не так, виноват автор кода, но не язык.
Кстати, на Ваш пример компилятор ругается:
Да, ошибся, для каста static_cast нужен:
и они же не работали, будучи объединены в один оператор:
Если считать, что код написан абсолютно верно, могу предположить, что компилятор ошибся с временем жизни некоторых промежуточных объектов. Добавьте в конструктор и деструктор всех объектов логирование и посмотрите, когда какой создается и когда уничтожается, возможно, и в коде ошибку найдете.
+
avatar
0
  • yup2
  • 15 мая 2026, 18:35
Написал именно так достаточно много приложений, ни разу не столкнулся с подобным.
Порылся в старых почему-то ещё не удалённых исходниках. По большей части там уже ссылки на мои самодельные файлы, а из тех самых ранних, где ещё оригинальный SDK задействован: в трёх в текстах самих программ прописано
typedef LONG NTSTATUS;
а в четвёртой вставлена куча типов и констант из iphlpapi.h и udpmib.h, и об этом прямо написано в комментариях к этим вставкам. Причём сам файл iphlpapi.h тоже подключён — вместе с ещё шестью другими файлами SDK. Очевидно, что разблокировка тех #ifdef, в которые в iphlpapi.h засунуты эти определения, вела к упомянутым выше конфликтам.
Проблема в том, что Win SDK обновляется.
Ага, когда выходит очередная версия Windows. Но при этом туда всего лишь добавляется что-то новое, пользоваться которым категорически не следует, если хочешь, чтобы твоя программа работала и под предыдущими версиями Windows тоже.
Без ООП у вас будет полностью открытая структура и функции. Никаких private переменных.
Концепцию приватных членов придумал не автор C++. И даже не создатели самого первого объектно-ориентированного языка. Они позаимствовали её из уже существовавших до того обычных функциональных языков. (И даже сам синтаксис для доступа к членам класса «через точку» был целиком содран с тех предшественников. Так что это всё идеи и технологии ещё 60-х годов.)
Вам лично чем ООП в C++ помогает?
Прежде всего, виртуальными функциями.
Оп-па! Я говорил, что бывают задачи, для которых применение ООП действительно оправдано. Но в этих ситуациях неизбежно возникает необходимость в полиморфизме и виртуальных функциях — тех самых, которые Вам так не нравились. И мы тут диспутируем именно о конструкциях без них.
Однако функцию можно задать одну и засовывать в неё всякое разное
В С/С++ — нет. У вас есть функция, она принимает строго определенный тип. С другим (если он не потомок первого) работать не будет. А если потомок, то это ведь то же самое наследование.
Совершенно верно — это наследование. И вот мы уже имеем, что из трёх базовых принципов ООП (инкапсуляция, наследование, полиморфизм) два имеются и без ООП — «запростотак». (Полиморфизм тоже имеется, вы это сами понимаете: «можно же адрес функции в структуру загнать, но на ООП это в разы удобней» — и с первой частью этого я полностью согласен. А по второй несогласие могу выразить разве что насчёт «в разы». У языков-предшественников вполне себе существовал тип «указатель на функцию», и им обыденно пользовались. Это у нынешних программистов подобных навыков нет.)

Идея объектов выросла из идеи структур (struct, record) и была всего лишь мелким шагом вперёд, добавлявшим чуток удобства при написании исходных текстов — доступ к полям классов-потомков оставался «одноэтажным», а не «многоэтажным» как у структур-потомков.
Но параллельно и в некоторых обычных языках реализовали сохранение одноэтажности, введя понятие расширения типа, оформляемого в духе:
type1 = record
  int field1;
  int field2;
  int field3;
end;

type2 = extension of type1
  int field4;
  int field5;
end;
Мне кажется, наигранный сценарий.
Вовсе нет. Исходным примером же было представление веб-странички в виде DOM-дерева, а там подобное частичное совпадение свойств и методов у разных подмножеств элементов — куда ни плюнь.
А еще есть множественное наследование, и хоть есть много рекомендаций его не использовать, иногда оно может решить как раз вашу задачу более элегантно.
Да, это и есть способ решить ту задачу, породив чёртову уйму промежуточных классов, в которой потом хрен разберёшься. Создатели браузеров явно решили, что их супер-мега-гипер-класс — меньшее зло.
Не сможет одна функция работать с разными данными.
Напоминаю условия поставленной Вами задачи: «Есть класс, от него породили потомка, добавившего к родительским поля новые. Методы родителя прекрасно работают с экземплярами потомка. Как сделать то же без ООП?»
typedef struct {
  unsigned int a;
  unsigned int b;
} ParentType;

unsigned int Func(ParentType param) {
  return param.a * param.b;
}

typedef struct {
  ParentType Base;
  unsigned int c;
} ChildType;

ChildType x = { ... };

unsigned int Result = Func(x.Base);
Если компилятор очень умный и способен понять, что ParentType является началом ChildType, то он и запись = Func(x); может позволить. Или если я готов несколько пожертвовать строгостью проверки типа параметра.
С++ — великолепный язык, сочетающий в себе простоту и близость к процессору языка С с высокоуровневыми конструкциями типа шаблонов и ООП.
П-р-о-с-т-о-т-у? Боже мой! Да он настолько перегружен всякой хренью, что является одним из ярчайших примеров того, как нельзя делать языки.
Вы можете назвать хоть один язык, который сложнее, чем C++?
Если х не нужен, функция должна быть статической!
Да-да-да. И вызываться как class::f(), а не как x.f(). А человек для сотен методов разных классов должен постоянно помнить, какой как вызывать. Всё же очень просто.
Если считать, что код написан абсолютно верно, могу предположить, что компилятор ошибся с временем жизни некоторых промежуточных объектов. Добавьте в конструктор и деструктор всех объектов логирование и посмотрите, когда какой создается и когда уничтожается, возможно, и в коде ошибку найдете.
Среди этих методов не было ни одного моего. Все они были из одной и той же библиотеки (Qt). Править её исходники и перекомпилировать у меня сейчас возможности нет (хотя в прошлом я это несколько раз делал).

Но я при описании тогдашней картины несколько неаккуратно выразился — программа не «тихо валилась», а просто молча завершалась. При этом от неё самой никакого сообщения об аварии не было. И от Windows никаких сообщений не было. А если запускал под отладчиком, то и отладчик писал только, что программа нормально завершилась.

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

Я подумал, что, может быть, дело в моём недостаточном знании C++, и не всякий объект пригоден к использованию в цепочке.
+
avatar
0
пользоваться которым категорически не следует
Очень часто пользоваться этим надо, т.к. надо адаптировать программу под новую версию винды. А чтобы работало и на старых, добавляется условная компиляция новых фич.
Но в этих ситуациях неизбежно возникает необходимость в полиморфизме и виртуальных функциях — тех самых, которые Вам так не нравились. И мы тут диспутируем именно о конструкциях без них.
Я никогда не говорил, что мне не нравятся виртуальные функции, я говорил, что они добавляют лишнее чтение из памяти. Что именно выбрать — решает программист.

Что касается примера без них — пожалуйста. У вас есть объект, вы делаете какое-то его свойство private, а для работы с ним извне добавляете getter/setter. Теперь любой, кто пользуется вашим объектом не может менять свойство напрямую, а должен вызывать getter/setter, в которых вы можете выполнить все нужные дополнительные операции по обновлению внутреннего состояния объекта. Без ООП вам пришлось бы лишь документировать необходимость обновления внутреннего состояния и надеяться, что разработчики прочитают и последуют вашим рекомендациям. То есть, ООП банально позволяет снизить количество багов в продукте.
из трёх базовых принципов ООП (инкапсуляция, наследование, полиморфизм) два имеются и без ООП — «запростотак».
Нет. Инкапсуляции нет. Вы не можете сделать часть свойств класса private, вы можете лишь попытаться скрыть часть определений внутри реализации (с-файла). Однако, вы не сможете далее наследоваться от этой реализации в других файлах. Полиморфизма тоже нет, т.к. использование адресов функций не есть полиморфизм, это костыль, помогающий его заменить. Также вы забыли четвертый базовый принцип — абстракцию, которой нет без ООП. Остается только наследование.
У языков-предшественников вполне себе существовал тип «указатель на функцию», и им обыденно пользовались. Это у нынешних программистов подобных навыков нет.)
Так это и хорошо, манипуляция с указателями — потенциально опасная операция и очень хорошо, если компилятор берет эту задачу на себя. Но, впрочем, никто вас не ограничивает, если хотите, можете использовать указатель на функцию и сейчас, и есть даже специальный объект std::function<>, который призван вам в этом сильно помочь.
Создатели браузеров явно решили, что их супер-мега-гипер-класс — меньшее зло.
Наверное, оно так и есть. Ведь на plain-c вы бы просто не смогли написать приложение уровня браузера — погрязли бы в багах. А если предположить, что средний размер картинки в памяти составляет, скажем, 25 КБ, тратить лишние 200 байт на ненужные свойства — не так уж и заметно.
unsigned int Result = Func(x.Base);
Так вы не вызываете функцию с другим типом, вы у другого типа получается базовый и вызываете функцию с ним. То есть, исходной вашей формулировке «засовывать в неё всякое разное» это, ну, никак не соответствует. По аналогии, вы можете у объекта сделать метод, который возвращает другой объект и вызывать нужный метод у другого объекта. Так что связь между методами и функциями, которые принимают структуру 1-к-1.
П-р-о-с-т-о-т-у? Боже мой! Да он настолько перегружен всякой хренью, что является одним из ярчайших примеров того, как нельзя делать языки.
Вы можете назвать хоть один язык, который сложнее, чем C++?
Простота — это была про Си. С++ непростой, но как я сказал — он сочетает простоту Си с наворотами С++. Но как именно использовать эти навороты — решаете вы.
Да-да-да. И вызываться как class::f(), а не как x.f(). А человек для сотен методов разных классов должен постоянно помнить, какой как вызывать. Всё же очень просто.
Не занимайтесь софизмом, пожалуйста. Во-первых, если у вас есть указатель на экземпляр, вам всё равно, вы можете и статический метод вызвать как x.f(). А если экземпляра нет, вам надо будет смотреть заголовок, чтобы понять, как определен метод. Или использовать современную IDE, которая подскажет сама. Но ведь в plain-с всё так же — часть методов будут принимать указатель на структуру, часть нет, и вы должны это помнить.
А если запускал под отладчиком, то и отладчик писал только, что программа нормально завершилась.
Возможно, там есть верхнеуровневый обработчик исключений, который отлавливал исключение и тихо выходил. Возможно, происходило что-то еще. Если это не ваш код, можно было бы попробовать обернуть все объекты в свои классы, где сделать логирование при создании и уничтожении. Да, муторно, но, скорее всего, даст ответ.
Я подумал, что, может быть, дело в моём недостаточном знании C++, и не всякий объект пригоден к использованию в цепочке.
Вообще, время жизни промежуточных объектов должно расширяться до тех пор, пока операция не будет выполнена, поэтому тут надо копать глубже — возможно, ошибка в компиляторе.
+
avatar
0
  • simsun
  • 12 мая 2026, 20:30
del
+
avatar
+2
  • trykov
  • 04 мая 2026, 23:12
Спасибо за добрые слова!
В принципе, проект и публиковался именно для демонстрации возможности простейшим контроллером и минимальным кодом обмениваться с индикатором и измерителем температуры.
Следующий шаг будет — сделать паяльную станцию с таким индикатором на таком же контроллере.
Попытаемся в килобайт памяти впихнуть код с приемлемым функционалом паяльной станции.
+
avatar
0
Надеюсь с PID? Иначе это не паяльная станция.
+
avatar
+1
  • trykov
  • 05 мая 2026, 00:22
А почему это без PID уже и не паяльная станция? ))
Вы сомневаетесь, что без ПИД можно поддерживать температуру с достаточной точностью?
В килобайт памяти вряд ли получится ещё и ПИД встроить.
+
avatar
+2
Почему нет? ПИД – это буквально пару строчек тривиального кода.
Нет, формально там конечно интеграл и производная, но покуда у вас микроконтроллер тактируется, то их вы будете считать из дискретного ряда значений. Ну а интеграл – суть сумма всех, а производная – разность двух последних.
Вот практическая реализация ПИДа и сведётся к арифметике на пальцах.

У AlexGyver был наглядный урок/статья про пид регулятор – там можно и теории покурить чтобы свой сделать и просто код своровать, скорее всего есть библиотека, он любит велосипеды писать.
+
avatar
+1
  • trykov
  • 05 мая 2026, 10:24
Всё равно не влезет. У меня и так максимально поджатый код для ATTiny13 в контроллере паяльной станции занимает 960 байт.
Не думаю, что оставшейся памяти хватит для реализации ПИД.
Да и смысла сильного не вижу.
В чём в паяльной станции преимущество ПИД?
+
avatar
+3
  • Detail
  • 05 мая 2026, 13:41
Смысл ПИДа — не только в точности поддержания параметра.

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

Смысл ПИДа еще и в том, чтобы уйти от автоколебаний, когда система за счет инерционности проскакивает установленное значение — датчик читает текущее значение и командует на возврат — возврат снова с проскоком из-за различных причин (та же самая инерция, например) — команда на обратный возврат в точку — ну и понеслась дерготня. Особенно замечательно будет, если после тяжелого полигона бросить паяльник на подставку — он еще какое то время будет качаться туда сюда туда сюда ) простой способ подавления через введение гистерезиса — ну да, наверное, проблему (отчасти) решит… «Жили же до этого как-то без этого» ©

но тогда другой вопрос от нашего читателя Олега Груненкова встает вертикально ))) то есть мы «городили городили да не выгородили»: зачем МК+вся электроника +..+..+..., если в конце концов мы вынуждены вернуться к введению гистерезиса как к самому простому, давно известному не идеальному способу подавления АК как в обычном начального уровня пропорциональном регуляторе с обратной связью??? А в Вашем случае гистерезис выглядит единственным действенным способом, в противном случае Вы сами сказали, что немедленно упираетесь в потолок по объему кода…

Красоту проекта я оценил. Трудозатраты — Вы молодец. Лаконичность кода — отлично ))) знание матчасти, умение пользоваться паяльником+программирование — супер.

Практическая значимость — ? Хотел бы повторить — Х. Рекомендовал бы кому-то к повторению — Х.

«Демонстратор возможностей» ©
+
avatar
+1
  • trykov
  • 05 мая 2026, 13:50
Да, в общем-то, публикация и создавалась больше для демонстрации возможностей сжатия кода и показа возможностей ATTiny13 в качестве вполне себе рабочей лошадки для различных не сложных проектов.
Просто мне нужен был свой термометр. Решил сделать из того, что было под рукой.
Глянул поисковиком — не нашел подходящего варианта на ATTiny13 + TM1637.
Ну и решил добавить MAX и поупражняться со сжатием кода.
А, заодно, поделиться практическими решениями компактного кодирования для ATTiny13. Может кому полезно будет при освоении простых контроллеров.
+
avatar
+2
  • kvarkk
  • 05 мая 2026, 14:14
Интересные нынче времена. Примерно за те же деньги, что стоит ATTiny13, можно купить плату на RP2040, возможности которого несравненно выше. RP2040 уже даже дешевле, чем Arduino Nano.
А для паяльной станции, может, ATTiny85 возьмете? Там все же памяти побольше.
+
avatar
0
  • vlo
  • 05 мая 2026, 15:36
если уж «экономить» — в электроокурках часто попадаются контроллеры семейства PY32F*, которые в разы толще тиньки по памяти. и — совершенно бесплатно.
+
avatar
-1
  • kvarkk
  • 05 мая 2026, 16:25
Для них есть поддержка в Arduino IDE?
+
avatar
+1
  • vlo
  • 05 мая 2026, 18:02
не вникал — моя тяга сэкономить настолько не простирается.
вот тут что-то было на тему mysku.club/blog/diy/103561.html
+
avatar
0
  • kvarkk
  • 05 мая 2026, 20:52
Точно, известная статья, спасибо.
+
avatar
0
  • trykov
  • 05 мая 2026, 16:09
А какой смысл мне покупать RP2040?
Тиньки я брал давно и меньше, чем по пол доллара.
Для простой паяльной станции на дисплее TM1637 тинек вполне хватает.
Для навороченной паяльной станции вполне хватит LGT8F328, которых тоже валяется жменя (тоже меньше, чем по доллару за штуку).
Ну и каких возможностей мне с ними не хватит?
+
avatar
0
  • kvarkk
  • 05 мая 2026, 16:25
Если есть в наличии LGT8F328, то да, смысла нет.
+
avatar
+2
Примерно за те же деньги, что стоит ATTiny13, можно купить плату на RP2040, возможности которого несравненно выше. RP2040 уже даже дешевле, чем Arduino Nano.
DIY — это не про экономию. Практически любой самодельный проект сейчас оказывается дороже покупного, поэтому DIY — это про удовольствие от разработки, про решение задач нестандартным способом (в том числе и на слабом МК) и т.д.
+
avatar
0
  • kvarkk
  • 06 мая 2026, 16:46
Да, согласен.
+
avatar
0
он любит велосипеды писать
обычно всё же не просто так их пишет, а ещё и оптимизирует и довольно сильно.
+
avatar
+2
  • sfs
  • 05 мая 2026, 07:49
Поддержу. Особенно если учесть, что с достаточной точностью для ПАЯЛЬНОЙ СТАНЦИИ. Меня прям умиляют героические усилия по борьбе за стабильное поддержание сотых долей градуса и ускорение на миллисекунды времени разогрева жала паяльника) Скоро нейронный регулятор начнут использовать. Хотя там порогового за глаза.
+
avatar
0
  • trykov
  • 05 мая 2026, 10:25
Таки да — не вижу особого смысла держать точность температуры жала выше +- пары градусов.
+
avatar
0
  • kvarkk
  • 05 мая 2026, 14:15
Как это — скоро начнут? Aixun уже использует его в своей топовой паяльной станции T420D.
+
avatar
0
  • sfs
  • 05 мая 2026, 15:31
Ну тогда ждём ИИ)
+
avatar
+1
Следующий шаг будет — сделать паяльную станцию с таким индикатором на таком же контроллере.
Попытаемся в килобайт памяти впихнуть код с приемлемым функционалом паяльной станции.
А зачем? МК с памятью раз так в 200 большей сейчас стоит дешевле, чем время, потраченное на впихивание в этот килобайт.
+
avatar
0
  • sfs
  • 05 мая 2026, 07:53
Наверное потому, что может. И наверное потому, что хобби, что DIY. Я, например, тоже люблю лепить что-нибудь полезное из имеющегося в наличии «мусора», хотя, естественно, могу купить и более эффективную элементную базу, да и просто готовое «фабричное» устройство в большинстве случаев.
+
avatar
+3
  • trykov
  • 05 мая 2026, 10:29
Спасибо за поддержку!
Вот и я про то же — ну нельзя всё деньгами мерять.
Как измерить удовольствие, полученное от того, что получилось решить поставленную себе задачу. ))
Хобби оно же не для денег.
+
avatar
+2
Вот, вроде же всё верно пишете «нельзя всё деньгами мерять» :) А потом снова начинаете в качестве аргументов приводить довод, что ваш вариант «дешевле». И провоцируете спор, хотя и спор может быть для рейтинга статьи полезен ;)
+
avatar
0
  • trykov
  • 05 мая 2026, 14:01
Так я же совместил — и для души проект и, при этом, совсем не дорого.
Это же вдвойне приятнее. ))
Про рейтинг это не ко мне — я довольно редко пишу здесь статьи. И чужие практически не комментирую.
+
avatar
+1
совместил — и для души проект и, при этом, совсем не дорого
Понял, сразу, сам так что-то делаю. Просто недорого он вам обошёлся, а если нам повторять, то будет уже совсем не очевидно это преимущество. А даже и наоборот. Вот вам и пишут про это. На самом деле — просто захотелось, и именно так. Сделали — поделились. Естественно, что есть варианты дешевле (не для вас). Лучше или нет — вопрос тоже спорный (и тоже — не для вас :). Так-то — интересно получилось :)
+
avatar
0
  • trykov
  • 05 мая 2026, 17:52
Ну вон тут в комментах kvarkk пишет — купил готовый прибор, а он на 10 градусов врёт. А подстроить уже не подстроишь.
Вроде и не сильно критично 10 градусов, а неприятно.
+
avatar
+1
Вот. А кого-то может эти 10 градусов вполне устраивают :) Ампервольтметр на ESP32+INA226+TFT на электронной нагрузке и ЛБП сделал. Экономически — совсем не выгодно, дешевле готовый, семисегментный или с экраном. Зато как приятно доверять показаниям амперметра и вольтметра, а не перепроверять их постоянно тестером. И бонусом работает быстро. Ещё и интересно было.
+
avatar
+1
  • trykov
  • 05 мая 2026, 18:52
Ну я тоже постоянно был не доволен точностью и скоростью китайских показометров. Но я пошел немножко другим путём.
И таки да — очень приятно доверять показаниям ампервольтметра.
mysku.club/blog/diy/105881.html
mysku.club/blog/diy/105870.html
+
avatar
0
  • trykov
  • 05 мая 2026, 10:27
Что же Вы всё на деньги то меряете? ))
Может мне важнее удовольствие получить от того, что удалось впихнуть нужный функционал в такую малютку-контроллер. ))
+
avatar
+1
  • IWRY
  • 05 мая 2026, 14:05
trykov05 мая 2026, 10:27
Что же Вы всё на деньги то меряете? ))
trykov04 мая 2026, 23:08
А какая вам нужна аргументация? ))
У меня при разработке была такая:
— была в наличии часть комплектующих
покупать готовый было дороже
...
)))
+
avatar
0
  • trykov
  • 05 мая 2026, 15:29
Вы, видать, не понимаете о чём речь. ))
Я вот про это Вам написал «время, потраченное на впихивание в этот килобайт».
Вы моё время и работу, которую я делаю для души, пытаетесь в деньги переводить. ))
А приводить Вам в качестве аргумента «работу для души» явно же бесполезно. ))
Вы в таких категориях, как я понял, мыслить не привыкли. ))
+
avatar
+1
  • IWRY
  • 06 мая 2026, 12:01
А приводить Вам в качестве аргумента «работу для души» явно же бесполезно. ))
Как раз наоборот — я отлично понимаю рукоприкладство ради удовольствия /и это можно легко увидеть, просто взглянув на мои статьи тут/, но категорически не понимаю, чего ради Вы пытаетесь так многословно и противоречиво это объяснять и оправдывать.
«Захотелось попробовать» — абсолютно достаточный аргумент, никакие иные не нужны.
+
avatar
+1
  • trykov
  • 06 мая 2026, 12:20
Ну вот всё равно не совсем так. ))
Не просто захотелось. А с одной стороны возникла потребность в устройстве.
С другой был некий задел по комплектующим, что позволяло получить результат за недорого. И с третьей — действительно посчитал, что приятнее будет сделать своими руками прибор более компактный, удобный и с возможностями развития, чем покупной и параллельно подготовить компактный код для паяльной станции на ATTiny13…
+
avatar
+1
  • IWRY
  • 06 мая 2026, 12:57
Не просто захотелось.
«Захотелось» — ключевое условие, пшт остальные влёт перекрываются примитивным «купить дешевле выйдет», особенно с учётом потраченного времени по рыночной цене инженера соответствующих компетенций))
Недавно тоже отвечал на подобное:
mysku.club/blog/diy/105562.html#comment4773963
+
avatar
0
  • trykov
  • 06 мая 2026, 13:33
Да нет — если бы не было кучки имеющихся комплектующих (термопара, экран, контроллер, клемки, аккумулятор, дисплей), может и купил бы. А так — нашлось применение тому, что и так в загашнике завалялось. Ну вот при наличии всего в звгвшнике и возникла мысль применить всё это.
+
avatar
+2
  • IWRY
  • 05 мая 2026, 14:12
почему-то вынужден оправдываться
Вряд ли кто-то стоит с пистолетом у него за спиной.
Захотел — сделал, хочет — оправдывается, хозяин-барин ))
+
avatar
0
  • trykov
  • 05 мая 2026, 15:37
Ну, «оправдываться», наверное не совсем то слово. ))
Я пытаюсь объяснить, что кроме финансовой мотивации, могут быть и другие аргументы:
— получить удовольствие от собственной работы,
— поделиться, возможно полезными, способами минимизации кода с любителями покопаться с тиньками
— заинтересовать кого-то возможностью создания на базе простого устройства собственных расширенных решений (высокотемпературного терморегулятора или контроллера превышения температуры, например).

Но далеко не всегда получается объяснить это людям, пересчитывающим моё свободное время на деньги. ))
+
avatar
0
  • IWRY
  • 06 мая 2026, 12:22
не всегда получается объяснить это людям, пересчитывающим моё свободное время на деньги
А таким и не надо ничего объяснять, смысл?
+
avatar
+1
  • MikeW
  • 05 мая 2026, 00:40
тогда бы уже тини25. Там, по идее, в 2 градуса можно уложиться со встроенным ацп и усилителем х20 без дополнительных микросхем.
+
avatar
+1
  • MikeW
  • 05 мая 2026, 01:06
Если уж очень нравится AVR tiny или китайское «одноцентовое», рекомендую к просмотру oshwlab.com/wagiminator/works
+
avatar
+1
  • trykov
  • 05 мая 2026, 10:39
Спасибо за ссылку — знакомый сайт, знакомый автор.
У него, кстати, есть интересный проект паяльной станции на агдуинке.
Я для себя его немного подшаманил — переделал на LGT8F328, добавил возможность работать с С245 дополнительно к Т12 и русифицировал меню.
Пришлось правда свои шрифты русские делать. С русскими шрифтами U8g2lib.h — не хватает памяти.
+
avatar
0
  • trykov
  • 05 мая 2026, 10:31
Так я же, вроде, написал — завалялись кое-какие детальки. Почему не сделать именно из них.
Ну нету у меня тиньки 25. А десяток тинек 13 ещё завалялся. ))
+
avatar
+1
За программу на Си действительно респект. Ибо тоже таким порой занимаюсь (а как иначе на тиньках то? асм если только тогда), то вот тут пара любительских вопросов:
Почему нельзя было сразу _delay_ms(100)? В чем была такая необходимость делать через цикл? Я понял, что в макрос _delay_ms нельзя подставить переменную, но у вас в коде вроде бы везде константы прописаны.
Для чего переменные kd и ks? Я увидел что они для вывода на экран, но для чего они в принципе, что вы из них иногда вычитаете сотни и десятки?
+
avatar
+4
  • trykov
  • 05 мая 2026, 13:37
Это всё маленькие хитрости, чтобы уменьшить объём кода.
Тот код, что в статье, даёт при компиляции скетч в 362 байта. Если заменить функцию delay_msTK на макрос _delay_ms() во всех местах в программе, то объём скетча вырастает до 402 байт. Я думаю, что это происходит потому, что макросы вставляются в программу напрямую, а не используются как однажды написанная и многократно используемая функция.
С такой же целью используются для получения значений десятков и сотен счётчики kd и ks вместо кода типа
int ed = t % 10; // 3 (единицы)
int des = (t / 10) % 10; // 2 (десятки)
int sot = (t / 100) % 10; // 1 (сотни)
который даёт ещё больший прирост размера программы — до 452 байт.
Счётчики экономичнее, чем деление. Особенно для ATTiny13 и им подобных AVR с урезанным математическим функционалом.
+
avatar
0
объём скетча вырастает до 402 байт
Первое — у gcc есть разные типы оптимизации, если нужен минимальный код, надо включать -Os. Второе, если вы не хотите, чтобы в каждом месте использования генерировался один и тот же код, вынесите его в функцию, которую пометьте __attribute__((noinline)).
+
avatar
+1
  • trykov
  • 05 мая 2026, 21:18
Так я и вынес макрос в отдельную функцию поэтому.
Что не так?
А по умолчанию Arduino IDE и так компилирует код с флагом -Os (оптимизация по размеру).
Впрочем, Вы всё можете проверить сами — код программы в статье есть.
+
avatar
0
Что не так?
Я разве говорил, что что-то не так? ) Именно в ардуино иде давно ничего не делал, сейчас использую vs code + platformio, там руками настраивал оптимизацию по необходимости. Но, вообще, для atiny13 обычно пишу на асме
+
avatar
0
А не проще было использовать в качестве датчика Pt100/Pt1000?
+
avatar
0
  • trykov
  • 05 мая 2026, 10:45
Так у меня была уже термопара от мультиметра. Зачем покупать другую?
Они обе типа «К» и дают одинаковый результат.
Только в том, что от мультиметра, уже есть подходящие контакты.
+
avatar
+2
  • ksiman
  • 05 мая 2026, 08:23
Термопара измеряет разность температур, поэтому надо учитывать температуру холодного спая
+
avatar
0
  • trykov
  • 05 мая 2026, 10:46
Ну так потому я и использовал MAX6675 — там уже есть учёт температуры холодного спая.
+
avatar
+1
  • ksiman
  • 05 мая 2026, 12:58
Но в обзоре ни слова про компенсацию, а это важно…
+
avatar
0
  • trykov
  • 05 мая 2026, 13:38
ну я просто не стал дублировать информацию из даташита MAX6675.
Хотя Вы, наверное правы — стоит добавить в статью.
Вечером подправлю.
+
avatar
0
Удалено.
+
avatar
0
  • trykov
  • 05 мая 2026, 14:15
Я не знаю, почему Ваш комментарий удалён, но Вы абсолютно правильно подметили, что минус термопары должен быть соединён с минусом питания. На схеме я это забыл показать — сегодня исправлю.
На плате капелькой припоя ножки 1 и 2 соединены. Вот фрагмент фото, на котором это хорошо видно.
+
avatar
0
  • knst
  • 05 мая 2026, 13:25
Это чисто термометр, и паяльником он не управляет?
+
avatar
0
  • trykov
  • 05 мая 2026, 13:41
А я разве где-то говорил, что этот термометр управляет паяльником?
Мне для кода паяльной станции на ATTiny13 важно было попробовать минимизировать код работы с TM1637, которая будет индикатором и обработчиком нажатий кнопок, а также управления пищалкой в схеме паяльной станции.
+
avatar
0
  • knst
  • 05 мая 2026, 19:09
Добавьте в схему оптрон и симистор, научите термометр держать заранее установленную температуру какого либо устройства и ваш термометр станет на порядок функциональнее.
+
avatar
0
  • trykov
  • 05 мая 2026, 19:55
Да я и писал в статье, что можно наращивать функционал. Но вот мне самому пока негде применить такие асширения.
+
avatar
0
  • Detail
  • 05 мая 2026, 13:43
Del
+
avatar
0
  • MikeW
  • 05 мая 2026, 17:59
mysku.club/blog/aliexpress/39832.html давно было…
нет смысла пытаться сделать это в тини13. Никакого. Вообще. Ладно бы если вопрос был 20 лет назад то все равно можно было бы рассматривать tiny25-45-85 или mega48-88-168-328, как полнофунциональную замену если место закночится. Но тут нет. Тини13 ни на что не заменить без серьезного переписавания кода.
Практического смысла оптимизировать код для AVR в 2026 — нет. Это ничем не поможет при разработке для stm32 или каких-нибудь risc-v.
B вы не «продадите» это даже тут или вообще в любом OSHW сообществе. Просто потому что не у всех есть «запасы», а покупать авр сегодня — бессмысленно.
+
avatar
+2
  • trykov
  • 05 мая 2026, 18:31
Я думаю, что Ваше мнение про популярность AVR может измениться, если Вы посмотрите сколько их на Алике покупается (там у всех товаров есть пунктик — сколько продано). ))
Я вот для электросамоката внуку делал на тиньке «плавный газ». Малюсенькая такая платка 2х2 см.
Вы серьёзно думаете, что это стоило делать не на тиньке, а на синей плате STM32 и потом попробовать это впихнуть в батарейный отсек самоката, где особо и места нет лишнего.
+
avatar
0
  • MikeW
  • 06 мая 2026, 14:36
Удачи вам в этом. У меня у самого куча всяких разных АВР в шкафу. Но они скорее всего будут преданы забвению, ибо для новых разработок я их не возьму.
2х2см — я бы на сегодня взял есп32-с3 (если там подходит по напряжению и прочим факторам)
+
avatar
+1
  • CsCs
  • 05 мая 2026, 18:00
Это… а тут компенсация температуры холодного спая есть?
Обычно же в промке ставят второй датчик температуры прям у клемм подключения кабеля термопары и измеряют темературу холодного спая. Чтобы по ней компенсировать дрейф.
Тут такое есть?
+
avatar
-1
В мультиметрах тоже нет.

Тем не менее, даже здесь, в комментариях к этой заметке раздаётся громкое «фу-у-у, купи мультиметр!».
+
avatar
+2
  • yup2
  • 05 мая 2026, 18:16
В мультиметрах как раз есть — там в роли датчика отдельный диод задействован.
И именно поэтому мультиметр при отсутствии термопары показывает комнатную температуру.

Да, диод нормально работает в довольно узких пределах, но и мультиметром никто не пользуется ни при -30, ни при +80.
+
avatar
0
  • trykov
  • 05 мая 2026, 18:21
У MAX 6675 компенсация холодного спая есть.
При написании кода для своих решений без спец микросхем, можно просто принять примерно 20 радусов в качестве температуры холодного спая, если будете измерять в нормальном помещении.
+
avatar
0
  • yup2
  • 05 мая 2026, 19:10
Кстати, я буквально час назад работал с этой микросхемой (в виде широкораспространённого модуля, в котором на плате только она, конденсатор и клеммы для термопары).

Прикрутил термопару, запускаю в работу — показывает, что в комнате 28,5 градусов. А я сижу возле открытой двери на балкон, и за бортом сейчас +15.

Удивился, заменил штатную термопару на ту, которая шла в комплекте с мультиметром. Стало показывать 30 градусов.
Прикрутил опять первую — 30,5.
Ага, значит как минимум с термопарами всё более-менее в порядке.

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

Пока думал и занимался другими делами, прошло минут 10, а программа всё это время работала, и смотрю — а показывает-то уже реалистичную температуру — 26,5.

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

Но ведь, по логике, при нагреве микросхемы выдаваемые ею показания должны или оставаться неизменными (если внутренняя коррекция есть), или уменьшаться по отношению к исходным (если коррекции нет). Почему же у меня они увеличились?
+
avatar
0
  • trykov
  • 05 мая 2026, 19:53
Ради интереса проверил сейчас на своем термометре.
Результат аналогичный. Держу минуту палец на микросхеме MAX6675. Температура растёт с 25 до 32 градусов.
Отпускаю палец — температура плавно начинает снижаться до первоначальной.
То есть микросхема складывает свою температуру с рассчитанным значением на основе данных от термопары.
+
avatar
0
То есть микросхема складывает свою температуру с рассчитанным значением на основе данных от термопары.
Это и есть компенсация холодного спая. Только спай в месте подключения термопары (разъем), а компенсация в корпусе микросхемы. Если бы нагревали вместе с микросхемой и спай, разницы быть не должно.
+
avatar
0
  • trykov
  • 05 мая 2026, 21:21
Да, возможно. Попробую чуть позже нагреть контакты и микросхему разом.
+
avatar
0
Лучше брать MAX31855 — elchupanibrei.livejournal.com/37378.html
+
avatar
0
  • trykov
  • 05 мая 2026, 21:48
Ну он то раза в три подороже будет.
Что должно меня заставить использовать его в столь простом и дешевом устройстве?
+
avatar
+1
Угу, паяльник без пид, без защиты при обыве термопары и тд и тп. Собирайте на 555 таймере — еще дешевле, а результат то же.
+
avatar
+2
  • trykov
  • 05 мая 2026, 22:53
А почему Вы решили, что без защиты от обрыв термопары. ))
Есть и защита от обрыва термопары, и защита от перегрева, и отключение через три минуты при установке ручки на подставку, и режим сна, и работа с двумя типами жал (Т12 и С245), и свето-звуковая индикация аварийных режимов, и турбо режим, и калибровка с шагом 5 градусов, и подстройка точности температуры подстроечным резистором, и изменение температуры кнопками с шагом 10 градусов.
ПИД нету, но и без него нормально куча проектов работает.
Гистерезиса в пару градусов вполне достаточно, чтобы не было качелей.
А чего ещё вам не хватает в функционале паяльной станции? ))
+
avatar
0
и подстройка точности температуры подстроечным резистором, и изменение температуры кнопками с шагом 10 градусов.
И всё это на tiny13? И на Си?
+
avatar
+7
  • trykov
  • 06 мая 2026, 07:35
Да. И всё это вот на такой простенькой схеме с кодом в 960 байт.
+
avatar
0
Неплохо. А в чем вы такие схемы рисуете?
+
avatar
+2
  • trykov
  • 06 мая 2026, 17:30
В splan70.
Удобный и бесплатный инструмент.
+
avatar
0
  • somon
  • 02 июня 2026, 16:26
Круто! а можно получить код прошивки для этой схемы? думаю её можно же адаптировать для управления температурой паяльного столика на PTC элементе? Или может быть подскажите более подходящую схему управления, искал как раз на каком ни будь простеньком МК семейства AVR, с подобным индикатором…
+
avatar
+1
  • trykov
  • 02 июня 2026, 20:26
Сейчас ещё в режиме отладки. Последние недели вожусь с машиной. Надеюсь, через недельку доведу до ума и выложу статью по ней здесь.
+
avatar
0
  • somon
  • 03 июня 2026, 19:56
Спасибо! С нетерпением жду…
+
avatar
0
  • somon
  • 19 июня 2026, 11:50
Надеюсь, через недельку доведу до ума и выложу

Ещё не выкладывали?
вожусь с машиной
или ещё возитесь...?
+
avatar
0
  • trykov
  • 19 июня 2026, 12:00
Увы нет — острая нехватка времени.
+
avatar
+1
  • sfs
  • 06 мая 2026, 07:03
Ну на 555 это перебор, а на 358 да, Вы абсолютно правы, отлично работает.
+
avatar
0
  • trykov
  • 06 мая 2026, 07:43
Да и на тиньке будет работать. 328 нужен, если у вас текстовый экранчик в проекте.Имено он сжирает основную часть памяти.
+
avatar
0
  • sfs
  • 06 мая 2026, 07:59
Я про LM358 за 5 центов)
+
avatar
0
  • trykov
  • 06 мая 2026, 08:16
Пардон — спросоня недоглядел. ))
+
avatar
+2
  • sav13
  • 06 мая 2026, 16:04
Покупать на Али высокотемпературный точный измеритель температуры просто жаба задавила.
Если только ражи того чтобы руки/мозги потренировать
А так TM-902C на Али/Озоне чуть больше 300р
+
avatar
0
  • trykov
  • 06 мая 2026, 17:29
Ну, на Азоне может и есть за такую цену.
Но я не в РФ.
А на Алике ниже 500 рублей со стоимостью доставки не вижу.
+
avatar
0
Справедливости ради, вот за 309 рублей:
https://aliexpress.ru/item/1005010777196446.html
+
avatar
0
  • trykov
  • 06 мая 2026, 18:26
Увы — это тоже зона Алик-СНГ. У меня он недоступна. Только зона .com
+
avatar
0
Ладно, вот уже на али.ком за 4 евро, это ведь явно меньше 500 рублей:

+
avatar
0
  • trykov
  • 07 мая 2026, 18:00
Вот Вы не угомонный. ))
Это снова цена для РФ.
Вот Вам скрины на тот же товар в том же магазине, но с отправкой в Чехию.
Докупаете к нему Крону и получаете те же 600 рублей.
+
avatar
+1
  • yup2
  • 07 мая 2026, 19:25
На aliexpress.com не может быть цены для РФ и всех прочих стран, объединённых в понятие «Aliexpress СНГ».

А что для разных стран мира цены разные — так оно всегда так было.

Плюс не забываем о милой привычке Aliexpress показывать не все из имеющихся предложений, из-за которой разные покупатели даже из одного города могут видеть существенно разные списки.
То есть, не исключено, что и для Чехии есть более дешёвые варианты.
+
avatar
+1
Это снова цена для РФ.
Нет, это был немецкий али, откуда там цена для РФ?
Вот Вы не угомонный. ))
Потому что я за справедливую оценку. Вы выше писали, что ничего меньше 500 рублей нет, но вот вам лот за 3.7 евро, что значительно меньше 500 рублей. Что касается бесплатной доставки — тут достаточно добавить еще что-то за 5 евро.

А батарейка — её и на озоне нет в комплекте.
+
avatar
0
  • trykov
  • 07 мая 2026, 21:07
Во-первых, я сравнивал своё устройство уже с аккумулятором в комплекте. Так что справедливо сравнивать покупной прибор с включенной ценой элемента питания.
Во-вторых, я Вам привёл пример именно вашего продавца с именно вашим товаром с приведённого Вам скрина. И там цена другая, как Вы можете видеть.
Если для Вас новость, что и цена товара и цена доставки для разных стран может быть разная, то я Вас поздравляю — Вы одогатили свои знания новым богатым опытом.
Можете сами указать другую страну и посмотреть, что выдаст Али по цене товара и цене доставки.
А то, что это был немецкий сайт, значения не имеет. Имеет значение в какую страну доставка.
+
avatar
0
Добавлять батарейку в цену устройства — несколько странно. Батарейка — это независимый универсальный источник питания, она может быть использована где-то еще. Например, у меня есть парочка неиспользованных крон, которые просто лежат в ящике и стареют, поэтому когда придет этот термометр (да, я тоже заказал), я просто возьму одну такую батарейку и поставлю в него.
я сравнивал своё устройство уже с аккумулятором в комплекте
Если вы перечитаете все мои комментарии, то не найдете в адрес вашего устройства ни одного слова осуждения или сравнения его цены с покупным. Я спорю только с двумя вашими другими утверждениями — что мультиметром нельзя нормально измерить температуру (можно), и что готовый термометр нельзя дешево купить на али (тоже можно).
И там цена другая
На вашем скриншоте цена 3.7 евро и бесплатная доставка при заказе на 8.7 евро. Именно об этом я писал выше, 3.7 евро меньше 500 рублей, а корзину можно добить другим товаром на 5 евро для получения бесплатной доставки.
Имеет значение в какую страну доставка.
Немецкий сайт не может доставлять в Россию, как вам справедливо заметили выше.
+
avatar
0
  • trykov
  • 08 мая 2026, 00:57
Что значит ДЕШЕВО в Вашем понимании. Дешево или дорого понимается только в сравнении. Я сравнивал с затратами на свою конструкцию. А если компенсировать цену доставки другими покупками, то я так и на свои комплектующие ещё цену снижу. ))
Я не знаю, что Вы указывали как страну назначения на немецком сайте.
Но этот же товар от этого же продавца бесплатно в Чехию не доставляется, как я Вам и показал на скрине.
По мультиметру готов уточнить — нельзя точно измерить ДЕШЕВЫМ мультиметром. Под словом ТОЧНО, в данном случае я говорю о точности в 1 градус, котоую я без проблем получил с MAX.
+
avatar
+2
С термопарой вы не сможете получить высокую точность — её выходное напряжение даже для типа К описывается дифуром 32 порядка (платина — платина-родий 6% == Type S ещё более нелинейна — там дифур 38 порядка), а погрешность ±3 градуса.

И по поводу конструкции — сделано красиво, но зачем возится коли есть заводской TM902C который делает тоже самое? И что важно — его можно поверить/откалибровать в любой метрологической лаборатории и тогда его показаниям можно будет доверять.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.