A Micro, a servo, and a battery pack can be put together on a longer breadboard. For more information on the ultrasonic module used in this experiment, visit Ultra Sonic range measurement module - Seeed Studio.
If you want to replicate this experiment, it might be a good idea to use a TI-Innovator Hub instead of a Micro/Leonardo.
Connect the signal pin of the ultrasonic module to D7 of the Arduino. And connect the control pin of the servo to D9 of the Arduino. To connect the handheld to the Micro or Leonardo, use an OTG cable or host cable with the handheld on the host side.
.ino
#include <Servo.h> #define ultraPin 7 #define servoPin 9 int deg = 0; class Ultrasonic { public: Ultrasonic(int pin); void DistanceMeasure(void); float microsecondsToCentimeters(void); private: int _pin; float duration; }; Ultrasonic::Ultrasonic(int pin) { _pin = pin; } void Ultrasonic::DistanceMeasure(void) { pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW); delayMicroseconds(2); digitalWrite(_pin, HIGH); delayMicroseconds(5); digitalWrite(_pin, LOW); pinMode(_pin, INPUT); duration = (float)pulseIn(_pin, HIGH); } float Ultrasonic::microsecondsToCentimeters(void) { return duration / 58.0; } Ultrasonic ultrasonic(ultraPin); Servo myservo; void setup() { myservo.attach(servoPin); Serial.begin(115200); } void loop() { while(deg < 160) { if(Serial.available() && Serial.read() == 'T') { myservo.write(deg); ultrasonic.DistanceMeasure(); Serial.print(ultrasonic.microsecondsToCentimeters()); Serial.print(" "); Serial.println(deg); deg = deg + 1; delay(0); } } while(deg > 20) { if(Serial.available() && Serial.read() == 'T') { myservo.write(deg); ultrasonic.DistanceMeasure(); Serial.print(ultrasonic.microsecondsToCentimeters()); Serial.print(" "); Serial.println(deg); deg = deg - 1; delay(0); } } }
.lua
require "asi" require "color" platform.window:setBackgroundColor(color.black) function on.resize() W, H = platform.window:width(), platform.window:height() X0, Y0 = W/2, H UNIT = H/50 -- H/50 pixels = 1 cm fontSize = W/13.25 maxHistory = 150 end function map(var, inMin, inMax, outMin, outMax) return (var - inMin) * (outMax - outMin) / (inMax - inMin) + outMin end function polar2screen(r, deg, x0, y0, unit) local rad = math.rad(deg) local x, y = r * math.cos(rad), r * math.sin(rad) return x0 + x * unit, y0 - y * unit end function constrain(var, min, max) return math.max(min, math.min(var, max)) end local PORT local DATA = 0 local RANGE = {} local DEGREE = {} ----------------------------------- -- シリアルデータの読み取り要求函数 ----------------------------------- function requestData() PORT:write('T') PORT:read() end -------------------------------------------------------------------------------- -- ASI ステートリスナーを定義する(ASI の準備が整ったらポートスキャンを開始する) -------------------------------------------------------------------------------- function stateListener(state) if state == asi.ON then asi.startScanning(portScanner) end end ---------------------------------------------------------------- -- ポートスキャナーを定義する(見つかったポートに接続要求を出す) ---------------------------------------------------------------- function portScanner(port) port:connect(portConnector) end ----------------------------------------------------------------------------------------------------- -- ポートコネクターを定義する ----------------------------------------------------------------------------------------------------- function portConnector(port, event) PORT = port if event == asi.CONNECTED then asi.stopScanning() requestData() port:setReadListener(readListener) end end ---------------------------------------------------------------------------- -- 読み取りリスナーを定義する(データを取得し、またデータ読み取り要求を出す) ---------------------------------------------------------------------------- function readListener(port) DATA = port:getValue() or 0 RANGE[#RANGE+1], DEGREE[#DEGREE+1] = unpack(string.split(DATA)) if #RANGE > maxHistory then table.remove(RANGE, 1) table.remove(DEGREE, 1) end platform.window:invalidate() requestData() end --------------------------------- -- ASI ステートリスナーを登録する --------------------------------- function on.construction() asi.addStateListener(stateListener) end ------------------------------------------------------------------------------- function on.paint(gc) gc:setPen("thin") for i = 1, #RANGE do local dimColor = map(i, 0, #RANGE, 0, 255) gc:setColorRGB(dimColor, 0, 0) gc:drawLine(X0, Y0, polar2screen(50, DEGREE[i], X0, Y0, UNIT)) gc:setColorRGB(0, dimColor, 0) gc:drawLine(X0, Y0, polar2screen(math.min(RANGE[i], 50), DEGREE[i], X0, Y0, UNIT)) end end