Преотличнейшие часы на завалявшемся жк-индикаторе и супермикросхеме ATMega48. Но не получились.



То есть, часы, конечно, работают, но, увы, проработают они недолго.


Давным-давно в коробке в дальней тумбочке болталась у меня пара семисегментных жк-индикаторов. И так же давно мне хотелось взять их в оборот и соорудить на основе одного из них часы. Давным-давно: это, в буквальном смысле, семь лет. Именно тогда, в 2011 году возник у меня интерес к электронике. Не думая долго, заказал я тогда всякой всячины в одном хорошем интернет магазине (нет, не на Али; не уверен, что он тогда уже был). Но как-то у меня не заладилось творить вечное. После нескольких протравленных плат, забросил я это развлечение и забыл.


И вот, когда с Али пришла посылка, содержавшая макетки, пакетик 595-х в dip-корпусах, Tiny RTC на ds1307, и, что самое важное, USBasp, пришло время вернуться к старой задумке. Из старой заначки у меня был ATMega48, тот который о 28 ног, lm7805, всякая мелочевка в виде резисторов/конденсаторов/кнопок, и, собственно, индикатор на 40 ногах.


Вообще говоря, изначально планировалось использовать AtTiny13, которые у меня тоже валяются, но прикинув и так, и этак, я не придумал как обойтись его 5 ногами что бы и на индикатор выводить, и две кнопки читать, и с часами по i2c общаться. С 28 ногами меги, экономить и извращаться с объединением ног уже не приходится. Хотя, конечно, и в этом случае без 595-х не обойтись. Но если с тини я планировал выводить все 32 бита данных для индикатора последовательно, то с мегой можно выводить картинку сразу на все четыре микросхемы параллельно.



Все 595-е спрятаны под индикатором. На фото видны выводы корпуса микросхемы.


595 было использовано именно четыре штуки, потому что индикатор, хотя и имеет 40 ног, но на сегменты выведены только 32. Увы, но это только 3.5 индикатор, то есть у него 3 полноценных цифры, плюс единица. Есть символ секунд, но никакого обозначения для AM/PM. Но уж что есть. Заказывать более продвинутый индикатор, не собрав ни разу в жизни ничего на жк-индикаторах, мне бы не хотелось.



Рабочая документация на индикатор. Пришлось тестером выяснять какая ножка какому сегменту соответствует.


Ну а дальше дело техники. Схемы никогда не было, но там все очевидно. Надо было только выделить четыре ноги на вход буферов, общую ногу для индикатора, ногу для SCLK/RCLK, ногу на OE, две ноги для i2c, две ноги для кнопок. Все это было, конечно, неправильно. Почему я решил, что OE надо заводить на контроллер, а SCLK объединять с RCLK — уже и сам не вспомню. Надо было делать как раз наоборот. А общий провод индикатора на контроллере не нужен вообще, можно было обойтись одним из выводов первой 595-й (что я тоже, в итоге, сделал).



Провода. Много их. Вид изнутри.



Вид снаружи.


Самое интересное во всем этом прожекте: код вывода на индикатор. Тонкость в том, что на жк-индикатор нельзя просто так подать напряжение и забыть. Надо около ста раз в секунду менять полярность между сегментами и общим контактом, что бы все было красиво и приятно глазу. В качестве среды разработки, не мудрствуя лукаво, я использовал Arduino IDE, лишь чуть помучавшись в паре моментов. Во-первых, пришлось использовать пакет MiniCore ( https://github.com/MCUdude/MiniCore ), ведь писать пришлось не для большой готовой ардуины, а для слабого и голого ATMega48. Во-вторых, прямая попытка использовать встроенную библиотеку для i2c ни к чему не привела. По какой-то не вполне понятной причине, работать оно не пожелало, пришлось найти другую библиотеку, а потом и обрезать ее для своих нужд.


Как оказалось, 4 килобайта — это очень мало. Особенно, если писать на C. Возможно, если бы я решился перейти на ассемблер, это ограничение не давило бы так серьезно, но помня мои прошлые эксерсизы в писании на ассемблере для AVR, желания у меня такого не возникло. А на C писать — много места надо. Чуть скобку ненароком поставил — сотня байт в трубу.


Собственно, комментированный код
#include <avr/io.h>
#include <util/delay.h>
#include <avr/power.h>

#define cbi(sfr, bit)   (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit)   (_SFR_BYTE(sfr) |= _BV(bit))

// на самом деле у меня ds1307, но адрес тот же
#define DS3231_I2C_ADDRESS 0x68

#define LCD_PORT PORTD
#define LCD_DDR DDRD
#define LCD_DATA1 PD0
#define LCD_DATA2 PD1
#define LCD_DATA3 PD2
#define LCD_DATA4 PD3
#define LCD_SCLK PD4
#define LCD_OE PD5
#define LCD_COM PD6

#define KEY1_PORT PORTB
#define KEY1_DDR DDRB
#define KEY1_PIN PINB
#define KEY1 PB0
#define KEY2_PORT PORTD
#define KEY2_DDR DDRD
#define KEY2_PIN PIND
#define KEY2 PD7

#define DS1307SQ PB1
#define DS1307SQ_INT PCIE0
#define DS1307SQ_PORT PORTB
#define DS1307SQ_DDR DDRB
#define DS1307SQ_PIN PINB
#define DS1307SQ_VEC PCINT0_vect
#define DS1307SQ_MSK PCMSK0

// были планы. но, во-первых, лениво, во-вторых все равно уже не лезет
#define LM335_PORT PORTC
#define LM335_DDR DDRC
#define LM335 PC3

// это фреймбуфер
unsigned char lcd_buf[4];

#define MODE_MAIN 0
#define MODE_CALENDAR 1
#define MODE_YEAR 2
#define MODE_TERMOMETER 3 // нет
#define MODE_VOLTMETER 4 // нет
#define MODE_SET_MINUTE 5
#define MODE_SET_HOUR 6
#define MODE_SET_DAY 7
#define MODE_SET_MONTH 8
#define MODE_SET_YEAR 9
#define MODE_SECOND 10
#define MODE_DEBUG 11 // не используется

// таймауты в виде количества десятков циклов по 10ms (грубо)
#define MODE_TIMEOUT 20 // 2 секунды
#define MODE_TIMEOUT_SET 100 // 10 секунд
#define KEY_TIMEOUT 10 // 1 секунда

byte mode = MODE_MAIN;
byte mode_timeout = 0;

byte key1_press = 0;
byte key1_time = 0;
byte key2_press = 0;
byte key2_time = 0;

byte cycle_count_10 = 0; // счетчик десятков циклов
byte even_10 = 0; // меняется раз в 1/10 секунды

// последние данные от ds1307
byte second;
byte minute;
byte hour;
byte dayOfWeek;
byte dayOfMonth;
byte month;
byte year;

volatile byte need_render_int = 1;
uint8_t porthistory = 0xFF;
volatile uint8_t debug_value = 0;

byte twi_problems = 0;

// раз в секунду ds1307 дергает линию SQ
// я это ловлю, читаю время и перерисовываю экран
ISR(DS1307SQ_VEC) {
  uint8_t changedbits = DS1307SQ_PIN ^ porthistory;
  porthistory = DS1307SQ_PIN;
  if (changedbits & _BV(DS1307SQ) && porthistory & _BV(DS1307SQ)) {
    need_render_int = 1;
  }
}

// рисует цифру в фреймбуфере в нужной позиции
void lcd_num(char pos, char num) {
  unsigned char buf = 0b01110110;
  if (pos < 1 || pos > 3) {
    return;
  }
  switch (num) {
    case 0:
      // а почему это у меня 3-я позиция обрабатывается иначе, чем две другие?
      // правильно, потому что я криворукий косоглаз, который в трех проводках 
      // постоянно путается :-(
      if (pos == 3) {
        buf = 0b11101110;
      } else {
        buf = 0b11100111;
      }
      break;
    case 1:
      if (pos == 3) {
        buf = 0b10001000;
      } else {
        buf = 0b10000001;
      }
      break;
    case 2:
      buf = 0b11010110;
      break;
    case 3:
      if (pos == 3) {
        buf = 0b11011100;
      } else {
        buf = 0b11010011;
      }
      break;
    case 4:
      if (pos == 3) {
        buf = 0b10111000;
      } else {
        buf = 0b10110001;
      }
      break;
    case 5:
      if (pos == 3) {
        buf = 0b01111100;
      } else {
        buf = 0b01110011;
      }
      break;
    case 6:
      if (pos == 3) {
        buf = 0b01111110;
      } else {
        buf = 0b01110111;
      }
      break;
    case 7:
      if (pos == 3) {
        buf = 0b11001000;
      } else {
        buf = 0b11000001;
      }
      break;
    case 8:
      if (pos == 3) {
        buf = 0b11111110;
      } else {
        buf = 0b11110111;
      }
      break;
    case 9:
      if (pos == 3) {
        buf = 0b11111100;
      } else {
        buf = 0b11110011;
      }
      break;
  }
  lcd_buf[pos] = buf;
}

// самоочевидные функции
void lcd_one(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 0);
  } else {
    lcd_buf[0] &= ~(1 << 0);
  }
}
void lcd_sec(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 7);
  } else {
    lcd_buf[0] &= ~(1 << 7);
  }
}
void lcd_minus(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 1);
  } else {
    lcd_buf[0] &= ~(1 << 1);
  }
}
void lcd_plus(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 6);
  } else {
    lcd_buf[0] &= ~(1 << 6);
  }
}
void lcd_lo(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 5);
  } else {
    lcd_buf[0] &= ~(1 << 5);
  }
}
void lcd_over(bool e) {
  if (e) {
    lcd_buf[0] |= (1 << 4);
  } else {
    lcd_buf[0] &= ~(1 << 4);
  }
}
void lcd_dot(int pos, bool e) {
  int pos_buf;
  if (pos == 1) {
    pos_buf = 3;
  } else if (pos == 2) {
    pos_buf = 2;
  } else if (pos == 3) {
    pos_buf = 1;
  } else {
    return;
  }
  if (pos_buf == 3) {
    if (e) {
      lcd_buf[pos_buf] |= (1 << 0);
    } else {
      lcd_buf[pos_buf] &= ~(1 << 0);
    }
  } else {
    if (e) {
      lcd_buf[pos_buf] |= (1 << 3);
    } else {
      lcd_buf[pos_buf] &= ~(1 << 3);
    }
  }
}

// дергается из основного цикла 100 раз в секунду
// выдает данные на 595-е, каждый раз меняя полярность
void lcd_refresh() {
  unsigned char data1 = lcd_buf[0];
  unsigned char data2 = lcd_buf[1];
  unsigned char data3 = lcd_buf[2];
  unsigned char data4 = lcd_buf[3];
  byte reverse = data1 & (1 << 3); // вот тут хранится бит текущей полярности
  if (reverse) { // и если он стоит, переворачиваем биты
    data1 = ~data1;
    data2 = ~data2;
    data3 = ~data3;
    data4 = ~data4;
  }
  for (int i = 0; i < 8; i++) {
    // берем данные из фреймбуфера побитно и выставляем на выводах контроллера
    if (data1 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA1);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA1);
    }
    if (data2 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA2);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA2);
    }
    if (data3 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA3);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA3);
    }
    if (data4 & (1 << i)) {
      LCD_PORT |= _BV(LCD_DATA4);
    } else {
      LCD_PORT &= ~_BV(LCD_DATA4);
    }
    // SCLK 595-х вверх
    sbi(LCD_PORT, LCD_SCLK);
    // SCLK 595-х вниз
    cbi(LCD_PORT, LCD_SCLK);
  }
  // еще раз дергаем SCLK
  // а все потому что у меня SCLK связан с RCLK и надо дернуть еще раз, что бы на выводах
  // оказалось то что мне нужно.
  // и все это, вообще-то, неправильно. надо было на контроллер выводить отдельно 
  // SCLK и RCLK, а OE тупо сажать на землю (см. даташит на 74HC595)
  // но и так сойдет.
  sbi(LCD_PORT, LCD_SCLK);
  cbi(LCD_PORT, LCD_SCLK);
  // включаем общий контакт жк-шки в нужной полярности
  // вообще-то у моей жк-шки два общих контакта, пины 1 и 40
  // (почему-то не соединенных между собой; теряюсь в догадках зачем так)
  // и второй контакт заведен на 4 вывод первой 595-й, так что провод к 
  // контроллеру немного лишний, но так уж распаялось
  if (reverse) {
    sbi(LCD_PORT, LCD_COM);
  } else {
    cbi(LCD_PORT, LCD_COM);
  }
  // переключаем полярность для следующего цикла
  lcd_buf[0] ^= (1 << 3);
}

