Mesa 7i95t with pwm firmware

More
18 Nov 2025 00:47 #338594 by Ferra
Mesa 7i95t with pwm firmware was created by Ferra
Hi everyone,
this is my first time using LinuxCNC and a Mesa board. I received my 7i95T a few days ago and have been running several tests since then.
I installed LinuxCNC 2.9.4 on an old desktop PC and everything runs smoothly. After that, I updated the system and installed the Mesa Configuration Tool, since I read that the 7i95T cannot be configured with the standard PNCconf wizard.I successfully connected to the board using the default IP address 192.168.1.121, and the PC communicates with it correctly.
Because I need a PWM output for my 0–10 V analog converter (my VFD does not support RS-485 unfortunately), I downloaded the appropriate firmware, flashed it to the board, and the update went fine.
After completing the basic configuration, I switched the GUI to qtDragon_hd for a better interface. LinuxCNC loads without errors, and I was able to test one axis (stepper + proximity sensor) without issues.Where I’m stuck: PWM generationReading the HMIDs, I can see that the last stepgen has been replaced by a PWM generator, but I’m not understanding how to properly use this PWM output.Here’s what I tried:
  • I connected the PWM signal to pin 9 on the 7i95T header.
  • I left the DIR pin disconnected for now because I only need the spindle to run clockwise.
  • I connected my 0–10 V PWM-to-analog converter, but no voltage output appears.
  • I also tried checking the signal using an oscilloscope, but I get no PWM activity at all.
So at this point I’m not sure whether:
  1. I misconfigured the PWM generator in LinuxCNC/HAL,
  2. I am misunderstanding how the PWM output on the 7i95T is supposed to work.
Additionally, I need to set the PWM frequency to 2 kHz (my converter requires ≤2 kHz), but I don’t know where to configure that correctly.

Also, I would also like to use my MPG wheel.
My idea is:
  • connect the MPG encoder to the left-side encoder input (ENC0),
  • connect the MPG pushbuttons and the selector to the input pins on the right side, according to the Mesa Config Tool assignments.
Can someone confirm whether this wiring plan is correct?
Thanks a lot to everyone in advance! :)
Attachments:

Please Log in or Create an account to join the conversation.

More
18 Nov 2025 01:12 #338595 by PCW
Replied by PCW on topic Mesa 7i95t with pwm firmware
Can you post your current hal/ini files?

Please Log in or Create an account to join the conversation.

More
18 Nov 2025 08:28 #338606 by Ferra
Replied by Ferra on topic Mesa 7i95t with pwm firmware
Hi, thanks for helping, here are the files!

Hal file
# This file was created with the Mesa Configuration Tool on nov 15 2025 15:24:04
# If you make changes to this file DO NOT run the configuration tool again!
# This file will be replaced with a new file if you do!

# kinematics
loadrt [KINS](KINEMATICS)

# motion controller
loadrt [EMCMOT](EMCMOT) servo_period_nsec=[EMCMOT](SERVO_PERIOD) num_joints=[KINS](JOINTS)

# hostmot2 driver
loadrt hostmot2
loadrt [HM2](DRIVER) board_ip=[HM2](ADDRESS) config="num_encoders=6 num_pwmgens=1 num_stepgens=6 sserial_port_0=00000000"

setp hm2_[MESA](BOARD).0.watchdog.timeout_ns 10000000

loadrt pid names=pid.x,pid.y,pid.z

# PID Information for Stepper Boards
# Mesa hardware step generators at every servo thread invocation, the step
# generator hardware is given a new velocity. Without feedback from the PID
# controller the hardware position would slowly drift because of clock speed and
# timing differences between LinuxCNC and the step generator hardware.
# The PID controller gets feedback from the actual (fractional) step position and
# corrects for these small differences.

# THREADS
addf hm2_[MESA](BOARD).0.read servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf pid.x.do-pid-calcs servo-thread
addf pid.y.do-pid-calcs servo-thread
addf pid.z.do-pid-calcs servo-thread
addf hm2_[MESA](BOARD).0.write servo-thread

# DPLL TIMER
setp hm2_[MESA](BOARD).0.dpll.01.timer-us -200
setp hm2_[MESA](BOARD).0.stepgen.timer-number 1

# amp enable
net motion-enable <= motion.motion-enabled

# Board: 7i95

# Axis: X Joint: 0 Output: 0
# PID Setup
setp pid.x.Pgain [JOINT_0](P)
setp pid.x.Igain [JOINT_0](I)
setp pid.x.Dgain [JOINT_0](D)
setp pid.x.bias [JOINT_0](BIAS)
setp pid.x.FF0 [JOINT_0](FF0)
setp pid.x.FF1 [JOINT_0](FF1)
setp pid.x.FF2 [JOINT_0](FF2)
setp pid.x.deadband [JOINT_0](DEADBAND)
setp pid.x.maxoutput [JOINT_0](MAX_OUTPUT)
setp pid.x.error-previous-target True
# limit stepgen velocity corrections caused by position feedback jitter
setp pid.x.maxerror [JOINT_0](MAX_ERROR)

# joint-0 enable chain
net joint-0-index-enable <=> pid.x.index-enable
net joint-0-index-enable <=> joint.0.index-enable

net joint-0-enable <= joint.0.amp-enable-out
net joint-0-enable => pid.x.enable

net joint-0-enable => hm2_[MESA](BOARD).0.stepgen.00.enable

# Joint 0 Step Generator Settings
setp hm2_[MESA](BOARD).0.stepgen.00.dirsetup [JOINT_0](DIRSETUP)
setp hm2_[MESA](BOARD).0.stepgen.00.dirhold [JOINT_0](DIRHOLD)
setp hm2_[MESA](BOARD).0.stepgen.00.steplen [JOINT_0](STEPLEN)
setp hm2_[MESA](BOARD).0.stepgen.00.stepspace [JOINT_0](STEPSPACE)
setp hm2_[MESA](BOARD).0.stepgen.00.position-scale [JOINT_0](SCALE)
setp hm2_[MESA](BOARD).0.stepgen.00.maxvel [JOINT_0](STEPGEN_MAX_VEL)
setp hm2_[MESA](BOARD).0.stepgen.00.maxaccel [JOINT_0](STEPGEN_MAX_ACC)
setp hm2_[MESA](BOARD).0.stepgen.00.step_type 0
setp hm2_[MESA](BOARD).0.stepgen.00.control-type 1


# position command and feedback
net joint-0-pos-cmd <= joint.0.motor-pos-cmd
net joint-0-pos-cmd => pid.x.command

net joint-0-pos-fb <= hm2_[MESA](BOARD).0.stepgen.00.position-fb
net joint-0-pos-fb => joint.0.motor-pos-fb
net joint-0-pos-fb => pid.x.feedback

# PID Output
net joint.0.output <= pid.x.output
net joint.0.output => hm2_[MESA](BOARD).0.stepgen.00.velocity-cmd

# Axis: Y Joint: 1 Output: 1
# PID Setup
setp pid.y.Pgain [JOINT_1](P)
setp pid.y.Igain [JOINT_1](I)
setp pid.y.Dgain [JOINT_1](D)
setp pid.y.bias [JOINT_1](BIAS)
setp pid.y.FF0 [JOINT_1](FF0)
setp pid.y.FF1 [JOINT_1](FF1)
setp pid.y.FF2 [JOINT_1](FF2)
setp pid.y.deadband [JOINT_1](DEADBAND)
setp pid.y.maxoutput [JOINT_1](MAX_OUTPUT)
setp pid.y.error-previous-target True
# limit stepgen velocity corrections caused by position feedback jitter
setp pid.y.maxerror [JOINT_1](MAX_ERROR)

# joint-1 enable chain
net joint-1-index-enable <=> pid.y.index-enable
net joint-1-index-enable <=> joint.1.index-enable

net joint-1-enable <= joint.1.amp-enable-out
net joint-1-enable => pid.y.enable

net joint-1-enable => hm2_[MESA](BOARD).0.stepgen.01.enable

# Joint 1 Step Generator Settings
setp hm2_[MESA](BOARD).0.stepgen.01.dirsetup [JOINT_1](DIRSETUP)
setp hm2_[MESA](BOARD).0.stepgen.01.dirhold [JOINT_1](DIRHOLD)
setp hm2_[MESA](BOARD).0.stepgen.01.steplen [JOINT_1](STEPLEN)
setp hm2_[MESA](BOARD).0.stepgen.01.stepspace [JOINT_1](STEPSPACE)
setp hm2_[MESA](BOARD).0.stepgen.01.position-scale [JOINT_1](SCALE)
setp hm2_[MESA](BOARD).0.stepgen.01.maxvel [JOINT_1](STEPGEN_MAX_VEL)
setp hm2_[MESA](BOARD).0.stepgen.01.maxaccel [JOINT_1](STEPGEN_MAX_ACC)
setp hm2_[MESA](BOARD).0.stepgen.01.step_type 0
setp hm2_[MESA](BOARD).0.stepgen.01.control-type 1


# position command and feedback
net joint-1-pos-cmd <= joint.1.motor-pos-cmd
net joint-1-pos-cmd => pid.y.command

net joint-1-pos-fb <= hm2_[MESA](BOARD).0.stepgen.01.position-fb
net joint-1-pos-fb => joint.1.motor-pos-fb
net joint-1-pos-fb => pid.y.feedback

# PID Output
net joint.1.output <= pid.y.output
net joint.1.output => hm2_[MESA](BOARD).0.stepgen.01.velocity-cmd

# Axis: Z Joint: 2 Output: 2
# PID Setup
setp pid.z.Pgain [JOINT_2](P)
setp pid.z.Igain [JOINT_2](I)
setp pid.z.Dgain [JOINT_2](D)
setp pid.z.bias [JOINT_2](BIAS)
setp pid.z.FF0 [JOINT_2](FF0)
setp pid.z.FF1 [JOINT_2](FF1)
setp pid.z.FF2 [JOINT_2](FF2)
setp pid.z.deadband [JOINT_2](DEADBAND)
setp pid.z.maxoutput [JOINT_2](MAX_OUTPUT)
setp pid.z.error-previous-target True
# limit stepgen velocity corrections caused by position feedback jitter
setp pid.z.maxerror [JOINT_2](MAX_ERROR)

# joint-2 enable chain
net joint-2-index-enable <=> pid.z.index-enable
net joint-2-index-enable <=> joint.2.index-enable

net joint-2-enable <= joint.2.amp-enable-out
net joint-2-enable => pid.z.enable

net joint-2-enable => hm2_[MESA](BOARD).0.stepgen.02.enable

# Joint 2 Step Generator Settings
setp hm2_[MESA](BOARD).0.stepgen.02.dirsetup [JOINT_2](DIRSETUP)
setp hm2_[MESA](BOARD).0.stepgen.02.dirhold [JOINT_2](DIRHOLD)
setp hm2_[MESA](BOARD).0.stepgen.02.steplen [JOINT_2](STEPLEN)
setp hm2_[MESA](BOARD).0.stepgen.02.stepspace [JOINT_2](STEPSPACE)
setp hm2_[MESA](BOARD).0.stepgen.02.position-scale [JOINT_2](SCALE)
setp hm2_[MESA](BOARD).0.stepgen.02.maxvel [JOINT_2](STEPGEN_MAX_VEL)
setp hm2_[MESA](BOARD).0.stepgen.02.maxaccel [JOINT_2](STEPGEN_MAX_ACC)
setp hm2_[MESA](BOARD).0.stepgen.02.step_type 0
setp hm2_[MESA](BOARD).0.stepgen.02.control-type 1


# position command and feedback
net joint-2-pos-cmd <= joint.2.motor-pos-cmd
net joint-2-pos-cmd => pid.z.command

net joint-2-pos-fb <= hm2_[MESA](BOARD).0.stepgen.02.position-fb
net joint-2-pos-fb => joint.2.motor-pos-fb
net joint-2-pos-fb => pid.z.feedback

# PID Output
net joint.2.output <= pid.z.output
net joint.2.output => hm2_[MESA](BOARD).0.stepgen.02.velocity-cmd

# Manual Tool Change Dialog
loadusr -W hal_manualtoolchange
net tool-number hal_manualtoolchange.number <= iocontrol.0.tool-prep-number
net tool-change-request hal_manualtoolchange.change <= iocontrol.0.tool-change
net tool-change-confirmed iocontrol.0.tool-changed => hal_manualtoolchange.changed

# tool prep loopback
net tool-prep-loop iocontrol.0.tool-prepare => iocontrol.0.tool-prepared

#######################################################
# SPINDLE PWM - MESA 7i95T pwmgen.00
#######################################################

# Imposto la frequenza PWM hardware (valore tipico 10 kHz)
# Usa il parametro dall'INI [SPINDLE_0](PWM_FREQUENCY)
setp hm2_[MESA](BOARD).0.pwmgen.pwm_frequency [SPINDLE_0](PWM_FREQUENCY)

# pwmgen.00: PWM su Out0, direzione su Out1 (che puoi anche non usare)
setp hm2_[MESA](BOARD).0.pwmgen.00.output-type 1

# Scala: valore in ingresso = RPM, duty = RPM / SCALE
# Esempio: SCALE = 24000 => 24000 rpm = 100% duty
setp hm2_[MESA](BOARD).0.pwmgen.00.scale [SPINDLE_0](SCALE)

# --- Collegamento con il motion ---

# Abilitazione PWM: attivo quando lo spindle è "on" (M3/M4)
net spindle-enable motion.spindle-on => hm2_[MESA](BOARD).0.pwmgen.00.enable

# Comando velocità in RPM dal planner
net spindle-speed-cmd-rpm motion.spindle-speed-out => hm2_[MESA](BOARD).0.pwmgen.00.value


ini file
# This file was updated with the Mesa Configuration Tool on nov 15 2025 15:24:04
# Changes to most things are ok and will be read by the Configuration Tool

[MESA]
VERSION = 2.1.8
BOARD = 7i95
BOARD_NAME = 7i95t
FIRMWARE = 7i95t_1pwmd.bin
CARD_0 = None
CARD_1 = None

[EMC]
VERSION = 1.1
MACHINE = Mesa_7i95t
DEBUG = 0x00000000

[HM2]
DRIVER = hm2_eth
ADDRESS = 192.168.1.121

[DISPLAY]
DISPLAY = qtvcp qtdragon_hd
EDITOR = geany
PROGRAM_PREFIX = /home/linuxcnc/linuxcnc/nc_files
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = COMMANDED
MAX_FEED_OVERRIDE = 1.5
MIN_LINEAR_VELOCITY = 0.0
DEFAULT_LINEAR_VELOCITY = 1.5
MAX_LINEAR_VELOCITY = 80.0
INCREMENTS = 10mm , 5mm , 1mm , 0.5mm , 0.1mm , 0.05mm , 0.01mm
CYCLE_TIME = 0.1
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 0
OPEN_FILE = ""

[KINS]
KINEMATICS = trivkins coordinates=XYZ
JOINTS = 3

[EMCIO]
EMCIO = iov2
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl

[RS274NGC]
PARAMETER_FILE = parameters.var
SUBROUTINE_PATH = /home/linuxcnc/linuxcnc/subroutines

