Maneesh GuptaHana Qudsi
Published

Thermistor Respiratory Monitor

A low-cost, easy-to-use device to monitor the breathing of patients.

Full instructions provided2,622
Thermistor Respiratory Monitor

Things used in this project

Hardware components

Through-Hole 30kΩ Resistor
×1
Through-Hole 100kΩ Resistor
×1
9V battery (generic)
9V battery (generic)
×1
White Board
×2
AtMega1284p Target Board
×1
LCD
×1
Nebulizer Mask
×1
NTC Thermistor SMD 402
×1
10K Trimpot
×1
Piezo Electric Speaker
×1
Button
×1
Op Amp LF353N
×1
Through-Hole 330Ω Resistor
×4
Through-Hole 1kΩ Resistor
×2
Through-Hole 3kΩ Resistor
×1
Through-Hole 10kΩ Resistor
×1
Through Hole 220µF Capacitor
×1
Through Hole 2200µF Capacitor
×1
Through Hole 1nF Capacitor
×1

Story

Read more

Code

resp_monitor.c

C/C++
resp_monitor.c
// Includes + Defines
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/eeprom.h> 
#include <math.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <string.h>
//#define F_CPU 16000000 UL
#include <util/delay.h> // needed for lcd_lib
#include <avr/sleep.h>

#include "uart.h"

#define begin {
#define end }
#define t1 15 //every 0.25 seconds
#define t2 500 //every 8.2 seconds
#define bat_tol 101 //tolerance value of battery code
#define tol 8 //tolerance value of determine if patient is breathing code
FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); //setup uart



//*************Macros************************************************
#define READ(U, N) ((U) >> (N) & 1u)
#define SET(U, N) ((void)((U) |= 1u << (N)))
#define CLR(U, N) ((void)((U) &= ~(1u << (N))))
#define FLIP(U, N) ((void)((U) ^= 1u << (N))) 


//*************Functions*********************************************
void thermistor(void);  //determine if patient is breathing
void battery(void);      //measure battery voltage
void display(void);      //display breathing rate (bpm) on LCD
void measure(void);      //measure breathing rate (bpm)
void initialize (void);    

//**************Variables***************************************
//LCD variables 
const int8_t LCD_initialize[] PROGMEM = "LCD Initialized\0";
const int8_t LCD_line[] PROGMEM = "line 1\0";
const int8_t LCD_number[] PROGMEM = "Number=\0";
int8_t lcd_buffer[20];	// LCD display buffer


volatile unsigned int time1, time2;  //time out variables
volatile int count;                  //keeps running count of clk cycles
float breathrate;                    //breathing rate bpm
char sample_old;                     //old time sample measured by ADC
char sample;                         //new time sample measured by ADC
volatile int tau1;                   //time 1 for respiration rate measurement
volatile int tau2;					 //time 2 for respiration rate measurement
int c;								 //counter for number of "no breaths"
volatile char measure_flag;   		 //set to one if AC ISR goes off
volatile int period;          		 //period of one breath in clk cycles
volatile char flag;          		 //set to one when AC ISR goes off
float avg_period;           		 //average period of one breath in clk cycles
char bat_samp;                		 //battery voltage sample

//************ISR************************************************

//***********Timeout Counter ISR********************************
// timer 0 compare ISR
ISR (TIMER0_COMPA_vect)
begin      
  //Decrement the three times if they are not already zero
  if (time1>0)	--time1; //Used to time the thermistor measurements
  if (time2>0) 	--time2; //Used to time the battery voltage measurements
  if (count == 20000) //reset count so it doesnt overflow
  begin
	  count = 0;
	  tau1 = 0;
  end
  count++;
end 


//**************AC ISR************************************
ISR (ANALOG_COMP_vect)
begin

	CLR(ACSR, ACIE);  		//turn off AC inturrupt
	flag = 1;  				//flag for turning on AC inturrupt

	tau2 = count;     		//store new count value
	period = tau2 - tau1;   //calculate period
	tau1 = tau2;    		//store old count value
	measure_flag = 1;  		//activate measure function
	
end 

//*************Main*********************************************
 //Main 
int main (void)
begin

