Как управлять сервомотором Arduino через Unity
Arduino:
const int butPin2 = 7;
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int delayTime = 2;
char myCol[10];
enum class READSTAT {NONE, READING, DONEREADING};
READSTAT readStat = READSTAT::NONE;
void setup() {
Serial.begin(9600);
pinMode(butPin1, INPUT);
pinMode(butPin2, INPUT);
digitalWrite(butPin1, HIGH);
digitalWrite(butPin2, HIGH);
}
void loop(){
if (digitalRead(butPin1) == LOW){
Serial.write(1);
Serial.flush();
delay(20);
}
if (digitalRead(butPin2) == LOW){
Serial.println("RIGHT");
Serial.write(2);
Serial.flush();
delay(20);
}
delay(1);
//Serial.setTimeout(0);
static int avalData = 0;
if ( Serial.available() > 0) {
readStat = READSTAT::READING;
myCol[avalData] = Serial.read();
avalData++;
} else {
//If we are in READING mode and there are no more available bytes, change mode to DONEREADING
if (readStat == READSTAT::READING ) {
readStat = READSTAT::DONEREADING;
myCol[avalData] = '\0';
}
}
//[CODE INSIDE HERE WILL RUN WHEN EVERY BYTE HAS BEEN RECEIVED FROM UNITY]
//If we are in DONEREADING mode, change mode to NONE
if (readStat == READSTAT::DONEREADING ) {
checkMotor(avalData);
//SET TO NONE then reset avalData
readStat = READSTAT::NONE;
avalData = 0;
}
}
void checkMotor(int avalData ) {
int Angle = atoi(myCol);
int Tick = ((Angle * 51.2) / 36.0);
if (0 < Tick) {
Tick = abs(Tick);
for ( int i = 0; i < Tick; i++) {
Play();
}
} else if (0 > Tick) {
Tick = abs(Tick);
for ( int i = 0; i < Tick; i++) {
Reverse();
}
}
}
void Play()
{
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(delayTime);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
delay(delayTime);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(delayTime);
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(delayTime);
}
void Reverse()
{
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(delayTime);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(delayTime);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
delay(delayTime);
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(delayTime);
}
Не знаю что не так в коде, потому что я перекидываю скрипты на Куб и Сервомотор не двигается от движения куба.
C#: Button Move
using System.Collections;
using System.IO.Ports;
using System.Threading;
public class Sending : MonoBehaviour
{
public SerialPort sp;
Thread SerialThread;
bool stopSerialCom = true;
bool sendNow = false;
int posTosend = 0;
void Start()
{
startCommuncation();
}
public void startCommuncation()
{
SerialThread = new Thread(onConnected);
SerialThread.IsBackground = true;
SerialThread.Start();
}
private void onConnected()
{
//Open Connection
openCon();
sp.ReadTimeout = 2;
//Run forever until stopSerialCom = true
while (!stopSerialCom)
{
//Check if we should send
if (sendNow)
{
Debug.Log("Sent: " + posTosend.ToString());
//Send
sendToSerial(posTosend);
posTosend = 0; //Reset to 0
sendNow = false;
}
Thread.Sleep(1);
}
}
private void openCon(string comPort = "COM4", int port = 9600)
{
sp = new SerialPort(comPort, port);
if (sp != null)
{
if (sp.IsOpen)
{
sp.Close();
sp.Open();
stopSerialCom = false;
Debug.Log("Opened!");
}
else
{
sp.Open();
stopSerialCom = false;
Debug.Log("Opened!");
}
}
}
public void closeConnection()
{
stopSerialCom = true;
//stop thread
if (SerialThread != null && SerialThread.IsAlive)
{
Debug.Log("Thread Aborted!");
SerialThread.Abort();
}
if (sp != null && sp.IsOpen)
{
sp.Close();
Debug.Log("Closed!");
}
}
void OnApplicationQuit()
{
closeConnection();
}
public void Send(int pos)
{
posTosend = pos;
sendNow = true;
}
private void sendToSerial(int pos)
{
try
{
string PosStr = pos.ToString();
sp.Write(PosStr);
}
catch (System.Exception e)
{
Debug.Log("Error: " + e.Message);
}
}
}
GetPosition:
using System.Collections;
using UnityEngine.EventSystems;
public class GetPosition : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Vector3 dragStartPosition;
float dragStartDistance;
float[] Xfloat;
Vector3 clickOffset = Vector3.zero;
Sending sending;
Camera mainCamera;
Transform camTransform;
void Start()
{
mainCamera = Camera.main;
camTransform = mainCamera.transform;
mainCamera.gameObject.AddComponent<PhysicsRaycaster>();
sending = GetComponent<Sending>();
}
public void OnBeginDrag(PointerEventData eventData)
{
dragStartPosition = transform.position;
dragStartDistance = (camTransform.position - transform.position).magnitude;
//Get offset
clickOffset = transform.position - mainCamera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, dragStartDistance));
}
public void OnDrag(PointerEventData eventData)
{
Vector3 tempPos = mainCamera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, dragStartDistance));
//Apply Offset to prevent the Cube from Jumping when mouse is clicke on the side/edge
tempPos = tempPos + clickOffset;
tempPos.y = dragStartPosition.y;
tempPos.z = dragStartPosition.z;
transform.position = tempPos;
}
public void OnEndDrag(PointerEventData eventData)
{
sending.Send((int)transform.position.x);
}
}
Надеюсь местные помогут мне с этим.