/***************************************************************************** * basestation.c * Lab 6: Final Project * ECE 476: Digital Systems Design Using Microcontrollers * Cornell University * April 2008 * Andrw Chin (hc454) and Ping-Hong Lu (pl328) ****************************************************************************/ /****************************************************************************/ #include #include #include #define SAMPLE_TIMEOUT 15 unsigned char sample_timer; unsigned char led; unsigned int led_toggle_count; unsigned char start_time_count; unsigned int timer_count; unsigned int cal_burned; unsigned char r_buffer[6]; //input string unsigned char old_meters; unsigned int speed_timer; unsigned char speed; float cal_const; /****************************************************************************/ // This interrupt runs when a compare-match occurs every 1 ms. It decrements // the sample_timer global variable which is then used to determine when the // "sample" task runs. interrupt [TIM0_COMPA] void ms_timer(void) { if (sample_timer > 0) sample_timer--; timer_count++; PORTD.2 = ~PORTD.2; } /****************************************************************************/ // This task runs every 15 ms and requests data from the transmitter each // time sample runs. It receives the distance, steps, and speed information // from the wearable sensor and calculates the calories burned. // and z accelerations going above and below certian thresholds. The distance, // steps, and speed information is sent to the basestation every time sample runs. void sample(void) { unsigned char delay; // Turn the radio from receive to transmit mode RF_rx_to_tx(); tx_frame_length = 1; transmit_frame[0] = DATA_REQ; // Get data ready for tx RF_download_frame(); // Transmit RF_transmit_frame(); RF_wait_for_transmit(); // Turn the radio from transmit to receive mode RF_tx_to_rx(); //get ready to rx RF_clear_IRQ(); delay_us(100); delay = RF_receiver_listen_timeout(40); //listen for 10ms if (delay != 0) { //we have received something PORTD.7 = ~PORTD.7; RF_upload_frame(); // Calculations are based on the speed at which the user moves // and can change dynamically so set the mult factor if (receive_frame[2] < 3) cal_const = .00098; else if (receive_frame[2] < 5) cal_const = .0015; else if (receive_frame[2] < 7) cal_const = .00192; else cal_const = .00348; // calories burned = factor * weight * time cal_burned = (int)(cal_const * (float)r_buffer[0] * (float)receive_frame[0] / (float)receive_frame[2]); if (cal_burned == -1) cal_burned = 0; printf("meters: %d steps: %d speed: %d cals burned: %d \r", receive_frame[0], receive_frame[1], receive_frame[2], cal_burned); if (old_meters != receive_frame[0]) { // speed = distance / time * 2.237 speed = (int)(((1 / timer_count)) * 2237); old_meters = receive_frame[0]; timer_count = 0; } } speed_timer++; // LED Toggling code to indicate Mega64 not hung /* led_toggle_count++; if (led_toggle_count == 8) { led_toggle_count = 0; if (led == 0) { led = 1; PORTD.2 = 0; } else { led = 0; PORTD.2 = 1; } } */ } /****************************************************************************/ // This function correctly initializes the necessary control registers and // I/O ports as well as initializes global variables to zero. Lastly, it // enables all interrupts. void initialize(void) { DDRD.2 = 1; PORTD.2 = 1; DDRD.7 = 1; DDRA = 0xFF; PORTA = 0; // Initialize Mega64's SPI settings init_spi(); // Initialize transceiver SPI RF_init_spi(); set_transceiver_clock(); // Put transceiver in receiver mode RF_init_receiver(); PORTD.7 = 0; sample_timer = SAMPLE_TIMEOUT; TCCR0A = 0b00000010; //OC0A & OC0B disconnected, WGM set up for CTC mode TCCR0B = 0b00000011; //Timer set up to osc/64... count to 125 for 1 ms OCR0A = 125; // Interrupt on compare match A TIMSK0 = 0b00000010; led = 0; led_toggle_count = 0; start_time_count = 0; timer_count = 0; cal_burned = 0; old_meters = 0; speed_timer = 0; // Set up UART & print welcome message UCSR0B = 0x18 ; UBRR0L = 51 ; printf("\rWelcome to the ECE 476 pedometer! \n\n\n\r") ; //Enable interrupts #asm sei #endasm } /****************************************************************************/ // This function prints the welcome message to the screen via a serial // connection. It also prompts the user for their weight which will be used // in the calories burned calculation. void get_inputs(void) { printf("1) Please keep the wearable sensor off\n\r2) Please enter your weight: "); scanf("%d",r_buffer); printf("%d\n\r3) Please turn on sensor and wait for green light\n\n\n\r", r_buffer[0]); } /****************************************************************************/ // The main function starts by calling the initialization function and // getting the user's weight. It then runs whenever the interrupt has counted // down the sample_timer variable to zero. void main(void) { initialize(); get_inputs(); while(1) { if (sample_timer == 0) { sample_timer = SAMPLE_TIMEOUT; sample(); } } } /****************************************************************************/