//charge capacitors
	DDRB = 0b00110000; //set B5,B4 to output
	SET(PORTB,PORTB4); //set B4 to 5V

	_delay_ms(5000); //wait for 5 seconds while charging

	CLR(PORTB,PORTB4); //turn B4 off
	DDRB = 0b00000000; //turn DDRB to all inputs

  	initialize();

	//for uart
	stdout = stdin = stderr = &uart_str;
	fprintf(stdout,"Starting...\n\r"); 

 //main task scheduler loop 
  while(1)
  begin  
	//testing fprintf statements
	  	//fprintf(stdout,"while\n\r"); 
    	//fprintf(stdout,"second = %d\n\r ",second);
		//fprintf(stdout,"tau 1 = %d     tau2 = %d \n\r",tau1, tau2);
		//fprintf(stdout,"count = %d \n\r", count);
		//fprintf(stdout,"tau2 = %d \n\r",tau2);
		//fprintf(stdout,"period = %d\n\r ",period);
		//fprintf(stdout,"tau1 = %d \n\r",tau1);
	
	if (flag == 1) //for turning back on AC inturrupt
	begin
	 
		_delay_ms(10);
		SET(ACSR,ACI);
		SET(ACSR, ACIE); //turn on AC inturrupt

		flag = 0; //reset flag
	end
	
	if (time1==0){ time1=t1; thermistor();}  //determines if patient is 
											 //breathing or not

    if (time2==0){ time2=t2; battery();}    //measures battery life

	if (measure_flag == 1){measure_flag = 0; measure();} //measures breathing rate

	if (PINB & 0b00000010){display();}  //if display button is pushed
	                                    //activate the display function

  end
end //main


//**************Thermistor****************************
void thermistor(void)
begin

	ADMUX = (1<<REFS0) | (1<<ADLAR) ;  //turn on left adjust result, turn on external reference

	
	while(ADCSRA & (1<<ADSC)) ;  // wait for conversion

	    sample_old = sample;  
	    sample = ADCH;      	// take sample from ADC

		ADCSRA |= (1<<ADSC); 	// shift left

		if(abs(sample_old - sample) <= tol) 
		begin
	
			c++; 				// increment counter if "no breath" detected
		
			if(c >= 10) {

			 //turn on pwm 
 		 
			 SET(DDRD,DDD5); 
			 TCCR1B = (1<<WGM12) | (1<< CS11); 	

			 TCCR1A = (1<<COM1A0); 
	         OCR1A = 255;

	         breathrate = 0;	//since patient isn't breathing, breathrate is 0

		     } 

		end 

		else 
		begin
			c = 0;				// reset "no breath" count
			TCCR1A = 0;			// keep PWM off
		end 
end

//*************Battery*******************************
void battery(void)
begin


		ADMUX = (1<<REFS0) | (1<<ADLAR) + 1 ;  //turn on left adjust result, turn on second external reference

		ADCSRA |= (1<<ADSC);

		while(ADCSRA & (1<<ADSC)) ;			  //wait for conversion

		bat_samp = ADCH;					  //set variable to ADC sample

		//for testing
		fprintf(stdout, "bat samp = %d\n\r", bat_samp);

		if(bat_samp <= bat_tol) 
		begin
		 
		 //turn on pwm 
		 
		 SET(DDRD,DDD5); 
		 TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10); 	

		 TCCR1A = (1<<COM1A0); 
         OCR1A = 255; 
	 
		 _delay_ms(1000); 					//pwm on for 5 seconds

		 TCCR1A = 0;
		 
		end 

end

//*************Display*******************************
void display(void)
begin
	
    LCDinit();	      		//initialize the display
	LCDcursorOFF();
	LCDclr();				//clear the display 

    //sprintf(lcd_buffer, "win"); for testing

	sprintf(lcd_buffer, "%f Bpm", breathrate);           
	LCDGotoXY(0,0);
	LCDstring(lcd_buffer, strlen(lcd_buffer));
    //fprintf(stdout,"display \n\r"); for testing

end

//*************Measure*******************************
void measure(void)
begin

	avg_period = 0.75*avg_period + 0.25*period; //calculate avg period
	breathrate = 3/(avg_period*0.00164);        //convert to bpm
		
	//for testing
    //fprintf(stdout,"breathrate: %f B/min\n\r", breathrate);

end // measure task

