Arduino 무인 프로젝트는 출력이로드 될 때마다 (ESC에 "개방 회로"신호 핀 또는 심지어 지상 캡), 입력 "조향"명령은 글리치를 시작합니다 (실제 낮은 값인 < <).Arduino Drone 프로젝트는 출력이 "로드"될 때까지 (심지어 cap에서 GND로) 입력 "조향"명령이 흐트러지기 시작합니다.
모터 속도는 조향 명령과 스로틀의 기능입니다. (아래의 코드에서 보듯이 하나의 모터 만있는이 테스트 케이스에서, unMotorSpeed = unThrottleIn +/- unSteeringIn)
스코프에 연결되면 물리적 입력 신호 (수신기에서 오는 스티어링 및 스로틀)는 다음과 같습니다. 그리고 수신기와 arduino 사이에 문제가 없는지 확인하기 위해 입력 핀을 바꿨습니다. 문제는 소프트웨어에서 오는 것 같지만, "로드"가 연결되어 있지 않을 때 입력 및 출력 값이 모두 훌륭하고 깨끗한 상태이므로 의미가 없습니다. (필자는 때때로 회로를 완성하기 위해 접지하지 않은 전자 속도 컨트롤러 (ESC)에 대한 수퍼 하이 임피던스 입력 신호이기 때문에 "로드"를 따옴표로 묶습니다.)
누구든지 코드를 확인하고 내가 누락 된 부분이 있는지 확인할 수 있습니까?
이 시점에서 다소 빠른 해결 방법은 새로운 글리치 값을 모터에 쓰지 않고 새 속도가 이전 속도보다 현저히 낮을 때마다 이전 속도 값을 유지하는 것입니다 (이 속도는 50khz 이상입니다). 그래서 분명히 한 걸음 만에 엄청난 도약이 조금 미친 것입니다.)
참고 : 코드에서 unMotorSpeed의 총 출력은 servoThrottle 핀에서 나옵니다. 원래의 명명 방식을 바꾸지는 않았지만 ... 코드를 읽고 모든 변수를 보면 분명합니다.
업데이트 : 이상한 것은 설정을 변경하지 않고 모든 작업을하지 않고 실행 한 것입니다. arduino를 여러 번 재검토하여 운이 좋지 않은 글리치가 아닌지 확인했습니다. 쪽으로. 그런 다음 리모콘을 바닥에 놓고 브레드 보드에있는 몇 개의 전선을 움직이면 설치가 다시 끝난 후 모든 것이 바뀌 었습니다. Idk 무엇을해야합니다!
// --> starting code found at: rcarduino.blogspot.com
// See related posts -
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
with.html
#include <Servo.h>
// Assign your channel in pins
#define THROTTLE_IN_PIN 3
#define STEERING_IN_PIN 2
// Assign your channel out pins
#define THROTTLE_OUT_PIN 9
//#define STEERING_OUT_PIN 9
// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
//Servo servoSteering;
// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;
// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
//uint32_t ulAuxStart;
void setup()
{
Serial.begin(9600);
// attach servo objects, these will generate the correct
// pulses for driving Electronic speed controllers, servos or other devices
// designed to interface directly with RC Receivers
servoThrottle.attach(THROTTLE_OUT_PIN);
// using the PinChangeInt library, attach the interrupts
// used to read the channels
attachInterrupt(digitalPinToInterrupt(THROTTLE_IN_PIN), calcThrottle,CHANGE);
attachInterrupt(digitalPinToInterrupt(STEERING_IN_PIN), calcSteering,CHANGE);
}
void loop()
{
// create local variables to hold a local copies of the channel inputs
// these are declared static so that thier values will be retained
// between calls to loop.
static uint16_t unThrottleIn;
static uint16_t unSteeringIn;
static uint16_t difference;
static uint16_t unMotorSpeed; // variable that stores overall motor speed
static uint8_t bUpdateFlags; // local copy of update flags
// check shared update flags to see if any channels have a new signal
if(bUpdateFlagsShared)
{
noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables
// take a local copy of which channels were updated in case we need to use this in the rest of loop
bUpdateFlags = bUpdateFlagsShared;
// in the current code, the shared values are always populated
// so we could copy them without testing the flags
// however in the future this could change, so lets
// only copy when the flags tell us we can.
if(bUpdateFlags & THROTTLE_FLAG)
{
unThrottleIn = unThrottleInShared;
}
if(bUpdateFlags & STEERING_FLAG)
{
unSteeringIn = unSteeringInShared;
}
// clear shared copy of updated flags as we have already taken the updates
// we still have a local copy if we need to use it in bUpdateFlags
bUpdateFlagsShared = 0;
interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
// as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
// service routines own these and could update them at any time. During the update, the
// shared copies may contain junk. Luckily we have our local copies to work with :-)
}
//Serial.println(unSteeringIn);
// do any processing from here onwards
// only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
// variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by
// the interrupt routines and should not be used in loop
// the following code provides simple pass through
// this is a good initial test, the Arduino will pass through
// receiver input as if the Arduino is not there.
// This should be used to confirm the circuit and power
// before attempting any custom processing in a project.
// we are checking to see if the channel value has changed, this is indicated
// by the flags. For the simple pass through we don't really need this check,
// but for a more complex project where a new signal requires significant processing
// this allows us to only calculate new values when we have new inputs, rather than
// on every cycle.
///// if-else chain commented out to determine/prove problem with steering signal --> buggy!
if(unSteeringIn < 1400) // if steering joystick moved left
{
difference = 1400 - unSteeringIn;
if(unThrottleIn - difference >= 0)
unMotorSpeed = unThrottleIn - difference;
}
else if(unSteeringIn > 1550) //if steering joystick moved right (needs to be tweaked, but works for now)
{
difference = unSteeringIn - 1600;
if(unThrottleIn + difference < 2000)
unMotorSpeed = unThrottleIn + difference;
}
else
{
unMotorSpeed = unThrottleIn;
}
//Serial.println(unMotorSpeed);
//Serial.println(unSteeringIn);
//Serial.println(unThrottleIn);
if(bUpdateFlags)
{
//Serial.println(servoThrottle.readMicroseconds());
if(servoThrottle.readMicroseconds() != unMotorSpeed)
{
servoThrottle.writeMicroseconds(unMotorSpeed);
Serial.println(unMotorSpeed);
}
}
bUpdateFlags = 0;
}
// simple interrupt service routine
void calcThrottle()
{
// if the pin is high, its a rising edge of the signal pulse, so lets record its value
if(digitalRead(THROTTLE_IN_PIN) == HIGH)
{
ulThrottleStart = micros();
}
else
{
// else it must be a falling edge, so lets get the time and subtract the time of the rising edge
// this gives use the time between the rising and falling edges i.e. the pulse duration.
unThrottleInShared = (uint16_t)(micros() - ulThrottleStart); // pulse duration
// use set the throttle flag to indicate that a new throttle signal has been received
bUpdateFlagsShared |= THROTTLE_FLAG;
}
}
void calcSteering()
{
if(digitalRead(STEERING_IN_PIN) == HIGH)
{
ulSteeringStart = micros();
}
else
{
unSteeringInShared = (uint16_t)(micros() - ulSteeringStart); // pulse duration
bUpdateFlagsShared |= STEERING_FLAG;
}
}
당신이 결함의 성격에 대한보다 구체적인 수 있을까? 어떤 범위의 가치를 기대하며 어떤 가치 범위를 준수합니까? 소프트웨어로 패스 필터를 추가하고 특정 실제 너비의 펄스에 대한 값만 허용 할 수 있습니다. – Tim
이 질문을 다듬을 수도 있습니다. 다소 장황하고 혼란 스럽습니다. 예를 들어, SO의 문맥에서 나는 첫 번째 문장을 "* Arduino 프로젝트 (즉, 컴파일 된 코드)의 출력이로드 될 때마다 (즉, 플래시로 레코딩) ... *"라고 즉시 해석합니다. 말이되지 않는다. * output * 및 * loaded *라는 용어는이 맥락에서 모호 합니다만, 분명히 내가 의도 한 해석을 의도하지 않았습니다. 전기 부하로서의 "부하"의 의미 에서조차, "개방 회로"는 실제로 * 전혀 부하가 걸리지 않기 때문에, 나는 당신이 의미하는 바에 관해서는 분명하지 않다. – Clifford
'unSteeringIn'의 유효 범위는 얼마입니까? 통계는 모두 0으로 초기화되지만 사용되기 전에 모든 경로에서 유효한 값이 지정되는 것처럼 보이지는 않습니다. 실제 값으로 초기화 할 수 있습니다. – Clifford