diff --git a/Makefile b/Makefile index 4fdab63..4ac96bc 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,8 @@ smoke-test: @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go @md5sum ./build/test.hex + tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go + @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go @md5sum ./build/test.hex tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go diff --git a/README.md b/README.md index c2c6392..158feda 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ The following 46 devices are supported. | [ESP8266/ESP32 AT Command set for WiFi/TCP/UDP](https://github.com/espressif/esp32-at) | UART | | [GPS module](https://www.u-blox.com/en/product/neo-6-series) | I2C/UART | | [HD44780 LCD controller](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | GPIO | +| [HC-SR04 Ultrasonic distance sensor](https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf) | GPIO | | [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI | | [ILI9341 TFT color display](https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf) | SPI | | [L293x motor driver](https://www.ti.com/lit/ds/symlink/l293d.pdf) | GPIO/PWM | diff --git a/easystepper/easystepper.go b/easystepper/easystepper.go index b6c26cc..653a400 100644 --- a/easystepper/easystepper.go +++ b/easystepper/easystepper.go @@ -18,8 +18,7 @@ type DualDevice struct { devices [2]Device } -// New returns a new easystepper driver given 4 pins numbers (not pin object), -// number of steps and rpm +// New returns a new easystepper driver given 4 pins, number of steps and rpm func New(pin1, pin2, pin3, pin4 machine.Pin, steps int32, rpm int32) Device { return Device{ pins: [4]machine.Pin{pin1, pin2, pin3, pin4}, @@ -34,8 +33,7 @@ func (d *Device) Configure() { } } -// NewDual returns a new dual easystepper driver given 8 pins numbers (not pin object), -// number of steps and rpm +// NewDual returns a new dual easystepper driver given 8 pins, number of steps and rpm func NewDual(pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8 machine.Pin, steps int32, rpm int32) DualDevice { var dual DualDevice dual.devices[0] = Device{ diff --git a/examples/hcsr04/main.go b/examples/hcsr04/main.go new file mode 100644 index 0000000..4115e97 --- /dev/null +++ b/examples/hcsr04/main.go @@ -0,0 +1,20 @@ +package hcsr04 + +import ( + "machine" + "time" + + "tinygo.org/x/drivers/hcsr04" +) + +func main() { + sensor := hcsr04.New(machine.D10, machine.D9) + sensor.Configure() + + println("Ultrasonic starts") + for { + println("Distance:", sensor.ReadDistance(), "mm") + + time.Sleep(100 * time.Millisecond) + } +} diff --git a/hcsr04/hcsr04.go b/hcsr04/hcsr04.go new file mode 100644 index 0000000..703fa78 --- /dev/null +++ b/hcsr04/hcsr04.go @@ -0,0 +1,81 @@ +// Package hcsr04 provides a driver for the HC-SR04 ultrasonic distance sensor +// +// Datasheet: +// https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf +package hcsr04 + +import ( + "machine" + "time" +) + +const TIMEOUT = 23324 // max sensing distance (4m) + +// Device holds the pins +type Device struct { + trigger machine.Pin + echo machine.Pin +} + +// New returns a new ultrasonic driver given 2 pins +func New(trigger, echo machine.Pin) Device { + return Device{ + trigger: trigger, + echo: echo, + } +} + +// Configure configures the pins of the Device +func (d *Device) Configure() { + d.trigger.Configure(machine.PinConfig{Mode: machine.PinOutput}) + d.echo.Configure(machine.PinConfig{Mode: machine.PinInput}) +} + +// ReadDistance returns the distance of the object in mm +func (d *Device) ReadDistance() int32 { + pulse := d.ReadPulse() + + // sound speed is 343000 mm/s + // pulse is roundtrip measured in microseconds + // distance = velocity * time + // 2 * distance = 343000 * (pulse/1000000) + return (pulse * 1715) / 10000 //mm +} + +// ReadPulse returns the time of the pulse (roundtrip) in microseconds +func (d *Device) ReadPulse() int32 { + t := time.Now() + d.trigger.Low() + time.Sleep(2 * time.Microsecond) + d.trigger.High() + time.Sleep(10 * time.Microsecond) + d.trigger.Low() + i := uint8(0) + for { + if d.echo.Get() { + t = time.Now() + break + } + i++ + if i > 10 { + if time.Since(t).Microseconds() > TIMEOUT { + return 0 + } + i = 0 + } + } + i = 0 + for { + if !d.echo.Get() { + return int32(time.Since(t).Microseconds()) + } + i++ + if i > 10 { + if time.Since(t).Microseconds() > TIMEOUT { + return 0 + } + i = 0 + } + } + return 0 +}