Skip to content

Instantly share code, notes, and snippets.

@donovankeith
Last active October 19, 2017 23:29
Show Gist options
  • Save donovankeith/7691d7370c1066a68e5a80b6bcc75efb to your computer and use it in GitHub Desktop.
Save donovankeith/7691d7370c1066a68e5a80b6bcc75efb to your computer and use it in GitHub Desktop.
Unity Arduino Input/Output
/* Arduino Serial I/O
* Allows you to send simple commands to an arduino and to receive data back.
*
* Source based on: https://www.alanzucconi.com/2015/10/07/how-to-integrate-arduino-with-unity/
*
* ## Setup
* 1. Edit > Player Settings
* 2. .NET Compatibility Level = `.NET 2.0`
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
public class ArduinoIO : MonoBehaviour {
// User Inputs
[Tooltip("Open Arduino serial monitor, and look for the name of the port at the end of the phrase 'Arduino/Genuino Uno at...")]
public string portName = "COM5";
[Tooltip("The baudrate of the serial port")]
public int baudrate = 9600;
public int outputValue = 0;
// Storage & I/O
private SerialPort stream;
public void Open () {
// Opens the serial port
stream = new SerialPort(portName, baudrate);
stream.ReadTimeout = 20;
stream.Open();
WriteToArduino ("INIT");
//this.stream.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
public void WriteToArduino(string message)
{
// Send the request
stream.WriteLine(message + '\n');
stream.BaseStream.Flush();
}
public string ReadFromArduino()
{
try
{
return stream.ReadLine();
}
catch
{
return null;
}
}
// Use this for initialization
void Start () {
Open ();
}
// Update is called once per frame
void Update () {
WriteToArduino ("DIST");
try{
string arduinoOutput = ReadFromArduino();
outputValue = int.Parse (arduinoOutput);
}
catch{
}
if (outputValue != -1) {
Vector3 immediatePostion = new Vector3 (0.0f, (float)outputValue * 0.1f, 0.0f);
transform.position = Vector3.Lerp(transform.position, immediatePostion, 0.75f);
}
}
}
/* SerialOutput.ino
Outputs simple commands to the Serial port based on the readings from an Ultrasonic Range Sensor
Using: HCS-SRO4
## Commands
- `INIT`: Flashes the Arduino's built-in LED 3, 2, 1 times.
- `DEBUG`: Writes sensor data to Serial in an unending stream.
- `END`: Stops `DEBUG` mode.
- `DIST`: Writes the current distance reading to the stream once.
*/
// Library Imports
#include <NewPing.h> // This is the Ultrasonic Sensor library
#include <RunningMedian.h> // This is a running median filter library
// Hardware Setup
#define BAUD_RATE 9600
const int TRIGGER_PIN = 2; //The pin attached to trig
const int ECHO_PIN = 3; // the pin attached to echco
const int MAX_DISTANCE = 65; // Measured in Centimeters
long distance; // I hope there aren't extra charges! :-P
// Message Properties
const char eomChar = '\n'; // The end of message terminator. Necessary for serial.readStringUntil to prevent timeout
String message;
// Setup Connection
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // Define "sonar" instance of Newping with parameters
// Data Smoothing
RunningMedian samples = RunningMedian(15); // Define "samples" instance of RunningMedian with 15 sample parameter
// Debug
bool debug = false;
void setup() {
// Open Serial Connection
Serial.begin(BAUD_RATE);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
// Reads input from Ultrasonic Rangefinder
// Read bytes from serial buffer if any
if (Serial.available()) {
message = Serial.readStringUntil(eomChar);
if (message == "DIST"){
printDistance();
}
else if (message == "INIT"){
ledCountDown();
}
else if (message == "DEBUG"){
debug = true;
}
else if (message == "END"){
debug = false;
}
}
if (debug) {
printDistance();
}
// Return the current distance measurement in cm
distance = sonar.ping_cm();
// Add current distance measurement to median filter
samples.add(distance);
}
void ledCountDown(){
// Countdown
int flashCount = 3;
int flashPeriod = 200;
int flashBreak = 500;
for (int count=flashCount; count>0; count--)
{
for (int j=0; j<count; j++){
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(flashPeriod);
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(flashPeriod);
}
delay(flashBreak);
}
}
void printDistance () {
/* Retrieves distance from cached values. Outputs it to the serial port.
* Message code: "DIST"
*/
int cm = samples.getMedian(); //return median distance from filter
if (cm <= MAX_DISTANCE)
Serial.println(cm); //send value if less than 65
else
Serial.println(-1); //else send string
}
@donovankeith
Copy link
Author

Added realtime printing when "DEBUG" command is sent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment