программирование

программирование

Подписчиков: 235     Сообщений: 747     Рейтинг постов: 12,158.1

it-юмор geek программирование велосипед вело гифки 

Развернуть

Отличный комментарий!

Работает же.
u17856 u1785626.06.202220:57ссылка
+24.7
Ехать чтоб. Педали крутишь вперёд едешь. ТЗ соблюдено
Melifaro Melifaro26.06.202220:59ссылка
+43.3

it-юмор geek программирование 

Александр Кучу к @аагехег Вообще весь мир обман, посмотрел я на этих мобильных разработчиков, целый день за компьютером сидят не вставая, очень мобильно 10 из 10.,it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,программирование
Развернуть

it-юмор geek программирование twitter интернет 

МИ Топеку @п1киопэку • Программирование — это как танец,it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,программирование,twitter,интернет
Развернуть

Отличный комментарий!

diamid diamid21.06.202213:07ссылка
+58.5

python программирование geek фриланс it-юмор 

Я: * ЗАХОЖУ НА ФРИЛАНС* ФРИЛАНСЕРЫ: Мы питонисты гордый народ 100 рублей сайт 50 рублей бот,python,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,фриланс,it-юмор
Развернуть

программирование geek python Илон Маск it-юмор 

Elon ... О @elonm... ■ Apr 28 Дальше я покупаю Python и добавляю фигурные скобки... Q 182.7К tl 841.1 К Z> 4.4М Д,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,python,Илон Маск,it-юмор
Развернуть

программирование geek разработка it-юмор 

кто взаимодействовал с казначейским софтом, тот поймёт...

Programmers in Enterprise Company Programmers in Startup Company Programmers in Government,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,разработка,it-юмор
Развернуть

Отличный комментарий!

ну так правильно, с квадратными колесами медленнее тащить, если быстрее докатишь, то тебе еще работы навалят и не факт, что по твоему профилю
balmashev balmashev09.06.202212:07ссылка
+54.0

программирование geek Wojak Мемы 

The 30 year old OOPer Project has 412 folders. 13.571 classes and not a single If statement because If statements are unclean, literally unreadable spaghetti D.R.Y. fundamentalist (except for the 500 near identical overload methods) Begins each new project with PrimordialSpaceTimeFabnc
Развернуть

программирование geek Мемы ООП Комиксы 

 Джо, этот класс должен ,авать только возможность говорить У перевод 2£шт.еи ■ ' • Й2АКК0С0»Л!С.В1СЮ5Р0Т.С0»Л Т\\>обпеьАЫ при использовании ООП,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор,Мемы,Мемосы, мемасы, мемосики, мемесы,ООП,Смешные комиксы,веб-комиксы с
Развернуть

Wojak Мемы программирование geek 

int * int*,Wojak,Вояк,Мемы,Мемосы, мемасы, мемосики, мемесы,программирование,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Развернуть

Отличный комментарий!

Это самое охуенное объяснение указателей что я видел!
DesuRider DesuRider01.06.202222:16ссылка
+33.7

песочница АСУ ТП программирование geek реактор образовательный длиннопост 

Часть 3, каркас архитектуры

Часть 1, введение
Часть 2, приоритеты и базовые сигналы

Мда, я дико извиняюсь за большое количество опечаток в предыдщих постах. Руки не поспевают за мыслью, а при редактировании потеряется часть оформления регулярно. Не зналь(

Имея на руках пример того, с чем предлагается работать, впору поговорить об архитектуре, которая и будет обеспечивать корректное и стабильное исполнение кода, однако, перед этим сделаем ряд важных оговорок:
1) концепт ориентирован на работу с жёстким распределением памяти (Siemens, OMRON CP/CJ series)
2) ввиду пункта 1 внутри одной структуры могут быть переменные которые И читаются, И пишутся, что существенно усложняет их проброс в коммуникацию(особенно тех, которые пишутся И с панели оператора, И из программы, например запуск в ручном режиме и сброс аварий в структуре управления)
3) объём памяти оперативность и для хранения кода, а также мощность CPU–считаются достаточно большими, чтобы не обращать на них внимания, в иных случаях требуется оптимизация кода
4) при работе с контроллерами, имеющими «классическое» распределение памяти, для обеспечения корректного управления моим кодом по ModBus RTU/TCP требуется дополнительная прослойка, которая будет пересобирать структуры в WORD и обратно, когда-нибудь я это исправлю, но явно не сейчас
5) вся концепция рассчитана на применение в обще-промышленной области, где потерять 10-20-30 мс роли не сыграет никакой, если вам нужна более высокая точность – добро пожаловать в чудный мир оптимизации и распределения кусков кода по разным циклам

