Случайный сброс Arduino Nano
В настоящее время я борюсь с периодически возникающей проблемой в проекте Arduino.
Предыстория
Я использую программу LabVIEW для управления несколькими аппаратными средствами. Одним из них является шаговый двигатель NEMA 17, который приводит в действие реечный привод. Я использую подлинный Arduino Nano с (официальным) драйвером двигателя EasyDriver для управления NEMA 17. Arduino отслеживает состояние DI-контакта, и если он вытянут высоко, он выдвигает стойку до тех пор, пока U-образный датчик не отправит высокий входной сигнал в крайнем крайнем положении, затем он прослушивает, чтобы этот DI-контакт был вытянут низко, и втягивает стойку, пока датчик приближения не отправит высокий входной сигнал. входной сигнал.
В чем проблема
Я заметил, что мой привод либо перестал реагировать на входные сигналы от LabVIEW DAQ, либо застрял в середине срабатывания (у двигателя достаточно крутящего момента для этого приложения). После изменения кода для печати обновлений на последовательный порт я понял, что после нескольких циклов Arduino сбрасывается и снова входит в функцию Setup ().
Я сменил Nano, и это не имело никакого значения. Я впервые использую функцию тайм-аута, и мне было интересно, может ли использование памяти этой функции вызывать проблемы, однако я закомментировал эту часть кода, и Arduino все еще сбрасывается. Код приведен ниже - очень хотелось бы услышать какие-либо мысли о том, может ли это быть аппаратной или программной проблемой. Я подключаю Arduino к сети 7 В от источника питания к порту Vin. Датчик prox работает при 24 В, но я делю напряжение выходного сигнала так, чтобы входное напряжение составляло ~ 4,8 В (я измерил это). Я использую тот же U-образный датчик с несколькими другими Arduino, и я не вижу этой проблемы. В прошлом я подключал ардуино к той же 7-вольтовой линии и также никогда не видел, чтобы они сбрасывались подобным образом.
Дайте мне знать, что вы думаете, спасибо!
const int uSensor = 12;
const int proxSensor = 10;
const int labViewHomePin = 9;
const int labViewInputPin = 8;
const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;
const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;
enum {IdleState, ForwardState, BackwardState} State; // этот случай переключения используется для вызова правильной функции, которая поворачивает двигатель в нужном направлении
boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;
boolean updateGiven = false;
int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;
boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;
void setup() {
Serial.begin(9600);
pinMode(uSensor, INPUT);
pinMode(proxSensor, INPUT);
pinMode(labViewHomePin, INPUT); // инициализация входных контактов
pinMode(labViewInputPin, INPUT); // инициализация входных контактов
pinMode(StepperDirectionPin, OUTPUT); //
pinMode(StepperStepPin, OUTPUT); // Шаг
pinMode(ENPin, OUTPUT); // Включить
Serial.println();
Serial.println("Setup phase called");
Serial.println();
pinMode(labViewInFeedback, OUTPUT);
pinMode(labViewOutFeedback, OUTPUT);
State = IdleState;
digitalWrite(ENPin,HIGH); // По умолчанию диск отключен
homingDone = false;
}
void loop() {
if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
Serial.println("Homing Pin High Detected");
homingRoutine();
homingDone = true;
Serial.print("Homing Done = ");
Serial.println(homingDone);
State = IdleState;
if(digitalRead(proxSensor) == HIGH) {
digitalWrite(labViewInFeedback,HIGH);
digitalWrite(labViewOutFeedback,LOW);
}
else if(digitalRead(uSensor) == HIGH) {
digitalWrite(labViewInFeedback,LOW);
digitalWrite(labViewOutFeedback,HIGH);
}
else {
digitalWrite(labViewInFeedback,LOW);
digitalWrite(labViewOutFeedback,LOW);
}
}
switch (State) {
case IdleState:
boolInitialMove = true;
digitalWrite(ENPin,HIGH);
if(updateGiven == false) {
Serial.println("I am in IdleState");
Serial.print("Pusher Out Boolean = ");
Serial.println(pusherOut);
Serial.print("Pusher In Boolean = ");
Serial.println(pusherIn);
Serial.print("Prox Sensor status: ");
Serial.println(digitalRead(proxSensor));
Serial.print("U-Sensor status: ");
Serial.println(digitalRead(uSensor));
updateGiven = true;
}
if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
digitalWrite(ENPin,LOW); // Включить привод
State = ForwardState;
Serial.println("LabVIEW High detected. Case switched to ForwardState");
Serial.println("");
updateGiven = false;
}
else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
digitalWrite(ENPin,LOW); // Включить привод
State = BackwardState;
Serial.println("LabVIEW Low detected. Case switched to BackwardState");
Serial.println("");
updateGiven = false;
}
else {
// ничего не делать
}
if(digitalRead(uSensor) == HIGH) {
pusherOut = true;
pusherIn = false;
}
else if(digitalRead(proxSensor) == HIGH) {
pusherOut = false;
pusherIn = true;
}
else {
// ничего не делать
}
break;
case ForwardState:
if(updateGiven == false) {
Serial.println("I am in ForwardState");
Serial.print("LabVIEW Actuate Pin = ");
Serial.println(digitalRead(labViewHomePin));
updateGiven = true;
}
if(boolInitialMove == true) {
digitalWrite(StepperDirectionPin, LOW);
rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
startTime = millis();
endTime = startTime;
boolInitialMove = false;
}
endTime = millis();
rotateForward(motorSpeed); // это вызывает функцию ForwardState, которая начинает выталкивать толкатель
if (digitalRead(uSensor) == HIGH) {
digitalWrite(labViewInFeedback,LOW);
digitalWrite(labViewOutFeedback,HIGH);
Serial.println("U-Sensor High detected. Case switched to Idlestate");
Serial.println("");
updateGiven = false;
pusherOut = true;
pusherIn = false;
State = IdleState;
}
else if((endTime-startTime) > timeInitialMove) {
digitalWrite(ENPin,HIGH);
digitalWrite(StepperStepPin, LOW);
digitalWrite(StepperDirectionPin, LOW);
digitalWrite(labViewOutFeedback,HIGH);
digitalWrite(labViewInFeedback,HIGH);
Serial.println("");
Serial.println("**TIMEOUT DETECTED**");
Serial.println("");
State = IdleState;
}
break;
case BackwardState:
if(updateGiven == false) {
Serial.println("I am in BackwardState");
Serial.print("LabVIEW Actuate Pin = ");
Serial.println(digitalRead(labViewHomePin));
updateGiven = true;
}
if(boolInitialMove == true) {
digitalWrite(StepperDirectionPin, HIGH);
rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
startTime = millis();
endTime = startTime;
boolInitialMove = false;
}
endTime = millis();
rotateBackward(motorSpeed);
if (digitalRead(proxSensor) == HIGH) {
digitalWrite(labViewInFeedback,HIGH);
digitalWrite(labViewOutFeedback,LOW); // Отключить диск
Serial.println("Prox Sensor High detected. Case switched to Idlestate");
Serial.println("");
updateGiven = false;
pusherOut = false;
pusherIn = true;
State = IdleState;
}
else if((endTime-startTime) > timeInitialMove) {
digitalWrite(ENPin,HIGH);
digitalWrite(StepperStepPin, LOW);
digitalWrite(StepperDirectionPin, LOW);
digitalWrite(labViewOutFeedback,HIGH);
digitalWrite(labViewInFeedback,HIGH);
Serial.println("");
Serial.println("**TIMEOUT DETECTED**");
Serial.println("");
State = IdleState;
}
break;
} // конечный выключатель
}
void rotateForward(int mtrSpeed) {
digitalWrite(StepperDirectionPin, LOW);
digitalWrite(StepperStepPin, HIGH);
delayMicroseconds(mtrSpeed);
digitalWrite(StepperStepPin, LOW);
}
void rotateBackward(int mtrSpeed) {
digitalWrite(StepperDirectionPin, HIGH);
digitalWrite(StepperStepPin, LOW);
delayMicroseconds(mtrSpeed);
digitalWrite(StepperStepPin, HIGH);
}
void homingRoutine() {
digitalWrite(ENPin,LOW);
Serial.println("Homing Routine called");
bool firstCycle = false;
bool secondCycle = false;
bool thirdCycle = false;
bool fourthCycle = false;
while(digitalRead(uSensor) != HIGH) {
rotateForward(rampStartSpeed);
}
delay(500);
Serial.println("First home movement completed");
while(digitalRead(proxSensor) != HIGH) {
rotateBackward(rampStartSpeed);
}
delay(500);
Serial.println("Second home movement completed");
while(digitalRead(uSensor) != HIGH) {
rotateForward(rampStartSpeed);
}
delay(500);
Serial.println("Third home movement completed");
while(digitalRead(proxSensor) != HIGH) {
rotateBackward(rampStartSpeed);
}
delay(500);
homingDone = true;
pusherIn = true;
pusherOut = false;
}
int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
int countedSteps = 0;
float amp = ((startSpeed-maximumSpeed)/2);
for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
digitalWrite(StepperStepPin, LOW);
delayMicroseconds(currentSpeed);
digitalWrite(StepperStepPin, HIGH);
countedSteps++;
}
return countedSteps;
}
@Jay, 👍3
Обсуждение2 ответа
Лучший ответ:
Спасибо вам всем за ваш вклад. Мне удалось найти проблему и решить проблему с прерывистым сбросом. Я ожидал найти аппаратную проблему в качестве основной причины, но на всякий случай, если это было связано с программным обеспечением, я тоже хотел проверить. Это оказалось аппаратным обеспечением
Гил, безусловно, ставит под сомнение правильность выбора оборудования. Это действительно была проводка датчика Prox. Я подключил как общие рельсы передачи данных, так и питания, чтобы облегчить работу датчика prox, но при проверке я решил оставить их раздельными, а напряжение разделить датчик prox подальше от рельсов и вместо этого подключить прямую линию 4,8 В к Arduino. Какой бы шум ни создавал шаговый двигатель, он не мог повлиять на линии передачи данных Arduino, и с тех пор я не видел, чтобы проблема возвращалась.
Очень ценю вашу помощь всем. Я не подключал линии питания к Arduino, так как проблема продолжалась независимо от того, что я подключал arduino только через COM-порт ПК, комбинацию COM-порта и 7V к линии Vin (предположим, что Arduino подключается к линии 7V, но я не уверен) и только Линия 7В. По-видимому, это был шум, нарушающий общую магистраль передачи данных Arduino.
Я ожидаю, что у вас много работы над вашим дизайном. Деление вниз никогда не является хорошим источником напряжения (мощности), независимо от того, что вы измеряете, если только вы не используете хороший прицел для измерения и его хорошо обходят стороной. Подумайте о понижающем регуляторе от одного из китайских поставщиков, он стоит всего несколько долларов и стабилизирует вашу цепь. Если датчик prox потребляет всего несколько мельниц, подумайте о том, чтобы запитать его от Arduino напряжением 5 вольт. Двигатели, как и другие индуктивные устройства, генерируют множество транзисторов, которые одновременно проводятся и излучаются, что-то подобное может попадать в вашу систему, возможно, через датчик prox. Это должно помочь вам начать.
- Как сбросить или отформатировать Arduino?
- Ошибка модуля часов реального Времени-DS3231
- Как мигать светодиодом и одновременно запускать другой код?
- Сброс при включении с Arduino Uno не происходит. Можно ли это исправить?
- Может ли Arduino UNO постоянно хранить код?
- Декодирование порта VGA с помощью Arduino
- Можно ли отправить 2 или более сигнала o/p одновременно?
- Светодиодный матричный модуль FC-16 на базе MAX7219
Можете ли вы отслеживать линии Vin и +5 В с помощью прицела _ во время работы шагового движка_? Электродвигатели могут создавать шум и нестабильность в источниках питания., @Edgar Bonet
Ваш счетчик * может * также иметь минимальный режим, который отслеживает минимальное напряжение, наблюдаемое с момента запуска. Это не так хорошо, как использование прицела, как предлагает Эдгар, но иногда это может помочь., @timemage