Wind Turbine Control System

left_Arrow

WhaleWurbine_circuit

Small circuit board I made for the system

The purpose of the control system is to reduce the effective load resistance
across the generator so that the generator can reach it’s desired speed of 4500 RPM. If the the load resistance across the generator is low, the generator will spin faster compared to when the load resistance is high. Reduction of load resistance is achieved by rapidly opening and closing the charging circuit; a technique also known as PWM (Pulse Width Modulation).

The Arduino micro-controller sends a PWM signal to a solid state relay, IRF510, to reduce the effective load resistance. The PWM signal has a magnitude or duty cycle that is proportional to blade speed: low PWM duty cycle (0) implies low effective load resistance and low resistive torque on generator whilst high PWM duty cycle (255) implies high effective load resistance and highest resistive torque on generator. The Arduino reduces effective load resistance only if blade speed is less than 4500 RPM; if blade speed is above 4500 RPM, the Arduino sends a PWM signal of magnitude 255 to maximize effective load resistance. The Arduino software the we used can be downloaded here.


Arduino code

// Author : J.Kadoko
// ME 43 Wind Turbine Design Project
// Here is the pin layout

/* Digital pins:
  1 - Nothing
  2 - Encoder (interupt 1)
  3 - LCD Screen (DB7)
  4 - LCD Screen (DB 6)
  5 - LCD Screen (DB 5)
  6 - LCD Screen (DB 4)
  7 - LCD Screen (Enable Pin)
  8 - LCD Screen (RS)
  9 - Nothing
  10 - Kick-start Transistor
  11 - PWM Load Transistor
  Analog Pins :
  0 - voltage across the generator reading
  1 - Nothing
  2 - nothing
  3 - Nothing
  4 - Nothing
  5 - Nothing
*/
/* Description:
  The turbine is expected to run at a speed of 4500RPM at wind speed of 10m/s in the wind tunnel. As the wind turbine is starting, the arduino will kick-start the
  generator by running it as a motor. The Arduino controls a transistor that opens and closes a circuit. During kick-starting, the PWM transistor should be open.
  Kick-starting will be short pulses of until the generator is rotating on its own due to wind.

  As the generator rotates on its own, the Arduino will lessen the load (and hence the overall power extracted from the generator) by PWMing the load so that the generator can get
  up to the desired speed of 4500rpm. Pin 11 controls the transistor that does PWM.

  Results:
  Not all of the desired features were implemented in the first iteration because of time limitations.
   The controller was not implemented because the encoder saturated at blade speeds of 1000RPM - we hope to spec a new encoder.
   The push buttons and kick-starting system were not implemented because there was no need to kick-start the generator; it had a cut-in speed of 3m/s
   Current measurements were not implemented because of time constraints
   Voltage measurement system was implemented during experiments but it is not yet perfect.

  This code was used for demonstration on December 9, 2011 at the CEEO (Tufts University). It provides a good starting point for people interested in further developing WhaleWurbine's
  Control system or learning about our design process.

*/

// Libraries
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 7, 6, 5, 4, 3);
// Other pins :
int voltSensor = A1;    // voltage across a 330k Ohm resistor , back calculate this to obtain the actual voltage across the generator
int loadPWM = 11;      // PWM the load - controls the transistor
int kickStart = 10; // Kick- start transistor
const int encoder = 2;

// Variables :
float w = 0; // expected blade speed (rd/s)
double wD = 40; // the desired blade speed (rd/s) 471 is the 4500 rpm
double v = 0; //  voltage across the generator (V)
double vD = 5; // desired voltage across the generator (V)
double kV = 0.01; // the kV value of the motor [V/(rd/s)];
long currTime = 0; // time in milliseconds
long oldTime1 = 0; // time in milliseconds used for speed
long oldTime2 = 0; // time in milliseconds used for pwm
float dt = 0; // change in time (s)
int RL = 0; // pwm output for the load transistor
double integral = 0; // the integral term in the generator;
double ki = 1; // integral constant
double kp = 0.01; // proportional constant
double error = 0;
double theta = 0; // the counter of the rotating disk
double thetaOld = 0; // the old counter value of theta

double current = 0; // I am not sure yet how we can measure this
double R = 0.1; // radius of the encoder disk
long R1 = 330000; // this is the resistor that goes from Vout to ground on the potential devider  (Ohms)
long R2 = 470000; // this is the resistor that goes from Vout to v Volts of the generator (Ohms);

// I will do a state machine
int state = 0;
int mode = 0; // mode 0 controls the turbine with voltage , mode 1 controlls the turbine using blade speed
const int kickState = 1;
const int pwmState = 2;
const int chargeState = 3;

void setup()
{
  // set the cursor to (0,0):
  lcd.begin(16, 2);
  lcd.print("ME 43 Design");
  // Start Serial port communication
  Serial.begin(9600);
  // declare the pin modes:
  pinMode(voltSensor, INPUT);
  pinMode(loadPWM, OUTPUT);
  pinMode(kickStart, OUTPUT);

  attachInterrupt(0, bladeSpeed, RISING);
  // print welcome message

  delay(5);
  // initialize variables
  currTime = millis();
}


void loop()
{
  //CALCULATIONS :
  if (theta > thetaOld)
  {
    currTime = micros();
    dt = (currTime - oldTime1) / 1000000.0;
    // calculate the speed of the blades in rd/s
    w = (theta - thetaOld) * 3.14 / dt;
    oldTime1 = currTime;
    thetaOld = theta;
  }

  // select the right state based on the mode  : mode 0 uses voltage readings to estimate w; mode 1 uses photointerruptor to calculate
  v = analogRead(voltSensor);
  v = v * 2.4242 / 1024.0; // voltage across the generator (V) should be measured across a potential devider with R1 and R2;
  v = map(v, 0.14, 0.22, 1, 7);
  if (mode == 0)
  {
    if (v == 0) // should change this depending on what the input noise is
    {
      state = kickState; // kick-start the generator
    }
    else if ( v < vD)
    {
      state = pwmState;
    }
    else if (v > vD)
    {
      state = chargeState;
    }
  }

  else
  {
    if (w == 0)
    {
      state = kickState; // kick-start the generator
    }
    else if (w < wD)
    {
      state = pwmState;
    }
    else if (w > wD)
    {
      state = chargeState;
    }

  }
  //  stuff into the serial stream:
  Serial.print(w);
  Serial.print(", voltage");
  Serial.print(v);
  Serial.print(",state");
  Serial.println(state);
  // stuff to the user:
  lcd.setCursor(0, 1);
  //lcd.print("Volt:");
  lcd.print(w);
  lcd.setCursor(5, 1);
  lcd.print("rd/s");

  delay(100);
  switch (state)
  {
    case kickState:

      analogWrite(loadPWM, 0); // open the loadPWM
      digitalWrite(kickStart, HIGH); // close the kick starting circuit
      delay(10); // delay for a few milliseconds
      digitalWrite(kickStart, LOW); // turn off the kick starting circuit
    case pwmState:
      currTime = millis();
      dt = (currTime - oldTime2) / 1000;
      // calculate the error signal
      error = vD - v; // vDesired - vMeasured
      integral = integral + error * dt; // Integral term
      // output
      RL = integral * ki + kp * error;
      // coerce the resistance to 255
      if (RL > 255)
      {
        RL = 255;
      }
      else if (RL < 0)
      {
        RL = 0;
      }
      digitalWrite(kickStart, LOW); // turn off the kick starting
      analogWrite(loadPWM, 100); // play with the duty cycle depending on what the voltage or blade speed is

      oldTime2 = currTime;
    case chargeState:
      // everything is good - go ahead and charge the battery !!!

      digitalWrite(kickStart, LOW);
      analogWrite(loadPWM, 255);

    default:
      lcd.setCursor(0, 1);
      //lcd.print("Check Wire Connections !!");
  }
}

void bladeSpeed()
{
  theta = theta + 1;
}