/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include // Standard Integer Types #include // Standard IO facilities #include // General utilities #include // Boolean #include // Strings #include // AVR device-specific IO definitions #include // Convenience functions for busy-wait delay loops #include // Interrupts #include // Watchdog timer handling #include // Program Space Utilities #include // Power Management and Sleep Modes #include "uart.h" // basic UART functions #include "main.h" // main definitions /* contants */ // max measurement jitter for high and low value 8/3 #define JITTER_HIGH 11 #define JITTER_LOW 5 // how many value have to be stable before showing output #define MEASUREMENT_STABLE 3 /* variables */ volatile uint8_t state_portD; // the state of port D volatile bool scale_on = false; // is the scale on (based on the SCALE_ON PIN) volatile bool scale_old = false; // the previous state (to detect changes) volatile bool pwm_high = false; // is the PWM for the weight measurement high volatile bool measurement_flag = false; // is a PWM measurement value ready volatile uint16_t measurement_value = 0; // the PWM measurement value from the timer /* switch off LED */ void led_off(void) { PORTB &= ~(1<=measurement_high-JITTER_HIGH) { // stable value measurement_high = (measurement_high+measurement_value)/2; count_high += 1; } else { measurement_high = measurement_value; count_high = 0; } } else { #ifdef DEBUG printf("low: %u\n", measurement_value); #endif if (measurement_value<=measurement_low+JITTER_LOW && measurement_value>=measurement_low-JITTER_LOW) { // stable value measurement_low = (measurement_low+measurement_value)/2; count_low += 1; } else { measurement_low = measurement_value; count_low = 0; } } #ifdef DEBUG printf("values high/low (stable): %u (%u)/%u (%u)\n", measurement_high, count_high, measurement_low, count_low); #endif measurement_flag = false; } /* display weight if values are stable */ if (count_high>=MEASUREMENT_STABLE && count_low>=MEASUREMENT_STABLE) { if (zero_high == 0 && zero_low == 0) { // initialize zero values zero_high = measurement_high; zero_low = measurement_low; #ifdef DEBUG printf("zero values high low: %u %u\n", zero_high, zero_low); #endif count_high = count_low = 0; } else { // print measurement weight #ifdef DEBUG printf("%u %u 0\n", zero_high, zero_low); printf("%u %u t1\n", measurement_high, measurement_low); #endif // the low measurement are linear and more stable // normally it should not have a origin, but the linear estimation shows one and it works better const double orig_low = -1.92285; const double coef_low = 0.0258119; double weight_low = (int16_t)(measurement_low-zero_low)*coef_low+orig_low; if (weight_loworig_low*1.5) { weight_low = 0; } printf("%.2f kg\n", weight_low); } count_high = count_low = 0; } /* display if scale switches off */ if (scale_old!=scale_on && !scale_on) { #ifdef DEBUG printf(PSTR("scale stop\n")); // actually measurement is finished and the on switch is released #endif scale_old = scale_on; // save new state } /* go to sleep and wait for next interrupt */ set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode(); } return 0; }