所以我决定制作一个简单的卫星跟踪器。我使用Orbitron作为跟踪软件。它有一个内置的DDE服务器,所以我可以通过java连接到它。所以我在java中编写了一个小应用程序,连接并读取有关Orbitron卫星的数据进行一些计算(比如计算错误并在错误太大而无法最小化时应用其他步骤)并将数据发送到arduino uno over serial控制两个步进器(当前只是一个步进器)。
我的问题是,当我开始将数据发送到arduino时,第一个数据包会被处理并使电机正确旋转方向和数量,但之后发送的每个其他数据包只会将其旋转错误的方向和/或数量,它没有任何效果,或只是让步进开始像疯了一样旋转。
我确实尝试为Adafruit Stepper Shield(我正在使用)上传示例草图,一切都运行得很好。显然我的arduino代码存在问题。
他是:
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); //Create the Adafruit_MotorShield object
float singleStepAzim; //Store the size of the azimuth stepper single step
float singleStepElev; //Store the size of the elevation stepper single step
void setup() {
Serial.begin(9600); //Start the serial comunication
AFMS.begin(); //Start the motor shield
/**Wait until data is available on the serial port**/
while(Serial.available() <= 0){
;
}
singleStepAzim = Serial.readStringUntil(':').toFloat(); //Read and store the value of a single azimuth step
singleStepElev = Serial.readStringUntil(';').toFloat(); //Read and store the value of a single elevation step
}
/**Create StepperMotor objects based on their single step size**/
Adafruit_StepperMotor *azimMotor = AFMS.getStepper(360 / singleStepAzim, 1);
Adafruit_StepperMotor *elevMotor = AFMS.getStepper(360 / singleStepElev, 2);
/**Same thing just by using static values**/
/*Adafruit_StepperMotor *azimMotor = AFMS.getStepper(360 / 7.5, 1);
Adafruit_StepperMotor *elevMotor = AFMS.getStepper(360 / 7.5, 2);*/
void loop() {
/**Read the data if available**/
if(Serial.available() > 0){
/**Read the type and the content of the packet**/
String type = Serial.readStringUntil(':');
String data = Serial.readStringUntil(';');
/**'type' == AZ - move the relavant stepper by 'data'**/
if(type.equals("AZ")){
//Move azimuth
azimMotor->setSpeed(10); //Set the speed
/**If the 'data' if negative then turn it backwards**/
if(data.toInt() < 0){
azimMotor->step(-data.toInt(), BACKWARD, INTERLEAVE); //USE SINGLE ??
}else{
azimMotor->step(data.toInt(), FORWARD, INTERLEAVE); //USE SINGLE ??
}
/**'type' == EL - move the relavant stepper by 'data'**/
}else if(type.equals("EL")){
//Move elevation
elevMotor->setSpeed(10); //Set the speed
/**If the 'data' if negative then turn it backwards**/
if(data.toInt() < 0){
elevMotor->step(-data.toInt(), BACKWARD, INTERLEAVE); //USE SINGLE ??
}else{
elevMotor->step(data.toInt(), FORWARD, INTERLEAVE); //USE SINGLE ??
}
/**'type' == RL - release the motor specified in 'data'**/
}else if(type.equals("RL")){
if(data == "AZ"){
azimMotor->release();
}else if(data == "EL"){
elevMotor->release();
}
/**'type' == HL - hold the motor specified in 'data' in place**/
}else if(type.equals("HL")){
if(data == "AZ"){
azimMotor->step(1, FORWARD, SINGLE);
azimMotor->step(1, BACKWARD, SINGLE);
}else if(data == "EL"){
elevMotor->step(1, FORWARD, SINGLE);
elevMotor->step(1, BACKWARD, SINGLE);
}
}
}
}
首先我认为问题在于我使用序列来设置单步值,但显然情况并非如此。我的下一个想法是arduino需要花费太多时间来处理所有内容,因此我将数据发送的间隔时间从0.5秒更改为1秒,然后一直更改为10秒。但仍然没有。步进器只是不想旋转正确的方向和数量。
感谢您的帮助!
P.S。:数据包格式为:
PACKET_TYPE:PACKET_DATA;
PACKET_TYPE为AZ(旋转方位角),EL(旋转高度),RL(释放PACKET_DATA中指定的电机)和HL(保持PACKET_DATA中指定的电机)。
这适用于从主循环中的串行端口读取的所有内容。
答案 0 :(得分:0)
这是我的建议。验证发送到Arduino的所有数据是否正确。完成后,保持代码简单。从头开始,我的意思是保持正值和单向运动。您甚至可以取出高程并先旋转它。验证这是否有效,然后继续升高。
P.S:在setSpeed(10)函数中10表示什么?