All pastes #105638 Raw Edit

Untitled

public c v1 · immutable
#105638 ·published 2006-07-29 19:58 UTC
rendered paste body
// Adam Davenport - goWeather#include <p18f252.h>					// PIC header#include <delays.h>					// delays header#include <portb.h>					// Portb utilities#include <timers.h>					// timer header#include <adc.h>					// ADC header#include "xlcd.h"					// XLCD header  must modify the following two lines in header file#define BAR_1	8					// Define for bar characters#define BAR_2	9					// Define for bar characters			#define BAR_3	10					// Define for bar characters#define BAR_4	11					// Define for bar characters#define BAR_5	12					// Define for bar characters#define BAR_6	13					// Define for bar characters#define BAR_7	14					// Define for bar characters	#define Button 		PORTAbits.RA2			// Define for button tact switch#define LCD		PORTAbits.RA3			// Define for LCD transistor switch#define	Pressure	PORTAbits.RA1			// Define for Pressure transistor switch#define LED		PORTAbits.RA5			// Define for the Red LEDvoid MakeBars(void);					// MakeBars prototype to make bar charactersint Find_Slope(void);					// calculate slope of data prototypevoid timer1_isr(void);					// timer1 interupt service routine////////////////////////////////////////////////////////////////////////////////// The following declarations create the special bar characters for the display// each bit corresponds to a single pixel of a particular character on the LCD// a 1 is a dark pixel and a 0 is no pixel////////////////////////////////////////////////////////////////////////////////unsigned char rom bar1[] =   					{  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b11111,  						0b00000  					};unsigned char rom bar2[] =   					{  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b11111,  						0b00000,  						0b00000  					};unsigned char rom bar3[] =   					{  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b11111,  						0b00000,  						0b00000,  						0b00000  					};unsigned char rom bar4[] =   					{  						0b00000,  						0b00000,  						0b00000,  						0b11111,  						0b00000,  						0b00000,  						0b00000,  						0b00000  					};unsigned char rom bar5[] =   					{  						0b00000,  						0b00000,  						0b11111,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000  					};unsigned char rom bar6[] =   					{  						0b00000,  						0b11111,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000  					};unsigned char rom bar7[] =   					{  						0b11111,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000,  						0b00000  					};////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Global Variables////////////////////////////////////////////////////////////////////////////////ram int dat[8];					// pressure data					int counter;					// keep timeunsigned char topmsg[]={"GoWeathr"};unsigned char scroll_msg[]{"         "};unsigned char bars[]=("            ");unsigned char pressure[]={"Pressure"};unsigned char pressure_data[]={"    . mb"};unsigned char weather_msg1[]={"ALERT:    A Storm is Coming "};unsigned char weather_msg2[]={"Weather is Stable           "};unsigned char weather_msg3[]={"Weather Should Improve      "};unsigned char *weather_msg;unsigned char lcdweather[]={"        "};int t_min;int t_max;int step;int t;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#pragma code high_vector=0x08				// put ISR code at vector 0x08void high_interupt(void)				// code for ISR direction{	_asm						// use assembly language code	GOTO timer1_isr					// goto timer1_isr	_endasm						// end assembly language code}#pragma code						// return to normal code area#pragma interrupt timer1_isr				// Put timer1 ISR at interrupt locationvoid timer1_isr (void)					// timer1 ISR{		int weather,i;				// local declarations		PIR1bits.TMR1IF = 0;			// clear timer1 flag		counter++;				// increment counter		weather = Find_Slope(); 		// calculate slope of data		if(Button == 0)				// Turn on the display if the button is pushed		{			LCD=1;							// apply power to the LCD			Delay10KTCYx(10);					// small delay to allow LCD to power up			OpenXLCD (FOUR_BIT & LINES_5X7);			// Initialize LCD			while(BusyXLCD());					// wait while LCD finishes last operation			MakeBars();						// Add the bar characters to the LCD			while(BusyXLCD());					// wait while LCD finishes last operation			WriteCmdXLCD(DON);					// Turn the Display ON			WriteTimer1(0);						// Reset Timer1 back to 0			t_min=15000;			t_max=0;			step=0;			for(i=0;i<8;i++)			{				if(dat[i] > t_max & dat[i] !=0)					t_max=dat[i];				if(dat[i] < t_min & dat[i] !=0)					t_min=dat[i];			}			WriteTimer1(0);							// Reset Timer1 to 0					if((t_max-t_min)/6 <= 3)			{				step=3;				t_min=t_max-20;			}			if((t_max-t_min)/6 > 3)			{				step=(t_max-t_min)/6;			}			WriteTimer1(0);							// Reset Timer1 to 0			for(i=0;i<8;i++)						// This for loop creates the bottom history of pressure from the data in dat[]			{				if(dat[i] < t_min)					// If the pressure is less than 9700mb turn only the first bar on					bars[i]=BAR_1;				if(dat[i] >=t_min & dat[i] <t_min+1*step)		// If the pressure is between XXXXmb and XXXXmb turn second bar on					bars[i]=BAR_2;				if(dat[i] >=t_min+1*step & dat[i] < t_min+2*step)	// If the pressure is between XXXXmb and XXXXmb turn third bar on					bars[i]=BAR_3;				if(dat[i] >=t_min+2*step & dat[i] <t_min+3*step)	// If the pressure is between XXXXmb and XXXXmb turn fourth bar on					bars[i]=BAR_4;				if(dat[i] >=t_min+3*step & dat[i] <t_min+4*step)	// If the pressure is between XXXXmb and XXXXmb turn fifth bar on					bars[i]=BAR_5;				if(dat[i] >=t_min+4*step & dat[i] <t_min+5*step)	// If the pressure is between XXXXmb and XXXXmb turn sixth bar on					bars[i]=BAR_6;				if(dat[i] >=t_min+5*step)				// If the pressure is between XXXXmb and XXXXmb turn seventh bar on					bars[i]=BAR_7;				if(dat[i] == 0)					bars[i]='0';			}			WriteTimer1(0);							// Reset Timer1 to 0			//			// Weather Info			//			weather = Find_Slope();			if( (weather*10)/2< (-10))					// If slope is less than -1mb			weather_msg=weather_msg1;					// A Storm is Coming			if( (weather*10)/2>=(-10)&(weather*10)/2<= 10)			// If slope is between -1mb and 1mb			weather_msg=weather_msg2;					// Weather is Stable											if( (weather*10)/2>10)						// If slope is greater than 1mb			weather_msg=weather_msg3;					// Weather Should Improve						// clear stuff before scroll loop			while(BusyXLCD());						// wait until LCD finishes last operation			WriteTimer1(0);							// Reset Timer1 to 0			WriteCmdXLCD(CLS);						// Clear the LCD (ZOMG NOEZ!)			//  Scrolling					for(t=0;t<20;t++)				{					while(BusyXLCD());					WriteCmdXLCD(CLS);					while(BusyXLCD());					WriteCmdXLCD(HOME);					while(BusyXLCD());					for(i=0;i<8;i++)					{						lcdweather[i]=*(weather_msg+i+t);					}					putsXLCD(lcdweather);					WriteTimer1(0);					if(t == 0)						Delay10KTCYx(25);					while(BusyXLCD());					SetDDRamAddr(0x28);					while(BusyXLCD());					putsXLCD(bars);					Delay10KTCYx(15);				}				//			// Pressure Info			//			temp=dat[7];							// Put dat[7] into array			pressure_data [0] = (temp/1000 + '0');			pressure_data [1] = ((temp/1000) - (10*(temp/10000)) + '0');			pressure_data [2] = ((temp/100) - (10*(temp/1000)) + '0');			pressure_data [3] = ((temp/10) - (10*(temp/100)) + '0');			pressure_data [5] = ((temp%10) + '0');			WriteTimer1(0);							// Reset Timer1 to 0			//			// Display weather info to LCD			//			while(BusyXLCD());			// wait while LCD completes last operation			WriteCmdXLCD(CLS);			// clear the LCD			while(BusyXLCD());			// wait while LCD completes last operation			WriteCmdXLCD(HOME);;			// return cursor to home position			while(BusyXLCD());			// wait while LCD completes last operation			putsXLCD(pressure);			// display pressure message			WriteTimer1(0);				// Reset Timer1 to 0			while(BusyXLCD());			// wait while LCD completes last operation			SetDDRamAddr(0x28);			// put cursor on second line			WriteTimer1(0);				// Reset Timer1 to 0			putsXLCD(pressure_data);		// display pressure_data message			Delay10KTCYx(100);			// delay so that user can see it			WriteTimer1(0);				// Reset Timer1 to 0			while(BusyXLCD());			// wait while LCD completes last operation			WriteCmdXLCD(CLS);			// clear the LCD			while(BusyXLCD());			// wait while LCD completes last operation			SetDDRamAddr(0x28);			// put cursor on second line			//putsXLCD(bars);			// put bar graph on LCDs bottom line			Delay10KTCYx(100);			// delay so that user can see it			WriteCmdXLCD(DOFF);			// turn the LCD OFF			LCD=0;					// switch power off of LCD					}			}void main(void)							// main function{		int i,j;					// local variable declaration		unsigned char current;				// local variable declaration			TRISA = 0b00000101;			// PORTA all outputs 0-ADC(input) 3-LCD(output) 1-Pressure(output) 2-switch(input)		TRISC = 0b00000010;			// PORTC all outputs except C1 for timer1 xtl		DisablePullups();			// turn PORTB pullups off		counter=0;				// make sure counter is 0 to begin with		OpenTimer1(	TIMER_INT_ON &		// configure Timer1 with interrupts on				T1_16BIT_RW &		// 16-bit operation 0 to 65536				T1_PS_1_2 &		// post scaler = 1:X use x=1 for 2sec x=2 for 4sec x=8 for 16sec				T1_OSC1EN_ON &		// Select external clock				T1_SYNC_EXT_OFF);	// syncronize timer1 to external clock		INTCONbits.GIE = 1;			// enable global interrupts		INTCONbits.PEIE = 1;			// enable peripheral interrupts		Pressure=1;				// turn the power on the ADC		OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_1ANA_0REF, ADC_CH0 & ADC_INT_OFF);  //open ADC		LCD=1;					// turn power on the LCD		Delay10KTCYx(10);			// small delay to let LCD turn on		OpenXLCD (FOUR_BIT & LINES_5X7);	//Initialize LCD		while(BusyXLCD());			// wait while LCD completes last operation		WriteCmdXLCD(CLS);			// clear the LCD		while(BusyXLCD());			// wait while LCD completes last operation		WriteCmdXLCD(HOME);;			// return cursor to home position		putsXLCD(topmsg);			// display turn on message		Delay10KTCYx(100);			// delay to let user see it		WriteCmdXLCD(DOFF);			// turn the LCD off		LCD=0;					// Turn the LCD power off				while(1)					// This is the main event loop that will continue indefinately	{		if(counter == 2)			// if timer scaler is 1_2 then 15 minutes will be counter=225							// you will want to use counter=2 during debuging or else							// you will have to wait for ever to get data		{			WriteTimer1(0);			// Reset Timer1 to 0				for(i=1;i<8;i++)			// This for loop shifts all of the data by one index									// this way new data comes into the right most position (on the display)									// the last data point is lost				{					dat[i-1] = dat[i];		// shift the data				}				data_ave = 0;				// reset data_ave to 0				for(i=0;i<10;i++)			// acquire and average 10 pressure readings				{					ConvertADC();			// make ADC conversion					while( BusyADC() );		// wait until ADC is finished					result = ADRESH;		// get high ADC 8-bits					result = result << 8;			// shift bits to left 8-bits					result = result | ADRESL;		// get low ADC 8-bits					result = ((result * 15) + 2200);	// convert volts to psi x 1000					data_ave = data_ave + result;		// sum for average				}				data_ave=data_ave/10;				// divide by the number of samples=10				data_ave=((data_ave*69)/100)+1168;		// convert the data to milli-bars   1168 is an approximate value				dat[7] = data_ave;				// set dat[7] (the rightmost data point on the LCD) to the current data measurement							WriteTimer1(0);					// Reset Timer1 to 0			//////////////////////////////////////////////////////////////////////			//////////////////////////////////////////////////////////////////////		}		Sleep();							// sleep to conserve power		Nop();								// no operation when returning from sleep	}				}	int Find_Slope(void)  // linear regression{	// this routine is a common way to calculate the slope of a line	// it assumes that there are 8 data points (the contents of dat[])	// it also assumes that the x values are 1,2,...8	// see Numerical Recipes book for FIT routine	int i;	float t,sx,st2,sxoss,b;	int slope;	sx=0;	st2=0;	slope=0;	for (i=0;i<8;i++)	{		sx = sx + i;	}	sxoss = sx/8;			// calculate linear increase in x	for (i=0;i<8;i++)	{		t = i - sxoss;		// calculate change along x		st2 = st2 + t*t;	// sum the square of the change along x		b = b + t*dat[i];	// use sum x dat to calculate slope	}	b = b/st2;				// divide st2	slope = (int)b;			// cast to integer value	return(slope);			// return slope}void MakeBars(void)				// This function loads the special bar characters into the LCD{	int i;	while(BusyXLCD());			// wait while LCD is completing last operation	SetCGRamAddr(0);			// set CharacterRam address to starting position 0	for(i=0;i<8;i++)	{		while(BusyXLCD());		// wait while LCD is completing last operation		WriteDataXLCD(bar1[i]);	// Write each byte of bar into CharacterRam	}	////////////////////////////////////////////////////////////	// Repeat first operation for each bar	////////////////////////////////////////////////////////////	while(BusyXLCD());	SetCGRamAddr(8);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar2[i]);	}	while(BusyXLCD());	SetCGRamAddr(16);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar3[i]);	}	SetCGRamAddr(24);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar4[i]);	}	SetCGRamAddr(32);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar5[i]);	}	SetCGRamAddr(40);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar6[i]);	}	SetCGRamAddr(48);	for(i=0;i<8;i++)	{		while(BusyXLCD());		WriteDataXLCD(bar7[i]);	}}