This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Curtain Dooya dt82tv
#1
Hello. I need to connect Dooya DT82TV electric curtains to a controller and control them via the RS-485 protocol. There are several problems. First, the curtains understand HEX(photo is attached) rather than the usual 0/1 or true/false, so I probably need to write code for conversion and understanding. Second, I also need a JSON profile (also code) to connect each device via Modbus. To be honest, I don't know how to program or write scripts at all. I would be very grateful if there was ready-made code and instructions on how to do everything.

Attached Files Thumbnail(s)
   
Reply
#2
How do you knw that they are modbus? Do you have any documentation? You cannot haev modbus and custom RS485 script running paraleal.
------------------------------
Ctrl+F5
Reply
#3
You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial')

port = serial.open('/dev/RS485-1', {
  baudrate = 9600,
  parity = 'even',
  duplex = 'half'
})

command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01)
port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).
Reply
#4
(02.02.2026, 13:01)admin Wrote: You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial')

port = serial.open('/dev/RS485-1', {
  baudrate = 9600,
  parity = 'even',
  duplex = 'half'
})

command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01)
port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).

Thanks its working. Now i have another question, is it possible to give it a range with event script?
Reply
#5
What do you mean by range? Do you want to stop it after a time? If yes then you can add os.delay(10) on the ened and then send stop command. Make sure to set event script execution to First instance only.
------------------------------
Ctrl+F5
Reply
#6
Attach an event script to a 4-bit object. A different command is sent depending on the input value (stop, up or down).
Code:
value = event.getvalue()

up = bit.band(value, 8) ~= 0
stop = bit.band(value, 7) == 0

if stop then
  command = string.char(0x55, 0x01, 0x01, 0x03, 0x03, 0x38, 0xC1)
elseif up then
  command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01)
else
  command = string.char(0x55, 0x01, 0x01, 0x03, 0x01, 0xB9, 0x00)
end

require('serial')

port = serial.open('/dev/RS485-1', {
  baudrate = 9600,
  parity = 'even',
  duplex = 'half'
})

port:write(command)
Reply
#7
(04.02.2026, 04:42)Zhiger2003 Wrote:
(02.02.2026, 13:01)admin Wrote: You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial')

port = serial.open('/dev/RS485-1', {
  baudrate = 9600,
  parity = 'even',
  duplex = 'half'
})

command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01)
port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).

Thanks its working. Now i have another question, is it possible to give it a range with event script?

Hi, I made this integration/ see the scripts
This one make string comand to send to rs485 port (with CRC calculation)
Code:
function cmd_str_crc (t)
    if type(t) ~= 'table' then
      log('входная переменная не таблица')
      return
      end
    x, y = CRC16(t)
    --log(x,y)
    table.insert(t,x)
    table.insert(t,y)
    --log(t)
    s=''
    for i = 1 , #t do
      s = s..string.char(t[i])
      end
    return s
    end
 
  function And(num1,num2)
      local tmp1 = num1
      local tmp2 = num2
      local ret = 0
      local count = 0
      repeat
          local s1 = tmp1 % 2
          local s2 = tmp2 % 2
          if s1 == s2 and s1 == 1 then
              ret = ret + 2^count
          end
          tmp1 = math.modf(tmp1/2)
          tmp2 = math.modf(tmp2/2)
          count = count + 1
      until(tmp1 == 0 and tmp2 == 0)
      return ret
  end
   
  function Xor(num1,num2)
      local tmp1 = num1
      local tmp2 = num2
      local ret = 0
      local count = 0
      repeat
          local s1 = tmp1 % 2
          local s2 = tmp2 % 2
          if s1 ~= s2 then
              ret = ret + 2^count
          end
          tmp1 = math.modf(tmp1/2)
          tmp2 = math.modf(tmp2/2)
          count = count + 1
      until(tmp1 == 0 and tmp2 == 0)
      return ret
  end
   
  function bit_rshift(value,n)
      value = math.modf(value / (2^n))
      return value
  end
 
  function CRC16(arr)
      local tmp = 0xffff
      for i=1,#arr do
          tmp = Xor(arr[i],tmp)
          for j=1,8 do
              local tmp1 = And(tmp,0x01)
              if tmp1 == 1 then
                  tmp = bit_rshift(tmp,1)
                  tmp = Xor(tmp,0xa001)
              else
                  tmp = bit_rshift(tmp,1)
              end
          end
      end
      local ret1 = (tmp % 256)
      local ret2 = math.modf( tmp / 256)
      return ret1,ret2
  end
 
  function motor_up(cur_group, cur_adr)
    cmd = {cur_group, cur_adr, 0x03,0x01}
    s = cmd_str_crc (cmd)
    return s
    end
 
 
  function motor_down(cur_group, cur_adr)
    cmd = {cur_group, cur_adr, 0x03,0x02}
    s = cmd_str_crc (cmd)
    return s
    end
 
  function motor_stop(cur_group, cur_adr)
    cmd = {cur_group, cur_adr, 0x03,0x03}
    s = cmd_str_crc (cmd)
    return s
    end
 
  function motor_set_address(cur_group, cur_adr, new_group, new_adr)
    cmd = {cur_group, cur_adr,0x02, 0x00, 0x02, new_group, new_adr}
    s = cmd_str_crc (cmd)
    return s
    end
