velxio/test/test_circuit/test/spice_mapped_l293d.test.js

64 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect } from 'vitest';
import { runNetlist } from '../src/spice/SpiceEngine.js';
/**
* Sanity check for the L293D dual H-bridge motor driver mapper (fase 10.5).
*
* Per output: OUT = EN · IN · V_motor
* When EN=LOW, outputs go high-impedance → weak pull to 0 V via 10 MΩ load.
*/
const T = 2.5;
function l293dNetlist({ en1, in1, in2, vMotor = 9 }) {
return `L293D
Vcc2 vcc2 0 DC ${vMotor}
Ven en 0 DC ${en1}
Vin1 in1 0 DC ${in1}
Vin2 in2 0 DC ${in2}
B_ch1a out1 0 V = u(V(en)-${T}) * u(V(in1)-${T}) * V(vcc2)
R_ch1a_load out1 0 10Meg
B_ch1b out2 0 V = u(V(en)-${T}) * u(V(in2)-${T}) * V(vcc2)
R_ch1b_load out2 0 10Meg
.op
.end`;
}
describe('componentToSpice — L293D basic truth table', () => {
it('EN=0: both outputs high-Z (≈ 0 V under weak load)', { timeout: 30_000 }, async () => {
const { dcValue } = await runNetlist(l293dNetlist({ en1: 0, in1: 5, in2: 0 }));
expect(dcValue('v(out1)')).toBeLessThan(0.1);
expect(dcValue('v(out2)')).toBeLessThan(0.1);
});
it('EN=HIGH, IN1=HIGH, IN2=LOW: OUT1=V_motor, OUT2=0 (forward)', { timeout: 30_000 }, async () => {
const { dcValue } = await runNetlist(l293dNetlist({ en1: 5, in1: 5, in2: 0 }));
expect(dcValue('v(out1)')).toBeGreaterThan(8.5);
expect(dcValue('v(out2)')).toBeLessThan(0.1);
});
it('EN=HIGH, IN1=LOW, IN2=HIGH: OUT1=0, OUT2=V_motor (reverse)', { timeout: 30_000 }, async () => {
const { dcValue } = await runNetlist(l293dNetlist({ en1: 5, in1: 0, in2: 5 }));
expect(dcValue('v(out1)')).toBeLessThan(0.1);
expect(dcValue('v(out2)')).toBeGreaterThan(8.5);
});
it('EN=HIGH, IN1=IN2=HIGH: both OUT=V_motor (brake — no voltage across motor)', { timeout: 30_000 }, async () => {
const { dcValue } = await runNetlist(l293dNetlist({ en1: 5, in1: 5, in2: 5 }));
expect(dcValue('v(out1)')).toBeGreaterThan(8.5);
expect(dcValue('v(out2)')).toBeGreaterThan(8.5);
// Brake: V_out1 V_out2 ≈ 0 → no motor torque
expect(Math.abs(dcValue('v(out1)') - dcValue('v(out2)'))).toBeLessThan(0.2);
});
});
describe('componentToSpice — L293D with V_motor variable', () => {
it('motor voltage parameterizes the output level', { timeout: 30_000 }, async () => {
for (const vm of [6, 9, 12]) {
const { dcValue } = await runNetlist(l293dNetlist({ en1: 5, in1: 5, in2: 0, vMotor: vm }));
expect(dcValue('v(out1)')).toBeGreaterThan(vm - 0.5);
expect(dcValue('v(out1)')).toBeLessThan(vm + 0.5);
}
});
});