Страница 1158 из 1186 ПерваяПервая ... 158658105811081148115611571158115911601168 ... ПоследняяПоследняя
Показано с 11,571 по 11,580 из 11853

Тема: ВОПРОС-ОТВЕТ (отвечаем на простые вопросы от новичков)

  1. #11571

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Симулятор панели работает с живым ПЛК, а не симулятором в codesys 2.3.
    В codesys 3.5 можно работать с виртуальным ПЛК.
    Спасибо, мне казалось что и так может тоже


    Подскажите еще пожалуйста вот такой момент, разбираюсь в чужом проекте 1.png 2.png


    Кнопка включения ПВС на панели имеет адрес 0x44, как я понял ведь должен быть адрес 3x0:05 (ON_OFF_PVS_FUG)

    ПВС вообще не работает и я вот не пойму проблема в неправильном адресе кнопки или вообще программный блок не полный 3.png 4.png 2.png

    Как я понял MAN_Regulator это ручной ввод(оно нам не интересно) , а нас интересует AUTO_MAN атематическое регулирование? а ON_OFF_PVS_FUG это сброс регулятора и разрешение работы.

    И мне нужно включить AUTO_MAN и ON_OFF_PVS_FUG



    PLC192.6.0.40.pro проект плк


    HMI 192.6.0.42.rar проект панели



    Обновил программу для подсчета адресов из конфигурации плк теперь считает как 3x , и так же пересчитывает в 0x

    Код:
    import tkinter as tk 
    from tkinter import ttk, messagebox, filedialog
    
    class ModbusAddressCalculatorOrder(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Калькулятор адресов")
            self.geometry("750x700")
            self.resizable(True, True)
    
            self.blocks = []
    
            self.create_widgets()
    
            self.columnconfigure(0, weight=1)
            self.columnconfigure(1, weight=1)
            self.rowconfigure(3, weight=1)
            self.rowconfigure(6, weight=1)
    
        def create_widgets(self):
            padding = {'padx': 10, 'pady': 5}
    
            ttk.Label(self, text="Тип блока:").grid(column=0, row=0, sticky="w", **padding)
            self.type_var = tk.StringVar()
            self.type_combo = ttk.Combobox(self, textvariable=self.type_var,
                                           values=["Float", "2 byte", "8 bit", "4 bytes"], state="readonly")
            self.type_combo.grid(column=1, row=0, sticky="ew", **padding)
            self.type_combo.current(0)
    
            ttk.Label(self, text="Количество:").grid(column=0, row=1, sticky="w", **padding)
            self.count_entry = ttk.Entry(self)
            self.count_entry.grid(column=1, row=1, sticky="ew", **padding)
            self.count_entry.insert(0, "1")
    
            self.btn_add = ttk.Button(self, text="Добавить блок", command=self.add_block)
            self.btn_add.grid(column=0, row=2, columnspan=2, pady=10, sticky="ew")
    
            # Галочка для пересчета адресов в 0x
            self.use_hex_var = tk.BooleanVar(value=False)
            self.chk_hex = ttk.Checkbutton(self, text="Показывать адреса в 0x", variable=self.use_hex_var)
            self.chk_hex.grid(column=0, row=2, columnspan=2, sticky="e", padx=10)
    
            self.btn_load_exp = ttk.Button(self, text="Загрузить .EXP", command=self.load_exp_file)
            self.btn_load_exp.grid(column=0, row=7, columnspan=2, pady=10, sticky="ew")
    
            tree_frame = ttk.Frame(self)
            tree_frame.grid(column=0, row=3, columnspan=2, sticky="nsew", padx=10, pady=5)
            tree_frame.columnconfigure(0, weight=1)
            tree_frame.rowconfigure(0, weight=1)
    
            self.tree = ttk.Treeview(tree_frame, columns=("Тип", "Количество"), show="headings")
            self.tree.heading("Тип", text="Тип блока")
            self.tree.heading("Количество", text="Количество")
            self.tree.column("Тип", width=250)
            self.tree.column("Количество", width=100)
            self.tree.grid(column=0, row=0, sticky="nsew")
    
            tree_scrollbar = ttk.Scrollbar(tree_frame, orient="vertical", command=self.tree.yview)
            tree_scrollbar.grid(column=1, row=0, sticky="ns")
            self.tree.configure(yscrollcommand=tree_scrollbar.set)
    
            btn_frame = ttk.Frame(self)
            btn_frame.grid(column=0, row=4, columnspan=2, pady=10, sticky="ew")
            btn_frame.columnconfigure((0, 1, 2), weight=1)
    
            ttk.Button(btn_frame, text="Удалить блок", command=self.delete_block).grid(column=0, row=0, padx=5, sticky="ew")
            ttk.Button(btn_frame, text="Вверх", command=self.move_up).grid(column=1, row=0, padx=5, sticky="ew")
            ttk.Button(btn_frame, text="Вниз", command=self.move_down).grid(column=2, row=0, padx=5, sticky="ew")
    
            self.btn_calc = ttk.Button(self, text="Рассчитать адреса", command=self.calculate_addresses)
            self.btn_calc.grid(column=0, row=5, columnspan=2, pady=10, sticky="ew")
    
            self.text_frame = ttk.Frame(self)
            self.text_frame.grid(column=0, row=6, columnspan=2, sticky="nsew", padx=10, pady=5)
            self.text_frame.columnconfigure(0, weight=1)
            self.text_frame.rowconfigure(0, weight=1)
    
            self.result_text = tk.Text(self.text_frame, wrap="none", font=("Consolas", 10))
            self.result_text.grid(column=0, row=0, sticky="nsew")
    
            self.scrollbar_v = ttk.Scrollbar(self.text_frame, orient="vertical", command=self.result_text.yview)
            self.scrollbar_v.grid(column=1, row=0, sticky="ns")
            self.result_text.configure(yscrollcommand=self.scrollbar_v.set)
    
            self.scrollbar_h = ttk.Scrollbar(self.text_frame, orient="horizontal", command=self.result_text.xview)
            self.scrollbar_h.grid(column=0, row=1, sticky="ew")
            self.result_text.configure(xscrollcommand=self.scrollbar_h.set)
    
            self.result_text.config(state="normal")
    
        def add_block(self):
            t = self.type_var.get()
            c = self.count_entry.get()
            try:
                c = int(c)
                if c <= 0:
                    raise ValueError
            except ValueError:
                messagebox.showerror("Ошибка", "Введите корректное положительное число для количества!")
                return
            self.blocks.append({"type": t, "count": c})
            self.refresh_tree()
    
        def refresh_tree(self):
            self.tree.delete(*self.tree.get_children())
            for idx, block in enumerate(self.blocks):
                self.tree.insert("", "end", iid=idx, values=(block["type"], block["count"]))
    
        def delete_block(self):
            selected = self.tree.selection()
            if not selected:
                messagebox.showinfo("Информация", "Выберите блок для удаления.")
                return
            idx = int(selected[0])
            del self.blocks[idx]
            self.refresh_tree()
    
        def move_up(self):
            selected = self.tree.selection()
            if not selected:
                messagebox.showinfo("Информация", "Выберите блок для перемещения.")
                return
            idx = int(selected[0])
            if idx == 0:
                return
            self.blocks[idx], self.blocks[idx - 1] = self.blocks[idx - 1], self.blocks[idx]
            self.refresh_tree()
            self.tree.selection_set(idx - 1)
    
        def move_down(self):
            selected = self.tree.selection()
            if not selected:
                messagebox.showinfo("Информация", "Выберите блок для перемещения.")
                return
            idx = int(selected[0])
            if idx == len(self.blocks) - 1:
                return
            self.blocks[idx], self.blocks[idx + 1] = self.blocks[idx + 1], self.blocks[idx]
            self.refresh_tree()
            self.tree.selection_set(idx + 1)
    
        def calculate_addresses(self):
            addr = 0
            lines = []
            use_hex = self.use_hex_var.get()  # галочка для hex
    
            def fmt_reg(r):
                return f"0x{r:02X}" if use_hex else f"3x{r}"
    
            for idx, block in enumerate(self.blocks):
                t = block["type"]
                c = block["count"]
    
                if t in ["Float", "4 bytes"]:
                    length = 2
                    total_length = c * length
                elif t == "2 byte":
                    length = 1
                    total_length = c * length
                elif t == "8 bit":
                    total_length = (c + 1) // 2
                else:
                    messagebox.showerror("Ошибка", f"Неизвестный тип блока: {t}")
                    return
    
                start_block = addr
                end_block = addr + total_length - 1
                lines.append(f"{idx + 1}. {t} ({c} шт.): от регистра {fmt_reg(start_block)} до {fmt_reg(end_block)}")
    
                if t in ["Float", "2 byte", "4 bytes"]:
                    for i in range(c):
                        start_el = addr + i * length
                        end_el = start_el + length - 1
                        if length == 1:
                            lines.append(f"   Элемент {i + 1}: регистр {fmt_reg(start_el)}")
                        else:
                            lines.append(f"   Элемент {i + 1}: регистры {fmt_reg(start_el)} - {fmt_reg(end_el)}")
                elif t == "8 bit":
                    for i in range(c):
                        reg = addr + i // 2
                        bit_pos = (i % 2) * 8
                        bit_addresses = [reg * 16 + bit_pos + b for b in range(8)]
                        bit_addresses_str = ", ".join(fmt_reg(b) for b in bit_addresses)
                        lines.append(f"   Элемент {i + 1}: регистр {fmt_reg(reg)}, биты {bit_pos}-{bit_pos + 7} → битовые адреса [{bit_addresses_str}]")
    
                addr = end_block + 1
    
            if lines:
                lines.append(f"\nИтоговый конечный адрес регистра: {fmt_reg(addr - 1)}")
            else:
                lines.append("Список блоков пуст")
    
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "\n".join(lines))
    
        def load_exp_file(self):
            filepath = filedialog.askopenfilename(
                title="Выберите файл .EXP",
                filetypes=[("EXP files", "*.exp"), ("Все файлы", "*.*")]
            )
            if not filepath:
                return
    
            blocks_from_file = self.parse_exp_modules(filepath)
            if blocks_from_file:
                self.blocks = []
                for count, block_type in blocks_from_file:
                    self.blocks.append({"type": block_type, "count": count})
                self.refresh_tree()
                messagebox.showinfo("Готово", f"Загружено {len(blocks_from_file)} блоков из файла.")
            else:
                messagebox.showwarning("Внимание", "Не удалось найти подходящие блоки в файле.")
    
        def parse_exp_modules(self, filename):
            results = []
            count = 0
            prev_module = None
    
            module_aliases = {
                'float': 'Float',
                '2 byte': '2 byte',
                '8 bits': '8 bit',
                '4 byte': '4 bytes'
            }
    
            encodings = ['utf-8', 'cp1251', 'latin1']
            for enc in encodings:
                try:
                    with open(filename, 'r', encoding=enc) as f:
                        for line in f:
                            line = line.strip()
                            if line.startswith("_MODULE_NAME:"):
                                start = line.find("'")
                                end = line.rfind("'")
                                if start != -1 and end != -1 and end > start:
                                    raw = line[start + 1:end].strip().lower()
                                    block_type = module_aliases.get(raw)
    
                                    if not block_type:
                                        if prev_module is not None:
                                            results.append((count, prev_module))
                                            prev_module = None
                                            count = 0
                                        continue
    
                                    if block_type == prev_module:
                                        count += 1
                                    else:
                                        if prev_module is not None:
                                            results.append((count, prev_module))
                                        prev_module = block_type
                                        count = 1
                        if prev_module is not None:
                            results.append((count, prev_module))
                    break
                except Exception:
                    continue
            return results
    
    
    if __name__ == "__main__":
        app = ModbusAddressCalculatorOrder()
        app.mainloop()

    3x.png 0x.png
    Последний раз редактировалось atomo2; 15.08.2025 в 06:59.

  2. #11572

    По умолчанию

    У вас все адреса не правильные, и посчитали вы не правильно. Читайте предыдущую страницу.
    Разберитесь сначала с адресами и функциями, проверьте в работе.
    0х - это запись и чтение бит,
    44 - номер бита, попадает в регистр 2 бит 12 ( 2*16+12=44 ),
    4х -чтение и запись регистров, 4х_Bit (Доступ к битам в регистре) адрес 2 бит 12 1 Бит в панели.jpg
    Последний раз редактировалось kondor3000; 15.08.2025 в 08:34.

  3. #11573

    По умолчанию

    ну как так то? почему не правильно посчитал, все остальные адреса работают и совпадают , на предыдущей станице тоже все адреса пересчитал прописал и все заработало
    Проекты не мои и все работает на 3x и 0x адресах (вообще не видел 4x адресов)


    вот берем конфигурацию плк 1.png

    первые 2шт 8bits у нас получается

    8 bit (2 шт.)
    Элемент 1: регистр 0, биты 0-7 → битовые адреса [0, 1, 2, 3, 4, 5, 6, 7]
    Элемент 2: регистр 0, биты 8-15 → битовые адреса [8, 9, 10, 11, 12, 13, 14, 15]

    или

    8 bit (2 шт.)
    Элемент 1: регистр 3x0, биты 0-7 → битовые адреса [3x0, 3x1, 3x2, 3x3, 3x4, 3x5, 3x6, 3x7]
    Элемент 2: регистр 3x0, биты 8-15 → битовые адреса [3x8, 3x9, 3x10, 3x11, 3x12, 3x13, 3x14, 3x15]

    или

    8 bit (2 шт.)
    Элемент 1: регистр 0x00, биты 0-7 → битовые адреса [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
    Элемент 2: регистр 0x00, биты 8-15 → битовые адреса [0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]

    разве нет?
    Последний раз редактировалось atomo2; 15.08.2025 в 09:14.

  4. #11574

    По умолчанию

    1х - только чтение бит,
    0х - запись и чтение бит,
    3х - только чтение регистров, 3х_Bit - только чтение бит в регистре,
    4х- запись и чтение регистров, 4х_Bit - запись и чтение бит в регистре,

  5. #11575

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    1х - только чтение бит,
    0х - запись и чтение бит,
    3х - только чтение регистров, 3х_Bit - только чтение бит в регистре,
    4х- запись и чтение регистров, 4х_Bit - запись и чтение бит в регистре,
    я это понимаю) Но все тут проекты как то работают так , как я написал)
    выше если интересно откройте проект панели HMI 192.6.0.42.rar проект панели и посмотрите все адреса.

  6. #11576

    По умолчанию

    Цитата Сообщение от atomo2 Посмотреть сообщение
    я это понимаю) Но все тут проекты как то работают так , как я написал)
    выше если интересно откройте проект панели HMI 192.6.0.42.rar проект панели и посмотрите все адреса.
    Что значит как то работают?
    0х не соответствует области 3х_Bit , если у вас только чтение, то область должна быть 1х (2х),
    для 0х соответствие 4х_Bit

    Это "как то работает" прокатит только на ПЛК Овен, и только на чтение, записи не будет.
    Последний раз редактировалось kondor3000; 15.08.2025 в 10:19.

  7. #11577

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Что значит как то работают?
    0х не соответствует области 3х_Bit , если у вас только чтение, то область должна быть 1х (2х),
    для 0х соответствие 4х_Bit

    Это "как то работает" прокатит только на ПЛК Овен, и только на чтение, записи не будет.
    вот как раз все на плк Овен и сделано) я и пытаюсь все исправить , потихоньку получается

  8. #11578

    По умолчанию

    Цитата Сообщение от atomo2 Посмотреть сообщение
    вот как раз все на плк Овен и сделано) я и пытаюсь все исправить , потихоньку получается
    Это не значит, что надо делать не правильно, а то так и будете дальше криво делать.

  9. #11579

    По умолчанию

    Здравствуйте у меня невозможно добавить во вкладку ресурсы никакие объекты. ПЛК110-32

  10. #11580

    По умолчанию

    Цитата Сообщение от MakSevos Посмотреть сообщение
    Здравствуйте у меня невозможно добавить во вкладку ресурсы никакие объекты. ПЛК110-32
    И что вы хотите добавить в Ресурсы, если там ничего добавить нельзя?
    Добавлять можно только во вложенные объекты. Например, биб-ки в Менеджер биб-к или переменные в Глобальные переменные.
    Последний раз редактировалось kondor3000; 20.08.2025 в 09:24.

Страница 1158 из 1186 ПерваяПервая ... 158658105811081148115611571158115911601168 ... ПоследняяПоследняя

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •