Измерение температуры сделал на термопарах с усилением их сигнала на отдельной плате-усилителе (в моем случае я калибровал для каждого канала отдельно каждую термопару). Если будете повторять, лучше сделать на модуле max31855, но придется немного изменить код и схему (там не много просто я занял оба SPI, но место еще есть, луче использовать SPI2) .
В основном меню устанавливаем температуру, поворотом энкодера, значения сохраняются во флеш. Если вам не нужен верх, то можно установить 0 в задании температуры.
Так же есть подменю с настройками ПИД регуляторов, тут перемещение нажатием кнопки на энкодере а поворот устанавливает значение.
ПИД регулятор получился не такой как все =). Его интегральная часть это единица времени, а не просто безразмерный коэффициент как в других цифровых регуляторах. Все цифровые регуляторы дискретны (мои срабатывают каждые 500мс(можно сделать быстрее если нужно)), за это время интегральная часть закидывает в буфер текущее значение ошибки регулирования. Дальше берется сумма этого буфера и вот мы получаем интеграл. Вот тут то и отличие, те регуляторы, что я видел, берут сумму всего буфера и умножают на безразмерный коэффициент. У моего регулятора интегратор это и есть число выборок, которое нужно взять. Допустим, время интегрирования установлено 10 т.к. частота дискретизации регулятора 0,5 с 10*0,5=5 секунд. Следовательно, регулятор будет использовать интеграл изменения ошибки за последние 5 секунд. Максимум 256 выборок. Хотел сделать, что то похожее с дифференциальным звеном, но чет забил. Там можно было бы уменьшать время для следующего отчета ошибки для диф. звена, но тогда придется слишком часто дергать АЦП, а нам еще данные по ЮСБ отправлять и на экран.
Чтобы получать данные по USB нужно установить драйвер от STM usb-cdc. Потом у Вас появится ком порт, куда каждые 500мс будут отправляться данные. Можно не использовать эту функцию, ну а если решите написать ГУИ, то в коде вся строка отправления лежит за sprintf. Так же можно отправлять команды на управление. Например, чтобы установить температуру верха нужно закинуть строковые “Ch5”+ 2 байта значение температуры (0x01ff-511 градусов).
Использован широко известный экран i2c на контроллере ssd1306 (128x64), я использую свою библиотеку к нему (урезанный adafruit).
В силовой части использовал тиристоры BTA41-600. Они на 40А, но т.к. китайские, для нагрузки в 2кВт поставил 2 штуки параллельно (говорят так нельзя делать, но я надеюсь, Вы никому не скажете). Чтобы ими управлять и использую внешние прерывания при переходе синуса сети через 0. Сделано на самой обычной оптопаре, диодном мосте и паре резисторов (на схеме d1-4, u5). На печатной плате разделил силовую часть от слаботочной. Предохранителей никаких не ставил, потому что думаю запитать от автомата.
С силовой частью все. Вот такое получилось устройство в сборе (пока без радиаторов). Нагружал силовую часть лампочками по 100Вт, все работает.
Остается сделать корпус, пока на это нет времени. Нагреватели уже куплены и лежат в коробочках. Нагреватели заказывал у компании Электронагрев, обошлись в 6 тысяч с доставкой в Уфу, но при получении у Деловых линии, возникли проблемы с тем, что у них висел какой то долг)). Через пару дней они закрыли долг и я смог получить свои нагреватели.
Что я бы изменил, если делал заново:
• Использовал max31855
• Не забыл включить вачдог)))
• Использовал freertos
• Дописал ГУЙ))
Схемы и ссылку на код прилагаю:
https://drive.google.com/open?id=1TT0NNhkICT5_5t9u4LS_0rpkKu...
https://easyeda.com/aminovilshat/Payalnik_ultra
З.Ы. я не занимаюсь профессионально программированием STM32, это всего лишь хобби. Но судите строго) кроме советов отказаться от HAL и СubeMX.