Fixed all logic. Check EEPROM scanner logic

This commit is contained in:
DWW 2021-06-27 22:20:55 +03:00
parent 4cf149a7f1
commit b9039f7af6

View File

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