Magnetisk loop #04A
Arduino med H-bridge
Hvis man anvender en H-bridge, kan man spare relæet i opstillingen med Arduino som PWM og på den måde lave en mere elegant motorstyring. Og hvad er så en H-bridge for en størrelse? I sin simpleste form er det blot fire kontakter, som er koblet parvis to og to. Sætter man en motor imellem, kan man få den til at køre forlæns og baglæns ved at skifte mellem de to sæt af kontakter. Se illustrationen nedenfor. Det er i øvrigt tydeligt, hvorledes navnet er opstået.
Det er let at udskifte de fire kontakter med transistorer, således at man kan åbne og lukke for transistorerne ved parvis at sætte spænding på deres basis. Derfra er der ikke langt til at bygge hele herligheden ind i en IC-kreds og montere dem i et kredsløb, som er egnet til at blive styret af en microcontroller. Jeg har valgt et kredsløb baseret på 2 stk. L9110, som kan købes på Aliexpress for en femmer inklusive porto. (nov. 2016). Kredsløbet kan drive en steppermotor eller to DC-motorer og det er ganske simpelt at forbinde det til en Arduino Nano. Det ser således ud:
Hvis ikke man bryder sig om de fem lysdioder, kan man blot udelade dem, men de fire kontakter skal naturligvis monteres. To af dem skifter mellem forlæns og baglæns. De to andre skifter mellem henholdsvis HIGH-MEDIUM og LOW-MEDIUM. Dette endte med at være min foretrukne konstruktion, så jeg lavede et printudlæg til den. Det kan ses herunder retvendt, spejlvendt og med komponentplacering.
De røde komponenter: lysdioderne og de fire push-buttons skal monteres på oversiden. De gule komponenter er smd, som i sagens natur skal loddes på kobbersiden. Kondensatoren og Shottky-dioden (som ikke er vist, men har loddeøer lige under tekstfeltet) kan man vælge at montere som smd eller som through-hole. De fem modstande på 220 Ohm er 0805. De fire modstande på 0 Ohm fungerer som lus og er 1206. I den størrelse er der plads til, at der kan gå en printbane under den, og det hjælper mig tit, når jeg lægger print ud. Jeg har anskaffet mig flere hundrede af dem, for det er min erfaring, at der ofte er brug for at hjælpe printet på rette vej med en lus.
Printet er lavet som et shield til en Arduino Uno. Hvis man anvender “Female Long Pin Headers” har man længde nok til både at lodde og nå tilstrækkelig dybt ned i de headers, der sidder på Uno’en.
OG man har adgang til alle porte, såfremt man skulle have tanker om at koble andet på konstruktionen. Færdigbygget ser den således ud:
Motoren skal kobles direkte til de to blå terminaler øverst på fotoet. De fire stykker fortinnet kobbertråd har alene til formål at agere ben for konstruktionen. Bemærk at jeg har fjernet den oprindelige header og erstattet den med seks stykker fortinnet kobbertråd.
En pdf med printudlægget i korrekt størrelse kan downloades her.
Gerberfilerne kan hentes her: PWM MagLoop Gerber.
Koden til sketchen kan ses nederst i denne post.
# | Titel | Title |
---|---|---|
01 | Intro | Intro |
02 | Materialer | BOM |
03 | Opbygningen | How to build |
04 | Arduino som PWM | Arduino running as PWM |
04A | Arduino med H-Bridge | |
05 | Kloge Åge | Elmers |
06 | On Air | On air |
07 | Vidunder eller myter? | Wonder or myths? |
08 | Fjernfelt | Far Field |
09 | Nærfelt | Near Field |
Hele koden kan hentes her:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
/* PWM for H-bridge version 1.03 Created by Jørgen Sand, oz1js, July 2016 and published under the GNU GPL as free software www.oz1js.net ------------------------------------------------ */ //MANDATORY: You MUST install 4 pushbuttons const byte REVERSE_PIN = 2; // reverse button const byte FAST_PIN = 3; //set PWM efficiency high - TOGGLE const byte SLOW_PIN = 4; //set PWM efficiency low - TOGGLE // otherwise PWM efficiency is medium const byte PWM_PINA = 5; // PWM output channel A const byte PWM_PINB = 6; // PWM output channel B const byte FORWARD_PIN = 7; // forward button //OPTIONALLY: You MAY install some or all of 5 LEDs, // - but you need the constants for compatibility const byte FAST_LED_PIN = 9; const byte MEDIUM_LED_PIN = 10; const byte SLOW_LED_PIN = 11; const byte REVERSE_LED_PIN = 12; const byte FORWARD_LED_PIN = 13; //adjust this to match the motor of your choice const byte SLOW_PWM = 125 ; const byte MEDIUM_PWM = 175; const byte FAST_PWM = 255; //delay between toggle FAST/SLOW/MEDIUM const unsigned int BUTTON_DELAY = 250; //start of CLASS class jsPWM_Hbridge { public: jsPWM_Hbridge(byte SlowPin, byte FastPin, byte ReversePin, byte ForwardPin, byte PWMPinA, byte PWMPinB, byte FastLedPin, byte MediumLedPin, byte SlowLedPin, byte ReverseLedPin, byte ForwardLedPin, byte SlowPwm, byte MediumPWM, byte FastPWM, unsigned int ButtonDelay); void run(); private: boolean _Forward = false, _Reverse = false, _Fast = false, _Slow = false, _Medium = false; byte _PWMEfficiency = 0; byte _SlowPin = 0, _FastPin = 0, _ReversePin = 0, _ForwardPin = 0; byte _PWMPinA, _PWMPinB, _FastLedPin, _MediumLedPin, _SlowLedPin; byte _ReverseLedPin = 0, _ForwardLedPin = 0, _RelayPin = 0; byte _SlowPwm = 0, _MediumPWM = 0, _FastPWM = 0; unsigned int _ButtonDelay = 0; unsigned long _DelayFast = millis(), _DelaySlow = millis(); unsigned long _HeatProtection = millis(); void readButtons(boolean &Forward, boolean &Reverse, boolean &Fast, boolean &Slow ); void showStatus(); void turnLedOnOff(byte Pin, boolean Button); void controlPWM(); }; // * * * * IMPLEMENTATION OF THE CLASS jsPWM_Hbridge::jsPWM_Hbridge(byte SlowPin, byte FastPin, byte ReversePin, byte ForwardPin, byte PWMPinA, byte PWMPinB, byte FastLedPin, byte MediumLedPin, byte SlowLedPin, byte ReverseLedPin, byte ForwardLedPin, byte SlowPwm, byte MediumPWM, byte FastPWM, unsigned int ButtonDelay) { _SlowPin = SlowPin; _FastPin = FastPin; _ReversePin = ReversePin; _ForwardPin = ForwardPin; _PWMPinA = PWMPinA; _PWMPinB = PWMPinB; _FastLedPin = FastLedPin; _MediumLedPin = MediumLedPin; _SlowLedPin = SlowLedPin; _ReverseLedPin = ReverseLedPin; _ForwardLedPin = ForwardLedPin; _SlowPwm = SlowPwm; _MediumPWM = MediumPWM; _FastPWM = FastPWM; _ButtonDelay = ButtonDelay; _PWMEfficiency = MediumPWM; _Medium = true; pinMode(_ForwardPin, INPUT_PULLUP); pinMode(_FastPin, INPUT_PULLUP); pinMode(_SlowPin, INPUT_PULLUP); pinMode(_ReversePin, INPUT_PULLUP); pinMode(_PWMPinA, OUTPUT); pinMode(_PWMPinB, OUTPUT); analogWrite(_PWMPinA, 0); // Motor off analogWrite(_PWMPinB, 0); // Motor off pinMode(_FastLedPin, OUTPUT); pinMode(_MediumLedPin, OUTPUT); pinMode(_SlowLedPin, OUTPUT); pinMode(_ReverseLedPin, OUTPUT); pinMode(_ForwardLedPin, OUTPUT); pinMode(_RelayPin, OUTPUT); } void jsPWM_Hbridge::controlPWM() { if (_Forward == true ) { analogWrite(_PWMPinB, 0); analogWrite(_PWMPinA, _PWMEfficiency); } else if (_Reverse == true) { analogWrite(_PWMPinA, 0); analogWrite(_PWMPinB, _PWMEfficiency); } else { analogWrite(_PWMPinA, 0); analogWrite(_PWMPinB, 0); } } void jsPWM_Hbridge::run() { readButtons(_Forward, _Reverse, _Fast, _Slow); controlPWM(); } void jsPWM_Hbridge::readButtons(boolean &Forward, boolean &Reverse, boolean &Fast, boolean &Slow) { Forward = (digitalRead(_ForwardPin) == LOW);//goes low when activated if (Forward == true) { Reverse = false; //js digitalWrite(_RelayPin, HIGH); } showStatus(); Reverse = (digitalRead(_ReversePin) == LOW);//goes low when activated if (Reverse == true) { Forward = false; //digitalWrite(_RelayPin, LOW); } showStatus(); if (digitalRead(_FastPin) == LOW) { if (millis() - _DelayFast > _ButtonDelay) { Fast = !Fast; _DelayFast = millis(); } } if (Fast == true) { Slow = false; _PWMEfficiency = _FastPWM; } showStatus(); if (digitalRead(_SlowPin) == LOW) { if (millis() - _DelaySlow > _ButtonDelay) { Slow = !Slow; _DelaySlow = millis(); } } if (Slow == true) { Fast = false; _PWMEfficiency = _SlowPwm; } if (Fast == false && Slow == false) { _Medium = true; _PWMEfficiency = _MediumPWM; } else { _Medium = false; } showStatus(); } void jsPWM_Hbridge::showStatus() { turnLedOnOff(_ForwardLedPin, _Forward); turnLedOnOff(_ReverseLedPin, _Reverse); turnLedOnOff(_FastLedPin, _Fast); turnLedOnOff(_SlowLedPin, _Slow); turnLedOnOff(_MediumLedPin, _Medium); } void jsPWM_Hbridge::turnLedOnOff(byte LedPin, boolean ButtonOn) { if (ButtonOn) { digitalWrite(LedPin, HIGH); } else { digitalWrite(LedPin, LOW); } } jsPWM_Hbridge MyPWM(SLOW_PIN, FAST_PIN, REVERSE_PIN, FORWARD_PIN, PWM_PINA, PWM_PINB, FAST_LED_PIN , MEDIUM_LED_PIN, SLOW_LED_PIN, REVERSE_LED_PIN, FORWARD_LED_PIN, SLOW_PWM , MEDIUM_PWM, FAST_PWM, BUTTON_DELAY); void setup() { } void loop() { MyPWM.run(); } |
Hej
Jeg undre mig over at der ikke står på diagrammet hvad funktionen er af de enkelte knapper og LED’er. F.eks “OP” , “NED”
Hvis du læser denne post (#04A) og post #04 står det sådan set forklaret. Resten kan ses ved at kigge i koden.
Frem/Tilbage afhænger jo desuden af, hvorledes du tilslutter motorens terminaler. Håber ikke at det har forhindret dig i at bygge projektet. 😉
Hvis du har brug for yderligere info, må du sige til.