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