0

所以我决定做一个简单的卫星跟踪器。我使用 Orbitron 作为我的跟踪软件。它有一个内置的 DDE 服务器,所以我可以通过 java 连接到它。所以我用java编写了一个小应用程序,它连接并从Orbitron读取有关卫星的数据进行一些计算(比如计算误差并在误差太大而无法最小化它时应用额外的步骤)并将数据发送到arduino uno over串行控制两个步进器(目前只是海拔一个)。

我的问题是,当我开始将数据发送到 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 秒。但还是一无所获。步进器只是不想旋转正确的方向和数量。

谢谢你的帮助!

PS:数据包格式为:

PACKET_TYPE:PACKET_DATA;

PACKET_TYPE 是 AZ(旋转方位角)、EL(旋转仰角)、RL(释放 PACKET_DATA 中指定的电机)和 HL(保持 PACKET_DATA 中指定的电机)。

这适用于从主循环中的串行端口读取的所有内容。

4

1 回答 1

0

这是我的建议。验证发送到 Arduino 的所有数据是否正确。完成后,保持代码简单。从头开始,我的意思是让它保持正值和单向运动。您甚至可以取出高程并先旋转它。验证这是否有效,然后继续进行海拔高度。

PS: setSpeed(10) 函数中的 10 表示什么?

于 2015-11-14T09:08:17.923 回答