/********************************************* 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> |