this one shows how to send 1 command
Code:
require('user.motor')
require('serial')
port = serial.open('/dev/RS485-1', {
  baudrate = 9600,
  databits = 8,
  stopbits = 1,
  parity = 'none',
  duplex = 'half'
})
-- движение
t = { 0x55, 0x03, 0x02, 0x03,0x01}
s = cmd_str_crc (t)
port:write(s)
os.sleep(2)
-- остановка
t = { 0x55, 0x03, 0x02, 0x03,0x03}
s = cmd_str_crc (t)
port:write(s)
--[[
-- запись адреса
t = { 0x55, 0x00, 0x00, 0x02,0x02, 0x01, 0x02}
s = cmd_str_crc (t)
port:write(s)
]]
And this is a deamon for several motors
Code:
-- kotov motors deamon
if not port then
    require('serial')
  port = serial.open('/dev/RS485-1', {
    baudrate = 9600,
    databits = 8,
    stopbits = 1,
    parity = 'none',
    duplex = 'half'
  })
  end
-- стуктура таблицы - id приводов BL - новер комнаты -номер привода = группа, номер
cmds = {
  'BL' = {
    ['27'] ={
      ['1'] = { 0x0C, 0x05 },
      ['2'] = { 0x0C, 0x06 },
      ['3'] = { 0x0C, 0x07 }
    },
    ['29'] ={
      ['1'] = { 0x0D, 0x08 },
      ['2'] = { 0x0E, 0x07 }
    }
  }
}
   
if not lb then
    require('user.motor')
  lb = require('localbus').new(0.5)
  function groupcallback(event)
    pref, cmd = unpack(grp.alias(event.dst):split('-'))
    val = event.getvalue()
    typ, room , num =unpack(pref:split('.'))
    if cmds[typ] then
      all_adr = cmds[typ][room][num]
      if cmd == 'short' then
        direction = 0x03
      elseif cmd == 'stop' then
        if val then
          direction =0x02
        else
          direction = 0x01
        end
      else
        log('некорректное имя группового адреса', grp.alias(event.dst))
      end
      port:write(motor_move(cur_group, cur_adr, direction))
   
    end
 
  --lb:sethandler('groupupdate', groupcallack)
  lb:sethandler('groupwrite', groupcallback)
  --lb:sethandler('groupresponse', groupcallback)
end
lb:step()
--log(lb)

GA names for  motors are next
BL.09.2-long
BL.09.2-stop
Reply


Forum Jump: