Start Elkretssimulator


Varvtalsreglera motor

Koncept

Konceptet här är att använda pulsbreddsmodulerad signal för att reglera hastigheten på motorn och verktyget för att göra detta och samtidigt styra i vilket riktning motorn roterar, det är att använda en H-brygga. Nedan är sedan 2 olika kodexempel, dels med analogWrite's pulsbreddsmodulerade signal och dels med mjukvarugenererad puls.

Uppkoppling

På det röda L298 -kretskortet är enA samt enB byglade, så de är alltid aktiverade.





analogWrite

Koden nedan sätter upp 2 pinnar som utsignaler. Jag väljer 5 och 6 eftersom jag där kan skriva analoga utsignaler, vilket i detta fall blir en pulsbreddsmodulerad utsignal. Vi läser av potentiometern, som är kopplad som en spänningsdelare som ger spänning 0-5V på pinne A0, vilket vi sedan kan läsa av i mjukvaran som ett värde 0-1023. Vi vill att mittenläget på potentiometern skall innebär att motorn står still. Vrider man åt vänster eller höger skall man få en rotiation medurs eller moturs med ökande hastighet.

#define in3 5
#define in4 6

int pot;
int motorSpeed;

void setup() 
{  
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() 
{
  pot  = analogRead(0); // 0-1023
  pot -=512; // -512 till 511
  motorSpeed = abs(pot/2)-1; // -1-254
  if(motorSpeed<0)
    motorSpeed=0;  // 0-254
  if(pot>=0)
  {
    analogWrite(in4,motorSpeed);
    analogWrite(in3,0);
  }
  else
  {
    analogWrite(in4,0);
    analogWrite(in3,motorSpeed);
  }
}

Exprimentresultat

Jag kopplar in logikanalysatorn på enA samt enB. Om potentiometern vrids mycket åt höger snurrar motorn fort medurs och det ser ut såhär på logikanalysatorn.



Om potentiometern vrids lite åt vänster snurrar motorn långsamt moturs och det ser ut såhär på logikanalysatorn.



Skapa pulsbredd i mjukvara

Det går att ändra den frekvens som analogWrite använder men om man ändå är inne och kodar om kan man lika gärna skapa hela vågformen själv. Nedan exempel ger lite större möjligheter att exprimentera med olika frekvenser på pulsbredden genom att ändra FREQ. Speciellt lägre frekvenser kan vara intressant exprimentera med. En lägre frekvens, t.ex. 50 Hz, är i princip en förutsättning för att få väldigt långsamma varvtal. Samtidigt blir motorn väldigt "ryckig" eller "skakig" vid dessa lägre frekvenser. Observera att p.g.a. hur timern räknar ut interruptet så kommer högre värden på FREQ inte skapa en pulsbredd på den frekvensen utan mycket högre, så det skall inte betraktas som exakt frekvens. Vid låga frekvenser stämmer det någorlunda, vid högre stämmer det dåligt.

Hursom helst. Nedan är ett exempel där vi skapar ett interrupt och sedan bygger vi ihop pulsen. Metoden jag snickrat ihop här (det finns många sätt) är att tänka mig en högre frekvens med vilken interrupt genereras. Jag bygger sedan ihop pulsen genom att vid varje interrupt studera om jag skall skicka ut en hög eller låg signal. Jag avgör detta genom att räkna upp ett värde vid varje interrupt, en förkalkylerad pulsbredd beroende på potentiometern, och se om detta värde är högre eller lägre än en hel pulsbredd (100% duty). Pulsen som skapas blir en bråkdel av interruptfrekvensen.

#define in3 5
#define in4 6
#define DUTYCYCLESLOTS 10
#define FREQ 50
int pot;
int motorSpeed;
byte dutyCWC=0;
byte thiscycle=0;

void setISRFreq(int freq)
{
  cli(); 
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = int(15625/freq)-1;
  TCCR1B |= (1 << WGM12); // CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024
  TIMSK1 |= (1 << OCIE1A); // timer comp inter.
  sei();
}

ISR(TIMER1_COMPA_vect)
{
  dutyCWC++;
  dutyCWC%=DUTYCYCLESLOTS;
  if(pot>=0)
  {
    digitalWrite(in3,0);
    digitalWrite(in4,(thiscycle<=dutyCWC)?HIGH:LOW);
  }
  else
  {
    digitalWrite(in3,(thiscycle<=dutyCWC)?HIGH:LOW);      
    digitalWrite(in4,0);
  }
}

void setup() 
{ 
  pinMode(5, OUTPUT); 
  pinMode(6, OUTPUT);
  setISRFreq(DUTYCYCLESLOTS*FREQ);
  Serial.begin(9600);
}

void loop() 
{
  noInterrupts();  
  pot  = analogRead(0); // 0 till 1024
  pot -=512; // -512 till 512
  motorSpeed = abs(pot)-1; // -1-254
  thiscycle=DUTYCYCLESLOTS-
        byte(motorSpeed/5/(100/DUTYCYCLESLOTS));    
  interrupts();
  delay(100);
}

Exprimentresultat

Jag kopplar in logikanalysatorn på enA samt enB. Om potentiometern vrids mycket åt höger snurrar motorn fort medurs och det ser ut såhär på logikanalysatorn.



Om potentiometern vrids lite åt vänster snurrar motorn långsamt moturs och det ser ut såhär på logikanalysatorn.