enum UltrasonicSensorEvent { //% block="object detected" ObjectDetected = 10, //% block="object near" ObjectNear = sensors.ThresholdState.Low } namespace sensors { //% fixedInstances export class UltraSonicSensor extends internal.UartSensor { private promixityThreshold: sensors.ThresholdDetector; private movementThreshold: number; constructor(port: number) { super(port) this.promixityThreshold = new sensors.ThresholdDetector(this.id(), 0, 255, 10, 100); // range is 0..255cm this.movementThreshold = 1; this._setMode(0); } _deviceType() { return DAL.DEVICE_TYPE_ULTRASONIC } _query(): number { return ((this.getNumber(NumberFormat.UInt16LE, 0) & 0x0fff) / 10) >> 0; // range is 0..2550, in 0.1 cm increments. } _info(): string { return `${this.distance()}cm` } _update(prev: number, curr: number) { // is there an object near? this.promixityThreshold.setLevel(curr); // did something change? if (Math.abs(prev - curr) > this.movementThreshold) control.raiseEvent(this._id, UltrasonicSensorEvent.ObjectDetected); } /** * Registers code to run when an object is close or detected * @param handler the code to run when detected */ //% help=sensors/ultrasonic/on-event //% blockId=ultrasonicOn //% block="on **ultrasonic** %this|%event" //% parts="ultrasonicsensor" //% blockNamespace=sensors //% this.fieldEditor="ports" //% weight=100 blockGap=8 //% group="Ultrasonic Sensor" onEvent(event: UltrasonicSensorEvent, handler: () => void) { control.onEvent(this._id, event, handler); } /** * Waits for the event to occur */ //% help=sensors/ultrasonic/pause-until //% block="pause until **ultrasonic** %this| %event" //% blockId=ultrasonicWait //% parts="ultrasonicsensor" //% blockNamespace=sensors //% this.fieldEditor="ports" //% weight=99 blockGap=8 //% group="Ultrasonic Sensor" pauseUntil(event: UltrasonicSensorEvent) { control.waitForEvent(this._id, event); } /** * Gets the distance from the sonar in centimeters * @param sensor the ultrasonic sensor port */ //% help=sensors/ultrasonic/distance //% block="**ultrasonic** %this|distance" //% blockId=sonarGetDistance //% parts="ultrasonicsensor" //% blockNamespace=sensors //% this.fieldEditor="ports" //% weight=65 //% group="Ultrasonic Sensor" distance(): number { // it supposedly also has an inch mode, but we stick to cm this._setMode(0) return this._query(); } /** * Sets a threshold value * @param condition the near or detected condition * @param value the value threshold */ //% blockId=ultrasonicSetThreshold block="set **ultrasonic** %this|%condition|to %value" //% group="Calibration" blockGap=8 weight=80 //% value.min=0 value.max=255 //% this.fieldEditor="ports" setThreshold(condition: UltrasonicSensorEvent, value: number) { switch (condition) { case UltrasonicSensorEvent.ObjectNear: this.promixityThreshold.setLowThreshold(value); break; case UltrasonicSensorEvent.ObjectDetected: this.movementThreshold = value; break; } } /** * Gets the threshold value * @param condition the proximity condition */ //% blockId=ultrasonicGetThreshold block="**ultrasonic** %this|%condition" //% group="Calibration" weight=79 //% this.fieldEditor="ports" threshold(condition: UltrasonicSensorEvent): number { switch (condition) { case UltrasonicSensorEvent.ObjectNear: return this.promixityThreshold.threshold(ThresholdState.Low); case UltrasonicSensorEvent.ObjectDetected: return this.movementThreshold; } return 0; } } //% fixedInstance whenUsed block="4" jres=icons.port4 export const ultrasonic4: UltraSonicSensor = new UltraSonicSensor(4) //% fixedInstance whenUsed block="1" jres=icons.port1 export const ultrasonic1: UltraSonicSensor = new UltraSonicSensor(1) //% fixedInstance whenUsed block="2" jres=icons.port2 export const ultrasonic2: UltraSonicSensor = new UltraSonicSensor(2) //% fixedInstance whenUsed block="3" jres=icons.port3 export const ultrasonic3: UltraSonicSensor = new UltraSonicSensor(3) }