Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Boiler control application. PWM output with a PIC16F876 to control valve.

Status
Not open for further replies.

Mitchy190

New Member
Hello everyone, bellow shows a question with regards to micro-controllers which I am currently interested in, but stuck on, and need some (a lot) of help! :(

A boiler has an analogue inlet and outlet temperature sensor and the output controls
a valve in the gas supply to determine the heat input. This valve must be activated
within 1ms from a change in demand. Pulse width modulation with a fundamental
period of 10ms is used to perform the activation and the temperature difference
between the two sensors is used to represent the on period of the valve.

I need to use the PIC16F8761 data sheet to study the subsystems that will be required and
develop a procedure to determine if the time response would be adequate for the application.

data sheet found at "http://ww1.microchip.com/downloads/en/DeviceDoc/30292c.pdf"

It can be assumed that:
i) 8-bit resolution is adequate for the analogue inputs
ii) A 20MHz crystal is used for the PIC

Basically I want to use the assembler language to create the appropriate code needed to perform the control of the valve within the time specifications shown above, and what I understand from the above so far is that:

duty cycle = outlet sensor - inlet sensor

and that the PIC I am using has a PWM module in which I have no clue on how to set it up. I would much appropriate some help in how to go about this question, and where to start first!

Many thanks Mitch! :)
 
I nicked the 'init' routine from the same site, and used in a few projects for pwm.
I just copied the initialise routine except for the first block, I call that routine at the start of the software, then its just a matter of dumping a value into CCPR1L to chage the width.
You'd need to look at the timings and make some changes if you need a 10ms period, which leads me to another point, if you need to make a change to the modulation valve within 1ms thats gonna be tricky with a pwm period of 10ms, it might be possible to do, you might be able to reset the prescaler for the pwm subsystem and force the output by using a bsf or bcf.
Even then however the a/d conversion time for the pic is around 1ms, if you need dead on 1ms or less then you might be able to over clock the a/d just a little, at 20mc processor clock you wouldnt need much time to execute the code.
 
Last edited:
The valve cannot respond within 1ms on a 10ms Duty cycle period, unless you reset the period upon a demand change which then defeats the purpose of PWM control.

What can happen is the PWM duty is altered within 1ms of a demand change being sensed, which then translates to the valve responding based on the new % On time of the 10mS period.

The 1mS guaranteed PWM response infers a 1mS interrupt handler that processes the duty cycle calc. as u indicated, and then updates the PIC pwm register to reflect the change.

As you have analogue Temp signals, they must be processed to 0-5V with a 5V PIC Supply. These are sequentially sampled by the ADC in the PIC using two different analog input pins and thse data can provide the calculation inputs to derive the duty cycle.
 
Thank you, yes I think that is what the question means with regards to the valve being activated
Within 1ms from a change in demand.

So this is what I have thought of so far, it is not in assembler, but more like pseudo code.

The two temperature sensors are connected to two different input pins on PORTA, and the valve is connected to the CCP1 pin of the MC.

The MC needs to sample the values of the inputs over a period of a specified time (A sample frequency?).

It then needs to calculate the duty cycle by doing the subtraction as mentioned above.

Then this value is sent then 'somewhere' which updates the PWM module and sets the new duty cycle which in turn changes the position of the valve.

All of the above is carried out at the, what I called, the sample frequency?

I know this isn't technical, as, that is the part I need help with. So if anyone could look at what I have said, and tell me if it is sort of down the right lines? And also how would I go actually about performing what I have just said in assembler?

Thanks Mitch!
 
I have found out that to set up the PWM mode i have to the following:

1. Establish the PWM period by writing to the PR2 register.

2. Establish the PWM duty cycle by writing to the DCxB9:DCxB0 bits.

3. Make the CCPx pin an output by clearing the appropriate TRIS bit.

4. Establish the TMR2 prescale value and enable Timer2 by writing to T2CON.

5. Configure the CCP module for PWM operation.