// рисуем в фреймбуфере что надо и когда надо, в соответствии с текущим режимом
void do_render() {
  lcd_buf[0] = 0;
  lcd_buf[1] = 0;
  lcd_buf[2] = 0;
  lcd_buf[3] = 0;
  if (twi_problems) {
    lcd_lo(1);
  }
  if (mode == MODE_MAIN) {
    lcd_num(3, minute % 10);
    lcd_num(2, minute / 10);
    byte hour1 = (hour <= 12) ? hour : (hour % 12);
    lcd_num(1, hour1 % 10);
    if (hour1 >= 10) {
      lcd_one(1);
    }
    // мигалка секунд одну секунду горит, другую не горит. эстетично.
    // собственно ради нее я и возился с линией SQ и прерыванием,
    // что бы оно мигало равномерно, и что бы интерференция между часами и 
    // циклами контроллера этому не мешала
    if (second % 2) {
      lcd_sec(1);
    }
  } else if (mode == MODE_CALENDAR) {
    lcd_num(3, dayOfMonth % 10);
    lcd_num(2, dayOfMonth / 10);
    lcd_num(1, month % 10);
    if (month >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_YEAR) {
    lcd_num(3, year % 10);
    lcd_num(2, year / 10);
    lcd_buf[1] = 0b10110011; // это буква y. типа
  } else if (mode == MODE_TERMOMETER) {
  } else if (mode == MODE_VOLTMETER) {
  } else if (mode == MODE_SET_MINUTE) {
    if (even_10) {
      lcd_num(3, minute % 10);
      lcd_num(2, minute / 10);
    }
    byte hour1 = (hour <= 12) ? hour : (hour % 12);
    lcd_num(1, hour1 % 10);
    if (hour1 >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_sec(1);
  } else if (mode == MODE_SET_HOUR) {
    lcd_num(3, minute % 10);
    lcd_num(2, minute / 10);
    if (even_10) {
      byte hour1 = (hour <= 12) ? hour : (hour % 12);
      lcd_num(1, hour1 % 10);
      if (hour1 >= 10) {
        lcd_one(1);
      } else {
        lcd_one(0);
      }
      if (hour > 12) {
        lcd_over(1);
      } else {
        lcd_over(0);
      }
    }
    lcd_sec(1);
  } else if (mode == MODE_SET_DAY) {
    if (even_10) {
      lcd_num(3, dayOfMonth % 10);
      lcd_num(2, dayOfMonth / 10);
    }
    lcd_num(1, month % 10);
    if (month >= 10) {
      lcd_one(1);
    } else {
      lcd_one(0);
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_SET_MONTH) {
    lcd_num(3, dayOfMonth % 10);
    lcd_num(2, dayOfMonth / 10);
    if (even_10) {
      lcd_num(1, month % 10);
      if (month >= 10) {
        lcd_one(1);
      } else {
        lcd_one(0);
      }
    }
    lcd_dot(2, 1);
  } else if (mode == MODE_SET_YEAR) {
    if (even_10) {
      lcd_num(3, year % 10);
      lcd_num(2, year / 10);
    }
    lcd_buf[1] = 0b10110011;
  } else if (mode == MODE_SECOND) {
    lcd_sec(1);
    lcd_num(3, second % 10);
    lcd_num(2, second / 10);
  } else if (mode == MODE_DEBUG) {
    byte d = debug_value;
    lcd_num(3, d % 10);
    d /= 10;
    lcd_num(2, d % 10);
    lcd_num(2, d / 10);
  }
}

int main(void)
{
  // мумбо-юмбо на тему энерго сохранения.
  // помогает, приблизительно, на никак.
  // ACSR = (1<<ACD);
  ADCSRA = (0<<ADEN);
  PRR = (1<<PRTIM0) | (1<<PRTIM1) | (1<<PRTIM2) | (1<<PRSPI) | (1<<PRADC) | (1<<PRUSART0);

  // 
  DDRB = 0x00;
  PORTB = 0xff;
  DDRC = 0x00;
  PORTC = 0xff;
  DDRD = 0x00;
  PORTD = 0xff;

  lcd_buf[0] = 0x0;
  lcd_buf[1] = 0x0;
  lcd_buf[2] = 0x0;
  lcd_buf[3] = 0x0;

  twi_begin();

  // светодиодик для отладки. у меня же usbasp, так что отладочной консоли нет
  // и, надо сказать, светодиодик очень помог
  // DDRB |= _BV(PB7);
  // PORTB |= _BV(PB7); // off

  // инициализация портов жк-шки
  LCD_DDR |= (_BV(LCD_DATA1) | _BV(LCD_DATA2) | _BV(LCD_DATA3) | _BV(LCD_DATA4) | _BV(LCD_SCLK) | _BV(LCD_OE) | _BV(LCD_COM));
  cbi(LCD_PORT, LCD_SCLK);
  cbi(LCD_PORT, LCD_OE);

  // кнопки
  KEY1_DDR &= ~(_BV(KEY1));
  KEY1_PORT |= _BV(KEY1);
  KEY2_DDR &= ~(_BV(KEY2));
  KEY2_PORT |= _BV(KEY2);

  // ежесекундный привет от ds1307 и его обработчик
  DS1307SQ_DDR &= ~_BV(DS1307SQ);
  DS1307SQ_PORT |= _BV(DS1307SQ);
  PCICR |= _BV(DS1307SQ_INT);
  DS1307SQ_MSK |= _BV(DS1307SQ);
  sei();

  // ds1307 без батарейки теряет данные и, будучи подключен вновь к питанию, даже не тикает
  // что бы он затикал, необходимо выставить хоть какое-то время
  // setDS3231time(30,40,21,6,11,3,18);

  while(1)
  {
    byte need_render = 0;
    byte need_date_set = 0;

    // пришел привет от ds1307, зафиксированный обработчиком прерываний
    // читаем
    if (need_render_int) {
      byte rc;
      if (mode == MODE_MAIN) {
        rc = readDS3231time_hms(&second, &minute, &hour);
      } else {
        rc = readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
      }
      if ( ! rc && twi_problems) {
        twi_problems -= 1;
      } else {
        twi_problems += rc;
      }
      need_render = 1;
      need_render_int = 0;
    }

    // выполняется раз в 1/10 секунды
    if ( ! cycle_count_10) {
      even_10 = ! even_10;

      // если включен неосновной режим, уменьшаем счетчик 
      if (mode_timeout > 0) {
        mode_timeout -= 1;
      }
      // и если счетчик кончился, возвращаемся в основной режим
      if (mode != MODE_MAIN && ! mode_timeout) {
        mode = MODE_MAIN;
        need_render = 1;
      }
      // если мы в режиме установки времени, мигаем 10 раз в секунду
      if (mode == MODE_SET_MINUTE || mode == MODE_SET_HOUR || mode == MODE_SET_DAY || mode == MODE_SET_MONTH || mode == MODE_SET_YEAR) {
        need_render = 1; 
      }

      // читаем кнопки
      byte key1_down = (KEY1_PIN & _BV(KEY1)) ? 0 : 1;
      byte key2_down = (KEY2_PIN & _BV(KEY2)) ? 0 : 1;
      if (key1_down || key2_down || key1_press || key2_press) {
        need_render = 1;
      }
      if (key1_down && key1_press) {
        key1_time += 1;
      }
      if (key2_down && key2_press) {
        key2_time += 1;
      }
      // и хитрым образом переключаем режимы
      if (key1_down && ! key1_press) {
          if (mode == MODE_SET_MINUTE) {
            mode = MODE_SET_HOUR;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_HOUR) {
            mode = MODE_SET_DAY;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_DAY) {
            mode = MODE_SET_MONTH;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_MONTH) {
            mode = MODE_SET_YEAR;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SET_YEAR) {
            mode = MODE_MAIN;
          } else if (mode == MODE_MAIN) {
            mode = MODE_SECOND;
            mode_timeout = MODE_TIMEOUT_SET;
          } else if (mode == MODE_SECOND) {
            mode = MODE_MAIN;
            mode_timeout = 0;
          }
      } else if ( ! key1_down && key1_press) {
        if (key1_time >= KEY_TIMEOUT) {
        } else {
        }
      } else if (key1_down && key1_press) {
        if (key1_time >= KEY_TIMEOUT) {
          if (mode == MODE_MAIN || mode == MODE_SECOND) {
            mode = MODE_SET_MINUTE;
            mode_timeout = MODE_TIMEOUT_SET;
          }
        } else {
        }
      }
      if (key2_down && ! key2_press) {
        if (mode == MODE_MAIN) {
          mode = MODE_CALENDAR;
          mode_timeout = MODE_TIMEOUT;
        } else if (mode == MODE_CALENDAR) {
          mode = MODE_YEAR;
          mode_timeout = MODE_TIMEOUT;
        } else if (mode == MODE_YEAR) {
          mode = MODE_MAIN;
          mode_timeout = 0;
        } else if (mode == MODE_SET_MINUTE) {
          minute += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_HOUR) {
          hour += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_DAY) {
          dayOfMonth += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_MONTH) {
          month += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SET_YEAR) {
          year += 1;
          mode_timeout = MODE_TIMEOUT_SET;
          need_date_set = 1;
        } else if (mode == MODE_SECOND) {
            second = 0;
            need_date_set = 1;
            mode_timeout = MODE_TIMEOUT_SET;
        }
      } else if ( ! key2_down && key2_press) {
        if (key2_time >= KEY_TIMEOUT) {
        } else {
        }
      } else if (key2_down && key2_press) {
        if (key2_time >= KEY_TIMEOUT) {
          if (mode == MODE_SET_MINUTE) {
            minute += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_HOUR) {
            hour += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_DAY) {
            dayOfMonth += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_MONTH) {
            month += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          } else if (mode == MODE_SET_YEAR) {
            year += 1;
            mode_timeout = MODE_TIMEOUT_SET;
            need_date_set = 1;
          }
        } else {
        }
      }
      key1_press = key1_down;
      if ( ! key1_press) {
        key1_time = 0;
      }
      key2_press = key2_down;
      if ( ! key2_press) {
        key2_time = 0;
      }
    }

    if (need_date_set) {
      // корректируем время
      // вообще я не очень понял как ds1307 проверяет валидность установки времени,
      // но, вроде бы, пока проблем не замечено
      if (minute > 59) {
        minute = 0;
      }
      if (hour > 23) {
        hour = 0;
      }
      if (dayOfMonth > 31) {
        dayOfMonth = 1;
      }
      if (month > 12) {
        month = 1;
      }
      if (year > 99) {
        year = 0;
      }
      // записываем время в ds1307
      setDS3231time(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }

    // собственно, рисуем фреймбуфер по необходимости
    if (need_render) {
      do_render();
    }

    // обновляем экран
    cli();
    lcd_refresh();
    sei();

    _delay_ms(10);

    cycle_count_10 += 1;
    if (cycle_count_10 >= 10) {
      cycle_count_10 = 0;
    }
  }

  return 0;
}

// это я взял где-то в другом месте
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}

// запись времени в ds1307
void setDS3231time(byte second, 
                   byte minute, 
                   byte hour, 
                   byte dayOfWeek, 
                   byte dayOfMonth, 
                   byte month, 
                   byte year)
{
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 0, (uint8_t) decToBcd(second));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 1, (uint8_t) decToBcd(minute));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 2, (uint8_t) decToBcd(hour));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 3, (uint8_t) decToBcd(dayOfWeek));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 4, (uint8_t) decToBcd(dayOfMonth));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 5, (uint8_t) decToBcd(month));
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 6, (uint8_t) decToBcd(year));
  // выставляем частоту на выходе SQ 1Hz
  // это надо сделать хотя бы только один раз, что бы ds1307 не устроил дос 
  // в обработчике прерываний на частоте 8kHz
  twi_write((uint8_t) DS3231_I2C_ADDRESS, (uint8_t) 7, (uint8_t) 0b00010000);
}

// чтение времени из ds1307
byte readDS3231time(byte *second,
                    byte *minute,
                    byte *hour,
                    byte *dayOfWeek,
                    byte *dayOfMonth,
                    byte *month,
                    byte *year)
{
  byte rc = twi_read(DS3231_I2C_ADDRESS, 0, 7);
  if (rc) return 1;
  *second = bcdToDec(twi_receive() & 0x7f);
  *minute = bcdToDec(twi_receive());
  *hour = bcdToDec(twi_receive() & 0x3f);
  *dayOfWeek = bcdToDec(twi_receive());
  *dayOfMonth = bcdToDec(twi_receive());
  *month = bcdToDec(twi_receive());
  *year = bcdToDec(twi_receive());
}

// чтение только секунд, минут и часов, то есть, для основного режима
byte readDS3231time_hms(byte *second, byte *minute, byte *hour) {
  byte rc = twi_read(DS3231_I2C_ADDRESS, 0, 3);
  if (rc) return 1;
  *second = bcdToDec(twi_receive() & 0x7f);
  *minute = bcdToDec(twi_receive());
  *hour = bcdToDec(twi_receive() & 0x3f);
}

/*
 * Код ниже, на самом деле, взят тут: http://dsscircuits.com/articles/arduino-i2c-master-library
 * Переработан и урезан до самого минимума, ибо иначе оно вместе с моим кодом в 4k не лезло.
 */
/*
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#define START           0x08
#define REPEATED_START  0x10
#define MT_SLA_ACK  0x18
#define MT_SLA_NACK 0x20
#define MT_DATA_ACK     0x28
#define MT_DATA_NACK    0x30
#define MR_SLA_ACK  0x40
#define MR_SLA_NACK 0x48
#define MR_DATA_ACK     0x50
#define MR_DATA_NACK    0x58
#define LOST_ARBTRTN    0x38
#define TWI_STATUS      (TWSR & 0xF8)
#define SLA_W(address)  (address << 1)
#define SLA_R(address)  ((address << 1) + 0x01)

#define MAX_BUFFER_SIZE 32

uint8_t twi_bytesAvailable = 0;
uint8_t twi_bufferIndex = 0;
uint8_t twi_totalBytes = 0;
uint16_t twi_timeOutDelay = 0;
uint8_t twi_returnStatus;
uint8_t twi_nack;
uint8_t twi_data[MAX_BUFFER_SIZE];

void twi_begin()
{
  sbi(PORTC, 4);
  sbi(PORTC, 5);
  cbi(TWSR, TWPS0);
  cbi(TWSR, TWPS1);
  TWBR = ((F_CPU / 100000) - 16) / 2;
  TWCR = _BV(TWEN) | _BV(TWEA); 
}
uint8_t twi_read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes)
{
  twi_bytesAvailable = 0;
  twi_bufferIndex = 0;
  if(numberBytes == 0){numberBytes++;}
  twi_nack = numberBytes - 1;
  twi_returnStatus = 0;
  twi_returnStatus = twi_start();
  if(twi_returnStatus){return(twi_returnStatus);}
  twi_returnStatus = twi_sendAddress(SLA_W(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(2);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(registerAddress);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_start();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(4);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendAddress(SLA_R(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(5);}
    return(twi_returnStatus);
  }
  for(uint8_t i = 0; i < numberBytes; i++)
  {
    if( i == twi_nack )
    {
      twi_returnStatus = twi_receiveByte(0);
      if(twi_returnStatus == 1){return(6);}
      if(twi_returnStatus != MR_DATA_NACK){return(twi_returnStatus);}
    }
    else
    {
      twi_returnStatus = twi_receiveByte(1);
      if(twi_returnStatus == 1){return(6);}
      if(twi_returnStatus != MR_DATA_ACK){return(twi_returnStatus);}
    }
    twi_data[i] = TWDR;
    twi_bytesAvailable = i+1;
    twi_totalBytes = i+1;
  }
  twi_returnStatus = twi_stop();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(7);}
    return(twi_returnStatus);
  }
  return(twi_returnStatus);
}
uint8_t twi_write(uint8_t address, uint8_t registerAddress, uint8_t data)
{
  twi_returnStatus = 0;
  twi_returnStatus = twi_start(); 
  if(twi_returnStatus){return(twi_returnStatus);}
  twi_returnStatus = twi_sendAddress(SLA_W(address));
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(2);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(registerAddress);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_sendByte(data);
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(3);}
    return(twi_returnStatus);
  }
  twi_returnStatus = twi_stop();
  if(twi_returnStatus)
  {
    if(twi_returnStatus == 1){return(7);}
    return(twi_returnStatus);
  }
  return(twi_returnStatus);
}
uint8_t twi_receive()
{
  twi_bufferIndex = twi_totalBytes - twi_bytesAvailable;
  if(!twi_bytesAvailable)
  {
    twi_bufferIndex = 0;
    return(0);
  }
  twi_bytesAvailable--;
  return(twi_data[twi_bufferIndex]);
}
uint8_t twi_start()
{
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if ((TWI_STATUS == START) || (TWI_STATUS == REPEATED_START))
  {
    return(0);
  }
  if (TWI_STATUS == LOST_ARBTRTN)
  {
    uint8_t bufferedStatus = TWI_STATUS;
    twi_lockUp();
    return(bufferedStatus);
  }
  return(TWI_STATUS);
}
uint8_t twi_sendAddress(uint8_t i2cAddress)
{
  TWDR = i2cAddress;
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if ((TWI_STATUS == MT_SLA_ACK) || (TWI_STATUS == MR_SLA_ACK))
  {
    return(0);
  }
  uint8_t bufferedStatus = TWI_STATUS;
  if ((TWI_STATUS == MT_SLA_NACK) || (TWI_STATUS == MR_SLA_NACK))
  {
    twi_stop();
    return(bufferedStatus);
  }
  else
  {
    twi_lockUp();
    return(bufferedStatus);
  } 
}
uint8_t twi_sendByte(uint8_t i2cData)
{
  TWDR = i2cData;
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  if (TWI_STATUS == MT_DATA_ACK)
  {
    return(0);
  }
  uint8_t bufferedStatus = TWI_STATUS;
  if (TWI_STATUS == MT_DATA_NACK)
  {
    twi_stop();
    return(bufferedStatus);
  }
  else
  {
    twi_lockUp();
    return(bufferedStatus);
  } 
}
uint8_t twi_receiveByte(uint8_t ack)
{
  unsigned long startingTime = millis();
  if(ack)
  {
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);

  }
  else
  {
    TWCR = (1<<TWINT) | (1<<TWEN);
  }
  while (!(TWCR & (1<<TWINT)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }
  }
  if (TWI_STATUS == LOST_ARBTRTN)
  {
    uint8_t bufferedStatus = TWI_STATUS;
    twi_lockUp();
    return(bufferedStatus);
  }
  return(TWI_STATUS); 
}
uint8_t twi_stop()
{
  unsigned long startingTime = millis();
  TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
  while ((TWCR & (1<<TWSTO)))
  {
    if(!twi_timeOutDelay){continue;}
    if((millis() - startingTime) >= twi_timeOutDelay)
    {
      twi_lockUp();
      return(1);
    }

  }
  return(0);
}
void twi_lockUp()
{
  TWCR = 0;
  TWCR = _BV(TWEN) | _BV(TWEA);
}

А дальше начались проблемы. Вернее, проблема выявилась одна, но глобальная — энергопотребление. Запустив часы на тестовой макетке, уже с частотой 1MHz, выяснил, что получается около 6mA. Предпринятые меры к уменьшению этого значения ни к чему не привели. Пытался, например, на время паузы уменьшать частоту контроллера до предела: в результате получил проблемы с USBasp-ом и крайне скромную экономию электричества.


Штука в том, что все рекомендации встреченные мною на тему энергопотребления AVR-ок замечательно описываются фразой "спите глубже". Но контроллеру в часах нельзя спать! Ему денно и нощно, 100 раз в секунду необходимо обновлять экран. А один только вывод из сна занимает как минимум 65ms, требуемые на стабилизацию осциллятора, что кратно больше требуемого промежутка между обновлениями экрана.


Возможно, есть какое-то неизвестное мне шаманство, при помощи которого можно в условиях часов применить сон для контроллера, но пока что я сдался, воткнул 7805 с кроной, и ожидаю остановку часов где-то через неделю.


Но! У меня же есть еще один такой же индикатор. Может быть, если взять какой-то более приспособленный к этой задаче контроллер, удастся создать, наконец, часы моей мечты? Я был бы признателен, если бы уважаемая публика подсказала мне куда следует смотреть для решения этой задачи. STM8/32? MSP430? Или, все-таки, шаманить с режимами AVR?


Комментарии (215)


  1. gbg
    18.03.2018 18:32
    +1

    Следует заметить, что крона — одна из наименее емких батарей и что при таком включении, 7805 рассеет примерно половину батарейкиной энергии в атмосферу.

    Далее, стоит рассмотреть применение специализированных RTC в отдельном чипе, которые работают годами от одной CR2032. Тогда основной контроллер может дрыхнуть сколько угодно, лишь изредка просыпаясь для смены картинки. Ну и взять менее жирный и древний контроллер, например, STM8.


    1. l_o_d
      18.03.2018 18:43

      RTC у автора как раз есть, проблема в том что контроллер не может спать из-за необходимости постоянно менять полярность напряжения на сегментах ЖК индикатора.


      1. DmitriyDev
        19.03.2018 09:22

        Это относительно.
        Для человека, менять полярность раз в секунду — это достаточно быстро, а для микроконтроллкра милионы тактов в холостую.


        1. safari2012
          19.03.2018 15:37

          По фотке не понятно, были ли там секунды вообще…


          1. safari2012
            19.03.2018 15:43

            Хотя, в тексте про секунды есть, что-то я затупил. В любом случае, можно просыпаться раз в секунду по прерыванию от RTC?


            1. moviq
              19.03.2018 16:52

              Раз в секунду от RTC маловато для ЖК индикатора. Надо хотя бы 50 раз в секунду. А читать раз в секунду из RTC в прицепе можно


    1. dmiceman Автор
      18.03.2018 18:45

      > 7805 рассеет примерно половину батарейкиной энергии в атмосферу.

      Конечно. Но если бы вся схема потребляла микроамперы, это было бы даже и не важно.

      > RTC в отдельном чипе, которые работают годами от одной CR2032

      Как раз у меня стоит очень специализированная ds1307 :-)

      > Тогда основной контроллер может дрыхнуть сколько угодно, лишь изредка просыпаясь для смены картинки

      А вот это нельзя по условиям задачи. ЖК-индикатор надо обновлять сто раз в секунду всегда.

      > STM8

      Вот это-то и интересно, как он себя чувствует в режиме постоянной работы?


      1. olartamonov
        18.03.2018 19:34
        +1

        Конечно. Но если бы вся схема потребляла микроамперы, это было бы даже и не важно.


        Собственное потребление 7805/78L05 — 3-5 мА, кроме того, её параметры не гарантируются при нагрузке менее 1 мА. В микропотребляющих схемах применяют LDO совершенно другого класса.


      1. ProstoUser
        19.03.2018 09:20
        +1

        > STM8

        Вот это-то и интересно, как он себя чувствует в режиме постоянной работы?


        В даташите написано, что STM8L просыпается (выходит из состояния HALT с потреблением порядка 1 мкА) за 5 микросекунд.

        Этого достаточно?


      1. HogsOfWar
        19.03.2018 09:22

        По поводу STM8 можете в сторону stm8l051 посмотреть, там есть режим работы Low-power run, где МК работает на частоте 32КГц но ест всего 5 микроАмпер (не считая периферии), к тому же в этом МК и часы встроенные есть, и цена копеечная.
        Если 100 раз в секунду ножкой подрыгать то такой режим хорошо подойдет


        1. Alexashka
          19.03.2018 09:44

          А у STM8L152 есть встроенный контроллер LCD, даже ножками дрыгать не надо, он сам умеет.


          1. Mike_soft
            19.03.2018 09:57

            а часы вообще купить можно :-)
            не, я не против DIY, но просто нужно понять, что же хочет автор: достичь микропотребления у атмеги, или сделать часы с ЖКИ собственными руками, или ему просто «нужны часы»?
            каждая из этих проблем решается своим способом.


  1. l_o_d
    18.03.2018 18:39
    +1

    Ну для начала можно убрать 7805 и питать напрямую от батарейки на 3-3.6 вольт. Стабилизатор тоже немало кушает. Или хотя бы выбрать стабилизатор с малым собственным потреблением. А вывод на индикатор можно сделать через специализированный контроллер типа HT1621. Там мизерное собственное потребление.


    1. dmiceman Автор
      18.03.2018 18:45

      > HT1621

      Вот спасибо, почитаю.


      1. dmiceman Автор
        18.03.2018 19:23

        А нет, готовый дисплей — это неспортивно :-)


        1. l_o_d
          18.03.2018 19:33

          А это и не готовый дисплей:
          LCD контроллер с организацией памяти 32х4 для работы с микроконтроллерами

          Основные характеристики

          Напряжение питания: 2.4…5.2В
          Встроенный 256 kHz RC генератор
          Работа с внешним 32.768 kHz кварцем или от источника частоты 256 kHz
          Выбор напряжения смещения (bias) 1/2 или 1/3 и выбор продолжительности работы 1/2, 1/3 или 1/4 (duty)
          Внутренний формирователь основной частоты
          Две частоты работы драйвера звонка (2kHz/4kHz)
          Режим пониженного энергопотребления
          Внутренний генератор и WDT
          Вывод основной частоты или вывод переполнения WDT
          8 видов источников для получения основной частоты и для WDT
          32x4 LCD драйвер
          Встроенная оперативная память дисплея 32х4
          Трехпроводный, последовательный интерфейс
          Встроенное формирование частоты возбуждение LCD
          Программное конфигурирование
          Два режима работы: c данными и с командами
          Операции обращения к памяти с автоинкрементом
          Три режима доступа к данным
          Вывод VLCD для настройки рабочего напряжения LCD

          Стоит кстати вполне демократично, даже в чип и дипе рублей 60 всего. Правда там корпус не очень удобный. В китае наверное и DIP можно найти.


  1. FGV
    18.03.2018 18:43

    7805 от кроны = кпд < 50%
    ставьте импульсный dc/dc, в два раза меньше кушать будет (а то и в 5-6 раз).


    1. dmiceman Автор
      18.03.2018 18:48

      Нет, нет, нет. Я, видимо, недостаточно раскрыл эту тему в статье. Потребление я смотрел до того как решился (для компактности) применить крону и 7805. Просто давал 5 вольт и смотрел в разрыве цешкой. И уже расстроившись решил, что как proof-of-concept и так сойдет.


      1. FGV
        18.03.2018 19:08

        Хм, тогда странно, вроде в активном режиме на 1МГц 48 кушает 1мА (по даташиту). Можно на полную схему взглянуть?


        1. dmiceman Автор
          18.03.2018 19:31

          Вот чего нет, того нет :-)

          Вероятно в даташите имеется в виду ситуация, когда контроллер что-то внутри себя перемалывает. А мне же надо все время ногами дрыгать.

          Четыре sn74hc595n дают 70 (max по даташиту) * 4 = 280 микроампер.

          Подтяжки на всю схему ровно две, по 15 kOhm.

          Tiny RTC должен давать совсем копейки.

          А как оценить потребление собственно индикатора — даже не знаю. Но наверняка там какие-нибудь наноамперы :-)


          1. FGV
            18.03.2018 19:51

            На ум приходит тока откинуть регистры и lcd и померять потребление.

            >А один только вывод из сна занимает как минимум 65ms

            а это откуда?


            1. dmiceman Автор
              18.03.2018 19:58

              Из форумов и моего понимания даташита :-)

              Но тут меня уже поправили. Возможно, все не так плохо.


    1. l_o_d
      18.03.2018 18:50

      Кстати слышал утверждение, что на малых токах импульсники не блещут высоким КПД. Самому замерять правда не приходилось…


      1. olartamonov
        18.03.2018 19:42

        Самому замерять


        А даташиты читать в наше время, я так понимаю, не модно.


        1. l_o_d
          18.03.2018 21:29

          Как то не было потребности в такой ситуации использовать импульсник. Да и в той промышленной аппаратуре с которой сталкивался обычно ставят литиевый элемент на 3.6 вольт и не парятся. Видимо в этом есть смысл.


          1. olartamonov
            18.03.2018 22:19

            А ведь вместо этого ля-ля можно было просто пойти на сайт TI, открыть табличку DC/DC понижаек, отсортировать по Iq и узнать много интересного.


            1. l_o_d
              18.03.2018 22:36

              Да я ведь не спорю что таких нет) Просто достать линейный стабилизатор с нужными характеристиками намного проще и дешевле. А в вашем примере еще и корпус довольно сложный в припайке. Ну и если делать не макет, а полноценное устройство то лучше сразу взять источник с подходящим напряжением. Будет меньше деталей, дольше время работы.


            1. DarkTiger
              18.03.2018 23:59

              А если пойти на алиэкспресс, там можно купить готовый слаботочный DC/DC за цену КРЕН-ки в рознице, и не ломать голову, если в конвертерах не специалист. Там, конечно, обвязка не совсем та, что в даташитах, что влияет на КПД, но потери все равно будут сильно, сильно меньше, чем у КРЕН-ки.
              Хотя на самом деле это не критично, 6мА потребляет схема или 3 — при использовании CR2032 «всю систему надо менять» (с)


              1. olartamonov
                19.03.2018 08:25

                И купите вы там с большой вероятностью что-то типа LM2596 с теми же 5-10 мА собственного потребления, что и у 7805.

                Интересно, когда до любителей алиэкспресса дойдёт, что их судьба — наколенные поделки, нормально работающие через три раза на четвёртый, а у нормального разработчика минимум половина времени уходит не на махание паяльником, а именно что на чтение даташитов?..


                1. Mike_soft
                  19.03.2018 10:08

                  потому, что электроника сильно «разрослась». уже доступна не пара десятков транзисторов, параметры которых можно было держать в голове, не полсотни цифровых микросхем, и т.п.
                  Т.е. чтобы заниматься этим профессионально — надо «очень быстро бежать»©.


                  1. olartamonov
                    19.03.2018 10:14

                    Надо уметь читать.

                    А чип с 360 нА собственного потребления, на который я ссылку давал, пять лет уже выпускается.


                    1. Mike_soft
                      19.03.2018 10:26

                      в контексте автора — «всего пять лет», ибо «интерес возник» в 2011 году.
                      Насчет «уметь читать» — согласен. ибо 99% всех возникающих вопросов решаются при изучении dataShit'ов :-) и TFM'ов.


                1. DarkTiger
                  19.03.2018 11:59

                  Э-э-э… Там фото более чем достаточного разрешения, чтобы увидеть маркировку чипа. Типичная LDO-шка китайская — это 1117, ее сразу видно и ни с чем не спутать :) Да и индуктивности, опять же :)
                  Еще раз — взять готовый будет быстрее и дешевле, если разработчик не спец в данном вопросе.
                  Вы про Point-of-Load в курсе? В телекоммуникационном оборудовании они используются сплошь и рядом, поскольку разработчики спецы в высокочастотных дизайнах, но питание — не их конек. Поэтому проще поставить что-нибудь приличное, от GE или Murata за полчаса, чем тратить неделю на курение даташитов. Там свои проблемы выползают, конечно, с охлаждением, например — тепло с PoL в плату почти не уходит, но в общем случае это быстрее и надежнее, чем ваять самому DC/DC конвертер с нуля


                  1. olartamonov
                    19.03.2018 12:09

                    Типичная LDO-шка китайская — это 1117, ее сразу видно и ни с чем не спутать :) Да и индуктивности, опять же :)


                    Что в названии LM2596 заставляет вас заподозрить, что я имел в виду LDO? Или вы не верите, что у DC/DC Iq может быть в десяток миллиампер? Ну, откройте даташит, что ли.

                    Еще раз — взять готовый будет быстрее и дешевле, если разработчик не спец в данном вопросе.


                    Большинство проблем имеет простое и очевидное неправильное решение.

                    Поэтому проще поставить что-нибудь приличное, от GE или Murata за полчаса, чем тратить неделю на курение даташитов


                    Я вам страшую вещь скажу: на все эти модули тоже есть даташиты. Которые тоже надо читать.


  1. l_o_d
    18.03.2018 19:35

    А из чего эти голубенькие стойки? Неужели бумага?


    1. dmiceman Автор
      18.03.2018 19:44

      Бумага :-) Как раз дочку привлек к процессу производства. Не оказалось в заначке подходящих шурупчиков, которые лезли бы в монтажные дырки этих макеток, поэтому стойки были сделаны из зубочисток, обернутых бумагой, покрытой цапонлаком. Крепление к макеткам — суперклей. На неделю конструкции хватит.


      1. l_o_d
        18.03.2018 21:25

        Еще один шаг к биоразлагаемым устройствам)


  1. olartamonov
    18.03.2018 19:42
    +1

    А один только вывод из сна занимает как минимум 65ms, требуемые на стабилизацию осциллятора


    Выкидываем внешний кристалл, тактируемся от внутреннего RC, у которого минимальное время запуска — 6+14 KCK, т.е. 20000/8000000 = 2,5 мс.


    1. dmiceman Автор
      18.03.2018 19:49

      Вот да, я про эти 65ms написал со слов на каком-то форуме. В даташите это как-то не очень ясно описано (ну или я не очень понял). Буду изучать это шаманство через неделю :-)

      Другое дело, будет ли от этого толк вообще, если спать надо 10ms всего.


      1. olartamonov
        18.03.2018 19:56

        image

        Я боюсь предположить, как можно ещё яснее-то это описать.

        Не говоря уже про то, что у вас есть ещё и Standby Mode, в котором внешний осциллятор продолжает работать, энергопотребление в районе 100 мкА, а выход из сна — за единицы тактов.


        1. dmiceman Автор
          18.03.2018 20:01

          Я вот это все время курю: ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2545-8-bit-AVR-Microcontroller-ATmega48-88-168_Datasheet.pdf

          Там такой таблицы я не нашел. Это откуда?


          1. olartamonov
            18.03.2018 20:07

            Там такой таблицы я не нашел


            Попробуйте посмотреть ещё раз. Например, на странице 58.


            1. dmiceman Автор
              18.03.2018 20:30

              Ээ… Мм… Да, действительно. Спасибо за науку.


    1. dmiceman Автор
      18.03.2018 19:57

      И, к слову, я как раз внутренний осциллятор использую.


    1. Gudin
      19.03.2018 19:27

      А почему 6+14, а не просто 14? Я так понял в случае выхода из сна (2 режима) будет только 6.


      1. olartamonov
        19.03.2018 20:46

        Да, вы правы, 6. И не KCK, а просто CK, т.е. ещё и микросекунды.

        Много лет не работал с атмегами, а сейчас глянул по диагонали.


  1. courser
    18.03.2018 19:46

    6ма однозначно говорят о криво написанной программе, извините.
    Неоткуда взяться 6ти ма, если программа будет выходить из спячки по прерыванию RTC 25раз в секунду или около того(этого достаточно при 5в размахе) для быстрого инверса сегментов. Да даже и при 100герцах это очень много.
    Используйте прерывания RTC, изучите внимательно типы сна.


    1. dmiceman Автор
      18.03.2018 19:55

      > 25раз в секунду

      Мало. Я пробовал разные режимы, и даже при 50 герцах заметно мерцание.

      И тут другой момент — ds1307 умеет только 1Hz, 4kHz, 8kHz и 32kHz. Ничего подходящего.

      > говорят о криво написанной программе, извините.

      А это запросто :-) Это пока самая большая и сложная программа для контроллера, которую я написал в жизни. Знание специфики у меня очень умозрительное.


      1. courser
        18.03.2018 20:28

        Используйте встроенный rtc меги, тактируйте проц от того же кварца 32768
        для часов это более чем достаточно.
        Постоянную времени вашего индикатора не знаю, но обычно мерцание заметно только под углом, и уж точно не на 50гц, это уже не увидит глаз. Скорее всего мерцание связано с другими причинами — цикл какой-нибудь вклинивается и тп.


        1. dmiceman Автор
          19.03.2018 09:28

          Подозреваю, в моем случае мерцание на 50 Hz связано с неправильной разводкой. Ведь я (ошибочно) сделал так, что все продвижения битов по 595-м неизбежно отображаются на индикаторе. А может и нет. Тайминги у меня в этом месте немного с потолка взятые.


          1. courser
            19.03.2018 14:38

            Я б вообще рекомендовал для этого проекта мегу64L или А, она не так дорого стоит, и развести сегменты по портам напрямую. RTC использовать встроенный, питание взять от двух мизинцев 3в. Будет очень лаконично и экономично. Сотня-две микроампер максимум, думаю.


  1. REPISOT
    18.03.2018 20:00
    +1

    Как оказалось, 4 килобайта — это очень мало. Особенно, если писать на C.

    Э, нет. Это не С. это Arduino IDE. Чистый C дает вполне себе компактный код.


    1. dmiceman Автор
      18.03.2018 20:05

      Так какая разница какая IDE? Оно же все равно компилирует avr-gcc, с -Os. Если не допускать с++-ного оверхеда, никакой разницы быть не должно.


      1. mksma
        18.03.2018 20:15

        Оставил по этому поводу комментарий ниже. По моим наблюдениям Arduino IDE в исполняемый файл подсовывает какую-то свою библиотеку, отсюда и разница.


      1. ProstoUser
        19.03.2018 09:41

        Там еще стиль написания довольно странный. По крайней мере то, что я увидел в самом начале, можно заметно уменьшить, как по количеству занимаемого места, так и по количеству выполняемых команд.

        Например, с самом начале, там где:

        switch (num) {
            case 0:
              if (pos == 3) {
                buf = 0b11101110;
              } else {
                buf = 0b11100111;
              }
              break;
        ......
        


        можно написать что-то вроде такого:

        static const unsigned char DigitCode = {0b11100111, .....};
        static const unsigned char DigitCodePos3 = {0b11101110, .....};
        if (num<9) 
          buf = (pos == 3) ? DigitCodePos3[num] : DigitCode[num] ;
        


        Оно и короче, и по крайней мере не медленнее получится.

        Подобных мест, где вместо простой таблички огромный копипаст, в вашем коде очень много. Так что, скорее, это стиль а не компилятор.


        1. dmiceman Автор
          19.03.2018 10:25

          Даже повода поспорить нет :-) Все так.


    1. HiTechSpoon
      20.03.2018 09:15

      Последнйи раз имел дело с Arduino лет 5 назад, и если я правильно помню, в Arduino IDE применялся язык Processing, у которого есть своя IDE — PDE (Processing Development Evironment). У этих IDE схожий вид и в Сети можно найти упоминания, что именно от Processing'а растут ноги у Arduino IDE. Также и слово «скетч» — название исходного кода программы в Arduino IDE, было позаимствовано из Processing.
      Сейчас же на сайте википедии написано, что в Arduino IDE используется С++. Интересно, не ошибка ли это или действительно язык поменяли?


      1. moviq
        21.03.2018 12:46

        Так вроде был тот же Си в обертке.Не?


        1. BigBeaver
          21.03.2018 12:54

          Там плюсы.


  1. mksma
    18.03.2018 20:11

    Как оказалось, 4 килобайта — это очень мало. Особенно, если писать на C.

    Поправьте меня кто нибудь если я не прав. Но у меня сложилось впечатление, что Arduino IDE в исполняемый файл подсовывает еще какой-то свой код. Который берет довольно много места. Например, когда для работы с LCD дисплеем я использовал Arduino IDE + liquidcrystal_i2c библиотеку, сборка заняла примерно 2500 байт. Без Arduino IDE и со своей библиотекой для i2c и дисплея та же функциональность уместилась в 750 байт.


    1. dmiceman Автор
      18.03.2018 20:22

      Загрузчик? Я-то использовал minicore, который для atmega48 загрузчика не использует.


      1. mksma
        18.03.2018 20:38

        Проверил что Arduino IDE добавляет в исполняемый файл. Среди прочего в линкер передавалось это:

        arduino_cache_122843\core\core_arduino_avr_uno_27ad0de2390183402c74f07cbe44f9f8.a
        На чистом C это можно убрать, но тогда нельзя использовать библиотеки созданные для Adruino IDE.


  1. DASM
    18.03.2018 20:33

    может лучше atxmega128 рассмотреть со встроенным контроллером сегментного ЖКИ?


  1. VTH
    18.03.2018 21:12

    В таком приложении стоило бы тупую работу по обновлению жк-экрана возложить на какой-то аппаратный rc таймер/генератор. Вполне при этом получив микропотребеление. Тем более, внешние чипы помимо контроллера задействованы


  1. Strange
    18.03.2018 21:28

    Посмотрите в сторону PCF8577C.


  1. andrrrrr
    18.03.2018 22:34

    может вместо ЖК попробовать электронную бумагу? обновил цифру и в сон на минуту. оно не перестаёт отрисовывать изображение даже после отключения ото всего.
    ссылка на али, цена $14, диагональ 2.9 дюймов
    image


    1. l_o_d
      18.03.2018 22:39

      Еще бы подешевле стоил( Почему то никогда не видел что нибудь самодельное с таким типом дисплея. Видимо есть какие то сложности в реализации…


      1. Alexashka
        18.03.2018 23:32

        Waveshare сейчас выпускает со встроенным контроллером и SPI-интерфейсом. Цена только не совсем демократичная, около 500р за 2.13"


      1. ploop
        19.03.2018 08:46

        Видимо есть какие то сложности в реализации…

        Дорого, да и появились они относительно недавно.



    1. dernuss
      19.03.2018 08:09

      На пару лет хватит, потом будет деградировать.


    1. Mogwaika
      19.03.2018 08:48

      Этот цветной перерисовывается очень долго, секунды. Надо брать мелкий ч/б, он отрисовывается за 0.3 с кажется…


  1. Proektmnd
    18.03.2018 22:43

    Можно взять 48 мегу с индексом V, или PA.У них нижний порог питания 1.8в. Для пущей экономии питания отключить ненужную периферию: компаратор(жрёт как конь), АЦП, УАРТ. RTC было бы лучше использовать, например, DS3231.У неё кварц уже на борту, питание 3.3в, потребление в активном режиме 200мкА. DS1307 тоже жрёт не мало, да ещё и кварц внешний(точности не добавляет).А что бы часы запустились, можно вписать в регистр секунд нолик и они пойдут без установки времени.


  1. sfrolov
    18.03.2018 22:49

    Если хотите использовать ЖКИ, то берите сразу микроконтроллер с драйвером ЖКИ. Это позволит разгрузить микроконтроллер и уменьшить токопотребление из-за того, что процессор не будет просыпаться 100 раз в секунду для обновления ЖКИ.
    Правильное батареечное устройство с постоянной работой ЖКИ должно работать минимум полгода от одного комплекта батарей. Это единицы микроампер. Предложенный HT1621 плохо для этого годится, потому что только он потребляет в районе 20-30 мкА.


    1. l_o_d
      18.03.2018 23:15

      Ну единиц микроампер в домашних условиях наверное сложно добиться. А при 100 — 200 мкА и комплекте хороших пальчиковых батареек думаю пол года проработать может.


      1. olartamonov
        19.03.2018 08:26

        Ну единиц микроампер в домашних условиях наверное сложно добиться


        И что же в домашних условиях этому мешает?


        1. l_o_d
          19.03.2018 10:49

          Большинство поделок лепится из того что под рукой) Иногда нет экономичного контроллера, иногда подходящих батареек или стабилизатора. Банально большинство самодельщиков скорее всего не имеют профильного образования или желания глубоко закапываться в даташиты. Одни могут написать экономичное ПО но у них проблемы с железом, у других обвязка почти ничего не жрет но не оптимальное ПО контроллера потребляет как паровоз.


          1. BigBeaver
            19.03.2018 10:53

            Так это не сложно, а не охота.


          1. ploop
            19.03.2018 10:54

            Эх, если бы это была проблема самодельщиков… Сколько статей о том, как вмонтировать в мышку аккумулятор на 100500 мАч, чтобы проработала хоть месяц без зарядки, хотя у того же Logitech мыша работает год(!) на одной батарейке, соответственно два — на двух.


            1. Meklon
              19.03.2018 11:01

              Это смотря какие.
              image
              Logitech Performance MX — офигенная мышь. Но аккумулятора там хватает на 3-5 дней. Причем от рождения так было.


          1. olartamonov
            19.03.2018 12:10

            То есть в домашних условиях возникает какая-то непреодолимая сила, не позволяющая прочитать даташит на контроллер и написать прошивку нормально?


            1. l_o_d
              19.03.2018 13:19

              В домашних условиях делают устройства не только те кто могут осмыслить даташит. Часто просто дергают примеры из инета, поправляют по месту и вперед. Кому то может интереснее процесс пайки и непосредственно сборки, а к ПО отношение «лишь бы было». Это же просто хобби) Это как добиваться рекордных урожаев на домашней картофельной грядке: есть энтузиасты, а есть те кому «как то растет и ладно».


              1. olartamonov
                19.03.2018 14:10

                То есть оригинальную фразу «в домашних условиях сложно добиться единиц микроампер» надо читать как «лично мне в домашних условиях сложно добиться единиц микроампер, потому что лень этим заниматься, а хочется побыстрее сляпать на коленке»?


                1. l_o_d
                  19.03.2018 14:42

                  Можно и так. Хотя нет все немного сложнее. Например я могу хорошо развести плату, сделать или подобрать приличный корпус, все красиво спаять и собрать, но вот с ПО проблемы. Глядя на творения людей на проводах и скотче залитые из «соплемета» называть свои устройства сделанными «на коленке» я не хочу. Причем некоторые сопливые поделия реально жрут микроамперы, потому что создатели хорошо пишут ПО, чего я не могу. Каждому свое как говориться) Не отрицаю что есть те у кого все получается цивилизованно: и прошивка, и плата, и корпус.


  1. Meklon
    18.03.2018 23:03

    Как вы руками такие пучки проводов паяете? Чисто субъективно гораздо меньше вариантов ошибок при проектировании в чем-то вроде Eagle. Хотя, вероятно, тут моей недостаток опыта сказывается.


    1. l_o_d
      18.03.2018 23:18

      Тоже всегда удивлялся такому терпению) Мне проще сразу развести плату, попробовать собрать, потом в случае ошибок еще раз вытравить, чем напаивать проводок за проводком. Но обилие поклонников вот такого способа сборки говорит о том, что не все такие нетерпеливые.


      1. dmiceman Автор
        19.03.2018 09:49

        Как раз нетерпеливые :-)

        На одну разводку я бы дня три убил. А так я всю схему в голове держал и паял, просто поглядывая на распиновку.


        1. ploop
          19.03.2018 10:51

          На одну разводку я бы дня три убил

          Это вы утрируете. Даже впервые попробовав это сделать в каком-нибудь спринте такая плата получится менее, чем за час. При том основная масса времени уйдёт на перфекционизм :)


        1. Meklon
          19.03.2018 11:02

          А потом внезапно помехи и наводки ловить на этот пучок проводов. А как делать дебаг такого я даже не представляю.


    1. ploop
      19.03.2018 00:21

      Хотя, вероятно, тут моей недостаток опыта сказывается.

      Ваш недостаток опыта вполне дополняется достатком здравого смысла :)
      Плату сделать действительно проще, быстрее, и с меньшим количеством ошибок. Просто под ЛУТ, дома.


      1. Meklon
        19.03.2018 08:02
        +2

        Лут у меня получается, но не очень стабильно. Сейчас жду фабричные платы. Первый раз пробую. Хочу как белый человек нормальные использовать с шелкографией и маской.
        image


        1. ploop
          19.03.2018 08:49

          ЛУТ для макета самое то. И то не всякого, если сложная двухслойная плата приходится и макеты заказывать на производстве.
          А так да, впервые держать в руках заводскую плату собственной разводки нереально круто!


          1. Meklon
            19.03.2018 10:01

            Лут я делал) только бумага из журнала медицинского оказалась неправильной. Тонер слишком тонким слоем перенёсся, хотя и отклеилась бумага сама без следов. В итоге вытравило сильно дорожки. Впрочем, для прототипа норм. Один чип я тупо сжёг перегрузкой) но это уже я проступил и ошибка была не в плате, а в коммутации гнезда наушников.


            1. acin
              19.03.2018 10:29

              Дорожки после травления хорошо бы залудить под паяльной кислотой и тщательно смыть (это если плата очень давно лежит и вся покрылась окислами, гидрокислами и прочей гадостью). Ну и попробовать сменить флюс и припой.


              1. Sworfly
                19.03.2018 11:06

                Зачем паяльной кислотой издеваться над жалом паяльника, дорожками, легкими и глазами? Пемолюкс на жесткую сторону губки, чуть воды и натереть плату этой кашей. Даже после сильного окисления медь становится как новой. Да и остатки тонера хорошо стираются.


              1. Meklon
                19.03.2018 11:47

                Я до травления и тонера поверхность платы обрабатывал алмазом на 2000 Grit. Вроде все снялось. Тут проблема в том, что после травления дорожка в мелкую сеточку. По факту даже участок обрыва был. Реально перетравлено сильно. Но на руках не было других материалов — работал с тем, что было. Флюс активный спирто-канифольный. Вроде смылся без остатков в изопропаноле. Дал полежать полчаса в нем, а потом хорошо потряс.

                Если я наносил олово как положено пучком медных волосков, то нанесение было ровным. Но перетравленные дорожки не давали непрерывного гладкого рисунка. Поэтому нанес жалом паяльника с избытком и не очень красиво. С другой стороны, сопротивление низкое, все норм. А когда заводские придут — уже переделаю на них.


              1. Meklon
                19.03.2018 13:14


                Вот такая грусть из-за плохого трансфера получилась. Причем там даже обрыв есть по питанию. В районе посадочной площадки конденсатора слева вверху. Что есть) Переделывать некогда было. Прототип, однако.


            1. Mike_soft
              19.03.2018 10:45

              ЛУТ требует навыка, «набивки руки» — именно в привязке к конкретному принтеру, утюгу и бумаге. Но при «набитой руке» крайне быстр. Фоторезист — более стабилен, хотя привычки тоже требует. Ну и чуть медленнее. ну а изготовление плат под заказ — медленно, но крайне качественно


              1. Meklon
                19.03.2018 10:57

                Мне очень редко нужно, поэтому привычки особо нет)


              1. ploop
                19.03.2018 11:05

                Фоторезист требует ещё и некоторого оборудования — как минимум самого резиста, лампы, плёнки для шаблонов. А для ЛУТа утюг, принтер и журнал с сиськами, то есть порог вхождения ниже, можно начать прям вот когда загорелось.


                1. Meklon
                  19.03.2018 11:07

                  Я смотрел на фоторезист. Но там реально порог для единичных экземпляров уже такой, что проще на заводе заказать.


                  1. Karlson_rwa
                    20.03.2018 22:20

                    Попробуйте ЛУТ на фольге.
                    Я когда активно сам платы делал, фольга очень выручила. Даже двухсторонние делал, правда, с особым подходом к проектированию таких изделий.


                1. Mike_soft
                  19.03.2018 12:24

                  абсолютно согласен. ЛУТ — это вотпрямщазз с нуля, фоторезист — следующий шаг, ибо надо заранее купить фоторезист (рублей 200), лампу (еще 200), пленку (еще 200). Зато когда это есть — оно по «старту» уже не отличается, но тут уже и качество выше, и повторяемость.
                  То же касается и паяльника — первый детекторный приемник можно и на скрутках, затем — дедовским стоваттником, потом хочется что-то нормально лежащего в руке и не перегреавющегося — ну а затем и станцию можно прикупить. То же касается и измерений. И отладки софта. Предела совершенству нет, но каждый останавливается на своем уровне.


                  1. DASM
                    19.03.2018 13:23

                    где Вы его за 200 видели? Давече покупал позитив 20 — 1000 р. Лампа — 2500 для ногтей, пленка может и 200, но лазерный принтер хорошо бы в смету добавить


                    1. Mike_soft
                      19.03.2018 13:37

                      видел.

                      не рекламы ради
                      1. DASM
                        19.03.2018 13:54

                        пленка тоже есть, но у меня с ней не заладилось, как-то грубо выходит, шаг 0.5 не протравливается. С позитивом лучше, там 0.5 не проблема. А черную лампу так и не нашел в продаже, пришлось купить косметическую лампу для полимеризации лака


                        1. Mike_soft
                          19.03.2018 14:16

                          это уже нюансы. но главное то, что сейчас окромя древних методов а-ля стеклянный рейсфедер и цапон-лак (а то и резака из ножовочного полотна ) — вполне доступны и ЛУТ, и фоторезист (не из «белка куриного яйца и еще чего-то», как в рецептуре книги «радиолюбительские технологии», а вполне заводской ), причем фоторезисты еще можно выбирать.
                          плюс smd. Это ж по радиокружковым меркам — просто рай :-)


                          1. DASM
                            19.03.2018 14:26

                            о да, молодежь наверное о рейсфедерах не в курсе… особо было сложно степень разведения лака ацетоном подобрать чтобы нормально наносились дорожки. А еще вариант был в стержень шариковой ручки лак заливать, а из наконечника выдавить шарик. Эх время


                            1. Mike_soft
                              19.03.2018 14:33

                              мы предпочитали «растягивать» стержень над спичкой и обрезать — поручившийся аналог рейсфедера ходил по фольге гораздо мягче, и не издавал скрипа…


            1. l_o_d
              19.03.2018 10:54

              Купите у китайцев бумагу для ЛУТ. Очень удобная вещь. Желтенькие такие листы:
              www.ebay.com/itm/10PCS-A4-Sheets-Heat-Toner-Transfer-Paper-For-DIY-PCB-Electronic-Prototype-Mak-/400505239086?hash=item5d3ff8f62e


              1. Meklon
                19.03.2018 10:57

                Я видел. Во всех комментариях стоят маты по поводу того, что китайцы не упаковывают в жесткий картон. В итоге все скомканное приходит.


                1. Mike_soft
                  19.03.2018 11:04

                  у нас в городе в радиолюбительских ее магазинах продают (хотя я не пробовал). Ну и фоторезист (которого тоже надолго хватает при хранении в прохладном месте) там же.


                  1. Meklon
                    19.03.2018 11:07

                    Надо Чип и Дип глянуть. На радиорынке не видел точно.


                1. l_o_d
                  19.03.2018 13:22

                  Это да) Мне вообще в трубочку свернули пачку листов. Поставил под стопку книг чтоб выровнялись. Я потом режу лист на четыре и приклеиваю клейкими ценниками к обычной бумаге. Так экономичнее выходит и неровность не так сильно сказывается.


    1. dimaviolinist
      19.03.2018 00:31

      О, это ещё не пучки совсем :)
      Там их меньше сотни даже.


      1. Meklon
        19.03.2018 08:03

        Нафиг-нафиг) я и на более простых вариантах сжигал детали)


    1. olartamonov
      19.03.2018 08:41

      Чисто субъективно гораздо меньше вариантов ошибок при проектировании в чем-то вроде Eagle


      Всё абсолютно правильно делаете. Время, потраченное на спагетти из проводов, ЛУТ и Sprint Layout — это время, потраченное впустую.


      1. akhkmed
        19.03.2018 10:28

        Про Sprint Layout не пойму, чем он плох для любительских устройств низкой сложности?


        1. l_o_d
          19.03.2018 10:56

          Да ничем не плох на самом деле. Да и провода не плохи. Это же для себя, развлечение типо. Если говорить про потраченное впустую время, то и часы можно за 50 рублей купить в ларьке ближайшем)


        1. argz
          19.03.2018 11:12

          Имхо, надо с самого начала приучаться делать всё по технологии.
          Гляньте в сторону KiCad.


          1. ploop
            19.03.2018 11:18

            Заводить комбайн из-за трёх колосков тоже не вариант. Если требуется развести диодный мост, гораздо быстрее это сделать в SL.


            1. BigBeaver
              19.03.2018 11:28

              Скорее не вариант иметь SL если делаешь хоть что-нибудь кроме диодного моста в течение года.


        1. olartamonov
          19.03.2018 12:12

          Нет сквозного проектирования, соответственно, непригоден для сколь-нибудь сложного устройства.

          Зачем тратить на него время, если тот же DipTrace бесплатен и осваивается за полчаса?


          1. Meklon
            19.03.2018 12:22

            Eagle для двухслойных тоже бесплатен. Более чем достаточно.


            1. ploop
              19.03.2018 12:30

              Не бесплатен, у него ограничение на размеры. Вроде для большинства поделок и достаточные (100х100мм ЕМНИП, лень точно искать), но иногда можно упереться по одному габариту, т.е. например узенькую линеечку на 150 уже не сделаешь.


              1. Meklon
                19.03.2018 12:37

                Это согласен. На большинство хобби-проектов не влияет. Ну KiCad есть, в конце концов. Хотя я и к Eagle-то мучительно привыкал с нуля. До него цапонлаком рисовал кривулины на текстолите руками.


                1. Mike_soft
                  19.03.2018 12:44

                  запах цапонлака, хлорного железа и канифоли — прям картин «детство в радиокружке».


                  1. Meklon
                    19.03.2018 12:57

                    Ага) Но оно было фантастически кривым. И еще все элементы выводные. Я сейчас прям не могу нарадоваться SMD. Сверлить не надо, места мало занимают.


                    1. Mike_soft
                      19.03.2018 13:10

                      «и ведь всего-то — просто НЕ НАДО БЫЛО приделывать выводы к деталям»© :-0


                      1. l_o_d
                        19.03.2018 14:09

                        Самое интересное ведь эти детали и раньше существовали. Помню в институте были древние советские гибридки с вполне себе современно выглядящими SMD конденсаторами. Почему их в обычных схемах не применяли непонятно… Видимо у нас эффект послезнания) Додуматься не приделывать ноги наверное было не так просто


                        1. Mike_soft
                          19.03.2018 14:27

                          вспоминаются даже «бескорпусные транзисторы со сферическми выводами» — нечто типа BGA, только 2х2 вывода :-) для этих гибридок.
                          говорили, что были проблемы с техпроцессом пайки на больших площадях текстолита.


                          1. l_o_d
                            19.03.2018 14:34

                            Видимо боялись бунта монтажниц на заводах)


    1. dmiceman Автор
      19.03.2018 09:47

      На самом деле, пайка пучка проводов на плате индикатора, вдумчиво и размеренно, заняла только около двух часов. Не то что бы это меня совсем не достало, но все же оказалось не так и страшно. В паре мест недопаял, в паре мест перепаял, но это легко удалось исправить. Где-то паяльником, а где-то кодом. Да, было бы здорово немного переделать, вывести линию RCLK на контроллер, но этим я вряд ли займусь :-)

      А вот ЛУТ, с его множеством операций меня не привлекает. Плавали, знаем. Сначала развести, причем в один слой там не получится, придется пачку мостиков городить. Потом напечатать-прокатать утюгом. Где у меня валяется подходящая бумага, я даже не помню, и как ЛУТ отнесется к имеющемуся в наличии неродному тонеру — не знаю. Травить, мыть — вонюче и грязно. Сверлить. Не помню почему, но это операция почему-то вызывает особенное отвращение.

      И при этом, в результате будет сложнее исправить неизбежные ошибки. Вон, пытался заодно реанимировать плату, красиво разведенную и распаянную семь лет назад под 0.3mm дорожки, TQFP и прочие smd. Думал когда-то красивый такой термометр соорудить. Оказалось — reset у AtMega8 забыл подтянуть. Поправить уже затруднительно.


      1. l_o_d
        19.03.2018 10:59

        А вот ЛУТ, с его множеством операций меня не привлекает.

        Это вы фоторезист не пробовали)
        Травить, мыть — вонюче и грязно

        Травите не хлорным железом, а перекисью и лимонной кислотой (ну еще соли щепотка) и будет все чисто.
        Сверлить.

        Переходить на поверхностный монтаж с минимумом дыр. В макете можно совсем без дырок обойтись.


  1. YegorVin
    18.03.2018 23:53

    А вы измеряли что именно жрет 6ма?
    Сам микроконтроллер или может быть ЖК индикатор.

    Если микроконтроллер то резать частоту. Зачем аж 1 МГц :)


    1. dmiceman Автор
      19.03.2018 09:54

      > А вы измеряли что именно жрет 6ма?

      На самом деле, нет. Методика получения этого результата хромает у меня на все ноги. Мерил я в одной точке, все целиком. И как бы даже с лишними деталями, имевшимися во время измерения в схеме.

      Вот, будет чем через неделю заняться :-)

      > Если микроконтроллер то резать частоту. Зачем аж 1 МГц :)

      А тут уже есть варианты.

      Вот хотелось бы всем участникам обсуждения спасибо сказать — здравых и интересных идей я увидел множество. Есть куда думать и что делать.


  1. ploop
    19.03.2018 00:31

    Как оказалось, 4 килобайта — это очень мало

    А какой посоветуете контроллер под часы под ТЗ ниже?
    Описание
    — 14 семисегментных индикаторов (светодиодных)
    — 2 датчика температуры (DS18B20)
    — Аналоговый датчик давления (выводить данные надо в мм.рт.ст с десятыми)
    — Авторегулировка яркости по логарифмическому закону (датчик света + плавная регулировка)
    — ИК пульт управления
    — Режим обучения для пульта, чтобы можно было использовать пульт от любой ненужной техники
    — Установка времени с пульта
    — Цифровая коррекция хода (RTC не используются, только МК), с пульта
    — Корректировка отображения давления (компенсация высоты) с пульта
    — 10 режимов отображения информации (с секундами, без, дата, разные комбинации температуры/давления)
    — Связь с ПК по UART (установка времени)


    1. dimaviolinist
      19.03.2018 00:51

      Можно Atmega328 (1.7$) или STM32F103C8T6 (2.13$).
      Проще, (и, уверен, дешевле) вместо 14 семисегментных индикаторов (светодиодных) использовать 0.96" I2C IIC Serial 128X64 за 2.91$.


      1. ploop
        19.03.2018 01:00

        Ладно, я не зря процитировал автора — скорее ему на заметку.
        Эти часы висят передо мной и работают 9й год, весь функционал как раз на ATMega48. И памяти ещё немного осталось :)

        Светодиодные индикаторы выбраны из-за габаритов (6 шт под время 35мм высотой, два блока по 4 индикатора на 20мм) — их видно с любого места зала. Ну и читаемость отличная.
        Авторегулировка позволяет не светить как ночник ночью, и нормально читаться при прямом солнечном свете. Индикаторы работают через те же 595е, т.к. никаких ног не хватит обслужить всё напрямую. Аналоговый датчик давления — за неимением лучшего.

        По поводу точности: цифровая коррекция, при условии, что часы постоянно находятся при комнатной температуре, позволила их отстроить до нескольких секунд в год (около 15ти, ЕМНИП, дальше уже муторно), что более, чем достаточно.


        1. dimaviolinist
          19.03.2018 01:12

          Вот. 595.
          Плюс их, хоть и копеечная, но стоимость, плюс время на разработку и пайку…

          работают 9й год

          Сейчас всё очень сильно дешевле и удобнее.
          Кстати, на больших светодиодных индикаторах у меня 595е неслабо даже грелись.


          1. ploop
            19.03.2018 07:42

            Кстати, на больших светодиодных индикаторах у меня 595е неслабо даже грелись.

            35-миллиметровые усиливал транзисторами. Под него как раз помещается 595й и 8 транзисторов :) 20-миллииетровые нормально тянут. Точнее, не просто «нормально», схема вся продумывалась и рассчитывалась по даташитам.
            Сейчас всё очень сильно дешевле и удобнее.

            И не так интересно :( Старею наверное…


            1. dimaviolinist
              20.03.2018 22:19

              Меня учили, что «чем меньше элементов на плате, тем лучше» (если при этом задача правильно исполняется). Транзисторы на ULN2003 поменял бы.
              И, кстати, интересно всё равно. Просто возможностей больше.


              1. ploop
                21.03.2018 08:01

                ULN2003

                Уж не помню, но по какой-то причине она меня не устроила. Может банально дороже выходила, может ещё что.


        1. dmiceman Автор
          19.03.2018 09:58

          Ну, поди, все-таки не на C прошивка? :-)

          Нет, я знаю как и с моего кода примерно килобайт срезать оставаясь на C, но такого желания не испытываю. Переживания главного героя известного рассказа «Один байт» я повторять не хочу :-)


          1. ploop
            19.03.2018 11:11

            Нет, не на Си, я тогда им ещё не владел на таком уровне. Но позже понял, что на Си это получилось бы ничуть не хуже.

            Тут ещё дело в архитектуре — ассемблер AVR8 настолько прост и логичен, что после килобайта кода, на нём начинаешь разговаривать и посылаешь к чёрту все остальные средства разработки :) С каким-нибудь STM8 уже так не получится, а STM32 — это будет просто баловством, никак не связанным с реальностью.


      1. dernuss
        19.03.2018 08:15

        0.96" I2C IIC Serial 128X64

        Если это OLED, то выгорит через год другой


  1. legustarasov
    19.03.2018 00:31

    На самом деле такие неудачи получаются, когда используешь микросхему широкого потребления для решения специфических задач.
    Во-первых у серии ATmega есть контроллеры с буквой L — это как раз со сниженным потреблением питания (типа ATmega8L). Еще меньше потребляют STM8L… У некоторых микросхем STM32L есть внутренние часы реального времени, специализированная ножка Vbat с помощью которой они питаются и отдельный вход для часового кварца.
    Во-вторых требуемый контроллеру ток пропорционален (кроме частоты работы, чего вы снижать не хотите из-за I2C) от напряжения питания. Снижайте напряжение питания до 1.8В.
    В-третьих в данной ситуации постоянно загружать в SN54HC595 новые данные — расточительство. Надо грузить их туда раза 2 (на самом деле чуть чаще, чтобы обновление было без рывков) в секунду, а осцилляции напряжения на выходе из микросхемы, чтобы обновлялся экран с частотой 100 Гц с помощью отдельной микросхемы ключей, которые будут дергать ногами от генератора с чатотой 100 Гц… мультивибратора какого-нибудь.
    В итоге микроконтроллер просыпается 2 раза в секунду, опрашивает часы, загружает информацию в буфер и засыпает.


    1. ploop
      19.03.2018 00:33

      Еще меньше потребляют STM8L

      … у которых есть серия с драйвером ЖК. Общее потребление уже в микроамперах идёт.


      1. Elmot
        19.03.2018 02:57

        в серии stm32l до черта чипов с LCD контроллерами. Я нежно любил stm8(f правда, не l), но возьня с теперь имеет мало смысла.


        1. ploop
          19.03.2018 07:47

          У других производителей тоже есть.
          Собственно, всё сводится у первому предложению выше: автор использовал "… микросхему широкого потребления для решения специфических задач", и он их решил отчасти, на сколько она позволяет.


          1. olartamonov
            19.03.2018 08:40

            Да ничего он не решил.

            У него в камне есть полдюжины режимов энергосбережения. Какой-нибудь Extended Standby Mode оставляет включённым внешний осциллятор, продолжает тактировать Timer/Counter2, имеет потребление 50 мкА на подходящем кристалле и выходит на полные обороты за 6 тактов.

            Это, конечно, не 0,5-1,5 мкА чипов с нормальным RTC и низкопотребляющей периферией, но это в десятки раз лучше того, что получил автор.


            1. ploop
              19.03.2018 08:53

              Решил в плане того, что устройство заработало. С потреблением конечно у него швах полный, можно было сократить намного, все варианты уже озвучили, но это всё равно не было бы решением задачи полностью (если она не звучит как «сделать кровь из носа на ATMega48»).


              1. olartamonov
                19.03.2018 09:34

                Я вот полистал даташит пятнадцать минут (а я в этом десятилетии, если мне память не изменяет, сделал один проект на AVR, да и тот был вспомогательной фигнёй на 8-ногой тиньке в одну страницу кода размером — это к вопросу о том, насколько хорошо я их знаю), и в принципе спокойно готов сделать на ATMega48 часы со средним потреблением не выше 10 мкА и без всякого внешнего обвеса.

                1) вешаем внешний кварц 32,768 кГц на TOSC1/TOSC2
                2) Timer/Counter2 включаем в асинхронный режим от этого кварца
                3) чип заводим от встроенного RC на 8 МГц с делителем 8
                4) уводим чип в Power-Save Mode, оставляя TC2 тикать асинхронно
                5) каждые 1/128 с = 7,8125 мс просыпаемся по прерыванию от TC2, раскочегаривание внутреннего RC занимает 6 тактов, т.е. меньше микросекунды
                6) перещёлкиваем полярность ЖК, добавляем 1/128 с в счётчик времени, засыпаем обратно

                Даташит не раскрывает нам, сколько оно жрёт в PSM с часовым кварцем, но это не должно быть больше 2-3 мкА.

                10 мкА среднего потребления — это почти три года работы на CR2032.


                1. BigBeaver
                  19.03.2018 09:49

                  Вместе с потерями на сдвиговых регистрах и рассыпухе будет все равно под 0,5мА. По крайней мере, если оставить, как у автора.


                  1. olartamonov
                    19.03.2018 10:03

                    Понятно, что 7805 придётся закопать, равно как и регистры на MC74VHC595 какой-нмбудь поменять.

                    Но в атмеге48 с 10 мкА среднего потребления в этой схеме совершенно ничего фантастического нет.


                    1. BigBeaver
                      19.03.2018 10:07

                      Не, с 7805 будет еще раз в 10-20 больше, но это так уж.

                      А вообще, я с вами полностью согласен, и для меня вообще было удивительно, что узким местом у автора какм-то образом оказался контроллер. Тем более, что они очень хорошие у Atmel, хоть и слабоваты по фаршу по нынешним меркам.


                      1. olartamonov
                        19.03.2018 10:20

                        А вообще, я с вами полностью согласен, и для меня вообще было удивительно, что узким местом у автора какм-то образом оказался контроллер


                        Для меня — нет, не удивительно. Нагромождение однотипных поверхностных руководств «для новичков» в интернете плюс привычка к тому, что думать не надо, надо на алиэкспрессе купить и готовую библиотечку скачать.

                        Причём последнее сейчас разными говорящими головами, которые попросту сами не умеют ничего более сложного, чем сунуть алиэкспрессу номер своей кредитки, воспитывается под лозунгами «стартап должен первым собрать MVP», «некогда тратить время на ненужные вещи» и т.п.

                        P.S. Параллельно этому треду наблюдаю, как в фейсбуке человеку в ответ на вопрос, как сделать в ардуине 10-секундный таймер, советуют в loop() воткнуть процедуру, которая на каждом витке будет смотреть аптайм и считать, не прошло ли десять секунд. Это при том, что даже в этом убожестве давно уже изобрели таймер с прерываниями, а для автора loop() вообще черти отдельную сковородку в аду греют.


                        1. l_o_d
                          19.03.2018 11:03

                          Тут кто то недавно автоматику лифта на ардуине делал) Скоро будут в производство пускать поделки сделанные на беспаечных макетках)


                          1. Mike_soft
                            19.03.2018 11:14

                            залил провода, воткнутые в макетку, из пистолета-соплемёта (это еще один — судя по ютубу- любимый инструмент импортных DIYщиков), и «в продакшн»©


                          1. olartamonov
                            19.03.2018 12:14

                            Так на GT были недавно чуваки, у которых китайский поставщик чип флэшки поменял на условно-совместимый — и всё встало, потому что скачанный из инета драйвер с новой флэшкой не работает, а как это отлаживать и править, они даже примерно не представляют.

                            У них там всё комьюнити за месяц (!) не смогло даже выяснить, что конкретно сломалось-то.


                            1. l_o_d
                              19.03.2018 13:30

                              Это все из за невероятно снизившегося порога вхождения. Сейчас любой может что то как то работающее сварганить посмотрев урок на ютубе и воткнув провода в ардуину. Это здорово повышает самооценку (и это очень даже хорошо). У многих повышает настолько, что они мнят себя гениальными конструкторами (что уже плохо) и начинают рожать «это». Раньше эти товарищи даже не сунулись бы в эту область или наняли бы профессионала.


    1. olartamonov
      19.03.2018 08:29

      У некоторых микросхем STM32L есть внутренние часы реального времени, специализированная ножка Vbat с помощью которой они питаются и отдельный вход для часового кварца.


      RTC и часовой кварц есть у всех STM32L.

      Ножки Vbat у STM32L нет, потому что она им не нужна.


  1. Dark_Purple
    19.03.2018 00:35

    Другая батарея, другой контроллер, лишние микросхемы выкинуть и всё будет ок.
    CR2032 должно хватать на пару лет минимум.


  1. dimaviolinist
    19.03.2018 00:35

    Я делал (давно, правда) счётчик импульсов с некоторыми наворотами типа запоминания, установки и тоже на 3x7 segment индикаторе. Так импульсы ловил через прерывание. Всё работало идеально (правда, на PIC16F628A). Выполнял функции все и при этом спокойно считал до 10к Hz. (Код есть).
    Сейчас как раз захотел попробовать на Atmega8 поуправлять пучком светодиодных лент в разных режимах, попробую и ваш код глянуть. Сразу удивляет отсутствие

    такой структуры.
    const unsigned char seg[] = {
    0b00000010, // 0
    0b01001111, // 1
    0b00010001, // 2
    0b00000101, // 3
    0b01001100, // 4
    0b10000100, // 5
    0b10000000, // 6
    0b00001111, // 7
    0b00000000, // 8
    0b00000100, // 9
    };


    1. dmiceman Автор
      19.03.2018 10:19

      Все так. Код писался как удобнее, а не что бы выжать такты и байты. Места для оптимизации оставлено много.


  1. NumLock
    19.03.2018 03:54

    Штука в том, что все рекомендации встреченные мною на тему энергопотребления AVR-ок замечательно описываются фразой «спите глубже». Но контроллеру в часах нельзя спать! Ему денно и нощно, 100 раз в секунду необходимо обновлять экран.

    Контроллер должен спать. Для обновления индикатора активируйте SQW/OUT на DS1307 и подайте его на ножку ОЕ 595-их. Для снижения потребляемой мощности от батарейки, можно также использовать солнечную панель, встроив её в корпус часов.


  1. gosha-z
    19.03.2018 06:40

    Заинтриговали. Попробую на MSP430FR4133 сделать, благо платка есть уже.


  1. ittakir
    19.03.2018 08:52

    Я бы так делал:
    1. Микроконтроллер взял самый современный ATxxxPA.
    2. Питание от 3 вольтовой литиевой батарейки напрямую.
    3. Частота обновления LCD 50Гц или меньше.
    4. ATmega почти все время в глубоком сне, запущен только Watchdog, который её и будит 50 раз в секунду. Потребление 4uA.
    5. ATmega тактируется либо от внутреннего RC генератора, либо от внешнего клока, поданного напрямую от микросхемы часов.
    6. Отключена вся остальная периферия.
    7. Вывод цифр идет с помощью заранее расчитанных таблиц.
    8. Никаких Arduino библиотек, пишем в нормальной среде с полным контролем кода на выходе (IAR) на С/С++.


  1. mkc
    19.03.2018 10:20

    А никто не подскажет где вообще описание на похожие жк дисплеи взять??? А то есть похожий, выбран из счетчика газа, только у него не 40 ног, а 8-мь. А как на него описание искать даже мыслей нет никаких(((


    1. dmiceman Автор
      19.03.2018 10:23

      8 ног — это либо одна цифра, либо там есть свой контроллер.

      Если это одна цифра, то соответствие сегментов ногам выясняется просто тестером и записывается на бумажке (как это делал я). А вот если там свой контроллер…


    1. olartamonov
      19.03.2018 10:25

      Это COG (Chip On Glass), у него внутри контроллер, с меньшей вероятностью — с I2C/SPI, с большей — просто сдвиговый регистр типа ML1001.

      Смотреть у производителя данного экрана. Если он неизвестен — надо было смотреть, что там на ножках происходит, до того, как экран выдирать.


    1. Alexashka
      19.03.2018 10:36

      Сегментный ЖК-индикатор. Скорее всего 4bit-параллельный интерфейс. Смотрите по плате счетчика, где питание, а где данные.


  1. Bobovor
    19.03.2018 10:21

    1. Снизить рабочее напряжение контроллера. 2.7V
    2. Снизить до минимума рабочее напряжение дисплея.
    3. Снизить временные периоды сигналов дисплея.
    4. Нафиг линейник и крону. 2032 и диод ваш друг.


  1. borisxm
    19.03.2018 11:04

    Все уже придумано. 20 мкА при питании от 3-х вольт: danyk.cz/avr_lcd_hod_en.html


  1. moviq
    19.03.2018 11:48

    Всякие DC/DC здесь, конечно, ни к чему. Мой вариант также на ATMega48 (хотел на Atmega8 сначала сделать) — собственно этот контроллер с работой от внутреннего генератора 1МГц (8МГц, деленное на 8), ЖК индикатор от мультиметра DT890. Управляется четырьмя регистрами 595. Сами часы на DS1302. Они и модуль с ЖК индикатором работают через аппаратный SPI. Он настроен на максимальную частоту. К контроллеру подключен часовой кварц для работы в асинхронном режиме. Настроено прерывание по совпадению. В прерывании в SPI выводятся 4 байта, которые записываются в регистры. Каждый раз в прерывании данные выводятся инвертированными по сравнению с значениями ранее. Прерывание происходит приблизительно 50 раз секунду. Все остальное время спим. Итого от 4 с небольшим вольт потребление около 160мкА. Точнее это то, что усредненно показывает мультиметр. Работает это от б/у мизинчиковых батареек от тонометра. Т.к. там они уже не тянут, хотя и напряжение на них 1.35В. А в таких часах вполне год могут отработать. Планирую заменить их на аккумуляторы с подзарядкой от солнечной батареи. Правда теряется некоторая мобильность в таком случае. А так же хочу добавить к часам датчик температуры DS1820 и выбросить его за окно (программно это уже реализовано), а также подсветку на светодиодах от светодиодной ленты.

    Часы
    image
    www.picshare.ru/view/8474684
    При предпросмотре не увидел картинок. На всякий случай — ссылки


    1. l_o_d
      19.03.2018 13:33

      Класс)

      Планирую заменить их на аккумуляторы с подзарядкой от солнечной батареи.

      Поставьте лучше вместо аккумулятора ионистор. Проблем с деградацией не будет (хотя ионистор тоже не вечен). Энергии как раз должно хватить.


      1. moviq
        19.03.2018 15:10

        Надо будет подрасчитать — если его ставить и ставить подсветку, которая дает +300...400мка дополнительного потребления, хватит ли на темное время. Часто в комнате свет почти не включается и зимой темное время еще больше получится.


  1. OLEGator_by
    19.03.2018 11:48

    Любой проект нужно начинать с исходного задания и выбора материалов.
    Если исходное задание уже выбрано – часы, то далее нужно подойти к выбору материалов.

    1 Конечно есть специализированные контроллеры в которых уже всё реализовано (сами часы включительно), однако это не интересно и не принесёт вам пользы – всё продумано за вас.
    Можно взять контроллер распространённый – но это чревато не оптимальностью схемы и сложностью схемы. Я бы конечно взял какой STM с встроенным RTC. По итогу получается компактнее и надёжнее. Но даже выбор ARDUINO не проблема – да, микросхема должна почти всё время спасть.
    2 Писать конечно нужно не на С а на ассемблере, так вы контролируете процесс поле полно.
    3 Батарея не нужна на 9в, возьмите литиевую. При меньшем размере вы получите большую ёмкость. И конечно никаких 7805.
    4 контроллер LCD – использовать в схеме прорисовки(обновления) контроллер — непозволительная роскошь. Для таких схем используются готовые контроллеры или как в вашем случае можно взять например К176ИЕ4(вместо 595 как я понял из описания вашей схемы). Там есть вход 6, на который подаётся сигнал модуляции для экрана. Частоту на эту ногу подавать с ds1307. В принципе должны быть аналоги данной микросхемы(если для вас советское не кошерно), нужно просто поискать.
    В таком случае контроллер будет спасть у вас 99,9% времени, а просыпаться только в момент изменения секунд. В этом случае ток потребления будет минимальный.


  1. SadAngel
    19.03.2018 11:48

    В PSoC 4 есть контроллер LCD дисплея:
    http://www.cypress.com/documentation/component-datasheets/psoc-4-segment-lcd-seglcd


  1. gerasimenkoao
    19.03.2018 11:48

    7805 — в топку, как и любой другой стабилизатор — они в любом случае единицы миллиампер потребляют.

    olartamonov практически прав, но я не люблю режимы сна.

    лучше взять атмег-у с индексом V, есть одна хитрость с питанием — как ни парадоксально, на одной и той-же частоте при снижении напряжения питания с 5 до 3.3, ток потребления падает на порядок. У меня на двух солевых батарейках АА безо всяких стабилизаторов напряжения месяц молотит без сна(1 мегагерц).


    1. olartamonov
      19.03.2018 12:16

      но я не люблю режимы сна


      месяц молотит без сна(1 мегагерц)


      Вот мы и дожили до счастливого момента, когда месяц работы электронных часов на батарейке — уже достижение, потому что автор «не любит режимы сна».

      Автор, не любящий режимы сна! У меня водосчётчик с ЖК-экраном и радио на одной батарейке молотит 8 лет (и часы в нём тоже есть).


      1. Mike_soft
        19.03.2018 12:31

        а можно схему? а то поставить-то счетчики «с контактом» — поставил, а до съема данных руки не доходят… :-(


        1. olartamonov
          19.03.2018 12:44

          Берёте провод от контакта, протягиваете к ножке микроконтроллера.

          С точки зрения схемотехники этого достаточно, далее начинается софт.


          1. Mike_soft
            19.03.2018 12:50

            радиоканал хочется. BLE, например.
            ну нет, так нет. дойдут руки — наваяю. главное, чтоб не в конце межповерочного интервала :-)


            1. Meklon
              19.03.2018 12:58

              А я все хочу во время глобального ремонта туда два Cat5e кабеля кинуть. И PoE и данные. Или один кабель, а в ванной Raspberry Pi, который уже ведет логи кидает куда надо.


              1. ploop
                19.03.2018 14:50

                Во, аналогично. При чём у меня уже мысль в каждую розетку по кабелю. Если не надо — закроется, а так и управление чем угодно можно замутить, да и просто розетку под LAN поставить.


                1. Meklon
                  19.03.2018 15:07

                  Сложно найти деньги на одномоментный ремонт всего. Приходится планировать кучу промежуточных стадий. Поэтому иногда сложновато в каждую розетку протащить. Я уже думаю о коммутационном шкафе в коридор.


                  1. Mike_soft
                    19.03.2018 15:17

                    Я кинул КСПВ. тоньше, и для RS485 хватит…


                  1. ploop
                    19.03.2018 15:23

                    Мне если делать, то всё. Квартира требует капитального ремонта — от пола до потолка.


            1. olartamonov
              20.03.2018 12:34

              Радиоканал тут LoRa, и разработка в общем и целом коммерческая.


              1. Mike_soft
                20.03.2018 13:28
                +1

                ну и нужно было начинать с того, что «разработка коммерческая» :-)
                но и за то спасибо, хот пинок получил — может, и правда на выходных займусь…


                1. olartamonov
                  20.03.2018 14:53

                  С точки зрения энергопотребления контроллеру всё равно, платили за это деньги или нет. С точки зрения выкладывания исходников на хабре — нет.


        1. Yurich
          21.03.2018 11:24

          А не нужна Вам схема (потому, мнээээ..., что она не поможет). А не поможет она потому, что Вы никогда не сможете гарантировать, что все импульсы прочитаны (села батарейка, например, или в розетке электричество кончилось и так далее).
          Совсем панковский вариант, который я встречал — OCR того, что у счетчика на морде. Это, кстати, 99% гарантия правильности сбора данных в колхозно-домашних условиях, 1% заложим на то, что софт глюканет и в первом разряде вместо 0 распознает 9, что приведет к довольно большому счету на воду (решается логикой софта, конечно же).
          А Олег, насколько я знаю, не пользуется готовыми счетчиками, которые генерят импульсы, он строит счетчики с нуля.


          1. Mike_soft
            21.03.2018 11:26

            ага, он и водой готовой не пользуется — он ее тоже генерит…


            1. Yurich
              21.03.2018 11:41

              Этот сможет


          1. olartamonov
            21.03.2018 15:31

            А Олег, насколько я знаю, не пользуется готовыми счетчиками, которые генерят импульсы, он строит счетчики с нуля.


            Да могу и готовыми пользоваться.

            А за батарейкой следить надо, конечно.


      1. l_o_d
        19.03.2018 13:35

        Однако ведь есть уже наручные часы которые каждый день заряжать надо) Так что месяц для настольных это прям лонг лайф)


    1. BigBeaver
      19.03.2018 14:11

      они в любом случае единицы миллиампер потребляют.
      Нет. Есть полно Low Quiescent Current LDO с собственным током на уровне 1-2µA. В том числе доступных.


      1. Bismuth208
        20.03.2018 11:54

        Именно! Я вот ставлю MCP1700, где это возможно.


        1. olartamonov
          20.03.2018 12:31

          Да их сейчас как грязи, с собственными токами в единицы-десятки микроампер.

          Даже у 1117 есть низкопотребляющая версия — TLV1117LV (и у неё же заодно нет требований по минимальной нагрузке).


          1. Bismuth208
            20.03.2018 14:02

            Да, вот только ток утечки без нагрузки в даташите указан от 50 до 100 мкА!
            Но с другой стороны, максимальный ток на нагрузку около ампера! В то время как MCP1700 2мкА утеки без нагрузки и не больше 250 мА на нагрузку.


            1. olartamonov
              20.03.2018 14:54

              Это замена LM1117, у которого 5 мА потребление и ещё 5 мА минимальная нагрузка.


  1. dmsav
    19.03.2018 13:16

    Ну. я не стал бы называть это неудачей, скорее это опыт. И очень полезный.
    Идея интересная, я бы все же поставил DC-DC преобразователь и две обычные батарейки или аккумуляторы типа АА.
    И еще один момент, ЖКИ без подсветки? Если да, то можно поставить вместо него сегментный LED индикатор. Есть модели как раз под часы.
    И их бы еще в корпус и классно было бы)
    А еще, бумажные стойки это оригинальное решение)


  1. madf
    19.03.2018 14:28

    1. Нельзя использовать обычный линейный стаб, КПД у него никакущее. Обычно узают DC-DC, причем есть специализированные, с сверх малым потреблением и режимом спячки.
    2. Почитайте документацию на на МК, там есть разные уровни засыпания, возможно схему надо было собрать так, чтобы можно было использовать(скажем) один таймер и ещё почитать по принцип управления ЖКИ (там же аля емкости, не всегда нужно аж на 180 градусов менять полярность): http://www.russianelectronics.ru/leader-r/review/2195/doc/57771/


  1. ZaitsXL
    19.03.2018 14:35

    Я бы посоветовал заменить скучный ЖК индикатор на что то более гиковское, газоразрядные лампы там, или светодиоды какие нить, и работать от сети т.к. даже в нынешнем виде часы явно не наручные. В противном случае не совсем ясно ради чего это все


    1. Alexashka
      19.03.2018 16:11

      FlipDot-дисплей. Дорого только.


  1. GarryC
    19.03.2018 18:24

    Лет 20 назад я делал устройство с батарейным питанием для анализа АОН сигналов, применил дешевый калькулятор (чип+индикатор) и управлял воспроизведением на нем из Atmel контроллера путем имитации нажатий на клавиши.


  1. izobr
    19.03.2018 19:29

    А кто подскажет RTC, которая просто имеет двоичный счётчик без всяких там календарей в бинарно-десятичном формате как у DS1307?

    Наверное это лет 20 назад было оправданно, когда подобная логика была в железе зашита. Сейчас контроллер любую конвертацию сделает сам. И наоборот, надо какие-то странные вычисления проводить, если, например, две таймзоны хочется отобразить. Почему все эти микросхемы с годами, месяцами, днями, минутами и секундами всё-ещё так популярны, а тупой счётчик миллисекунд не найти?


    1. ploop
      19.03.2018 22:40

      Конвертацию чего он сделает, если обесточен? В том и смысл RTC — работать независимо ни от чего.

      Если нужен тупой счётчик — ставьте тупой счётчик. Их, кстати, и в МК можно использовать независимо от ядра (когда то спит), минимизируя потребление.


      1. izobr
        19.03.2018 23:20

        Конвертацию сделает, когда проснётся, чтобы прочитать время из RTC, работающей независимо и питающейся от CR2032 и обновит индикатор. Из DS1307 он прочитает год, месяц, день, час (в 12 или 24 часовом формате, как настроено), минуты и секунды. При этом это всё по одной цифре в двоично-десятичном формате. И большинство RTC имеют такой API. А я хочу прочитать тупо 64 бит счётчика миллисекунд и сам сконвертить в дату.


        1. Mike_soft
          20.03.2018 08:02

          Вы хотели это: DS1602 — Elapsed Time Counter?


  1. Polaris99
    20.03.2018 09:17

    Ардуино такое ардуино! Не получается — воткнуть кое-как, и так сойдет!


  1. avf1906
    20.03.2018 15:15

    1. сама 7805 жрет минимум 5-6мА. вывод — заменить на менее жручее.
    2. емкость кроны 200мАч. Заменить на более емкое.
    Простой вариант — 7805 убрать, запитать от 3 последовательных алкалиновых элемента АА емкость 2000мАч, время работы — два-три месяца.
    Хороший вариант — взять stm32L053, L152 и т.п. со встроенными часами и контроллером LCD и запитать напрямую от CR2032 потребление будет не больше 30мкА, проработает минимум год. Потренироваться взять такую штуку ru.aliexpress.com/item/Free-Shipping-1pc-ST-STM32L-Discovery-STM32L152-Cortex-M3-development-board/1238095354.html


  1. dan939
    20.03.2018 23:07

    решение есть. 176ИЕ18, 176ИЕ13, 176ИД3. от «Кроны» будет работать несколько месяцев.)))
    а вообще у автора в корне неверный подход к проектированию устройств с малым потреблением. жечь половину энергии батареи на 7805-жесть конечно.


    1. Mike_soft
      21.03.2018 07:48

      автор ничего не проектировал. он нашел одно, другое, третье — слепил в кучу (просто потому, что это «уже было») и удивляется, что работа полученного устройства не соотвествует некоторым ожиданиям…