Prototype Code

/*********************************************

Project : ATmega128_MT

Version : 01

Date    : 14.1.2007

Author  : Slavcho TOmov  - altered by Paul McIntosh              

Company : Olimex                           

Comments: Demo program

 

 

Chip type           : ATmega128

Program type        : Application

Clock frequency     : 16,000000 MHz

Memory model        : Small

External SRAM size  : 0

Data Stack size     : 1024

*********************************************/

#include <avr/io.h>

// #include <avr/iom128.h>

#include <avr/interrupt.h>

 

#include <stdio.h>

#include "system.h"

#include "bits.h"

#include "lcd.h"

#include "delay.h"

                                                       

 

#define              B1                         (PINA&BIT0) 

#define              B2                         (PINA&BIT1)

#define              B3                         (PINA&BIT2)

#define              B4                         (PINA&BIT3)

#define              B5                          (PINA&BIT4)

 

 

#define       RELAY_HIGH           PORTA |= BIT6

#define       RELAY_LOW            PORTA &= ~BIT6                            

 

#define              TXD                        (PIND&BIT3)  

#define              RXD                        (PIND&BIT2)  

#define              DALLAS               (PINA&BIT5)

    

unsigned char ch;

int wheelSensorTiggered = 0;                           // rising edge trigger for wheelsensor (debounce needed?)

double volatile wheelSensorPeriodms = 0; // measure ms since last sensor trigger

double volatile lastWheelSensorPeriodms = 0;// last measure ms since last sensor trigger

double volatile wheelDiameter = 1.354;                        // metre measureed around tyre 1354mm Vespa PX Sava MC18

double volatile speedmps = 0;                          // internally we'll use m/s for keeping track of speed

double volatile lastSpeedmps = 0;                             // keep the last reading for keeping a track of acceleration

int triggerCount = 0;                                         // int speedkmhr = 0;

int flash = 0;

int volatile vespaMass = 110;                                        // Kg (wet weight)

int volatile riderMass = 100;                                        // Kg (rider plus gear)

double volatile maxKWpositive = 0;              // Highest positive reading of KW based on change in speed

double volatile lastKWpositive = 0;                    // Last positive reading of KW based on change in speed

double volatile maxKWnegative = 0;              // Highest negative reading of KW based on change in speed

double volatile lastKWnegative = 0;                    // Last negative reading of KW based on change in speed

 

int main(void) {    

 

       //Ports

       InitPorts();

 

       // Enable Interupts

       InterruptInit();

 

       // 1 second timer for display updates

       TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode

       TCCR1B |= ((1 << CS10) | (1 << CS12)); // Start timer at Fcpu/1024

       OCR1A   = 15625; // Set CTC compare value to 1Hz at 16MHz AVR clock, with a prescaler of 1024

 

       // A timer for speed measurement

       //  (may decrease this later for more accurate measurement)

       TCCR3B |= ((1 << CS30) | (1 << CS32)); // Start timer at Fcpu/1024

                             

       //LCD initialisation

       LCD_Ini();                                    

       // delay_ms(2);           

       SEND_CMD(DISP_ON);

       // delay_ms(10);                                      

       SEND_CMD(CLR_DISP);

       // write

 

       char  buf[14];

       sprintf(buf, "Vespa Labs");

       SEND_STR(buf);

       delay_ms( 200 );

 

       while (1)

       { 

              if (B4==0) // reset max values

              {

                     maxKWpositive = 0;

                     maxKWnegative = 0;

                     SEND_CMD(CLR_DISP);

              }

 

              if (TIFR & (1 << OCF1A))

      {

                     if (flash)

                     {

                           sprintf(buf, "km/hr: %3.1f %3.1f %3.1f ", speedmps*60*60/1000,maxKWpositive*1.341,maxKWnegative*1.341);//(speedmps/1000*60*60));

                           flash = 0;

                     }

                     else

                     {

                           sprintf(buf, "km/hr  %3.1f %3.1f %3.1f ", speedmps*60*60/1000,maxKWpositive*1.341,maxKWnegative*1.341);//(speedmps/1000*60*60));

                           flash = 1;

                     }

                     SEND_STR(buf);

              TIFR = (1 << OCF1A); // clear the CTC flag (writing a logic one to the set flag clears it)

      }

       }

}

 

//-------------------------------

// Initialize External Interrupts

//-------------------------------

void InterruptInit()

{

       EIMSK |= (0 << INT0);   // disable interrupt INT0 in external interrupt mask

      

       DDRD |= (0 << DDD0);    // enable Port D, pin 0 (INT0) for input

       EICRA |= (1 << ISC01) | (0 << ISC00);   // falling edge generates interrupt

       // set port pin for internal pull up, so only when switch grounds out should this interrupt

       PORTD &= 0xff;  

      

       EIFR  = (1 << INTF0 );  // clear interrupt flag for INT0 before setting mask

       EIMSK |= (1 << INT0);   // enable interrupt INT0 in external interrupt mask

 

       sei();

 

} // InterruptInit()

 

//-------------------------------

// Wheel Sensor Interrupt

//-------------------------------

ISR (INT0_vect)

{

       cli();                                   // disable interrupts    

        

      

       // Measure wheel sensor period and reset the clock                                                                  

       wheelSensorPeriodms = TCNT3 / 15.625;    // calculated time to revolve in ms

       TCNT3 = 0;

                                                              // Reset timer value

       // Calculate speed in metres per second                                                               

       speedmps = 1000/wheelSensorPeriodms * wheelDiameter;

             

       // Determine KW from change in speed (letting compiler optimize this to make it easier to read)

       double acceleration = (speedmps - lastSpeedmps)/(wheelSensorPeriodms + lastWheelSensorPeriodms) * 1000; // metres second per second

       double newtons = (vespaMass + riderMass) * acceleration;     

       double KWatts = (newtons * ((lastSpeedmps + speedmps)/2))/1000;

       if (KWatts >= 0 && KWatts > maxKWpositive) maxKWpositive = KWatts;

       if (KWatts <= 0 && KWatts < maxKWnegative) maxKWnegative = KWatts;

       EIFR  |= (1 << INTF0 );  // clear interrupt flag for INT0, ya it's odd to write a 1 to clear it, but that's AVR

      

       // Keep a track of last value for other measurements

       lastSpeedmps = speedmps;

       lastWheelSensorPeriodms = wheelSensorPeriodms;

 

       //debounce delay

       int i = 1000;

       while (--i!=0);

 

       sei();

 

} // ISR (INT0_vect)

 

 

</body> </html>