El servo a veces se congela cuando se usa con otro servo y lector RFID MFRC522

1

He mirado, he buscado en Google y he investigado por todas partes hasta ahora y no he podido encontrar a nadie que tenga un problema similar al mío, así que pensé que ahora sería el momento de hacer mi propia pregunta sobre SE.

Si funciona correctamente, mi circuito haría lo siguiente:

  1. El lector RFID lee una etiqueta válida, el Servo NFC debe girar de 0 a 90 grados y permanecer allí.
  2. El usuario hace clic en un botón.
  3. El Servidor del dispensador comienza a 160 grados, luego a 180 grados, luego a 30 grados, y luego vuelve a 160 grados.
  4. El Servo NFC vuelve a 0 grados.

Sin embargo, lo que sucede ocasionalmente es que el Servo NFC tiembla de regreso a 0, y luego, la próxima vez que se lea una etiqueta RFID, girará a lo que parece ser 180 o quizás más. Después de esto, el Arduino ya no puede enviar señales al servo NFC, pero el servo del dispensador sigue funcionando bien, al igual que el lector RFID. Al reiniciar el Arduino, al presionar el botón Restablecer, se restablece la conexión con el Servo NFC para que funcione un par de veces, pero siempre se congela en poco tiempo.

El circuito completo incluye un Arduino Uno R3, un escudo Ethernet, dos servos, un lector RFID, 2 botones con LED incorporado y 4 LED blancos. No creo que los botones o los LED sean el problema, así que para no sobrecargar a las personas amables con información, este es un esquema simplificado del circuito:

Delmismomodo,estaesunaversiónsimplificadadelcódigoArduino:

//Includes#include<SPI.h>#include<MFRC522.h>#include<Ethernet.h>#include<Servo.h>//Ethernetvariablesstaticuint8_tmac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0x01};staticuint8_tmyip[]={10,0,0,200};IPAddresspc_server(10,0,0,31);//TheaddresstosendtoviaEthernetEthernetClientclient;//RFIDvariables#defineRST_PIN9#defineSS_PIN8MFRC522mfrc522(SS_PIN,RST_PIN);//CreateMFRC522instancebooleancardPresent=false;booleancardPresent_old=false;StringcardID="";
String cardID_old = "";

// Servo variables
Servo servoNFC;
Servo servoDispenser;

#define servoNFCPin A2
#define servoDispenserPin A4

// Positions for the Servos in angles
int posNFC = 0;
int posNFCClosed = 90;
int posDispenser = 160;

// System variables
boolean hasReadNFC = false;
boolean hasDispensed = false;
String languageChosen = "";

void setup() {
  Serial.begin(9600);

  SPI.begin();
  mfrc522.PCD_Init(); // Init MFRC522 (RFID reader)

  Ethernet.begin(mac, myip);

  delay(5000); // wait for Ethernet card
  activateEthernetSPI(false);

  // Attach servos
  servoNFC.attach(servoNFCPin);
  servoDispenser.attach(servoDispenserPin);

  servoNFC.write(posNFC);
  servoDispenser.write(posDispenser);

  // Ready to start
  Serial.println("Ready");

}

void loop() {
  // PHASE 1 : Check for a token
  if (!hasReadNFC) {
    checkForNFC();
  }

  // PHASE 2 : check for button presses
  // Omitted for simplification

  // PHASE 3 : Dispense with servo
  if (hasReadNFC) {
    dispense();
    printDiagnosis();
  }

}

// CHECKS FOR A PRESENTED NFC TAG (TOKEN)
void checkForNFC() {

  if(cardPresent) {
    if ( mfrc522.PICC_ReadCardSerial()) {
      getID();
    }
    hasReadNFC = true;
    delay(500);

    closeNFCServo(); // Close NFC coin slot
  }

  if ( mfrc522.PICC_ReadCardSerial()) {
    getID();
  }

  cardPresent_old = cardPresent;

  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    cardPresent = false;
    return;
    delay(10);
  }

  cardPresent = true;

  delay(10);
}

// DISPENSES WITH SERVODISPENSER
void dispense() {
  servoDispenser.write(160);
  delay(2000);
  servoDispenser.write(180);
  delay(500);
  servoDispenser.write(30);

  delay(2000);
  servoDispenser.write(160);

  hasDispensedPill = true;
}

// PRINT RECEIPT
void printReceipt() {
  Serial.println("Printing");
  submitData();
}

// RESET THE SYSTEM
void resetSystem() {
  hasReadNFC = false;
  hasDispensed = false;

  openNFCServo();
}

void submitData() {

  activateEthernetSPI(true);

  String datastring = "GET /machine//readval.php?tag=" + String(cardID) + " HTTP/1.0";

  if(client.connect(pc_server,80)) {
      client.println(datastring);
      client.println("Connection: close");
      client.println();
      client.stop();
      delay(100);
    }


  activateEthernetSPI(false);
  resetSystem();
}

void activateEthernetSPI(boolean x) {
  // change SPI/Slave... turn RFID shield off, ethernet on (LOW=on)
  // http://tronixstuff.com/2011/05/13/tutorial-arduino-and-the-spi-bus/

  digitalWrite(SS_PIN,x);
  digitalWrite(10,!x);
}

void closeNFCServo() {
  for (posNFC = 0; posNFC <= posNFCClosed; posNFC += 1) {
    servoNFC.write(posNFC);
    delay(10);
  }
  return;
}

void openNFCServo() {
  for (posNFC = posNFCClosed; posNFC >= 0; posNFC -= 1) {
    servoNFC.write(posNFC);
    delay(10);
  }
  return;
}


void getID() {
  String  cardIDtmp = "";
  for (byte i = 0; i < 3; i++) {
    byte tmp = (mfrc522.uid.uidByte[i]);
    cardIDtmp.concat(tmp);
  }

  // has ID changed?
  if (cardIDtmp != cardID_old) {
    cardID = cardIDtmp;
    cardID_old = cardID;
  }
}

Ya lo he intentado (sin éxito):

  1. Asegurándose con demoras de que los servos no se ejecuten simultáneamente.
  2. Separando cada servo después de que haya terminado con su tarea.
  3. Reemplazo del Servo NFC

Actualmente estoy considerando obligar a Arduino a reiniciarse a través del software (usando el temporizador de vigilancia o el truco asm volatile (" jmp 0"); ) después de cada iteración, pero es una solución un tanto desordenada, por lo que definitivamente prefiero algo más confiable.

Estoy en mi punto final, ¡así que realmente espero que alguno de ustedes haya tenido un problema similar!

    
pregunta jepster

0 respuestas

Lea otras preguntas en las etiquetas