Windmill controller with PIC12F675

1. Description:

Update (Oct.13, 2011)

- PCB better suited for production.

Update (Apr.10, 2011): The controller has been revised!

1. Changes made to schematic:

- changed the voltage divider resistors: replaced 22K with 10K and 10K with 1K - no problems now, device is very responsive;

- I let the RA5 pin free, it was used only on PICAXE for loading programs;

- added an ICSP connector, for Pickit2 programmer or compatibles - now you can program the microcontroller on board;

- I noted on schematic the optional blocks - this mean you can omit them at montage.

2. Changes made to firmware level:

The new method will help you to calibrate your controller without having a variable power source! (you still need to have a digital multimeter for measuring the resistors).

I used mikroPascal Pro 4.60 to design the firmware (expect other languages as well) due to temporary problems with Jallib ADC library and an undiscovered problem at an analog pin of a defective microcontroller which I replaced. The project remained on mikroPascal but I will do it also in JAL, PMP, mikroBasic and others.

I also intend to use this little project as a benchmark for different languages/compilers so, I intend to write "by hand" the ADC() procedure, to eliminate the use of any "system" library, for fair results. You can think that the benchmark is useless for such a small code but these days, compilers get added more and more enhanced new microcontrollers support, libraries become very fat and small PICs are neglected so, you get bigger hex files on the same project using new versions of the compiler.

Note: This controller does not have logging capabilities. For a Windmill charger/logger with PIC12F675 you can go there (I have to rewrite that some day).

When I started this project, I had two objectives in mind:

- To learn how to use ADC (analog-to-digital converter) and software serial transmission.

- To recover the PICAXE08M for other projects. Is a pity to waste the most powerful 8 pin PIC12F683/PICAXE08M for a project where PIC12F675 can do all the job (even for Glenn's windmill controller/logger).

So, I managed to successfully replace the PICAXE08M, using the same "motherboard". And the controller is in use.

2. Kicad files:

Click on images to see the schematic and pcb

3. Setup the controller without a variable power source:

We will need only a digital ohmmeter/multimeter. We are going for a maximum voltage of 55Vcc, as in this page. So, the resistors have:

- R1 = 10K

- R2 = 1K, ideal values.

for this simple voltage divider:

In practice, we don't have 10K and 1K exact values so after we get our resistors, we must measure them to see the exact values. Write them down, and go to the Raltron page to use their Voltage divider calculator to find out what is the maximum voltage for our resistor combination. It's very important to know the maximum real input voltage (Vin) for our divider, which correspond to 5V output voltage (Vout) - some kind of reverse engineering.

So, fill the form as in the image bellow and press "Compute" button to see the value (I'm using the ideal values as example).

Take the Input Voltage value (55, in our ideal case) and divide it with 1024 (we are using 10bit ADC conversion).

55 / 1024 = 0.053710937

Take the first three non-zero numbers and that will be our magical number:

0.053710937 --> 537

We will use this number in a 32bit integer math calculation inside microcontroller to see directly the voltage values measured by microcontroller. And the following piece of code does exactly this.

    Volt := ADC_Read(3);

tmp1 := 537 * (Volt + 1);

    realvolt := tmp1 div 1000;
    if realvolt > 144 then //-- 14.4V
      GPIO.GP1 := 0; //charging off
    if realvolt < 130 then //-- 13.0V
      GPIO.GP1 := 1; //charging on
    if realvolt > 129 then //-- 12.9V
      GPIO.GP2 := 0; // consumer on
    if realvolt < 120 then //-- 12.0V
      GPIO.GP2 := 1; // consumer off

As you can see, the beginner with a minimal set of tools can work directly with real volt values, programs being more readable. No need of a variable power source but, you know, is good to have one ;) .

Of course, you can use smaller values for a bigger resolution. For example, for our 12V system (the solar panel I use outputs a maximum of 17Vcc) we can have a maximum input voltage of 28.5Vcc so, R1 = 4k7 and R2 = 1k . You must measure the resistors to calculate the real maximum input voltage - value needed to find out the magic number.

On the first version, I used a maximum of 16Vcc input voltage, I removed the 4.7V zener diode for accurate readings, and my solar panel outputting 17Vcc burned my input analog pin :) so, never chose tight values for your resistive divider.

4. The firmware:

Here is the complete code for mikroPascal Pro 4.60 (at Attachments you can find the archive with source code and hex file):

program P12f675_voltmeter;
  Volt: word;
  tmp1: dword;
  realvolt: dword;
// main program
  INTCON := %00000000;
  IOC := 0;
  T1CON := %00000001;
  OPTION_REG := %10000001;
  CMCON := %00000111;   // comparators OFF
    CALL 0x3FF
  ANSEL := %01011000; // FOSC/16 and AN3 as analog
  TRISIO := %00111000;
  ADCON0       := %00000001;
  ADCON0.ADFM  := 1;  // 0 = left justified, 1 = right justified
  ADCON0.VCFG  := 0;  // voltage ref is VDD
  ADCON0.ADON  := 1;  // turn on ADC module
  ADCON0.CHS0  := 1; 
  ADCON0.CHS1  := 1;
  while true do begin
    Volt := ADC_Read(3);
    //ADCON0.GO := 1;
    // Let's do the math for the real voltage value:
    // (The resistive divider values are:
    // R1 = 10K and R2 = 1K)

tmp1 := 537 * (Volt + 1); //this value, "537", depends on the values of resistors from divider

    realvolt := tmp1 div 1000;
    if realvolt > 144 then //-- 14.4V
      GPIO.GP1 := 0; //charging off
    if realvolt < 130 then //-- 13.0V
      GPIO.GP1 := 1; //charging on
    if realvolt > 129 then //-- 12.9V
      GPIO.GP2 := 0; // consumer on
    if realvolt < 120 then //-- 12.0V
      GPIO.GP2 := 1; // consumer off
    //Wait for 2 seconds.  This way, your charging relay will
    //not be afected if you have a defective battery (if your 
    //battery can't hold the charge and is discharging fast bellow
    //the charged value, your relay will "flash" fast between
    //"charge/don't charge" - with that delay, this will not happen)
  end; // while

The project settings (I think is the same for mikroBasic and MikroC - not checked yet)

Running under Wine on Ubuntu 10.10 - not very clean but workable

5. Compiler benchmarks:

Ok, I did the tests for Pascal like languages, JALv2 2.4n, Pic Micro Pascal 1..6.0.86 (beta, not released), mikroPascal PRO 4.60 but I will speak about on another page, linked here.

6. Result:

I'm still using the old hardware where I made the new changes. I re-programmed the 12F675 with Pickit2 programmer and his PC software which takes care of factory calibrated clock value (see this page to see what I mean). The controller is in use and is working nice. Initially, I wanted to replace it with a more advanced microcontroller, 16F690, but now I think I will use that for another purpose.

Why the chip is looking so weird? Well, the story is here.