Paso 11: Motor de inducción lineal - alimentación y controles
Al principio usamos protectores de Adafruit controlador del Motor para proporcionar energía a las bobinas. Los pines de salida digital del Arduino proporcionan 5volts en una corriente más bien baja. El escudo del regulador del motor utiliza la pequeña señal digital para enviar hasta 1 amperio de corriente a los motores, en este caso nuestras bobinas. Para utilizar las tablas de Adafruit que también utilizamos la biblioteca de código de Arduino que proporcionan. Aunque esto hizo el trabajo y mueve el coche, no se movió lo fuertemente.
Finalmente optó por construir tablero de conductor del propio utilizando piezas de tiendas de electrónica de salvamento en la zona. Nuestro propio Consejo, circuito de cada bobina puede alojar a un máximo de 8 amperios de corriente y cada conductor puede alimentar las bobinas de ambos lados del coche que se activan juntas (cableados en paralelo). Habíamos estado usando una fuente de alimentación de 12 voltios. Para aumentar la potencia a las bobinas que compramos una fuente de alimentación 10 amperios 24 voltios. Estos venden bastante barato en línea para tiras de LED de potencia, y funcionan muy bien para nuestro propósito.
Para el acercamiento final para los controles se utilizó un Arduino Mega puesto que tenía un montón de pines analógicos y digitales disponibles. El sketch de Arduino (programa) es bastante simple en que bucles alrededor de mirar cada sensor y decidir si hay una lectura significativa y si es así, es al norte o al sur. Si es norte, bobina de ese sensor es convertido a sur (para que se tire). Y vice-versa.
Para primeras pruebas hemos utilizado un pequeño coche de madera en las ruedas y un único conjunto de bobinas. En un momento ya estaba empezando a trabajar, observamos "cogging", tartamudeo de las bobinas tirando los imanes de una manera desigual. En el sketch de Arduino tuvimos Serial.print comandos envío de lecturas a la consola para ver lo que sucedía. Eliminación de las declaraciones de Serial.print aceleró el bosquejo así se movió el coche pequeño de madera muy bien.
En otro punto en la prueba, ponemos en las marcas de tiempo al principio y al final del bucle para ver cuánto tiempo todo estaba tomando. El lazo llevó 20 a 25 milisegundos. Esto es demasiado lento para reaccionar a un coche en movimiento en nuestro esperado de 20 pies por segundo. He intentado sacar las llamadas a la biblioteca de Adafruit y el tiempo fue abajo a entre 0 y 1 milisegundo. Vale. Confirmó la decisión de hacer nuestro propio conductor de la energía.
Lista de herramientas y componentes
Tools - see general list of Tools Components o 24v 10A Power Supply – Ebay $22 o Arduino Mega – Ebay $20 o Toggle switch o Controller/Driver Board o Part # quantity price cost o TIP122 16 0.59 9.44 o Tip125 16 0.49 7.84 o 1n4148 16 0.05 0.8 o IN5231 16 0.09 1.44 o 2n3904 8 0.12 0.96 o resistors 40 0.04 1.6 o Proto PCB 1 5 5 TOTAL 27.08
Este es el dibujo utilizado para ejecutar los motores.
/* LinMotorIndepCoil For use with the Adafruit Motor Shield v2 Version 01 - Independent Sensor/Coil sets, up to 4 sets per motor board Assumes car with PMs is pushed into first sensor/coil pair Permanent magnets are spaced w alternating polarity on car so when pulling on one PM, there will be pushing on the previous. Version 02 - abandon resing/falling tests and use static value of sensors to set coils. Use Serial input to adjust sensor sensitivity Version 03 - log times for coils on/off etc and save timings for print later when interrupt tripped Set timeouts to prevent coils from staying on too long Version 04 - no more Adafruit motor shields - 8 coil pairs */ //#include <Wire.h> int hallPin[] = {0,1,2,3,4,5,6,7}; // analog pins for Hall sensors int coilN[] = { 34, 30, 28, 22, 36, 32, 26, 24 }; // digital pins for setting coil to N int coilS[] = { 35, 31, 29, 23, 37, 33, 27, 25 }; // digital pins for setting coil to S #define HowMany 8 // how many sensor/coil pairs we have int hallVal[] = {0,0,0,0,0,0,0,0 }; //saved values for Hall sensors int hallTrim[] = {0,0,0,0,0,0,0,0 }; // value to be subtracted so // "no field detected" will read 0 #define hallThresh 60 // what reading is significant #define coilMaxTime 1000 //one second should be plenty of time long coilHoldTimeS[HowMany] = {0,0,0,0,0,0,0,0}; // to prevent staying on too long long coilHoldTimeN[HowMany] = {0,0,0,0,0,0,0,0}; // to prevent staying on too long long coilOnTimeS[HowMany] = {0,0,0,0,0,0,0,0}; // when coil came on - first S magnet only long coilOffTimeS[HowMany] = {0,0,0,0,0,0,0,0}; // when coil came off long coilOnTimeN[HowMany] = {0,0,0,0,0,0,0,0}; // when coil came on - first N magnet only long coilOffTimeN[HowMany] = {0,0,0,0,0,0,0,0}; // when coil came off volatile boolean printFlag = false; // flag to indicate button pushed to start printing //long testStart = 0; //long testEnd = 0; //String sense = "0"; void setup() { Serial.begin(9600); // set up Serial library at 9600 bps Serial.println("Starting LinMotorIndepCoil04"); for (int i=0; i< HowMany; i++) { //make sure coils are off pinMode(coilN[i], OUTPUT); digitalWrite(coilN[i], LOW); // set N pin to low pinMode(coilS[i], OUTPUT); digitalWrite(coilS[i], LOW); // set S pin to low } for (int i=0; i < HowMany; i++) { //set sensor trim values assuming no field initially hallTrim[i] = analogRead(hallPin[i]); //sb close to 0 if no field } pinMode(2, INPUT); // set up interrupt on pin 2 digitalWrite(2, HIGH); attachInterrupt(0, setPrintFlag, FALLING); //pin 2 is interrupt 0 } void loop() { //testStart = millis(); if (printFlag == true) printStats(); // button pushed, take time to print stats // look at each of the active sensors to see how its coil should be set for (int i=0; i < HowMany; i++) { int testVal = analogRead(hallPin[i]) - hallTrim[i]; //sb close to 0 if no field if (testVal > hallThresh) { // South pole PM detected // sense = "S"; //Serial.print("South testVal=");Serial.print(testVal); //Serial.print(" i=");Serial.println(i); digitalWrite(coilN[i], HIGH); // set N pin to high digitalWrite(coilS[i], LOW); // set S pin to low coilHoldTimeN[i] = 0; // reset N hold time if (coilHoldTimeS[i] == 0) { coilHoldTimeS[i] = millis(); //save the time } if (coilOnTimeS[i] == 0) { coilOnTimeS[i] = millis(); //save the time for 1st magnet only } if (millis()- coilHoldTimeS[i] > coilMaxTime) { turnOffCoils(i); // if coil has been S too long, turn it off } } else if (testVal < -hallThresh) { // North //sense = "N"; //Serial.print("North testVal=");Serial.print(testVal); //Serial.print(" i=");Serial.println(i); digitalWrite(coilN[i], LOW); // set N pin to low digitalWrite(coilS[i], HIGH); // set S pin to high coilHoldTimeS[i] = 0; // reset S hold time if (coilHoldTimeN[i] == 0) { coilHoldTimeN[i] = millis(); //save the time } if (coilOnTimeN[i] == 0) { coilOnTimeN[i] = millis(); //save the time for 1st magnet only } if (millis()- coilHoldTimeN[i] > coilMaxTime) { turnOffCoils(i); // if coil has been N too long, turn it off } } else { // no signigicant reading // sense = "0"; //Serial.print("Neither testVal=");Serial.print(testVal); //Serial.print(" i=");Serial.println(i); turnOffCoils(i); //they get turned off, // but the coilHoldTime doesn't get reset } } //testEnd = millis(); // Serial.print("test ms=");Serial.print(testEnd - testStart);Serial.print(" ");Serial.println(sense); // delay(2000); } void turnOffCoils(int i) { //Serial.println("turnOffCoils"); digitalWrite(coilN[i], LOW); //turn off the coil digitalWrite(coilS[i], LOW); // if (coilOnTimeS[i] > 0 && coilOffTimeS[i] == 0) { //first time S off for this coil coilOffTimeS[i] = millis(); //time stamp it } if (coilOnTimeN[i] > 0 && coilOffTimeN[i] == 0) { //first time N off for this coil coilOffTimeN[i] = millis(); //time stamp it } // leave coilHoldTime as it is until magnet polarity changes } void setPrintFlag() { //interrupt service routine printFlag = true; } void printStats() { //only do this if interrupt happens for (int i=0; i < HowMany; i++) { //for each of 4 coils Serial.print("Coil "); Serial.print(i+1); Serial.print(" S On Time "); Serial.println(coilOffTimeS[i] - coilOnTimeS[i]); Serial.print("Coil "); Serial.print(i+1); Serial.print(" N On Time "); Serial.println(coilOffTimeN[i] - coilOnTimeN[i]); } printFlag = false; for (int i=0; i < HowMany; i++) { //reset counters after printing coilOnTimeS[i] = 0; coilOnTimeN[i] = 0; coilOffTimeS[i] = 0; coilOffTimeN[i] = 0; } }
Este es el dibujo utilizado para probar los sensores y las bobinas.
/* CoilTest3 to work with hall sensors and our own motor driver board reads all the sensors and prints the value reads input 1-8 from serial and turns that coil to North for 5 seconds */ int hallsave[8]; //no-reading value for setting sensor reading to zero int halls[8]; int coilN[] = { 34,30,28,22,36,32,26,24}; // digital pins for setting coil to N - arranged for jumper geography int coilS[] = { 35,31,29,23,37,33,27,25}; // digital pins for setting coil to S #define howMany 8 void setup() { //while (!Serial); Serial.begin(9600); // set up Serial library at 9600 bps Serial.println("CoilTest3"); Serial.println("Input 1 thru 8 to run specific coil pair for 5 seconds"); for(int i=0;i<howMany;i++) { // save no-reading values hallsave[i] = analogRead(i); } // make sure all coils are off for(int i=0;i<howMany;i++) { pinMode(coilN[i], OUTPUT); digitalWrite(coilN[i], LOW); pinMode(coilS[i], OUTPUT); digitalWrite(coilS[i], LOW); } } // int i; void loop() { for(int i=0;i<howMany;i++) { halls[i] = analogRead(i) - hallsave[i]; //sb close to 0 if no field Serial.print(halls[i]); Serial.print(" "); // debug value } Serial.println(""); delay(1000); char cmd ; if (Serial.available()) { cmd = Serial.read(); //read character from serial } else return; if (cmd >= '1' && cmd <='8') { int x=cmd-48; digitalWrite(coilN[x - 1], HIGH); // turn on coil set to N Serial.print("testing #"); Serial.println(x); delay(2000); Serial.println("off"); digitalWrite(coilN[x-1], LOW); // turn off both coils of pair } }