//****************Initialize*****************************
void initialize(void)
begin

	DDRA = 0b00000000;                	 //Make PortA all inputs
	PORTA = 0b00000000;              	 //turn off pull up resistors 


 	DDRB = 0b01000000;   				 //set B6 to output
	SET(PORTB,PORTB6);  				 //set B6 to 5V output

	ADMUX = (1<<REFS0) | (1<<ADLAR) ;    //turn on left adjust result, turn on external reference
	ADCSRA = (1<<ADEN) | (1<<ADSC) + 7;  //turn on ADC, start conversion and set sample rate to 1Mhz

	//set up timer 0 for 1 mSec timebase 
	TIMSK0= (1<<OCIE0A);				 //turn on timer 0 cmp match ISR 
	OCR0A = 255;  						 //set the compare reg to 256 time ticks

	//turn on AC   
  	SET(ACSR, ACIE);   					 //turn analog input capture on
  	SET(ACSR, ACIS1);    				 //ACIS1 and ACIS0 make the comparater trigger on the rising edge

	//set prescalar to divide by 1024 
	TCCR0B= 5; 	

	// turn on clear-on-match
	TCCR0A= (1<<WGM01) ;

	//init variables
	flag = 0;
	avg_period = 0;

    time1=t1;
    time2=t2;

	uart_init();
	
	//crank up the ISRs
	sei();
end

lcd_lib.h

C/C++
lcd_lib.h
//*****************************************************************************
//
// File Name	: 'lcd_lib.h'
// Title		: 8 and 4 bit LCd interface
// Author		: Scienceprog.com - Copyright (C) 2007
// Created		: 2007-03-29
// Revised		: 2007-08-08
// Version		: 1.0
// Target MCU	: Atmel AVR series
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef LCD_LIB
#define LCD_LIB

#include <inttypes.h>


//Uncomment this if LCD 4 bit interface is used
//******************************************
#define LCD_4bit
//***********************************************

#define LCD_RS	0 	//define MCU pin connected to LCD RS
#define LCD_RW	1 	//define MCU pin connected to LCD R/W
#define LCD_E	2	//define MCU pin connected to LCD E
#define LCD_D0	0	//define MCU pin connected to LCD D0
#define LCD_D1	1	//define MCU pin connected to LCD D1
#define LCD_D2	2	//define MCU pin connected to LCD D1
#define LCD_D3	3	//define MCU pin connected to LCD D2
#define LCD_D4	4	//define MCU pin connected to LCD D3
#define LCD_D5	5	//define MCU pin connected to LCD D4
#define LCD_D6	6	//define MCU pin connected to LCD D5
#define LCD_D7	7	//define MCU pin connected to LCD D6
#define LDP PORTC	//define MCU port connected to LCD data pins
#define LCP PORTC	//define MCU port connected to LCD control pins
#define LDDR DDRC	//define MCU direction register for port connected to LCD data pins
#define LCDR DDRC	//define MCU direction register for port connected to LCD control pins

#define LCD_CLR             0	//DB0: clear display
#define LCD_HOME            1	//DB1: return to home position
#define LCD_ENTRY_MODE      2	//DB2: set entry mode
#define LCD_ENTRY_INC       1	//DB1: increment
#define LCD_ENTRY_SHIFT     0	//DB2: shift
#define LCD_ON_CTRL         3	//DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY      2	//DB2: turn display on
#define LCD_ON_CURSOR       1	//DB1: turn cursor on
#define LCD_ON_BLINK        0	//DB0: blinking cursor
#define LCD_MOVE            4	//DB4: move cursor/display
#define LCD_MOVE_DISP       3	//DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT      2	//DB2: move right (0-> left)
#define LCD_FUNCTION        5	//DB5: function set
#define LCD_FUNCTION_8BIT   4	//DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3	//DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2	//DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM           6	//DB6: set CG RAM address
#define LCD_DDRAM           7	//DB7: set DD RAM address
// reading:
#define LCD_BUSY            7	//DB7: LCD is busy
#define LCD_LINES			2	//visible lines
#define LCD_LINE_LENGTH		16	//line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR		0x00
#define LCD_LINE1_DDRAMADDR		0x40
#define LCD_LINE2_DDRAMADDR		0x14
#define LCD_LINE3_DDRAMADDR		0x54
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR	6