Ещё одно лирическое отступление

Я осознанно не буду вам рассказывать как работает Промышленный Логический Контроллер (ПЛК), распределение его памяти, времени CPU по задачам системным и пользовательским, типы данных и прочую лабуду – это вы можете узнать на любых вводных курсах от любого производителя железа. Моя задача – показать пример прикладной реализации тех или иных задач.
Кстати, на ардуине в своё время использовал Union, который прекрасно решал проблему компоновки памяти, однако подавляющее большинство сред разработки для промышленного оборудования его или не поддерживают, или имеют кастрированную реализацию.

Генерация импульсов

Начнём с терминологии:
- импульс – это нечто, существующее предельно короткое время, в нашем случае сие ровно 1 цикл контроллера.

Большинство контроллеров предлагает свои системные генераторы импульсов в том или ином виде, но выглядят они следующим образом на примере 1 секунды: 

0.5 сек <-----►
<---->
0.5 сек
------>
время,песочница,АСУ ТП,программирование,geek,Прикольные гаджеты. Научный, инженерный и  айтишный юмор,реактор образовательный,длиннопост

Что это значит на практике? Предположим, время цикла ПЛК = 10 мс, тогда:

50 циклов <----->
<--->
50 циклов
<----------->
100 циклов
----->
циклы,песочница,АСУ ТП,программирование,geek,Прикольные гаджеты. Научный, инженерный и  айтишный юмор,реактор образовательный,длиннопост

Ёбушки воробушки, наш самописный таймер то проверяет когда сигнал = 1, а он равен 1 в течении 50 циклов, а за это время он насчитает 50 секунд, вместо 1! Лажа какая-то. Мы должны получить следующее:

о
1 цикл
циклы
>,песочница,АСУ ТП,программирование,geek,Прикольные гаджеты. Научный, инженерный и  айтишный юмор,реактор образовательный,длиннопост

Для этого есть несколько вариантов, и сначала мы отметём в сторону самый очевидный: мы НЕ будем в каждом таймере проверять фронт системного генератора импульсов, потому что каждая проверка фронта это +1 переменная в памяти ПЛК, а мы не хотим засирать его бесполезным хламом.
Итого остаётся:
1) вызывать системный импульс, проверять его передний или задний фронт и закидывать в pulse_1s;
2) вызвать стандартный таймер TON с длительностью 1 секунда и зациклить на самого себя, при срабатывании таймера взводить pulse_1s;
3) читать системное время и по внутренним часам ПЛК и при смене секунды однократно взводить pulse_1s, потребуется буфер для хранения и сравнения предыдущего времени;
4) прочитать из недр контроллера время предыдущего цикла, насуммировать несчастные наносекунды до 1 секунды и тоже записать в pulse_1s единичку, после чего очистить буфер.
5) ещё что-нибудь на ваше усмотрение.

Мне глубоко фиолетово, каким способом вы получаете в итоге pulse_1s, но вам достаточно получить его корректно 1 раз и все таймеры во всей программе сразу же заработают, причём корректно и, вау, синхронно. Т.е. если у вас в двух местах с разбегом менее 1 секунды начался счёт до 5, то закончится он тоже одновременно. В этом и плюс, и минус. Мы теряем точность. Но так ли она нужна?
Хотите точность до 100 мс? Пишем таймер Time_R для дробных значений генерируем pulse_01s.
Хотите точность до 10 мс? Ну… сделайте отдельный цикл ПЛК с такой частотой и там считайте. Или убедитесь, что ваше время цикла менее 10 мс на всю программу.

1
2
3
4
5
€
7
3
S
10
11
12
TYPE Time_R :	
STRUCT	
Start	:BOOL.
Q	:BOOL.
Pause	:BOOL.
Reset	:BOOL.
SP	:REÀL,
AP	:REAL,
One	:REÀL,
Percent	:REAL,
END_STRUCT	
END TYPE	
//вес импульса //прогресс выполнения,песочница,АСУ ТП,программирование,geek,Прикольные гаджеты. Научный,


FUNCTION drv_Time_R : bool VAR_IN_OUT
T	:Time_R;
END_VAR VAR
END VAR
// Таймер с произвольной кратностью счёта T.One := 0.1;
IF T.Start AND NOT T.Reset THEN // Работа таймера IF T.AP < T.SP THEN
IF NOT T.Pause THEN
IF sys.pulse_01s THEN
T.AP := T.AP + T.One; END_IF;
END_IF;
T.Q :=

Обратите внимание, что этот таймер сложнее – мы считаем прогресс времени от 0 до 1,который можно использовать для вспомогательных операций (типа на 30% всего времени моргнуть правой пяткой) и красивого прогресс-бара на экране.

Архитектура

Перейдём к тому, ради чего был затеян данный раздел. Следите за руками…

1 цикл ПЛК,песочница,АСУ ТП,программирование,geek,Прикольные гаджеты. Научный, инженерный и  айтишный юмор,реактор образовательный,длиннопост

Где-то там приютилось ещё регулирование, типа ПИДов, но о них как-нибудь в другой раз.

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

К глобальным относится всё, что ранее было названо глобальным, а также туда настоятельно рекомендуется выносить:
- все структуры управления драйверами
- все структуры параметров драйверами
- все структуры состояний драйверами
- общие параметры техпроцесса
- общее управление техпроцессом, типа включить/выключить установку

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

1
2
3
4
5
€
7
3
з
10
11
12
13
14
15
1€
17
13
13
20
21
22
23
24
25
2 €
27
23
23
30
31
32
VAR GLOBAL RETAIN
//Дискретные входа
DIx_cfg	¡ARRAY
//Дискретные вы:-:ода	
D0x_cfg	¡ARRAY
//Приводы с ЧП	
MDx_cfg	¡ARRAY
//Пневмоцилиндр	>ы
VDx_cfg	¡ARRAY
[0..10] OF

REQ – Request, запрос запуска. Сюда мы из авторежима будем писать команду для устройства, а затем скармливать драйверам в CMD.Start_A.
DONE – состояние устройств, если оно выключено или в аварии то соответствующий флаг =0, если успешно запущен = 1. Это хорошо заходит для минимизации алгоритма авторежима и всяких вспомогательных операций.

А что же тогда попадает в call’ы?Нерадивые любители звонков с автонабором? Увы, их неплохо бы там запереть, но места маловато. Там будут вызваны непосредственно экземпляры драйверов на исполнение со всей обвязкой. На примере уже рассмотренных дискретных входов это выглядит так… опс, в этом проекте их нет, вот вам выхода:


FUNCTION_BLOCK call_DO
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
DOx ¡ARRAY [0..10] OF drv_DO; END VAR
//Пневматика
//выталкиватель трубы из захвата dev := 0;
DOx[dev](
Signal := REQ.KC[0],
CHD := DOx_CHD[dev], cfg := DOx_cfg[dev],
Result => KC_0_CMD );
//выталкиватель трубы из

Из вкусного – вы можете создавать массивы и обрабатывать их пакетно, можете обрабатывать индивидуально, можете создавать со своим именем на каждый сигнал…но концепция не изменится. Они управляются одинаково, ведут себя одинаково, выглядят плюс-минус одинаково. Вы можете спокойно ковыряться внутри драйвера, подкручивая ему те или иные плюшки под конкретный проект, но вся остальная обвязка не сдвинется ни на бит. И это, йа щитаю, прекрасно!
Развернуть
В этом разделе мы собираем самые смешные приколы (комиксы и картинки) по теме программирование (+747 картинок, рейтинг 12,158.1 - программирование)