add weight measurement
This commit is contained in:
parent
b30d73f3fa
commit
336d4e5bda
|
@ -10,6 +10,8 @@ OBJDUMP=avr-objdump
|
||||||
OBJCOPY=avr-objcopy
|
OBJCOPY=avr-objcopy
|
||||||
SIZE=avr-size
|
SIZE=avr-size
|
||||||
CFLAGS=-g -Wall -Werror -O3 -std=c99
|
CFLAGS=-g -Wall -Werror -O3 -std=c99
|
||||||
|
# for this project we need float capable printf
|
||||||
|
LDFLAGS=-lm -Wl,-u,vfprintf -lprintf_flt
|
||||||
# the target (arduino nano)
|
# the target (arduino nano)
|
||||||
DEVICE=atmega328p
|
DEVICE=atmega328p
|
||||||
F_CPU=16000000UL
|
F_CPU=16000000UL
|
||||||
|
@ -66,7 +68,7 @@ compile: $(TARGET).elf
|
||||||
|
|
||||||
# link compiled files
|
# link compiled files
|
||||||
%.elf: $(OBJ)
|
%.elf: $(OBJ)
|
||||||
$(CC) $(CFLAGS) -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) -Wl,-Map=$(TARGET).map,--cref -o $@ $(OBJ)
|
$(CC) $(LDFLAGS) -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) -Wl,-Map=$(TARGET).map,--cref -o $@ $(OBJ)
|
||||||
|
|
||||||
# create extended listing for additional information
|
# create extended listing for additional information
|
||||||
%.lst: %.elf
|
%.lst: %.elf
|
||||||
|
|
|
@ -25,16 +25,24 @@
|
||||||
#include <avr/pgmspace.h> // Program Space Utilities
|
#include <avr/pgmspace.h> // Program Space Utilities
|
||||||
#include <avr/sleep.h> // Power Management and Sleep Modes
|
#include <avr/sleep.h> // Power Management and Sleep Modes
|
||||||
|
|
||||||
|
|
||||||
#include "uart.h" // basic UART functions
|
#include "uart.h" // basic UART functions
|
||||||
#include "main.h" // main definitions
|
#include "main.h" // main definitions
|
||||||
|
|
||||||
|
/* contants */
|
||||||
|
// max measurement jitter for high and low value
|
||||||
|
#define JITTER_HIGH 8
|
||||||
|
#define JITTER_LOW 3
|
||||||
|
// how many value have to be stable before showing output
|
||||||
|
#define MEASUREMENT_STABLE 3
|
||||||
|
// weight coefficient (timer 1 ticks/kg)
|
||||||
|
// proportionally decreasing for high, increasing for low
|
||||||
|
#define COEF_HIGH 41.78
|
||||||
|
#define COEF_LOW 39.87
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
volatile uint8_t state_portD; // the state of port D
|
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_on = false; // is the scale on (based on the SCALE_ON PIN)
|
||||||
#ifdef DEBUG
|
|
||||||
volatile bool scale_old = false; // the previous state (to detect changes)
|
volatile bool scale_old = false; // the previous state (to detect changes)
|
||||||
#endif
|
|
||||||
volatile bool pwm_high = false; // is the PWM for the weight measurement high
|
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 bool measurement_flag = false; // is a PWM measurement value ready
|
||||||
volatile uint16_t measurement_value = 0; // the PWM measurement value from the timer
|
volatile uint16_t measurement_value = 0; // the PWM measurement value from the timer
|
||||||
|
@ -144,37 +152,76 @@ void io_init(void)
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
uint16_t measurement_high = 0, measurement_low = 0; // the average measurement value
|
||||||
|
uint16_t zero_high = 0, zero_low = 0; // the intial zero value
|
||||||
|
uint8_t count_high = 0, count_low = 0; // the number of stable counts
|
||||||
|
|
||||||
io_init(); // initialize IOs
|
io_init(); // initialize IOs
|
||||||
|
|
||||||
printf(PSTR("welcome to the body scale weight reader\n")); // print welcome message
|
printf(PSTR("welcome to the body scale weight reader\n")); // print welcome message
|
||||||
while (true) { // endless loop for micro-controller
|
while (true) { // endless loop for micro-controller
|
||||||
#ifdef DEBUG
|
|
||||||
/* display if scale switches on */
|
/* display if scale switches on */
|
||||||
if (scale_old!=scale_on && scale_on) {
|
if (scale_old!=scale_on && scale_on) {
|
||||||
|
#ifdef DEBUG
|
||||||
printf(PSTR("scale start\n"));
|
printf(PSTR("scale start\n"));
|
||||||
scale_old=scale_on;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
measurement_high = measurement_low = zero_high = zero_low = count_high = count_low = 0; // re-initialize values
|
||||||
|
scale_old = scale_on; // save new state
|
||||||
|
}
|
||||||
/* display value if available */
|
/* display value if available */
|
||||||
if (measurement_flag) {
|
if (measurement_flag) {
|
||||||
if (pwm_high) {
|
if (pwm_high) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("high: %u\n",measurement_value);
|
printf("high: %u\n", measurement_value);
|
||||||
#endif
|
#endif
|
||||||
|
if (measurement_value<=measurement_high+JITTER_HIGH && measurement_value>=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 {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("low: %u\n",measurement_value);
|
printf("low: %u\n", measurement_value);
|
||||||
#endif
|
#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;
|
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
|
#ifdef DEBUG
|
||||||
|
printf("zero values high/low: %u/%u\n", zero_high, zero_low);
|
||||||
|
#endif
|
||||||
|
} else { // prinf measurement weight
|
||||||
|
double weight_high = (int16_t)(zero_high-measurement_high)/COEF_HIGH;
|
||||||
|
double weight_low = (int16_t)(measurement_low-zero_low)/COEF_LOW;
|
||||||
|
double weight = (weight_high+weight_low)/2;
|
||||||
|
printf("%d kg\n", zero_high-measurement_high);
|
||||||
|
printf("%.2f kg\n", weight);
|
||||||
|
}
|
||||||
|
count_high = count_low = 0;
|
||||||
|
}
|
||||||
/* display if scale switches off */
|
/* display if scale switches off */
|
||||||
if (scale_old!=scale_on && !scale_on) {
|
if (scale_old!=scale_on && !scale_on) {
|
||||||
|
#ifdef DEBUG
|
||||||
printf(PSTR("scale stop\n"));
|
printf(PSTR("scale stop\n"));
|
||||||
scale_old=scale_on;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
scale_old = scale_on; // save new state
|
||||||
|
}
|
||||||
/* go to sleep and wait for next interrupt */
|
/* go to sleep and wait for next interrupt */
|
||||||
set_sleep_mode(SLEEP_MODE_IDLE);
|
set_sleep_mode(SLEEP_MODE_IDLE);
|
||||||
sleep_mode();
|
sleep_mode();
|
||||||
|
|
Loading…
Reference in New Issue