User Tools

Site Tools


carel

Carel cooling controllers

New models Carel cooling controllers have Modbus RTU, while older models have a proprietary Carel communication protocol. The protocol is quite efficient one, becuase it only sends changes of its parameter, or “no changes” telegram. So the host syncronize its variable once and then gets updates.

Older controllers have the following communication features:

The modules often do not have an integrated RS-485 driver, and the connection must be made to the TTL serial bus port via TTL-RS485 converter. The default transmission format - 19200, 8 data bits, no parity, 2 stop bits.

These modules can be read with the custom protocol. Turn to your local representative for more details.

-example.lua
function readRegister (reg, device, unitId)
 
   if not carel.synced then 
                                            DEBUG("Trying to sync, packet #1...")
       local newId = unitId + ADDR_OFFSET
       carel.pollTemplate[2] = newId
 
       makeSync(carel.syncTemplate, newId)
       local reply = readUntil(ETX, true)
 
       if reply then
           hexPrint(reply)
           if (#reply > 30) then 
               DEBUG("Sync 1 done!")
               -- now 2nd sync 
               makeSync(carel.sync2_Tmpl, newId)
               reply = readUntil(ACK, false)
               if reply then 
                   hexPrint(reply)       ; DEBUG("sync 2 ok!")
                   carel.synced = true 
               end 
           end 
        end 
   end 
 
   if carel.synced then  -- synced 
      local poll_counter, POLL_LIMIT = 0, 40
 
      repeat 
          poll_counter = poll_counter + 1 
          sendBytes(carel.pollTemplate) ; local reply = readUntil(ETX, true)
 
          if not reply then 
              ERROR("could not receive reply from device...")
              carel.synced = false 
              return false 
          end 
 
          if (reply[1] == NULL) then 
                                            DEBUG("Got NULL! - no changes")
              sendBytes{ACK}                                
              break 
          else
                                            DEBUG("Normal sequence, got something!")
              sendBytes{ACK}
 
              local idx = {type = 3, addr_hi = 4, addr_lo = 5, data_start = 6}
              local type_ = string.char(reply[idx.type]) ; DEBUG("type = " .. type_)
              if not (type_ == 'B' or type_ == 'U' or type_ == 'S') then 
                                            ERROR("Unknown type of the device!")
                  return -1
              else 
                  local dev_addr = getHexFromASCII(reply[idx.addr_hi], reply[idx.addr_lo])
                  dev_addr = string.sub(dev_addr, 1, -2)
                  dev_addr = tonumber(dev_addr, 16) ; DEBUG("dev_addr detected = " .. dev_addr)
 
                  local dev_data_len = ((type_ == 'B' and 2) or 4)
 
                  local tmp_t = {}
                  for j = idx.data_start, idx.data_start + dev_data_len - 1 do 
                      table.insert(tmp_t, string.char(reply[j]))
                  end 
                  local dev_data = tonumber(table.concat(tmp_t), 16) 
                  DEBUG('dev type  addr data = ' .. type_ .. ' ' .. sf("%X", dev_addr) .. ' ' .. sf("%X", dev_data))
 
                  carel.data[type_][dev_addr] = dev_data
              end 
        end 
 
      if (poll_counter >= POLL_LIMIT) then 
         DEBUG("Poll counter finish!")          
      end 
      until (poll_counter >= POLL_LIMIT)
 
    local value = carel.data[device.name][reg.internalAddr]
    return value 
 
   end -- synced 
end -- readRegister