The problem is I do not know how to write to the DCxB9:DCxB0 bits so that the differences between the two temp sensors is the duty cycle, and for the chip to do this continually or for a discrete period of time.
 
Your on the right lines.
You'll need some sort of basic algorithm to calculate the pwm value, just dumping the difference is a bit too simple, a simple pi process might do the job.
PID's are a whole topic in theor own right however.
 
I am not allowed to use a PID loop. It has to be done with the specified micro controller using PWM. So I guess the first step is to step up the CCP1 output for PWM like a stated above then? :)
 
Decided it will be easier for me to write the code in C as I am very familiar with the language, but not withing embedded systems.
 
Hey Mitchy.... I have been watching this thread... I thought that you were getting the help you required, so I kept back a little..

However.. I pointed to Nigels tutorials with a simple PWM setup...

I have re-written all the asm samples in C

Code:
#include <pic.h>				// pic specific identifiers
#define _XTAL_FREQ 20000000
__CONFIG(0x3F71);				// Config bits

#define MOTOR_PORT 	PORTC		// constants
#define MOTOR_TRIS	TRISC		//
#define RL	 		RC0
#define FL			RC3
#define RR	 		RC4
#define FR			RC5

		// Required prototypes.. each function needs to be declared
		// if called BEFORE definition.

void delayMs(int dly),speed(char motor, int speed);
void reverse(char motor), forward(char motor);

void main(void)						// program entry
	{
	int index = 0;
	unsigned char ch;
	ADCON1 = 0x6;					// Analogue off
	MOTOR_TRIS = 0b00000000;		// Motor port as outputs

	ch = CCP1CON;   // get CCP1 modules config
	ch &= 0xF0;    // we need to keep the top nibble
	ch |= 0x0C;   // and set PWM mode
	CCP1CON = ch;   // done

	ch = CCP2CON;   // same for CCP2 module
	ch &= 0xF0;
	ch |= 0x0C;
	CCP2CON = ch;

	PR2 = 126;    // 0x7F ( 8 bit )

	ch = T2CON;  // now configure Timer 2 module
	ch &= 0xF8;   // keep top bits ( post scaler blah blah....)
	ch |= 0x02;  // set pre-scaler
	T2CON = ch;  // done

	ch = T2CON;
	ch &= 0x07;  // set pre-scaler and switch on
	ch |= 0x00;
	T2CON = ch;

	TMR2ON = 1; // check its on

	while(1)						// endless Loop
		{
		speed(1,64);     // motor 1  = 50% forward
		speed(0,64);    // motor 0 = 50% forward
		delayMs(5000);

		speed(1,64);   // motor 1  = 50% forward
		speed(0,192);  // motor 0  = 50% backward
		delayMs(5000);

		speed(1,10);    // motor 1  = 90% forward
		speed(0,228);   // motor 0  = 90% backward
		delayMs(5000);

		speed(1,228);  // motor 1  = 90% backward
		speed(0,10);  // motor 0  = 90% forward
		delayMs(5000);
		
		}
	}

void speed(char motor, int speed)
	{
	if(speed > 128)
		reverse(motor);
	else
		forward(motor);
	speed &= 0x7F;
	if(motor)
		CCPR1L = speed;
	else
		CCPR2L = speed;
	}

void forward(char motor)
	{
	if(motor)
		{
		RL = 1;
		FL = 0;
		}
	else
		{
		RR = 1;
		FR = 0;
		}
	}

void reverse(char motor)
	{
	if(motor)
		{
		RL = 0;
		FL = 1;
		}
	else
		{
		RR = 0;
		FR = 1;
		}
	}

void delayMs(int dly)
	{
	while(dly--)
		__delay_ms(1);
	}

This will work straight off... There is a PWM init portion so you can get a leg up..
 
Last edited:
thank you :) I am using mikroC and it is not recognizing the #include <pic.h> library, do you have any ideas why it is doing that?
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top