[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
SERVO_PERIOD = 2000000

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[TRAJ]
COORDINATES = XYZ
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 80.0
NO_FORCE_HOMING = 1
SPINDLES = 1

[HAL]
HALFILE = main.hal
HALFILE = io.hal

[AXIS_X]
MIN_LIMIT = 0
MAX_LIMIT = 295
MAX_VELOCITY = 80
MAX_ACCELERATION = 500

[JOINT_0]
CARD = 0
TAB = 0
AXIS = X
MIN_LIMIT = 0
MAX_LIMIT = 295
MAX_VELOCITY = 80
MAX_ACCELERATION = 500
TYPE = LINEAR
SCALE = 200
DRIVE = Custom
STEP_INVERT = False
DIR_INVERT = False
STEPGEN_MAX_VEL = 96.00
STEPGEN_MAX_ACC = 600.00
DIRSETUP = 3000
DIRHOLD = 3000
STEPLEN = 2000
STEPSPACE = 2000
ENCODER_SCALE =
FERROR = 0.01
MIN_FERROR = 0.005
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = 0
HOME_SEARCH_VEL = 30
HOME_LATCH_VEL = 3
HOME_FINAL_VEL = 6
HOME_SEQUENCE = 2

[AXIS_Y]
MIN_LIMIT = 0
MAX_LIMIT = 195
MAX_VELOCITY = 80
MAX_ACCELERATION = 500

[JOINT_1]
CARD = 0
TAB = 1
AXIS = Y
MIN_LIMIT = 0
MAX_LIMIT = 195
MAX_VELOCITY = 80
MAX_ACCELERATION = 500
TYPE = LINEAR
SCALE = 200
DRIVE = Custom
STEP_INVERT = False
DIR_INVERT = False
STEPGEN_MAX_VEL = 96.00
STEPGEN_MAX_ACC = 600.00
DIRSETUP = 3000
DIRHOLD = 3000
STEPLEN = 2000
STEPSPACE = 2000
ENCODER_SCALE =
FERROR = 0.01
MIN_FERROR = 0.005
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = 195
HOME_SEARCH_VEL = 30
HOME_LATCH_VEL = 3
HOME_FINAL_VEL = 6
HOME_SEQUENCE = 1

[AXIS_Z]
MIN_LIMIT = -135
MAX_LIMIT = 0
MAX_VELOCITY = 40
MAX_ACCELERATION = 500

[JOINT_2]
CARD = 0
TAB = 2
AXIS = Z
MIN_LIMIT = -135
MAX_LIMIT = 0
MAX_VELOCITY = 40
MAX_ACCELERATION = 500
TYPE = LINEAR
SCALE = 200
DRIVE = Custom
STEP_INVERT = False
DIR_INVERT = False
STEPGEN_MAX_VEL = 48.00
STEPGEN_MAX_ACC = 600.00
DIRSETUP = 3000
DIRHOLD = 3000
STEPLEN = 2000
STEPSPACE = 2000
ENCODER_SCALE =
FERROR = 0.01
MIN_FERROR = 0.005
DEADBAND = 0
P = 1000
I = 0
D = 0
FF0 = 0
FF1 = 1
FF2 = 0
BIAS = 0
MAX_OUTPUT = 0
MAX_ERROR = 0.0127
HOME = 0
HOME_OFFSET = 0
HOME_SEARCH_VEL = 30
HOME_LATCH_VEL = 3
HOME_FINAL_VEL = 6
HOME_SEQUENCE = 0

[INPUTS]
# DO NOT change the inputs they are used by the configuration tool
INPUT_0_0 = Joint 0 Home
INPUT_INVERT_0_0 = False
INPUT_SLOW_0_0 = False
INPUT_0_1 = Joint 1 Home
INPUT_INVERT_0_1 = False
INPUT_SLOW_0_1 = False
INPUT_0_2 = Joint 2 Home
INPUT_INVERT_0_2 = False
INPUT_SLOW_0_2 = False
INPUT_0_3 = E Stop 0
INPUT_INVERT_0_3 = False
INPUT_SLOW_0_3 = False
INPUT_0_4 = Probe Input
INPUT_INVERT_0_4 = False
INPUT_SLOW_0_4 = False

[OUTPUTS]
# DO NOT change the outputs they are used by the configuration tool
OUTPUT_0_1 = Spindle CW
OUTPUT_INVERT_0_1 = False
OUTPUT_0_2 = Coolant Flood
OUTPUT_INVERT_0_2 = False
OUTPUT_0_3 = E-Stop Out
OUTPUT_INVERT_0_3 = False

[OPTIONS]
# DO NOT change the options they are used by the configuration tool
LOAD_CONFIG = False
INTRO_GRAPHIC = emc2.gif
INTRO_GRAPHIC_TIME = 0
MANUAL_TOOL_CHANGE = True
CUSTOM_HAL = False
POST_GUI_HAL = False
SHUTDOWN_HAL = False
HALUI = False
PYVCP = False
GLADEVCP = False
LADDER = False
BACKUP = True


[SPINDLE_0]
# RPM corrispondenti al 100% di duty-cycle
SCALE = 24000

# Massimo RPM ammesso per G-code / GUI
MAX_RPM = 24000
MIN_RPM = 1000

# Frequenza del PWM hardware (Hz)
PWM_FREQUENCY = 2000

Please Log in or Create an account to join the conversation.

More
18 Nov 2025 14:39 #338617 by PCW
Replied by PCW on topic Mesa 7i95t with pwm firmware
That looks like it should work, although it's a bit odd because it looks like a
fairly old version of LinuxCNC (before the changes to support multiple spindles)

I would next check the PWM value and enable pins in halshow when you expect
the spindle to be running and say set for 1/2 full speed:

hm2_7i95.0.pwmgen.00.enable
hm2_7i95.0.pwmgen.00.value

Please Log in or Create an account to join the conversation.

More
18 Nov 2025 18:32 #338645 by Ferra
Replied by Ferra on topic Mesa 7i95t with pwm firmware
How can I perform this kind of verification?
I was able to add the two variables you mentioned into HALShow, but when I start the spindle or run M3 S12000, nothing changes in those values. What am I missing?

Please Log in or Create an account to join the conversation.

More
18 Nov 2025 18:39 #338646 by PCW
Replied by PCW on topic Mesa 7i95t with pwm firmware
# Abilitazione PWM: attivo quando lo spindle è "on" (M3/M4)
net spindle-enable motion.spindle-on => hm2_[MESA](BOARD).0.pwmgen.00.enable

# Comando velocità in RPM dal planner
net spindle-speed-cmd-rpm motion.spindle-speed-out => hm2_[MESA](BOARD).0.pwmgen.00.value

I would in addition, check the above signals and pins to try and trace backwards
to find out  why  you don't have PWM enable and value set properly.

Please Log in or Create an account to join the conversation.

Moderators: PCWjmelson
Time to create page: 0.081 seconds
Powered by Kunena Forum