Fixed all logic. Check EEPROM scanner logic
This commit is contained in:
parent
4cf149a7f1
commit
b9039f7af6
191
code/main.c
191
code/main.c
@ -68,10 +68,10 @@ uint32_t ms = 0;
|
||||
|
||||
const uint8_t PROGMEM rot_table[16] =
|
||||
{
|
||||
EVENT_NONE, EVENT_ROT_CW, EVENT_ROT_CCW, EVENT_NONE,
|
||||
EVENT_ROT_CCW, EVENT_NONE, EVENT_NONE, EVENT_ROT_CW,
|
||||
EVENT_NONE, EVENT_ROT_CCW, EVENT_ROT_CW, EVENT_NONE,
|
||||
EVENT_ROT_CW, EVENT_NONE, EVENT_NONE, EVENT_ROT_CCW,
|
||||
EVENT_NONE, EVENT_ROT_CCW, EVENT_ROT_CW, EVENT_NONE
|
||||
EVENT_ROT_CCW, EVENT_NONE, EVENT_NONE, EVENT_ROT_CW,
|
||||
EVENT_NONE, EVENT_ROT_CW, EVENT_ROT_CCW, EVENT_NONE
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM unfold_table[16] =
|
||||
@ -121,7 +121,7 @@ void display_init();
|
||||
void display_enable(uint8_t en);
|
||||
void get_symbol16(uint8_t index, uint8_t *out);
|
||||
void print_symbol(uint8_t symbol_idx, uint8_t x, uint8_t y, uint8_t invert);
|
||||
void print_mm(uint32_t value, uint32_t highlight);
|
||||
void print_mm(uint32_t value, uint8_t highlight);
|
||||
void print_direction(uint8_t is_up, uint8_t invert);
|
||||
void print_voltage(uint16_t value);
|
||||
uint16_t adc_measure();
|
||||
@ -131,6 +131,7 @@ void read_eeprom_val(uint16_t idx, uint32_t *value, uint8_t *dir);
|
||||
void write_eeprom_val(uint16_t idx, uint32_t value, uint8_t dir);
|
||||
void do_sleep();
|
||||
void update_display(uint32_t value, uint32_t highlight, uint8_t dir, uint8_t dir_highlight);
|
||||
uint8_t extract_digit(uint32_t value, uint8_t digit_num);
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
@ -198,9 +199,10 @@ int main()
|
||||
uint16_t eeprom_idx = 0;
|
||||
uint8_t move_dir = 0;
|
||||
int8_t rot_value = 0;
|
||||
uint8_t dir_highlight = 0;
|
||||
uint8_t highlight = 0;
|
||||
uint8_t needs_update = 0;
|
||||
|
||||
uint32_t highlight;
|
||||
uint8_t dir_highlight;
|
||||
uint8_t curr_event;
|
||||
uint8_t state;
|
||||
|
||||
@ -217,6 +219,8 @@ int main()
|
||||
{
|
||||
eeprom_idx = 0;
|
||||
state = STATE_SETTING;
|
||||
highlight = 6;
|
||||
needs_update = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -224,6 +228,8 @@ int main()
|
||||
if (0 == eeprom_value)
|
||||
{
|
||||
state = STATE_SETTING;
|
||||
highlight = 6;
|
||||
needs_update = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -234,6 +240,7 @@ int main()
|
||||
|
||||
if (STATE_COUNTING == state)
|
||||
{
|
||||
sleep_when_ms = 1;
|
||||
display_enable(0);
|
||||
}
|
||||
|
||||
@ -243,7 +250,7 @@ int main()
|
||||
switch (state)
|
||||
{
|
||||
case STATE_COUNTING:
|
||||
if (event_count > 0)
|
||||
while (event_count > 0)
|
||||
{
|
||||
// Consume Event
|
||||
cli();
|
||||
@ -259,7 +266,7 @@ int main()
|
||||
long_press_when_ms = ms + LONG_PRESS;
|
||||
sleep_when_ms = ms + DISPLAY_DELAY;
|
||||
display_enable(1);
|
||||
update_display(count_value, 0, move_dir, 0);
|
||||
needs_update = 1;
|
||||
break;
|
||||
|
||||
case EVENT_BUTTON_UP:
|
||||
@ -303,13 +310,30 @@ int main()
|
||||
adjust = -1;
|
||||
}
|
||||
|
||||
count_value_fine += (rot_coeff * adjust * rot_abs);
|
||||
count_value = (uint32_t) count_value_fine;
|
||||
rot_value -= (rot_abs * adjust);
|
||||
count_value_fine += (rot_coeff * adjust * rot_abs);
|
||||
|
||||
if (count_value_fine < 0)
|
||||
{
|
||||
count_value_fine = 0;
|
||||
state = STATE_SETTING;
|
||||
display_enable(1);
|
||||
needs_update = 1;
|
||||
sleep_when_ms = 0;
|
||||
}
|
||||
|
||||
// Update EEPROM When Meter Value Changes
|
||||
if ((uint32_t)count_value_fine / 1000 != count_value / 1000)
|
||||
{
|
||||
++eeprom_idx;
|
||||
eeprom_idx %= EEPROM_SIZE;
|
||||
write_eeprom_val(eeprom_idx, (uint32_t)count_value_fine, move_dir);
|
||||
}
|
||||
count_value = (uint32_t) count_value_fine;
|
||||
|
||||
if (0 != sleep_when_ms)
|
||||
{
|
||||
update_display(count_value, 0, move_dir, 0);
|
||||
needs_update = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,14 +341,13 @@ int main()
|
||||
{
|
||||
sleep_when_ms = 0;
|
||||
long_press_when_ms = 0;
|
||||
highlight = 100000;
|
||||
update_display(count_value, highlight, move_dir, 0);
|
||||
highlight = 6;
|
||||
needs_update = 1;
|
||||
state = STATE_SETTING;
|
||||
}
|
||||
|
||||
if ((0 != sleep_when_ms) && (sleep_when_ms < ms))
|
||||
{
|
||||
sleep_when_ms = 0;
|
||||
display_enable(0);
|
||||
do_sleep();
|
||||
}
|
||||
@ -333,7 +356,7 @@ int main()
|
||||
break;
|
||||
|
||||
case STATE_SETTING:
|
||||
if (event_count > 0)
|
||||
while (event_count > 0)
|
||||
{
|
||||
// Consume Event
|
||||
cli();
|
||||
@ -347,7 +370,6 @@ int main()
|
||||
{
|
||||
case EVENT_BUTTON_DOWN:
|
||||
long_press_when_ms = ms + LONG_PRESS;
|
||||
display_enable(1);
|
||||
break;
|
||||
|
||||
case EVENT_BUTTON_UP:
|
||||
@ -370,15 +392,23 @@ int main()
|
||||
if (0 != highlight)
|
||||
{
|
||||
uint32_t temp_count = count_value;
|
||||
temp_count = count_value % (highlight * 10);
|
||||
uint32_t div = 1;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 1; i < highlight; ++i)
|
||||
{
|
||||
div *= 10;
|
||||
}
|
||||
|
||||
temp_count = count_value % (div * 10);
|
||||
count_value -= temp_count;
|
||||
temp_count += highlight;
|
||||
temp_count %= highlight * 10;
|
||||
temp_count += div;
|
||||
temp_count %= div * 10;
|
||||
count_value += temp_count;
|
||||
count_value_fine = count_value;
|
||||
}
|
||||
|
||||
update_display(count_value, highlight, move_dir, dir_highlight);
|
||||
needs_update = 1;
|
||||
}
|
||||
long_press_when_ms = 0;
|
||||
|
||||
@ -393,29 +423,37 @@ int main()
|
||||
|
||||
if (0 != highlight)
|
||||
{
|
||||
highlight /= 10;
|
||||
--highlight;
|
||||
if (0 == highlight)
|
||||
{
|
||||
dir_highlight = 1;
|
||||
}
|
||||
needs_update = 1;
|
||||
}
|
||||
else if (0 != dir_highlight)
|
||||
{
|
||||
dir_highlight = 0;
|
||||
state = STATE_COUNTING;
|
||||
sleep_when_ms = ms + DISPLAY_DELAY;
|
||||
needs_update = 1;
|
||||
|
||||
++eeprom_idx;
|
||||
eeprom_idx %= EEPROM_SIZE;
|
||||
write_eeprom_val(eeprom_idx, count_value, move_dir);
|
||||
}
|
||||
|
||||
update_display(count_value, highlight, move_dir, dir_highlight);
|
||||
needs_update = 1;
|
||||
long_press_when_ms = 0;
|
||||
}
|
||||
|
||||
// STATE_SETTING
|
||||
break;
|
||||
}
|
||||
if (needs_update)
|
||||
{
|
||||
update_display(count_value, highlight, move_dir, dir_highlight);
|
||||
needs_update = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,8 +462,8 @@ void simple_init()
|
||||
// Set pull-ups on button and rotary encoder
|
||||
PORTB = (1 << 1) | (1 << 3) | (1 << 4);
|
||||
|
||||
// Prescaler 1024
|
||||
TCCR1 = (1 << CS13) | (1 << CS11) | (1 << CS10);
|
||||
// Prescaler 4 (1 MHz / 256 / 4 ~ 1000)
|
||||
TCCR1 = (1 << CS11) | (1 << CS10);
|
||||
|
||||
// Enable Interrupt on overflow
|
||||
TIMSK = (1 << TOIE1);
|
||||
@ -442,8 +480,8 @@ void simple_init()
|
||||
// Measure Vbg(1.1V) with Vcc reference
|
||||
ADMUX = (1 << MUX3) | (1 << MUX2);
|
||||
|
||||
// ADC prescaler 16
|
||||
ADCSRA = (1 << ADPS2);
|
||||
// ADC prescaler 8
|
||||
ADCSRA = (1 << ADPS1) | (1 << ADPS0);
|
||||
|
||||
// Power reduction - Disable timer 0
|
||||
PRR = (1 << PRTIM0);
|
||||
@ -623,29 +661,26 @@ void print_symbol(uint8_t symbol_idx, uint8_t x, uint8_t y, uint8_t invert)
|
||||
display_send_data(unfolded_symbol, sizeof(unfolded_symbol));
|
||||
}
|
||||
|
||||
void print_mm(uint32_t value, uint32_t highlight)
|
||||
void print_mm(uint32_t value, uint8_t highlight)
|
||||
{
|
||||
static uint32_t old_value = 0;
|
||||
static uint8_t old_highlight = 0;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t symbol;
|
||||
uint8_t invert;
|
||||
uint8_t is_first;
|
||||
uint32_t div_factor;
|
||||
uint8_t i;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
div_factor = 1000000;
|
||||
value %= div_factor;
|
||||
div_factor /= 10;
|
||||
is_first = 1;
|
||||
|
||||
// Print 6 digits
|
||||
while (div_factor != 0)
|
||||
// Print 6 digits (only needed ones)
|
||||
for (i = 6; i > 0; --i)
|
||||
{
|
||||
symbol = value / div_factor;
|
||||
value %= div_factor;
|
||||
|
||||
if (div_factor == highlight)
|
||||
symbol = extract_digit(value, i);
|
||||
if (highlight == i)
|
||||
{
|
||||
invert = 1;
|
||||
}
|
||||
@ -654,8 +689,7 @@ void print_mm(uint32_t value, uint32_t highlight)
|
||||
invert = 0;
|
||||
}
|
||||
|
||||
// Check if we need to print (for leading zeroes)
|
||||
if (is_first && (0 == highlight) && (0 == symbol))
|
||||
if (is_first && (0 == highlight) && (0 == symbol) && (1 != i))
|
||||
{
|
||||
symbol = 0xFF;
|
||||
}
|
||||
@ -663,20 +697,30 @@ void print_mm(uint32_t value, uint32_t highlight)
|
||||
{
|
||||
is_first = 0;
|
||||
}
|
||||
print_symbol(symbol, x, y, invert);
|
||||
|
||||
if ((0 == old_value) || (symbol != extract_digit(old_value, i)) || (old_highlight != highlight))
|
||||
{
|
||||
print_symbol(symbol, x, y, invert);
|
||||
}
|
||||
x += (CHAR_SIZE + 1) * 2;
|
||||
div_factor /= 10;
|
||||
}
|
||||
|
||||
// Print 'mm'
|
||||
print_symbol(10, x, y, 0);
|
||||
x += (CHAR_SIZE + 1) * 2;
|
||||
print_symbol(10, x, y, 0);
|
||||
if (0 == old_value)
|
||||
{
|
||||
print_symbol(10, x, y, 0);
|
||||
x += (CHAR_SIZE + 1) * 2;
|
||||
print_symbol(10, x, y, 0);
|
||||
}
|
||||
old_value = value;
|
||||
old_highlight = highlight;
|
||||
}
|
||||
|
||||
void print_direction(uint8_t is_up, uint8_t invert)
|
||||
{
|
||||
uint8_t symbol_index[2];
|
||||
static uint8_t old_is_up = 0;
|
||||
static uint8_t old_invert = 1;
|
||||
|
||||
if (is_up)
|
||||
{
|
||||
@ -689,44 +733,53 @@ void print_direction(uint8_t is_up, uint8_t invert)
|
||||
symbol_index[1] = 15;
|
||||
}
|
||||
|
||||
print_symbol(symbol_index[0], OLED_X_SIZE - CHAR_SIZE * 2, 0, invert);
|
||||
print_symbol(symbol_index[1], OLED_X_SIZE - CHAR_SIZE * 2, 1, invert);
|
||||
if ((old_is_up != is_up) || (old_invert != invert))
|
||||
{
|
||||
print_symbol(symbol_index[0], OLED_X_SIZE - CHAR_SIZE * 2, 0, invert);
|
||||
print_symbol(symbol_index[1], OLED_X_SIZE - CHAR_SIZE * 2, 1, invert);
|
||||
}
|
||||
old_is_up = is_up;
|
||||
old_invert = invert;
|
||||
}
|
||||
|
||||
void print_voltage(uint16_t value)
|
||||
{
|
||||
static uint16_t old_value = 0;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t symbol;
|
||||
uint32_t div_factor;
|
||||
uint8_t i;
|
||||
|
||||
x = 0;
|
||||
y = 1;
|
||||
div_factor = 1000;
|
||||
value %= div_factor;
|
||||
div_factor /= 10;
|
||||
|
||||
// Print 3 digits
|
||||
while (div_factor != 0)
|
||||
for (i = 3; i > 0; --i)
|
||||
{
|
||||
symbol = value / div_factor;
|
||||
value %= div_factor;
|
||||
symbol = extract_digit(value, i);
|
||||
if ((0 == old_value) || (symbol != extract_digit(old_value, i)))
|
||||
{
|
||||
print_symbol(symbol, x, y, 0);
|
||||
}
|
||||
|
||||
print_symbol(symbol, x, y, 0);
|
||||
if (0 == x)
|
||||
{
|
||||
x += (CHAR_SIZE + 1) * 2;
|
||||
}
|
||||
|
||||
x += (CHAR_SIZE + 1) * 2;
|
||||
div_factor /= 10;
|
||||
}
|
||||
|
||||
// Print 'V'
|
||||
print_symbol(11, x, y, 0);
|
||||
if (0 == old_value)
|
||||
{
|
||||
// Print 'V'
|
||||
print_symbol(11, x, y, 0);
|
||||
|
||||
// Print '.'
|
||||
x = (CHAR_SIZE + 1) * 2;
|
||||
print_symbol(12, x, y, 0);
|
||||
// Print '.'
|
||||
x = (CHAR_SIZE + 1) * 2;
|
||||
print_symbol(12, x, y, 0);
|
||||
}
|
||||
old_value = value;
|
||||
}
|
||||
|
||||
uint16_t adc_measure()
|
||||
@ -742,6 +795,11 @@ uint16_t adc_measure()
|
||||
// Read ADC value
|
||||
result = ADC;
|
||||
|
||||
// Redo to get a better reading
|
||||
ADCSRA |= (1 << ADSC);
|
||||
while (ADCSRA & (1 << ADSC));
|
||||
result = ADC;
|
||||
|
||||
// Disable ADC
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
@ -754,7 +812,7 @@ uint16_t measure_voltage()
|
||||
uint16_t result;
|
||||
|
||||
val = 110;
|
||||
val *= 1024;
|
||||
val *= 1023;
|
||||
val /= adc_measure();
|
||||
result = val;
|
||||
|
||||
@ -763,6 +821,7 @@ uint16_t measure_voltage()
|
||||
|
||||
uint16_t find_eeprom_idx()
|
||||
{
|
||||
// TODO: double check everything
|
||||
uint16_t idx = 0;
|
||||
uint8_t found = 0;
|
||||
|
||||
@ -865,3 +924,13 @@ void update_display(uint32_t value, uint32_t highlight, uint8_t dir, uint8_t dir
|
||||
print_direction(dir, dir_highlight);
|
||||
print_voltage(measure_voltage());
|
||||
}
|
||||
|
||||
uint8_t extract_digit(uint32_t value, uint8_t digit_num)
|
||||
{
|
||||
while (1 != digit_num)
|
||||
{
|
||||
value /= 10;
|
||||
--digit_num;
|
||||
}
|
||||
return value % 10;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user