void LCDsendChar(uint8_t);		//forms data ready to send to 74HC164
void LCDsendCommand(uint8_t);	//forms data ready to send to 74HC164
void LCDinit(void);			//Initializes LCD
void LCDclr(void);				//Clears LCD
void LCDhome(void);			//LCD cursor home
void LCDstring(uint8_t*, uint8_t);	//Outputs string to LCD
void LCDGotoXY(uint8_t, uint8_t);	//Cursor to X Y position
void CopyStringtoLCD(const uint8_t*, uint8_t, uint8_t);//copies flash string to LCD at x,y
void LCDdefinechar(const uint8_t *,uint8_t);//write char to LCD CGRAM 
void LCDshiftRight(uint8_t);	//shift by n characters Right
void LCDshiftLeft(uint8_t);	//shift by n characters Left
void LCDcursorOn(void);		//Underline cursor ON
void LCDcursorOnBlink(void);	//Underline blinking cursor ON
void LCDcursorOFF(void);		//Cursor OFF
void LCDblank(void);			//LCD blank but not cleared
void LCDvisible(void);			//LCD visible
void LCDcursorLeft(uint8_t);	//Shift cursor left by n
void LCDcursorRight(uint8_t);	//shif cursor right by n
// displays a horizontal progress bar at the current cursor location
// <progress> is the value the bargraph should indicate
// <maxprogress> is the value at the end of the bargraph
// <length> is the number of LCD characters that the bargraph should cover
//adapted from AVRLIB - displays progress only for 8 bit variables
void LCDprogressBar(uint8_t progress, uint8_t maxprogress, uint8_t length);


#endif

lcd_lib.c

C/C++
lcd_lib.c
//*****************************************************************************
//
// File Name	: 'lcd_lib.c'
// Title		: 8 and 4 bit LCd interface
// Author		: Scienceprog.com - Copyright (C) 2007
// Created		: 2007-03-29
// Revised		: 2007-08-08
// Version		: 1.0
// Target MCU	: Atmel AVR series
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include "lcd_lib.h"
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

const uint8_t LcdCustomChar[] PROGMEM=//define 8 custom LCD chars
{
	0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
	0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
	0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
	0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
	0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
	0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
	0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
	0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00  // 7. fast-forward arrow
};


void LCDsendChar(uint8_t ch)		//Sends Char to LCD
{

#ifdef LCD_4bit
	//4 bit part
	LDP=(ch&0b11110000);
	LCP|=1<<LCD_RS;
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);	
	LCP&=~(1<<LCD_RS);
	_delay_ms(1);
	LDP=((ch&0b00001111)<<4);
	LCP|=1<<LCD_RS;
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);	
	LCP&=~(1<<LCD_RS);
	_delay_ms(1);
#else
	//8 bit part
	LDP=ch;
	LCP|=1<<LCD_RS;
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);	
	LCP&=~(1<<LCD_RS);
	_delay_ms(1);
#endif
}
void LCDsendCommand(uint8_t cmd)	//Sends Command to LCD
{
#ifdef LCD_4bit	
	//4 bit part
	LDP=(cmd&0b11110000);
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	LDP=((cmd&0b00001111)<<4);	
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
#else
	//8 bit part
	LDP=cmd;
	LCP|=1<<LCD_E;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);	
