use pokeys_lib::*;
use std::io::{self, Write};
fn main() -> Result<()> {
println!("PoKeys Pulse Engine Setup Example");
println!("=================================");
let network_devices = enumerate_network_devices(2000)?;
let target_device = network_devices
.iter()
.find(|device| device.serial_number == 32223)
.ok_or_else(|| PoKeysError::Parameter("Device 32223 not found".to_string()))?;
let mut device = connect_to_network_device(target_device)?;
println!("Configuring 3-axis internal pulse generator...");
device.enable_pulse_engine(true)?;
let config = PulseEngineConfig::three_channel_internal(3, false)
.power_states(0x06) .build();
let axis_enabled_mask = 0x04;
println!("Setup pulse engine config:");
println!(" enabled_axes: {}", config.enabled_axes);
println!(" charge_pump_enabled: {}", config.charge_pump_enabled);
println!(" generator_type: 0x{:02X}", config.generator_type);
println!(" buffer_size: {}", config.buffer_size);
println!(
" emergency_switch_polarity: {}",
config.emergency_switch_polarity
);
println!(" power_states: 0x{:02X}", config.power_states);
println!(" axis_enabled_mask: 0x{:02X}", axis_enabled_mask);
device.setup_pulse_engine_with_axes(&config, axis_enabled_mask)?;
println!("Simple test - enabling axis 3 (bit 2)...");
device.set_pulse_engine_state(0x02, 0x00, axis_enabled_mask)?;
println!("Getting pulse engine status (0x85/0x00)...");
device.get_pulse_engine_status()?;
println!("Pulse engine status:");
println!(
" pulse_engine_activated: {}",
device.pulse_engine_v2.pulse_engine_activated
);
println!(
" pulse_engine_state: {}",
device.pulse_engine_v2.pulse_engine_state
);
println!(
" axis_enabled_states_mask: 0x{:02X}",
device.pulse_engine_v2.axis_enabled_states_mask
);
println!(
" axis_enabled_mask: 0x{:02X}",
device.pulse_engine_v2.axis_enabled_mask
);
println!(" nr_of_axes: {}", device.pulse_engine_v2.info.nr_of_axes);
println!("Axis positions from status:");
for i in 0..3 {
println!(
" Axis {} position: {}",
i + 1,
device.pulse_engine_v2.current_position[i]
);
}
let axis_enabled_mask = 0x01;
device.enable_pulse_engine(true)?;
device.set_pulse_engine_state(0x02, 0x00, axis_enabled_mask)?;
device.set_axis_configuration(2)?;
device.get_pulse_engine_status()?;
println!(
"Device axis_enabled_mask: 0b{:08b} (0x{:02X})",
device.pulse_engine_v2.axis_enabled_mask, device.pulse_engine_v2.axis_enabled_mask
);
println!(
"Expected mask for axis 3: 0b{:08b} (0x{:02X})",
axis_enabled_mask, axis_enabled_mask
);
println!(
"Bit 0 (axis 1): {}",
(device.pulse_engine_v2.axis_enabled_mask & 1) != 0
);
println!(
"Bit 1 (axis 2): {}",
(device.pulse_engine_v2.axis_enabled_mask & 2) != 0
);
println!(
"Bit 2 (axis 3): {}",
(device.pulse_engine_v2.axis_enabled_mask & 4) != 0
);
println!(
"Axis 3 enabled after config: {}",
device.pulse_engine_v2.is_axis_enabled(2)
);
device.enable_pulse_engine(true)?;
device.get_pulse_engine_status()?;
println!(
"✓ Pulse engine configured: {} axes, generator type 0x{:02X}",
device.pulse_engine_v2.info.nr_of_axes, device.pulse_engine_v2.pulse_generator_type
);
println!("Configuring axis 3...");
device
.configure_axis(2)
.max_speed(12500.0)
.max_acceleration(10.0)
.max_deceleration(10.0)
.soft_limit_min(-100000)
.soft_limit_max(100000)
.step_angle(1.8)
.step_resolution(pulse_engine::StepResolution::SixteenthStep)
.build(&mut device)?;
device.set_motor_drivers_configuration()?;
std::thread::sleep(std::time::Duration::from_millis(100));
device.get_motor_drivers_configuration()?;
device.set_axis_configuration(2)?;
println!(
"Values sent to device: speed={}, accel={}, decel={}",
1000.0, 100.0, 100.0
);
device.get_axis_configuration(2)?;
println!(
"Raw device values: speed={:.3}, accel={:.3}, decel={:.3}",
device.pulse_engine_v2.max_speed[2],
device.pulse_engine_v2.max_acceleration[2],
device.pulse_engine_v2.max_deceleration[2]
);
println!(
"✓ Axis 3 configured: speed={}, accel={}, decel={}, limits=[{}, {}]",
device.pulse_engine_v2.max_speed[2] as f32,
device.pulse_engine_v2.max_acceleration[2] as f32,
device.pulse_engine_v2.max_deceleration[2] as f32,
device.pulse_engine_v2.soft_limit_minimum[2],
device.pulse_engine_v2.soft_limit_maximum[2]
);
let step_names = [
"1/1",
"1/2 non-circular",
"1/2",
"1/4",
"1/8",
"1/16",
"1/32",
"1/128",
"1/256",
];
println!("Reading motor driver configuration from device...");
let step_setting = device.pulse_engine_v2.motor_step_setting[2]; let current_setting = device.pulse_engine_v2.motor_current_setting[2];
let current_amps = (current_setting as f32) * 2.5 / 255.0;
println!(
"✓ Axis 3 motor driver: step={} ({}), current={:.2}A",
step_setting,
step_names.get(step_setting as usize).unwrap_or(&"Unknown"),
current_amps
);
println!("Step setting already configured by AxisConfigBuilder...");
let new_step_setting = device.pulse_engine_v2.motor_step_setting[2];
println!(
"✓ Axis 3 motor driver updated: step={} ({})",
new_step_setting,
step_names
.get(new_step_setting as usize)
.unwrap_or(&"Unknown")
);
println!("Resetting position to 0...");
device.set_axis_position(2, 0)?;
println!("✓ Position reset to 0");
println!("\n--- Interactive Move Command ---");
print!("Enter position for axis 3: ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let position: i32 = input.trim().parse().unwrap_or(0);
println!("Setting axis 3 to position {}...", position);
device.enable_pulse_engine(true)?;
let axis_state_0 = device.get_axis_state(0)?;
println!("Axis 1 state before move: {:?}", axis_state_0);
println!(
"Axis 1 enabled: {}",
device.pulse_engine_v2.is_axis_enabled(0)
);
let current_pos_0 = device.get_axis_position(0)?;
println!("Axis 1 current position: {}", current_pos_0);
let axis_state_1 = device.get_axis_state(1)?;
println!("Axis 2 state before move: {:?}", axis_state_1);
println!(
"Axis 2 enabled: {}",
device.pulse_engine_v2.is_axis_enabled(1)
);
let current_pos_1 = device.get_axis_position(1)?;
println!("Axis 2 current position: {}", current_pos_1);
let axis_state_2 = device.get_axis_state(2)?;
println!("Axis 3 state before move: {:?}", axis_state_2);
println!(
"Axis 3 enabled: {}",
device.pulse_engine_v2.is_axis_enabled(2)
);
let current_pos_2 = device.get_axis_position(2)?;
println!("Axis 3 current position: {}", current_pos_2);
device.move_axis_to_position(2, position, 50.0)?; println!("✓ Move command sent");
println!("Monitoring position...");
for i in 0..20 {
device.get_pulse_engine_status()?;
let current_pos = device.pulse_engine_v2.current_position[2];
let state = match device.pulse_engine_v2.axes_state[2] {
0 => "Stopped",
1 => "Moving",
2 => "Accelerating",
3 => "Decelerating",
_ => "Unknown",
};
println!(
" Step {}: Position = {}, State = {}",
i, current_pos, state
);
if state == "Stopped" && i > 5 {
break;
}
std::thread::sleep(std::time::Duration::from_millis(50));
}
loop {
println!("\n--- Interactive Move Command ---");
print!("Enter target position for axis 3: ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let target_position: i32 = match input.trim().parse() {
Ok(pos) => pos,
Err(_) => {
println!("Invalid input, please enter a number");
continue;
}
};
let soft_min = device.pulse_engine_v2.soft_limit_minimum[2];
let soft_max = device.pulse_engine_v2.soft_limit_maximum[2];
if (soft_min != 0 || soft_max != 0)
&& (target_position < soft_min || target_position > soft_max)
{
println!(
"Error: Target position {} is outside soft limits [{}, {}]",
target_position, soft_min, soft_max
);
continue;
}
println!("Moving to position {}...", target_position);
device.move_axis_to_position(2, target_position, 100.0)?;
loop {
device.get_pulse_engine_status()?;
let current_pos = device.pulse_engine_v2.current_position[2];
let state = match device.pulse_engine_v2.axes_state[2] {
0 => "Stopped",
1 => "Moving",
2 => "Accelerating",
3 => "Decelerating",
_ => "Unknown",
};
println!(
"Position: {}, Target: {}, State: {}",
current_pos, target_position, state
);
let soft_limits_active = device.pulse_engine_v2.soft_limit_minimum[2] != 0
|| device.pulse_engine_v2.soft_limit_maximum[2] != 0;
let close_enough = if soft_limits_active {
(current_pos - target_position).abs() <= 2
} else {
current_pos == target_position
};
let overrun = if !soft_limits_active {
if target_position > 0 && current_pos > target_position {
true } else if target_position < 0 && current_pos < target_position {
true } else {
false
}
} else {
false
};
if close_enough
|| overrun
|| (state == "Stopped" && (current_pos - target_position).abs() <= 2)
{
if overrun {
println!(
"⚠ Warning: Overran target {} (Final: {})",
target_position, current_pos
);
} else {
println!(
"✓ Target position {} reached! (Final: {})",
target_position, current_pos
);
}
break;
}
std::thread::sleep(std::time::Duration::from_millis(25));
}
}
}