using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;
public class Sending : MonoBehaviour {
//public static SerialPort sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
public static SerialPort sp = new SerialPort("COM3", 9600);
void Start () {
OpenConnection();
}
public void OpenConnection()
{
if (sp != null)
{
if (sp.IsOpen)
{
sp.Close();
}
else
{
sp.Open();
}
}
}
void OnApplicationQuit()
{
sp.Close();
}
public static void Contact(int pos)
{
string PosStr = pos.ToString ();
Debug.Log(PosStr);
sp.Write(PosStr);
}
}
/////////////////////////////////////////////// ///////////
using UnityEngine;
using System.Collections;
public class GetPosition : MonoBehaviour
{
Vector3 dragStartPosition;
float dragStartDistance;
float[] Xfloat;
void OnMouseDown ()
{
dragStartPosition = transform.position;
dragStartDistance = (Camera.main.transform.position - transform.position).magnitude;
}
void Update ()
{
}
int OnMouseDrag ()
{
Vector3 worldDragTo = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, dragStartDistance));
transform.position = new Vector3 (worldDragTo.x, dragStartPosition.y, dragStartPosition.z);
new Vector3 (worldDragTo.x, dragStartPosition.y, dragStartPosition.z);
int Newpos = (int)worldDragTo.x;
return (Newpos);
}
void OnMouseUp ()
{
int NewPos = OnMouseDrag ();
Sending.Contact (NewPos);
}
}
/////////////////////////////////////////////// //////////////////
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int delayTime = 2;
int i = 0;
char myCol[5];
void setup() {
Serial.begin (9600);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
}
void loop()
{
int lf = 5;
Serial.readBytesUntil(lf, myCol, 5);
Serial.setTimeout(0);
int Angle = atoi(myCol);
int Tick = ((Angle * 51.2) / 36.0);
Serial.println(Tick);
if ( i < Tick)
{
Play();
i++;
}
if (i > Tick)
{
Reverse();
i--;
}
}
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);
}
嗨,我的单位控制马达有问题,我有一个包含立方体的Unity场景,我可以在x轴上滑动这个立方体,我通过COM3发送x值,我在我的Arduino中得到了值将它转换为我的电机的角度。
我的问题是: 当我在Unity中移动立方体时,我的电机旋转但是在我滑动立方体几次之后,团结冻结了15/20秒然后我的电机移动但不是直角。
谁能告诉我问题出在哪里?
答案 0 :(得分:2)
在您的代码中发现了许多错误,我不知道哪个错误导致了问题。修复了所有这些问题。请阅读下面的内容,看看我修复了什么。
1.团结冻结是因为你没有使用Thread
。
2.Arduino很可能因为Serial.println(Tick);
而冻结。它发送到Unity,但你没有从Unity端读取。也许有缓冲区溢出。评论出来了。
3. OnMouseDrag
是一个Unity回调函数。自己从OnMouseUp
函数调用它不是一个好主意。
4.单击立方体的一侧将使其跳转到鼠标的位置。通过添加偏移值来修复它。
5.使用拖动回调函数替换OnMouseDown
,OnMouseDrag
,OnMouseUp
。
6.改变了Arduino端数据的读取方式。已移除Serial.readBytesUntil(lf, myCol, 5);
代码。
7.在致电delay(1);
之前添加Serial.available()
。不要删除它。一些Arduino板需要或者Serial.available()不能按预期运行。
8.删除代码中的所有静态内容。
9.您的字符串未终止。您必须在阅读myCol[index]= '\0';
或myCol[index]= 0
;
我不明白你的角度转换是如何在Arduino方面完成的,所以我保持原样。将每个脚本替换为下面的新脚本,如果出现问题则发表评论。我没有你的电机所以无法测试电机部件。
<强> Arduino的强>:
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(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
}
void loop()
{
//Must delay 1 milliseconds to make Serial.available() work properly
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);
}
发送:
using UnityEngine;
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 = "COM3", 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 UnityEngine;
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);
}
}
确保Sending
和GetPosition
附加到相同的GameObject / Cube。仅使用一个立方体进行测试。