Просмотр полной версии : массив из Bit
MichailG
28.02.2023, 19:32
Здравствуйте, форумчане. Возник вопрос, как это сделать, но пока не получается, точнее получилось, но не очень удобно. Есть массив
BoolArray:ARRAY[0..15] OF BOOL;
Пришлось каждый элемент массива прописывать в Modbus Slave во всех 16 битах (битовых каналах).
Хотелось получить доступ к битам через массив. Забиваю этот массив в Channel 0[0] (2-й элемент в иерархии) - выдает ошибку "Типы канала и соотнесённой переменной Application.PLC_PRG.BoolArray не совпадают", забиваю в Channel 0 - компилится, но происходит следующее:
bit1 меняю - не меняется, но устанавливается bit8 (256) и не сбрасывается, bit0 только меняется. Использую функцию Read Holding Registers (03) длина 1. Т.е. реально тип BOOL занимает 8 бит, а BIT - 1 бит, поэтому такое поведение. Массив из BIT объявить нельзя, как сказано в "Работа с памятью в CODESYS V3". Есть примеры как объединить BIT в WORD через структуру, а как это сделать в массив, чтобы программно можно было перебрать все биты через цикл и не прописывая каждый бит Modbus каналах?
Евгений Кислов
28.02.2023, 19:37
Здравствуйте, форумчане. Возник вопрос, как это сделать, но пока не получается, точнее получилось, но не очень удобно. Есть массив
BoolArray:ARRAY[0..15] OF BOOL;
Пришлось каждый элемент массива прописывать в Modbus Slave во всех 16 битах (битовых каналах).
Хотелось получить доступ к битам через массив. Забиваю этот массив в Channel 0[0] (2-й элемент в иерархии) - выдает ошибку "Типы канала и соотнесённой переменной Application.PLC_PRG.BoolArray не совпадают", забиваю в Channel 0 - компилится, но происходит следующее:
bit1 меняю - не меняется, но устанавливается bit8 (256) и не сбрасывается, bit0 только меняется. Использую функцию Read Holding Registers (03) длина 1. Т.е. реально тип BOOL занимает 8 бит, а BIT - 1 бит, поэтому такое поведение. Массив из BIT объявить нельзя, как сказано в "Работа с памятью в CODESYS V3". Есть примеры как объединить BIT в WORD через структуру, а как это сделать в массив, чтобы программно можно было перебрать все биты через цикл и не прописывая каждый бит Modbus каналах?
Добрый день.
Если цель - работать с битами в цикле, то см. в библиотеке Util функции EXTRACT/PUTBIT.
MichailG
01.03.2023, 18:15
Спасибо огромное! Теперь я объявил вместо массива переменную X типа WORD и не пришлось расписывать битовые каналы, но теперь другое неудобство!? Я не могу имитировать нужный бит отдельно, только введя число. Это нужно заранее перевести двоичный код в число и потом это число.
Евгений Кислов
01.03.2023, 18:16
Я не могу имитировать нужный бит отдельно, только введя число. Это нужно заранее перевести двоичный код в число и потом это число.
Поясните вашу проблему скриншотами - что вы делаете сейчас и как бы вам хотелось это делать.
MichailG
04.03.2023, 09:38
Вот скриншот, 66299, но когда был массив расписан по битам, то можно было менять бит по-отдельности. Скриншот: 66300. Пробовал объявлять BIT в структуре - пишет базовый тип недоступен.
Евгений Кислов
04.03.2023, 09:55
То есть в итоге:
- не хочется "каждый элемент массива прописывать в Modbus Slave"
- нужно "чтобы программно можно было перебрать все биты через цикл"
- нужно "чтобы можно было менять бит по отдельности" (в режиме онлайн-отладки)
Тогда можно сделать так - создать UNION, в котором разместить WORD и структуру с BIT (тут вы совершенно верно выбрали направление).
См. п. 1.1.3 и 1.3 в этой статье:
https://ftp.owen.ru/CoDeSys3/98_Books/CodesysMemoryManipulation.pdf
WORD - для привязки к Modbus Slave и "программного перебора битов", структура с битами - "чтобы можно было менять бит по отдельности".
MichailG
04.03.2023, 13:11
Сделал как вы рекомендовали, но отдельно бит устанавливать у меня не получается.
1) Пришлось объявить биты по-отдельности, массив не принимает, пишет "BIT недопустим в качестве базового типа массива". Тогда смысл объявлять структуру, масло масляное. Закомментировал массив.
2) Перебрав всякие варианты привязки к Modbus Slave, подобрал вроде рабочий вариант, но при изменении бита в окне Подготовка значения выдает значение System.Object[], пробовал вводить true и 1 - выдает ошибку. И то сначала нужно значение WORD поменять, только потом разрешает менять бит!? Что я делаю не так? Исправьте пожалуйста ошибку на примере SHSHU_A. Использую Codesys 3.5 SP14 Patch 3. Выкладываю проект.
Евгений Кислов
04.03.2023, 13:17
Вы всё правильно сделали.
Теперь надо нажать Вид - Просмотр - Watch 1.
В панели просмотра внизу введите имя вашей переменной - PLC_PRG.SHSHU_A.
А далее просто изменяйте значения отдельных бит - делать что-то с WORD вообще не потребуется.
66302
MichailG
04.03.2023, 14:07
Работает! Правда я не сразу догадался, что нужно именно PLC_PRG.SHSHU_A, а не Device.Sim.Device.Application.PLC_PRG.SHSHU_A, как предлагает ассистент ввода, тогда все норм. Только жаль все-таки не обойти массив в структуре? Придется каждый бит объявлять...
Евгений Кислов
04.03.2023, 14:10
Работает! Правда я не сразу догадался, что нужно именно PLC_PRG.SHSHU_A, а не Device.Sim.Device.Application.PLC_PRG.SHSHU_A, как предлагает ассистент ввода, тогда все норм. Только жаль все-таки не обойти массив в структуре? Придется каждый бит объявлять...
Чтобы "обойти биты" - у вас внутри UNION есть WORD и функции EXTRACT/PUTBIT из библиотеки Util.
MichailG
04.03.2023, 14:24
Это я понял, я про то что SHSHU:ARRAY[0..15] OF BIT не получится объявить в структуре, нужно bit_0, bit_1, bit_2, bit_3, bit_4, bit_5, bit_6, bit_7, bit_8, bit_9, bit_10, bit_11, bit_12, bit_13, bit_14, bit_15:BIT. Спасибо за ответы!
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot