Hamsterloop (11 / 14 steg)

Steg 11: Linjär asynkronmotorn - makt och kontroller



Först använde vi Adafruit Motor Controller sköldar för att ge ström till spolarna. Arduino digital utgång stiften ger 5volts på en ganska låg ström. Motor controller skölden använder små digitala signalen för att skicka upp till 1 Amp av makt till motorer, i detta fall våra spolar. Att använda Adafruit styrelser vi använde också bibliotek för Arduino kod ger de. Trots detta fungerade och flyttade bilen, rörde det sig inte det starkt.

Så småningom valde vi för att bygga ut egna förare ombord med delar från elektroniska bärgning butiker i området. Med vår egen styrelse, varje spole krets rymmer en topp på 8 ampere ström, och varje förare kan driva spolarna på båda sidor av bilen som aktiveras tillsammans (wired parallellt). Vi hade använt en 12 volts strömkälla. För att öka kraften att spolarna köpte vi en 10 Amp 24 volts strömkälla. De säljer dessa ganska billigt online att driva LED strips, och de fungerar bra för vårt syfte.

För den slutlig inflygning för kontroller använde vi en Arduino Mega eftersom det hade massor av analoga och digitala pins tillgängliga. Arduino skiss (program) är är ganska enkel eftersom det loopar runt titta på varje sensor och besluta om det finns en betydande behandling och i så fall det norr eller söder. Om det är norr, att sensorn spole visade på söder (så det kommer att dra). Och vice versa.

För tidigt provande använde vi en liten bil i trä på hjul och en enda uppsättning spolar. Vid ett tillfälle som det började att arbeta, observerat vi "samkvämsystemet", stamning av spolarna drar på magneterna på ett ojämnt sätt. I Arduino skiss hade vi Serial.print kommandon skickar mätvärden till konsolen för att se vad som hände. Att eliminera de Serial.print rapporterna rusade upp skissen så det flyttade lilla trä bilen fint.

En annan punkt i testning, sätter vi i tidsstämplar i början och slutet av slingan att se hur lång tid allt tog. Loopen tog 20 till 25 millisekunder. Detta är alldeles för långsam att reagera på en bil som rör sig med våra hoppades för 20 fot en sekund. Jag försökte ta ut samtal till Adafruit biblioteket och tiden gick ner till mellan 0 och 1 millisekund. Ok då. Som bekräftade beslutet att göra vår egen makt föraren.

Lista över verktyg & komponenter

Verktyg - se allmänna lista över verktyg

Komponenter
o 24v 10A strömförsörjning-Ebay $22
o Arduino Mega-Ebay $20
o Vippbrytare
o Controller/förare ombord
o del # kvantitet pris kostnad
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 motstånd 40 0,04 1.6
o Proto PCB 1 5 5
TOTALA 27,08

Detta är den skiss som används för att köra motorerna.

/*
LinMotorIndepCoil
För användning med Adafruit Motor sköld v2
Version 01 - oberoende Sensor/spole uppsättningar, upp till 4 uppsättningar per motor styrelse
Tar bilen med PMs trycks in första sensor/spole paret
Permanenta magneter är fördelade w växla polaritet på bil
så när du drar på en PM, det kommer att driva på den tidigare.
Version 02 - abandon resing/faller testar och använder statiskt värde av sensorer
att ange spolar. Använda seriell in för att justera sensor känslighet
Version 03 - logga in tider för spolar på/av etc och
Spara tidsinställningarna för Skriv ut senare när avbrott trippade
Ange tidsgränser för att förhindra spolar från att stanna för länge
Version 04 - ingen mer Adafruit motor sköldar - 8 spole par
*/

#include < Wire.h >

int hallPin [] = {0,1,2,3,4,5,6,7}. analoga stift för hallgivare
int coilN [] = {34, 30, 28, 22, 36, 32, 26, 24};
Digital stift för att spolen som N
int spolar [] = {35, 31, 29, 23, 37, 33, 27, 25};
Digital stift för att spolen som S

