### Question:
SoftPwm extends AbstractPwm implements Runnable { public SoftPwm(Pin pin) { super(pin); if(!pin.hasFeature(DigitalOutput.class)) { throw new IllegalArgumentException("The pin must be able to act as a DigitalOutput"); } this.output = pin.getFeature(DigitalOutput.class); pin.getFeatures().add(this); } SoftPwm(Pin pin);  SoftPwm(DigitalOutput output); @Override void run(); @Override void setupImpl(); @Override void teardownImpl();  }### Answer:
@Test public void testSoftPwm() { DigitalOutput output = pin.as(DigitalOutput.class); SoftPwm pwm = new SoftPwm(output); pwm.setDuty(0.2); pwm.setFrequency(10.0); pwm.enable(); BulldogUtil.sleepMs(100); int highCount = 0; int lowCount = 0; for(int i = 0; i < 100; i++) { Signal signal = output.getAppliedSignal(); if(signal == Signal.High) { highCount++; } else { lowCount++; } BulldogUtil.sleepMs(1); } TestCase.assertEquals(80, lowCount); TestCase.assertEquals(20, highCount); pwm.disable(); pwm.disable(); BulldogUtil.sleepMs(50); Signal signal = output.getAppliedSignal(); for(int i = 0; i < 100; i++) { TestCase.assertEquals(signal, output.getAppliedSignal()); BulldogUtil.sleepMs(1); } }