View Single Post
Old 03-22-2008, 12:13 PM   #83 (permalink)
Coyote X
nut
 
Coyote X's Avatar
 
Join Date: Dec 2007
Location: Southen West Virginia
Posts: 654

Metro XFi - '93 Geo Metro XFi Convertible
90 day: 62.17 mpg (US)

DR650SE - '07 Suzuki DR650SE
90 day: 55.26 mpg (US)
Thanks: 0
Thanked 37 Times in 26 Posts
Send a message via MSN to Coyote X
if you guys want an atmel based system to chew on here is a programmable nitrous controller I wrote that is based on rpm and uses pwm to drive a solenoid. It uses an atmega32 and 4x20 lcd with 4 buttons. The menu interface is very simple and can do anything you can imagine, it is on the bottom half of the code. This was written in Codevision AVR C

Code:
/*********************************************
This program was produced by the
CodeWizardAVR V1.24.0 Standard
Automatic Program Generator
© Copyright 1998-2003 HP InfoTech s.r.l.
http://www.hpinfotech.ro
e-mail:office@hpinfotech.ro

Project : 
Version : 
Date    : 1/22/2005
Author  : Rick                            
Company :                                 
Comments: 


Chip type           : ATmega32
Program type        : Application
Clock frequency     : 16.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 512
*********************************************/

#include <mega32.h>
#include <delay.h>
#include <stdio.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15
#endasm
#include <lcd.h>
// Declare your global variables here
unsigned long int timecount = 0; //global time counter
unsigned long int period;
unsigned long int time, oldtimecount = 0;
unsigned int rpm = 0; // engine rpm
unsigned int pulsecount = 0;
char lcd_buffer[16];   // LCD display buffer
char display = 1;
char Key = 0, menutimer = 0,per = 0;
eeprom unsigned int pprpm = 2;
eeprom unsigned int cutoff_rpm = 6500;
eeprom unsigned int start_rpm = 3500, fullpower_rpm = 4500;

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if (pulsecount == pprpm*2){
	time = timecount<<8;
	time = time + TCNT0;
	if (time > oldtimecount) period = time - oldtimecount;  
	  else period = 4294967295 - time + oldtimecount;
	  rpm = (60000000/(float)period)*(float)pprpm*2;
          oldtimecount = time;
          pulsecount = 1;
        }
   else pulsecount +=1;       
 
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
	if (timecount == 16777215) timecount = 0; else timecount += 1;

}




void setpwm(void)
{
if (rpm <= cutoff_rpm) {
   if (rpm < start_rpm) per = 0;
   if (rpm > fullpower_rpm) per = 255;
   if ((rpm >= start_rpm) && (rpm <= fullpower_rpm))
         {
         per = ( (unsigned long int)(rpm-start_rpm )*255/( (unsigned long int)fullpower_rpm-(unsigned long int)start_rpm) );
        
    
         }//else

    }//if cutoff-rpm
     else per = 0;
 OCR1A = per;
} // setpwm
//////////////////////////////////////////////////////////////////////KEYSCAN///////////////////////////////////////////////////////// 
void KeyScan(void)
{
	Key = 0;
	if (PINB.0 == 0)	// UP
		Key = 1;
	if (PINB.1 == 0)	// left
		Key = 2;
	if (PINB.2 == 0)	// right
		Key = 3;
	if (PINB.3 == 0)	// down
		Key = 4;
} // KeyScan Subroutine
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In 
// State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out Func7=Out 
// State0=0 State1=0 State2=0 State3=0 State4=0 State5=0 State6=0 State7=0 
PORTB=0xFF;
DDRB=0xFF;

