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:
- El lector RFID lee una etiqueta válida, el Servo NFC debe girar de 0 a 90 grados y permanecer allí.
- El usuario hace clic en un botón.
- El Servidor del dispensador comienza a 160 grados, luego a 180 grados, luego a 30 grados, y luego vuelve a 160 grados.
- 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):
- Asegurándose con demoras de que los servos no se ejecuten simultáneamente.
- Separando cada servo después de que haya terminado con su tarea.
- 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!