#define HowMany 8 / / hur många sensor/spole par vi har
int hallVal [] = {0,0,0,0,0,0,0,0}. sparade värden för Hall sensorer
int hallTrim [] = {0,0,0,0,0,0,0,0}. värde som ska subtraheras så
"inget fält upptäckt" kommer att läsa 0
#define hallThresh 60 / / vad behandlingen är betydande

#define coilMaxTime 1000 //one bör andra vara gott om tid
lång coilHoldTimeS [HowMany] = {0,0,0,0,0,0,0,0}. att förhindra att vistas på för länge
lång coilHoldTimeN [HowMany] = {0,0,0,0,0,0,0,0}. att förhindra att vistas på för länge

lång coilOnTimeS [HowMany] = {0,0,0,0,0,0,0,0}. När spolen kom på - första S magnet endast
lång coilOffTimeS [HowMany] = {0,0,0,0,0,0,0,0}. När spolen lossnade
lång coilOnTimeN [HowMany] = {0,0,0,0,0,0,0,0}. När spolen kom på - första N magnet endast
lång coilOffTimeN [HowMany] = {0,0,0,0,0,0,0,0}. När spolen lossnade

flyktiga boolean printFlag = false; flagga för att Visa knappen skjuts till Starta utskriften

långa testStart = 0;
lång testEnd = 0;
Sträng bemärkelse = "0";

void setup() {
Serial.BEGIN(9600); Ställ in följetong bibliotek på 9600 bps
Serial.println ("från LinMotorIndepCoil04");

för (int jag = 0; jag < HowMany; i ++) {//make säker spolar är avstängda
pinMode (coilN [i], produktionen);
digitalWrite (coilN [i], låg); Ange N pin till låg
pinMode (spolar [i], produktionen);
digitalWrite (spolar [i], låg); Ange S pin till låg
}

för (int jag = 0; jag < HowMany; i ++) {//set sensor trim värden förutsatt att inget fält från början
hallTrim [i] = analogRead(hallPin[i]); SB nära 0 om inget fält
}

pinMode (2, ingång); Ställ in avbrott på pin 2
digitalWrite (2, hög).
attachInterrupt (0, setPrintFlag, faller); stift 2 är avbrott 0

}

void loop() {
testStart = millis();
om (printFlag == true) printStats();
knappen sköt, ta tid att skriva ut statistik

titta på var och en av de aktiva sensorerna att se hur dess spolen bör ställas in
för (int jag = 0; jag < HowMany; i ++) {
int testVal = analogRead(hallPin[i]) - hallTrim [i]; SB nära 0 om inget fält
om (testVal > hallThresh) {/ / sydpolen PM upptäckts
känsla = "S";
Serial.Print ("South testVal ="); Serial.Print(testVal);
Serial.Print ("jag ="); Serial.println(i);
digitalWrite (coilN [i], hög); N PIN-kod har angetts till hög
digitalWrite (spolar [i], låg); Ange S pin till låg
coilHoldTimeN [i] = 0; N hålla tid återställs
om (coilHoldTimeS [i] == 0) {
coilHoldTimeS [i] = millis(); spara tid
}
om (coilOnTimeS [i] == 0) {
coilOnTimeS [i] = millis(); spara tid för 1: a magnet endast
}
om (millis()-coilHoldTimeS [i] > coilMaxTime) {
turnOffCoils(i); om spolen har varit S för lång tid, stänga av
}
} else om (testVal < - hallThresh) {/ / North
känsla = "N";
Serial.Print ("North testVal ="); Serial.Print(testVal);
Serial.Print ("jag ="); Serial.println(i);
digitalWrite (coilN [i], låg); Ange N pin till låg
digitalWrite (spolar [i], hög); Ange S pin till hög
coilHoldTimeS [i] = 0; Återställ S håll tid
om (coilHoldTimeN [i] == 0) {
coilHoldTimeN [i] = millis(); spara tid
}
om (coilOnTimeN [i] == 0) {
coilOnTimeN [i] = millis(); spara tid för 1: a magnet endast
}
om (millis()-coilHoldTimeN [i] > coilMaxTime) {
turnOffCoils(i); om spolen har varit N för lång tid, stänga av
}
}
annat {/ / inga signigicant läsning
känsla = "0";
Serial.Print ("varken testVal ="); Serial.Print(testVal);
Serial.Print ("jag ="); Serial.println(i);
turnOffCoils(i); de få avstängda,
men coilHoldTime inte få återställa

}
}
testEnd = millis();
Serial.Print ("testa ms ="); Serial.Print (testEnd - testStart); Serial.Print(""); Serial.println(Sense);
Delay(2000);
}

void turnOffCoils(int i) {
Serial.println("turnOffCoils");
digitalWrite (coilN [i], låg); stänga av spolen
digitalWrite (spolar [i], låg); //
om (coilOnTimeS [i] > 0 & & coilOffTimeS [i] == 0) {//first S ledig tid för denna spole
coilOffTimeS [i] = millis(); tid stämpel det
}
om (coilOnTimeN [i] > 0 & & coilOffTimeN [i] == 0) {//first N ledig tid för denna spole
coilOffTimeN [i] = millis(); tid stämpel det
}
lämna coilHoldTime som det är tills magnet polaritet ändras
}

void setPrintFlag() {//interrupt rutin
printFlag = sant;
}

void printStats() {//only göra detta om avbrott sker
för (int jag = 0; jag < HowMany; i ++) {//for varje av 4 spolar
Serial.Print ("Coil"); Serial.Print(i+1);
Serial.Print (S i tid"); Serial.println (coilOffTimeS [i] - coilOnTimeS[i]);
Serial.Print ("Coil"); Serial.Print(i+1);
Serial.Print "N i tid". Serial.println (coilOffTimeN [i] - coilOnTimeN[i]);
}
printFlag = false;
för (int jag = 0; jag < HowMany; i ++) {//reset räknare efter utskrift
coilOnTimeS [i] = 0; coilOnTimeN [i] = 0;
coilOffTimeS [i] = 0; coilOffTimeN [i] = 0;
}
}

Detta är den skiss som används för att testa sensorerna och spolar.

/ * CoilTest3 att arbeta med hallgivare och vår egen motor förare ombord
läser alla sensorer och skriver ut värdet
läser in 1-8 från seriell och visar att spolen norr i 5 sekunder

*/
int hallsave [8]. nr-behandlingen värde för att ange sensor behandlingen till noll
int hallar [8].

int coilN [] = {34,30,28,22,36,32,26,24};
Digital stift för att spolen som N - ordnat för jumper geografi
int spolar [] = {35,31,29,23,37,33,27,25};
Digital stift för att spolen som S
#define howMany 8

void setup() {
tag (!. Seriell);
Serial.BEGIN(9600); Ställ in följetong bibliotek på 9600 bps
Serial.println("CoilTest3");
Serial.println ("Input 1 till 8 att köra specifika spole par i 5 sekunder");

för (int jag = 0; jag < howMany; i ++) {/ / spara nr behandlingen värden
hallsave [i] = analogRead(i);
}

se till att alla spolar är avstängda
för (int jag = 0; jag < howMany; i ++) {
pinMode (coilN [i], produktionen);
digitalWrite (coilN [i], låg);
pinMode (spolar [i], produktionen);
digitalWrite (spolar [i], låg);
}
}

int i;

void loop() {
för (int jag = 0; jag < howMany; i ++) {
hallar [i] = analogRead(i) - hallsave [i]; SB nära 0 om inget fält
Serial.Print(Halls[i]); Serial.Print(""); debug värde
}
Serial.println("");
Delay(1000);

char cmd;
om (Serial.available()) {
CMD = Serial.read(); Läs karaktär från seriell
} annars återvända;

om (cmd > = '1' & & cmd < = '8') {
int x = cmd-48.
digitalWrite (coilN [x - 1], hög); slå på spolen satt till N
Serial.Print ("testing #"); Serial.println(x);
Delay(2000);
Serial.println("off");
digitalWrite (coilN [x-1], låg); Stäng av både ringar för par
}
}

Se Steg
Relaterade Ämnen