int deviceIOExpanderGetInterface(unsigned char commandHeader, DeviceInterfaceMode mode, bool fillDeviceArgumentList) {
    if (commandHeader == COMMAND_IO_EXPANDER_WRITE_SINGLE_BIT) {
        if (fillDeviceArgumentList) {
            setFunction("Write Single Bit", 5, 0);
            setArgumentUnsignedHex2(0, "IO Expander Index");
            setArgumentSeparator(1);
            setArgumentUnsignedHex2(2, "IO Index");
            setArgumentSeparator(3);
            setArgumentUnsignedChar1(4, "Value (bool)");
        }
        return commandLengthValueForMode(mode, 7, 0);
    }
    if (commandHeader == COMMAND_IO_EXPANDER_WRITE_VALUE) {
        if (fillDeviceArgumentList) {
            setFunction("Write Value", 3, 0);
            setArgumentUnsignedHex2(0, "IO Expander Index");
            setArgumentSeparator(1);
            setArgumentUnsignedHex2(2, "Value");
        }
        return commandLengthValueForMode(mode, 5, 0);
    }
    else if (commandHeader == COMMAND_IO_EXPANDER_READ_SINGLE_BIT) {
        if (fillDeviceArgumentList) {
            setFunction("Read Single Bit", 3, 1);
            setArgumentUnsignedHex2(0, "IO Expander Index");
            setArgumentSeparator(1);
            setArgumentUnsignedHex2(2, "IO Index");

            setResultUnsignedChar1(0, "Value (bool)");
        }
        return commandLengthValueForMode(mode, 5, 1);
    }
    else if (commandHeader == COMMAND_IO_EXPANDER_READ_VALUE) {
        if (fillDeviceArgumentList) {
            setFunction("Read Value", 1, 1);
            setArgumentUnsignedHex2(0, "IO Expander Index");
            setResultUnsignedHex2(0, "Value");
        }
        return commandLengthValueForMode(mode, 2, 2);
    }
    else if (commandHeader == COMMAND_IO_EXPANDER_DEBUG) {
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("Debug as Table");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }
    return DEVICE_HEADER_NOT_HANDLED;
}
int deviceMotionGetInterface(char commandHeader, DeviceInterfaceMode mode, bool fillDeviceArgumentList) {
    if (commandHeader == COMMAND_MOTION_LOAD_DEFAULT_PARAMETERS) {
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("loadDefaultParameters");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }
    // goto
    else if (commandHeader == COMMAND_MOTION_GOTO_IN_PULSE) {
        if (fillDeviceArgumentList) {
            setFunction("gotoPulse", 4, 0);
            setArgument(0, DEVICE_ARG_SIGNED_HEX_6, "left");
            setArgument(1, DEVICE_ARG_SIGNED_HEX_6, "right");
            setArgumentUnsignedHex2(2, "a");
            setArgumentUnsignedHex2(3, "s");
        }
        return commandLengthValueForMode(mode, 16, 0);
    }// forward MM
    else if (commandHeader == COMMAND_MOTION_FORWARD_IN_MM) {
        if (fillDeviceArgumentList) {
            setFunction("forwardMM", 1, 0);
            setArgumentUnsignedHex4(0, "distMM");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }// backward MM
    else if (commandHeader == COMMAND_MOTION_BACKWARD_IN_MM) {
        if (fillDeviceArgumentList) {
            setFunction("backwardMM", 1, 0);
            setArgumentUnsignedHex4(0, "distMM");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }// turn left in degree
    else if (commandHeader == COMMAND_MOTION_LEFT_IN_DECI_DEGREE) {
        if (fillDeviceArgumentList) {
            setFunction("rotLeftDecDeg", 1, 0);
            setArgumentUnsignedHex4(0, "leftAngleDecDeg");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }// turn right in degree
    else if (commandHeader == COMMAND_MOTION_RIGHT_IN_DECI_DEGREE) {
        if (fillDeviceArgumentList) {
            setFunction("rotRightDecDeg", 1, 0);
            setArgumentUnsignedHex4(0, "rightAngleDecDeg");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }// ONLY ONE WHEEL
        // turn left (only right in degree
    else if (commandHeader == COMMAND_MOTION_LEFT_ONE_WHEEL_IN_DECI_DEGREE) {
        if (fillDeviceArgumentList) {
            setFunction("rotLeft1WheelDecDeg", 1, 0);
            setArgumentUnsignedHex4(0, "leftAngleDecDeg");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }// turn right (only right wheel) in degree
    else if (commandHeader == COMMAND_MOTION_RIGHT_ONE_WHEEL_IN_DECI_DEGREE) {
        if (fillDeviceArgumentList) {
            setFunction("rotRight1WheelDecDeg", 1, 0);
            setArgumentUnsignedHex4(0, "rightAngleDecDeg");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }
    // motion : Cancel
    else if (commandHeader == COMMAND_MOTION_CANCEL) {
        // Same INPUT/OUTPUT
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("cancelMot");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }// motion : Obstacle
    else if (commandHeader == COMMAND_MOTION_OBSTACLE) {
        // Same INPUT/OUTPUT
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("motionObstacle");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }// Calibration
    else if (commandHeader == COMMAND_SQUARE_CALIBRATION) {
        if (fillDeviceArgumentList) {
            setFunction("squareCalib", 3, 0);
            setArgumentUnsignedHex2(0, "left/right");
            setArgumentSeparator(1);
            setArgumentUnsignedHex4(2, "length");
        }
        return commandLengthValueForMode(mode, 7, 0);
    }// Parameters
    else if (commandHeader == COMMAND_GET_MOTION_PARAMETERS) {
        if (fillDeviceArgumentList) {
            setFunction("getMotionParam", 1, 2);
            setArgumentUnsignedHex2(0, "motionType");
            setResultUnsignedHex2(0, "a");
            setResultUnsignedHex2(1, "s");
        }
        return commandLengthValueForMode(mode, 2, 4);
    } else if (commandHeader == COMMAND_SET_MOTION_PARAMETERS) {
        if (fillDeviceArgumentList) {
            setFunction("setMotionParam", 3, 0);
            setArgumentUnsignedHex2(0, "motionType");
            setArgumentUnsignedHex2(1, "a");
            setArgumentUnsignedHex2(2, "s");
        }
        return commandLengthValueForMode(mode, 6, 0);
    }
	// MODE REPLACE / ADD
	else if (commandHeader == COMMAND_MOTION_MODE_ADD) {
		if(fillDeviceArgumentList) {
			setFunctionNoArgumentAndNoResult("motionModeAdd");
		}
		return commandLengthValueForMode(mode, 0, 0);
	}
	else if (commandHeader == COMMAND_MOTION_MODE_REPLACE) {
		if(fillDeviceArgumentList) {
			setFunctionNoArgumentAndNoResult("motionModeReplace");
		}
		return commandLengthValueForMode(mode, 0, 0);
	}
	else if (commandHeader == COMMAND_MOTION_MODE_GET) {
		if (fillDeviceArgumentList) {
			setFunction("motionModeGet", 0, 1);
			setResultUnsignedChar1(0, "value");
		}
		return commandLengthValueForMode(mode, 0, 1);
	}
	// NOTIFICATION
    if (DEVICE_MODE_NOTIFY == mode) {
        if (commandHeader == NOTIFY_MOTION_STATUS_REACHED) {
            if (fillDeviceArgumentList) {
                fillNotifyResults("notifyReached");
            }
            return 14;
        }
        else if (commandHeader == NOTIFY_MOTION_STATUS_FAILED) {
            if (fillDeviceArgumentList) {
                fillNotifyResults("notifyFailed");
            }
            return 14;
        }
        else if (commandHeader == NOTIFY_MOTION_STATUS_OBSTACLE) {
            if (fillDeviceArgumentList) {
                fillNotifyResults("notifyObstacle");
            }
            return 14;
        }
        else if (commandHeader == NOTIFY_MOTION_STATUS_MOVING) {
            if (fillDeviceArgumentList) {
                fillNotifyResults("notifyMoving");
            }
            return 14;
        }
    }
    return DEVICE_HEADER_NOT_HANDLED;
}
int trajectoryGetInterface(unsigned char commandHeader, DeviceInterfaceMode mode, bool fillDeviceArgumentList) {
    if (commandHeader == COMMAND_TRAJECTORY_GET_ABSOLUTE_POSITION) {
        if (fillDeviceArgumentList) {
            setFunction(GET_ABS_POS_STRING, 0, 5);
            setResultFloatHex4(0, X_MM);
            setResultSeparator(1);
            setResultFloatHex4(2, Y_MM);
            setResultSeparator(3);
            setResultUnsignedHex4(4, ANGLE_1_10_DEG);
        }
        return commandLengthValueForMode(mode, 0, 14);
    } else if (commandHeader == COMMAND_TRAJECTORY_DEBUG_GET_ABSOLUTE_POSITION) {
        // Same return in case of input / output
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult(GET_DEBUG_ABS_POS_STRING);
        }
        return commandLengthValueForMode(mode, 0, 0);
	}
	else if (commandHeader == COMMAND_TRAJECTORY_DEBUG_CODERS) {
		// Same return in case of input / output
		if (fillDeviceArgumentList) {
			setFunctionNoArgumentAndNoResult("Debug Coders History");
		}
		return commandLengthValueForMode(mode, 0, 0);
	} else if (commandHeader == COMMAND_TRAJECTORY_SET_ABSOLUTE_POSITION) {
        if (fillDeviceArgumentList) {
            setFunction(SET_ABS_POS_STRING, 5, 0);
            setArgumentFloatHex6(0, X_MM);
            setArgumentSeparator(1);
            setArgumentFloatHex6(2, Y_MM);
            setArgumentSeparator(3);
            setArgumentUnsignedHex4(4, ANGLE_1_10_DEG);
        }
        return commandLengthValueForMode(mode, 18, 0);
	} else if (commandHeader == COMMAND_TRAJECTORY_ADJUST_X) {
        if (fillDeviceArgumentList) {
            setFunction("Adjust X", 1, 1);
            setArgumentFloatHex6(0, X_MM);
            setResultUnsignedChar1(0, "Done or not");
        }
        return commandLengthValueForMode(mode, 6, 1);
	} else if (commandHeader == COMMAND_TRAJECTORY_ADJUST_Y) {
        if (fillDeviceArgumentList) {
            setFunction("Adjust Y", 1, 1);
            setArgumentFloatHex6(0, X_MM);
            setResultUnsignedChar1(0, "Done or not");
        }
        return commandLengthValueForMode(mode, 6, 1);
    }
    // NOTIFY PARAMETERS
    else if (commandHeader == COMMAND_TRAJECTORY_NOTIFY_OFF) {
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("Notify Off");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }
    else if (commandHeader == COMMAND_TRAJECTORY_NOTIFY_ON) {
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("Notify On");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }
    else if (commandHeader == COMMAND_TRAJECTORY_NOTIFY_SET_PARAMETERS) {
        if (fillDeviceArgumentList) {
            setFunction("Notify Set Param", 3, 0);  
            setArgumentFloatHex4(0, "Dist (mm)");
            setArgumentSeparator(1);
            setArgumentFloatHex4(2, "Angle (deciDegree)");
        }
        return commandLengthValueForMode(mode, 9, 0);
    }
    // NOTIFICATION
    if (DEVICE_MODE_NOTIFY == mode) {
        if (commandHeader == NOTIFY_TRAJECTORY_CHANGED) {
            if (fillDeviceArgumentList) {
                setNotification("Trajectory Changed", 7);
                setArgumentUnsignedHex4(0, "x(mm)");
                setArgumentSeparator(1);
                setArgumentUnsignedHex4(2, "y(mm)");
                setArgumentSeparator(3);
                setArgumentUnsignedHex4(4, "ang(1/10)deg");
                setArgumentSeparator(5);
                setArgumentUnsignedChar1(6, "Trajectory Type");
            }
            return 16;
        }
    }
    return DEVICE_HEADER_NOT_HANDLED;
}
int deviceTimerGetInterface(unsigned char commandHeader, DeviceInterfaceMode mode, bool fillDeviceArgumentList) {
    if (commandHeader == COMMAND_TIMER_LIST) {
        if (fillDeviceArgumentList) {
            setFunctionNoArgumentAndNoResult("show Timer List");
        }
        return commandLengthValueForMode(mode, 0, 0);
    }
    else if (commandHeader == COMMAND_TIMER_COUNT) {
        if (fillDeviceArgumentList) {
            setFunction("timer Count", 0, 1);
            setResultUnsignedHex2(0, "count");
        }
        return commandLengthValueForMode(mode, 0, 2);
    }
    else if (commandHeader == COMMAND_TIMER_READ) {
        if (fillDeviceArgumentList) {
            setFunction("timer Read", 1, 13);
            setArgumentUnsignedHex2(0, "timerIndex");
            setResultUnsignedHex2(0, "Index");
            setResultSeparator(1);
            setResultUnsignedHex2(2, "Code");
            setResultSeparator(3);
            setResultUnsignedHex4(4, "Diviser");
            setResultSeparator(5);
            setResultUnsignedHex4(6, "InternalCounter");
            setResultSeparator(7);
            setResultUnsignedHex6(8, "time");
            setResultSeparator(9);
            setResultUnsignedHex6(10, "markTime");
            setResultSeparator(11);
            setResultUnsignedChar1(12, "enabled");
        }
        return commandLengthValueForMode(mode, 2, 31);
    }
    else if (commandHeader == COMMAND_TIMER_ENABLE_DISABLE) {
        if (fillDeviceArgumentList) {
            setFunction("timer Enable", 3, 0);
            setArgumentUnsignedHex2(0, "timerIndex");
            setArgumentSeparator(1);
            setArgumentUnsignedChar1(2, "enable/disable");
        }
        return commandLengthValueForMode(mode, 4, 0);
    }
    // Mark
    else if (commandHeader == COMMAND_TIMER_TIME_SINCE_LAST_MARK) {
        if (fillDeviceArgumentList) {
            setFunction("time Since Last Mark", 1, 1);
            setArgumentUnsignedHex2(0, "timerIndex");
            setResultUnsignedHex6(0, "mark");
        }
        return commandLengthValueForMode(mode, 2, 6);
    }
    else if (commandHeader == COMMAND_TIMER_MARK) {
        if (fillDeviceArgumentList) {
            setFunction("mark Timer !", 1, 1);
            setArgumentUnsignedHex2(0, "timerIndex");
            setResultUnsignedHex6(0, "markTime");
        }
        return commandLengthValueForMode(mode, 2, 6);
    }
    else if (commandHeader == COMMAND_TIMER_TIMEOUT) {
        if (fillDeviceArgumentList) {
            setFunction("timeout check", 3, 3);
            setArgumentUnsignedHex2(0, "timerIndex");
            setArgumentSeparator(1);
            setArgumentUnsignedHex6(2, "time to check");
            setResultUnsignedHex2(0, "timerIndex");
            setResultSeparator(1);
            setResultUnsignedChar1(2, "timeout or not");
        }
        return commandLengthValueForMode(mode, 9, 4);
    }
    
    // Demo
    else if (commandHeader == COMMAND_TIMER_DEMO) {
        if (fillDeviceArgumentList) {
            setFunction("Enable/Disable Timer Demo", 1, 0);
            setArgumentUnsignedChar1(0, "enable/disable");
        }
        return commandLengthValueForMode(mode, 1, 0);
    }
    // wait
    else if (commandHeader == COMMAND_TIMER_DELAY_WAIT) {
        if (fillDeviceArgumentList) {
            setFunction("Timer Delay Wait", 1, 0);
            setArgumentUnsignedHex4(0, "milli Seconds");                
        }
        return commandLengthValueForMode(mode, 4, 0);
    }
    return DEVICE_HEADER_NOT_HANDLED;
}