#endif
}
void LCDinit(void)//Initializes LCD
{
#ifdef LCD_4bit	
	//4 bit part
	_delay_ms(15);
	LDP=0x00;
	LCP=0x00;
	LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
	LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
   //---------one------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//-----------two-----------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//-------three-------------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4; //4 bit mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//--------4 bit--dual line---------------
	LCDsendCommand(0b00101000);
   //-----increment address, invisible cursor shift------
	LCDsendCommand(0b00001100);
		//init 8 custom chars
	uint8_t ch=0, chn=0;
	while(ch<64)
	{
		LCDdefinechar((LcdCustomChar+ch),chn++);
		ch=ch+8;
	}


#else
	//8 bit part
	_delay_ms(15);
	LDP=0x00;
	LCP=0x00;
	LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_D3
			|1<<LCD_D2|1<<LCD_D1|1<<LCD_D0;
	LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
   //---------one------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
			|0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//-----------two-----------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
			|0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//-------three-------------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|0<<LCD_D3
			|0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
	//--------8 bit dual line----------
	LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_D3
			|0<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(1);
   //-----increment address, invisible cursor shift------
	LDP=0<<LCD_D7|0<<LCD_D6|0<<LCD_D5|0<<LCD_D4|1<<LCD_D3
			|1<<LCD_D2|0<<LCD_D1|0<<LCD_D0; //8 it mode
	LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;		
	_delay_ms(1);
	LCP&=~(1<<LCD_E);
	_delay_ms(5);
		//init custom chars
	uint8_t ch=0, chn=0;
	while(ch<64)
	{
		LCDdefinechar((LcdCustomChar+ch),chn++);
		ch=ch+8;
	}

#endif
}			
void LCDclr(void)				//Clears LCD
{
	LCDsendCommand(1<<LCD_CLR);
}
void LCDhome(void)			//LCD cursor home
{
	LCDsendCommand(1<<LCD_HOME);
}
void LCDstring(uint8_t* data, uint8_t nBytes)	//Outputs string to LCD
{
register uint8_t i;

	// check to make sure we have a good pointer
	if (!data) return;

	// print data
	for(i=0; i<nBytes; i++)
	{
		LCDsendChar(data[i]);
	}
}
void LCDGotoXY(uint8_t x, uint8_t y)	//Cursor to X Y position
{
	register uint8_t DDRAMAddr;
	// remap lines into proper order
	switch(y)
	{
	case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
	case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
	case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
	case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
	default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
	}
	// set data address
	LCDsendCommand(1<<LCD_DDRAM | DDRAMAddr);
	
}
//Copies string from flash memory to LCD at x y position
//const uint8_t welcomeln1[] PROGMEM="AVR LCD DEMO\0";
//CopyStringtoLCD(welcomeln1, 3, 1);	
void CopyStringtoLCD(const uint8_t *FlashLoc, uint8_t x, uint8_t y)
{
	uint8_t i;
	LCDGotoXY(x,y);
	for(i=0;(uint8_t)pgm_read_byte(&FlashLoc[i]);i++)
	{
		LCDsendChar((uint8_t)pgm_read_byte(&FlashLoc[i]));
	}
}
//defines char symbol in CGRAM
/*
const uint8_t backslash[] PROGMEM= 
{
0b00000000,//back slash
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000
};
LCDdefinechar(backslash,0);
*/
void LCDdefinechar(const uint8_t *pc,uint8_t char_code){
	uint8_t a, pcc;
	uint16_t i;
	a=(char_code<<3)|0x40;
	for (i=0; i<8; i++){
		pcc=pgm_read_byte(&pc[i]);
		LCDsendCommand(a++);
		LCDsendChar(pcc);
		}
}

void LCDshiftLeft(uint8_t n)	//Scrol n of characters Right
{
	for (uint8_t i=0;i<n;i++)
	{
		LCDsendCommand(0x1E);
	}
}
void LCDshiftRight(uint8_t n)	//Scrol n of characters Left
{
	for (uint8_t i=0;i<n;i++)
	{
		LCDsendCommand(0x18);
	}
}
void LCDcursorOn(void) //displays LCD cursor
{
	LCDsendCommand(0x0E);
}
void LCDcursorOnBlink(void)	//displays LCD blinking cursor
{
	LCDsendCommand(0x0F);
}
void LCDcursorOFF(void)	//turns OFF cursor
{
	LCDsendCommand(0x0C);
}
void LCDblank(void)		//blanks LCD
{
	LCDsendCommand(0x08);
}
void LCDvisible(void)		//Shows LCD
{
	LCDsendCommand(0x0C);
}
void LCDcursorLeft(uint8_t n)	//Moves cursor by n poisitions left
{
	for (uint8_t i=0;i<n;i++)
	{
		LCDsendCommand(0x10);
	}
}
void LCDcursorRight(uint8_t n)	//Moves cursor by n poisitions left
{
	for (uint8_t i=0;i<n;i++)
	{
		LCDsendCommand(0x14);
	}
}
//adapted fro mAVRLIB
void LCDprogressBar(uint8_t progress, uint8_t maxprogress, uint8_t length)
{
	uint8_t i;
	uint16_t pixelprogress;
	uint8_t c;

	// draw a progress bar displaying (progress / maxprogress)
	// starting from the current cursor position
	// with a total length of "length" characters
	// ***note, LCD chars 0-5 must be programmed as the bar characters
	// char 0 = empty ... char 5 = full

	// total pixel length of bargraph equals length*PROGRESSPIXELS_PER_CHAR;
	// pixel length of bar itself is
	pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
	
	// print exactly "length" characters
	for(i=0; i<length; i++)
	{
		// check if this is a full block, or partial or empty
		// (u16) cast is needed to avoid sign comparison warning
		if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
		{
			// this is a partial or empty block
			if( ((i*(uint16_t)PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
			{
				// this is an empty block
				// use space character?
				c = 0;
			}
			else
			{
				// this is a partial block
				c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
			}
		}
		else
		{
			// this is a full block
			c = 5;
		}
		
		// write character to display
		LCDsendChar(c);
	}

}

Credits

Maneesh Gupta

Maneesh Gupta

1 project • 2 followers
Hana Qudsi

Hana Qudsi

1 project • 2 followers

Comments