// Port C initialization
// Func0=Out Func1=Out Func2=Out Func3=Out Func4=Out Func5=Out Func6=Out Func7=Out 
// State0=0 State1=0 State2=0 State3=0 State4=0 State5=0 State6=0 State7=0 
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=In Func5=Out Func6=In Func7=Out 
// State0=T State1=T State2=T State3=T State4=T State5=0 State6=T State7=0 
PORTD=0x00;
DDRD=0xA0;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 2000.000 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x02;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15.625 kHz
// Mode: Ph. correct PWM top=00FFh
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x81;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 250.000 kHz
// Mode: Phase correct PWM top=FFh
// OC2 output: Non-Inverted PWM
ASSR=0x00;
TCCR2=0x64;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
// INT2: Off
GICR|=0x40;
MCUCR=0x03;
MCUCSR=0x00;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      {
setpwm();
KeyScan();


if (Key == 1)
       {
        while (Key != 0) KeyScan(); // wait for key to let go.
	if (display <= 10) display = display + 1; else display = 2;
	menutimer = 0;
        };//if key = 1

if (menutimer == 100) {menutimer = 0; display = 1;};

switch (display)
    { 
    case 1:
        {lcd_gotoxy(0,0);
        _lcd_ready();
	_lcd_write_data(0xC);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
         sprintf(lcd_buffer,"%4u RPM %u%%",rpm,(int)((double)per/2.55));
	 lcd_puts(lcd_buffer);
	 break;
        }//1
    case 2:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Start RPM ");
        sprintf(lcd_buffer,"%-4u",start_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(10,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if (start_rpm/1000 < 9) start_rpm = start_rpm + 1000; 
			else start_rpm = start_rpm - 9000;
		} //if
	break;
        }//2
     case 3:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Start RPM ");
        sprintf(lcd_buffer,"%-4u",start_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(11,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (start_rpm-start_rpm/1000*1000)/100 < 9) start_rpm = start_rpm + 100; 
			else start_rpm = start_rpm - 900;
		} //if
	break;
        }//3
      case 4:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Start RPM ");
        sprintf(lcd_buffer,"%-4u",start_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(12,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (start_rpm - (start_rpm/1000*1000) - ((start_rpm-start_rpm/1000*1000)/100*100) ) /10 < 9) start_rpm = start_rpm + 10; 
			else start_rpm = start_rpm - 90;
		} //if
	break;
        }//4
    ////////////////////// full power rpm
    case 5:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("100% RPM  ");
        sprintf(lcd_buffer,"%-4u",fullpower_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(10,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if (fullpower_rpm/1000 < 9) fullpower_rpm = fullpower_rpm + 1000; 
			else fullpower_rpm = fullpower_rpm - 9000;
		} //if
	break;
        }//5
     case 6:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("100% RPM  ");
        sprintf(lcd_buffer,"%-4u",fullpower_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(11,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (fullpower_rpm-fullpower_rpm/1000*1000)/100 < 9) fullpower_rpm = fullpower_rpm + 100; 
			else fullpower_rpm = fullpower_rpm - 900;
		} //if
	break;
        }//6
      case 7:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("100% RPM  ");
        sprintf(lcd_buffer,"%-4u",fullpower_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(12,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (fullpower_rpm - (fullpower_rpm/1000*1000) - ((fullpower_rpm-fullpower_rpm/1000*1000)/100*100) ) /10 < 9) fullpower_rpm = fullpower_rpm + 10; 
			else fullpower_rpm = fullpower_rpm - 90;
		} //if
	break;
        }//7
///////////////////////////////       cutoff
case 8:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Cutoff RPM ");
        sprintf(lcd_buffer,"%-4u",cutoff_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(11,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if (cutoff_rpm/1000 < 9) cutoff_rpm = cutoff_rpm + 1000; 
			else cutoff_rpm = cutoff_rpm - 9000;
		} //if
	break;
        }//8
     case 9:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Cutoff RPM ");
        sprintf(lcd_buffer,"%-4u",cutoff_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(12,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (cutoff_rpm-cutoff_rpm/1000*1000)/100 < 9) cutoff_rpm = cutoff_rpm + 100; 
			else cutoff_rpm = cutoff_rpm - 900;
		} //if
	break;
        }//9
      case 10:{
        if (Key == 0){
         lcd_gotoxy(0,0);
         lcd_putsf("                ");
	 lcd_gotoxy(0,0);
	 lcd_putsf("Cutoff RPM ");
        sprintf(lcd_buffer,"%-4u",cutoff_rpm);
        lcd_puts(lcd_buffer);
        lcd_gotoxy(13,0);
        _lcd_ready();
	_lcd_write_data(0xF);
	}//if
	if (Key == 2){
		while (Key != 0) KeyScan();      //debounce
		menutimer = 0;
		if ( (cutoff_rpm - (cutoff_rpm/1000*1000) - ((cutoff_rpm-cutoff_rpm/1000*1000)/100*100) ) /10 < 9) cutoff_rpm = cutoff_rpm + 10; 
			else cutoff_rpm = cutoff_rpm - 90;
		} //if
	break;
        }//10    
      
    }//switch
delay_ms(50);
menutimer += 1;
}//while 1

}

that book I recommended earlier in this thread and the free version of codevision is all that is required to understand this setup totally. Once you read that book understanding this code will be really easy. I don't think you can get a simpler to program system than an atmel. Also this code can be modified to display mpg without a lot of effort, just kill the pwm output for the nitrous solenoid and modify the menu to calc your mileage #s you want.
__________________


  Reply With Quote