Ejemplo n.º 1
0
// Creates new ModbusRTU connection
func NewRtuConnection(device string, baud int, parity byte, data_bit uint8, stop_bit uint8) (*RtuConnection, error) {
	cs := C.CString(device)
	defer C.free(unsafe.Pointer(cs))
	context, errno := C.modbus_new_rtu(cs, C.int(baud), C.char(parity), C.int(data_bit), C.int(stop_bit))
	if context == nil {
		return nil, errors.New(fmt.Sprintf("Failed to create libmodbus context: %s", modbus_strerror(errno)))
	}

	return &RtuConnection{context, INVALID_SLAVE, false}, nil
}
func NewModbusRTUConnection(DeviceName string,
	Speed int, SerialMode string, Hook ioCtlHook) (*ModbusRTUConnection, error) {
	// is allready opened?
	for _, connection := range ModbusRTUConnections {
		if connection.Device() == DeviceName {
			if connection.serialMode == SerialMode {
				return connection, nil
			} else {
				return nil, errors.New(
					fmt.Sprintf("Device '%s' used by connection %d, mode '%s'",
						DeviceName, connection.ID(), connection.serialMode))
			}
		}
	}

	result := &ModbusRTUConnection{deviceName: DeviceName, speed: Speed,
		serialMode: SerialMode, hook: Hook}

	if Hook != nil {
		result.rwCtlChan = make(chan int)

		go func(oneByteTime time.Duration) {
			for v := range result.rwCtlChan {
				if v < 0 {
					break
				}
				result.hook.OnStartTransmitting()
				time.Sleep(oneByteTime * time.Duration(v))
				result.hook.OnEndTransmitting()
			}
		}(time.Duration(math.Ceil(float64(time.Second*(1+8+0+1)) / float64(result.speed))))
	}

	// try open
	match := parser.FindStringSubmatch(result.serialMode)
	if len(match) != (1 + 3) {
		result.ctx = C.modbus_new_rtu(C.CString(result.deviceName), C.int(result.speed),
			C.char('N'), C.int(8), C.int(1))
	} else {
		databits, _ := strconv.ParseInt(match[1+0], 10, 32)
		stopbits, _ := strconv.ParseInt(match[1+2], 10, 32)
		result.ctx = C.modbus_new_rtu(C.CString(result.deviceName), C.int(result.speed),
			C.char(match[1+1][0]),
			C.int(databits),
			C.int(stopbits))
	}
	if result.ctx == nil {
		return nil, errors.New(fmt.Sprintf("Unable to create the libmodbus context\n%s",
			C.GoString(C.modbus_strerror(C.getErrno()))))
	}
	runtime.SetFinalizer(result, finaliserModbusRTUConnection)

	result.id = index
	index++
	if len(ModbusRTUConnections) != 0 &&
		ModbusRTUConnections[len(ModbusRTUConnections)-1] == nil {
		for i := len(ModbusRTUConnections) - 1; i > -1; i-- {
			if ModbusRTUConnections[i] != nil {
				ModbusRTUConnections[i+1] = result
				break
			}
		}
	} else {
		ModbusRTUConnections = append(ModbusRTUConnections, result)
	}

	return result, nil
}