Неудача с часами на ATMega48

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



    UPD: Крона сдохла, отрезал два провода, применил сон, 0.3-1.6mA


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


    Давным-давно в коробке в дальней тумбочке болталась у меня пара семисегментных жк-индикаторов. И так же давно мне хотелось взять их в оборот и соорудить на основе одного из них часы. Давным-давно: это, в буквальном смысле, семь лет. Именно тогда, в 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?




    UPD


    Спустя всего три дня, что на пару дней раньше планируемого, крона сдохла. И вот что интересно. По задумке, сначала должен был отрубиться канал общения i2c между контроллером и ds1307. Согласно даташиту, связь отрубается при падении VCC до уровня 1.2*VBAT. Я на это рассчитывал, предполагая показывать значок севшей батарейки при проблемах с i2c. По факту получилось так: цифры на индикаторе едва видны, на шине +5v едва-едва 2.5v, а i2c работает, часы тикают. На VBAT Tiny RTC замечательные 3v. Непонятно.


    Затем стал я смотреть почему у меня индикатор помаргивает. Чуть заметно, но все же неприятно. Выяснилась неприятная штука — то что я завел, в дополнение к общему контакту индикатора от контроллера, второй общий контакт от одной из 595, было категорически неправильно. То есть оно было бы правильно, если бы я правильно сделал линию RCLK, но так у меня вышло, что при каждом обновлении индикатора, через общий контакт бегают совершенно левые битики, в противофазу другому общему контакту и всему остальному. Хотите верьте, хотите нет, но это стоило доброго миллиампера электричества. К счастью, кусачки легко смогли помочь в этом вопросе.


    После этого, взялся за реализацию сна. Не знаю почему я так легко поверил какому-то случайному сообщению на случайном форуме, едва его увидев, тому самому, где утверждалось, что выход AVR из спячки непременно занимает более 65 миллисекунд. То есть оно конечно действительно так, но только в некоторых режимах, тогда как в других все происходит значительно быстрее. Мысль о том, что сон неприменим для AVR в моей ситуации, была, конечно, неверна. Еще раз спасибо olartamonov за открытие моих глаз.


    Ну и наконец, методика измерений у меня безусловно оставляет желать лучшего, 6mA я получил, имея lm7805, подключенную в схему задницей (Vout и земля в схему; Vin в воздухе). После применения кусачек — минус 4mA.


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


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

    Поделиться публикацией
    Никаких подозрительных скриптов, только релевантные баннеры. Не релевантные? Пиши на: adv@tmtm.ru с темой «Полундра»

    Зачем оно вам?
    Реклама
    Комментарии 216
    • +6
      Следует заметить, что крона — одна из наименее емких батарей и что при таком включении, 7805 рассеет примерно половину батарейкиной энергии в атмосферу.

      Далее, стоит рассмотреть применение специализированных RTC в отдельном чипе, которые работают годами от одной CR2032. Тогда основной контроллер может дрыхнуть сколько угодно, лишь изредка просыпаясь для смены картинки. Ну и взять менее жирный и древний контроллер, например, STM8.
      • –1
        RTC у автора как раз есть, проблема в том что контроллер не может спать из-за необходимости постоянно менять полярность напряжения на сегментах ЖК индикатора.
        • +1
          Это относительно.
          Для человека, менять полярность раз в секунду — это достаточно быстро, а для микроконтроллкра милионы тактов в холостую.
          • 0
            По фотке не понятно, были ли там секунды вообще…
            • 0
              Хотя, в тексте про секунды есть, что-то я затупил. В любом случае, можно просыпаться раз в секунду по прерыванию от RTC?
              • 0
                Раз в секунду от RTC маловато для ЖК индикатора. Надо хотя бы 50 раз в секунду. А читать раз в секунду из RTC в прицепе можно
        • +2
          > 7805 рассеет примерно половину батарейкиной энергии в атмосферу.

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

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

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

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

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

          > STM8

          Вот это-то и интересно, как он себя чувствует в режиме постоянной работы?
          • +7
            Конечно. Но если бы вся схема потребляла микроамперы, это было бы даже и не важно.


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

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


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

              Этого достаточно?
              • +1
                По поводу STM8 можете в сторону stm8l051 посмотреть, там есть режим работы Low-power run, где МК работает на частоте 32КГц но ест всего 5 микроАмпер (не считая периферии), к тому же в этом МК и часы встроенные есть, и цена копеечная.
                Если 100 раз в секунду ножкой подрыгать то такой режим хорошо подойдет
                • +1
                  А у STM8L152 есть встроенный контроллер LCD, даже ножками дрыгать не надо, он сам умеет.
                  • 0
                    а часы вообще купить можно :-)
                    не, я не против DIY, но просто нужно понять, что же хочет автор: достичь микропотребления у атмеги, или сделать часы с ЖКИ собственными руками, или ему просто «нужны часы»?
                    каждая из этих проблем решается своим способом.
            • +1
              Ну для начала можно убрать 7805 и питать напрямую от батарейки на 3-3.6 вольт. Стабилизатор тоже немало кушает. Или хотя бы выбрать стабилизатор с малым собственным потреблением. А вывод на индикатор можно сделать через специализированный контроллер типа HT1621. Там мизерное собственное потребление.
              • +1
                > HT1621

                Вот спасибо, почитаю.
                • 0
                  А нет, готовый дисплей — это неспортивно :-)
                  • 0
                    А это и не готовый дисплей:
                    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 можно найти.
              • 0
                7805 от кроны = кпд < 50%
                ставьте импульсный dc/dc, в два раза меньше кушать будет (а то и в 5-6 раз).
                • 0
                  Нет, нет, нет. Я, видимо, недостаточно раскрыл эту тему в статье. Потребление я смотрел до того как решился (для компактности) применить крону и 7805. Просто давал 5 вольт и смотрел в разрыве цешкой. И уже расстроившись решил, что как proof-of-concept и так сойдет.
                  • 0
                    Хм, тогда странно, вроде в активном режиме на 1МГц 48 кушает 1мА (по даташиту). Можно на полную схему взглянуть?
                    • 0
                      Вот чего нет, того нет :-)

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

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

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

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

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

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

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

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


                      А даташиты читать в наше время, я так понимаю, не модно.
                      • 0
                        Как то не было потребности в такой ситуации использовать импульсник. Да и в той промышленной аппаратуре с которой сталкивался обычно ставят литиевый элемент на 3.6 вольт и не парятся. Видимо в этом есть смысл.
                        • +2
                          А ведь вместо этого ля-ля можно было просто пойти на сайт TI, открыть табличку DC/DC понижаек, отсортировать по Iq и узнать много интересного.
                          • 0
                            Да я ведь не спорю что таких нет) Просто достать линейный стабилизатор с нужными характеристиками намного проще и дешевле. А в вашем примере еще и корпус довольно сложный в припайке. Ну и если делать не макет, а полноценное устройство то лучше сразу взять источник с подходящим напряжением. Будет меньше деталей, дольше время работы.
                            • 0
                              А если пойти на алиэкспресс, там можно купить готовый слаботочный DC/DC за цену КРЕН-ки в рознице, и не ломать голову, если в конвертерах не специалист. Там, конечно, обвязка не совсем та, что в даташитах, что влияет на КПД, но потери все равно будут сильно, сильно меньше, чем у КРЕН-ки.
                              Хотя на самом деле это не критично, 6мА потребляет схема или 3 — при использовании CR2032 «всю систему надо менять» (с)
                              • 0
                                И купите вы там с большой вероятностью что-то типа LM2596 с теми же 5-10 мА собственного потребления, что и у 7805.

                                Интересно, когда до любителей алиэкспресса дойдёт, что их судьба — наколенные поделки, нормально работающие через три раза на четвёртый, а у нормального разработчика минимум половина времени уходит не на махание паяльником, а именно что на чтение даташитов?..
                                • +1
                                  потому, что электроника сильно «разрослась». уже доступна не пара десятков транзисторов, параметры которых можно было держать в голове, не полсотни цифровых микросхем, и т.п.
                                  Т.е. чтобы заниматься этим профессионально — надо «очень быстро бежать»©.
                                  • 0
                                    Надо уметь читать.

                                    А чип с 360 нА собственного потребления, на который я ссылку давал, пять лет уже выпускается.
                                    • 0
                                      в контексте автора — «всего пять лет», ибо «интерес возник» в 2011 году.
                                      Насчет «уметь читать» — согласен. ибо 99% всех возникающих вопросов решаются при изучении dataShit'ов :-) и TFM'ов.
                                  • 0
                                    Э-э-э… Там фото более чем достаточного разрешения, чтобы увидеть маркировку чипа. Типичная LDO-шка китайская — это 1117, ее сразу видно и ни с чем не спутать :) Да и индуктивности, опять же :)
                                    Еще раз — взять готовый будет быстрее и дешевле, если разработчик не спец в данном вопросе.
                                    Вы про Point-of-Load в курсе? В телекоммуникационном оборудовании они используются сплошь и рядом, поскольку разработчики спецы в высокочастотных дизайнах, но питание — не их конек. Поэтому проще поставить что-нибудь приличное, от GE или Murata за полчаса, чем тратить неделю на курение даташитов. Там свои проблемы выползают, конечно, с охлаждением, например — тепло с PoL в плату почти не уходит, но в общем случае это быстрее и надежнее, чем ваять самому DC/DC конвертер с нуля
                                    • +1
                                      Типичная LDO-шка китайская — это 1117, ее сразу видно и ни с чем не спутать :) Да и индуктивности, опять же :)


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

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


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

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


                                      Я вам страшую вещь скажу: на все эти модули тоже есть даташиты. Которые тоже надо читать.
                      • 0
                        А из чего эти голубенькие стойки? Неужели бумага?
                        • 0
                          Бумага :-) Как раз дочку привлек к процессу производства. Не оказалось в заначке подходящих шурупчиков, которые лезли бы в монтажные дырки этих макеток, поэтому стойки были сделаны из зубочисток, обернутых бумагой, покрытой цапонлаком. Крепление к макеткам — суперклей. На неделю конструкции хватит.
                          • +6
                            Еще один шаг к биоразлагаемым устройствам)
                        • +4
                          А один только вывод из сна занимает как минимум 65ms, требуемые на стабилизацию осциллятора


                          Выкидываем внешний кристалл, тактируемся от внутреннего RC, у которого минимальное время запуска — 6+14 KCK, т.е. 20000/8000000 = 2,5 мс.
                          • 0
                            Вот да, я про эти 65ms написал со слов на каком-то форуме. В даташите это как-то не очень ясно описано (ну или я не очень понял). Буду изучать это шаманство через неделю :-)

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

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

                              Не говоря уже про то, что у вас есть ещё и Standby Mode, в котором внешний осциллятор продолжает работать, энергопотребление в районе 100 мкА, а выход из сна — за единицы тактов.
                          • 0
                            И, к слову, я как раз внутренний осциллятор использую.
                            • 0
                              А почему 6+14, а не просто 14? Я так понял в случае выхода из сна (2 режима) будет только 6.
                              • 0
                                Да, вы правы, 6. И не KCK, а просто CK, т.е. ещё и микросекунды.

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

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

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

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

                                А это запросто :-) Это пока самая большая и сложная программа для контроллера, которую я написал в жизни. Знание специфики у меня очень умозрительное.
                                • 0
                                  Используйте встроенный rtc меги, тактируйте проц от того же кварца 32768
                                  для часов это более чем достаточно.
                                  Постоянную времени вашего индикатора не знаю, но обычно мерцание заметно только под углом, и уж точно не на 50гц, это уже не увидит глаз. Скорее всего мерцание связано с другими причинами — цикл какой-нибудь вклинивается и тп.
                                  • 0
                                    Подозреваю, в моем случае мерцание на 50 Hz связано с неправильной разводкой. Ведь я (ошибочно) сделал так, что все продвижения битов по 595-м неизбежно отображаются на индикаторе. А может и нет. Тайминги у меня в этом месте немного с потолка взятые.
                                    • 0
                                      Я б вообще рекомендовал для этого проекта мегу64L или А, она не так дорого стоит, и развести сегменты по портам напрямую. RTC использовать встроенный, питание взять от двух мизинцев 3в. Будет очень лаконично и экономично. Сотня-две микроампер максимум, думаю.
                              • +7
                                Как оказалось, 4 килобайта — это очень мало. Особенно, если писать на C.

                                Э, нет. Это не С. это Arduino IDE. Чистый C дает вполне себе компактный код.
                                • 0
                                  Так какая разница какая IDE? Оно же все равно компилирует avr-gcc, с -Os. Если не допускать с++-ного оверхеда, никакой разницы быть не должно.
                                  • +2
                                    Оставил по этому поводу комментарий ниже. По моим наблюдениям Arduino IDE в исполняемый файл подсовывает какую-то свою библиотеку, отсюда и разница.
                                    • +1
                                      Там еще стиль написания довольно странный. По крайней мере то, что я увидел в самом начале, можно заметно уменьшить, как по количеству занимаемого места, так и по количеству выполняемых команд.

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

                                      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] ;
                                      


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

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

                                    Поправьте меня кто нибудь если я не прав. Но у меня сложилось впечатление, что Arduino IDE в исполняемый файл подсовывает еще какой-то свой код. Который берет довольно много места. Например, когда для работы с LCD дисплеем я использовал Arduino IDE + liquidcrystal_i2c библиотеку, сборка заняла примерно 2500 байт. Без Arduino IDE и со своей библиотекой для i2c и дисплея та же функциональность уместилась в 750 байт.
                                    • 0
                                      Загрузчик? Я-то использовал minicore, который для atmega48 загрузчика не использует.
                                      • +1
                                        Проверил что Arduino IDE добавляет в исполняемый файл. Среди прочего в линкер передавалось это:
                                        arduino_cache_122843\core\core_arduino_avr_uno_27ad0de2390183402c74f07cbe44f9f8.a
                                        На чистом C это можно убрать, но тогда нельзя использовать библиотеки созданные для Adruino IDE.
                                    • 0
                                      может лучше atxmega128 рассмотреть со встроенным контроллером сегментного ЖКИ?
                                      • 0

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

                                        • 0
                                          Посмотрите в сторону PCF8577C.
                                          • +1

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

                                            • +2
                                              Еще бы подешевле стоил( Почему то никогда не видел что нибудь самодельное с таким типом дисплея. Видимо есть какие то сложности в реализации…
                                              • +1
                                                Waveshare сейчас выпускает со встроенным контроллером и SPI-интерфейсом. Цена только не совсем демократичная, около 500р за 2.13"
                                                • 0
                                                  Видимо есть какие то сложности в реализации…

                                                  Дорого, да и появились они относительно недавно.
                                                    • 0
                                                    • 0
                                                      На пару лет хватит, потом будет деградировать.
                                                      • 0
                                                        Этот цветной перерисовывается очень долго, секунды. Надо брать мелкий ч/б, он отрисовывается за 0.3 с кажется…
                                                      • 0
                                                        Можно взять 48 мегу с индексом V, или PA.У них нижний порог питания 1.8в. Для пущей экономии питания отключить ненужную периферию: компаратор(жрёт как конь), АЦП, УАРТ. RTC было бы лучше использовать, например, DS3231.У неё кварц уже на борту, питание 3.3в, потребление в активном режиме 200мкА. DS1307 тоже жрёт не мало, да ещё и кварц внешний(точности не добавляет).А что бы часы запустились, можно вписать в регистр секунд нолик и они пойдут без установки времени.
                                                        • 0
                                                          Если хотите использовать ЖКИ, то берите сразу микроконтроллер с драйвером ЖКИ. Это позволит разгрузить микроконтроллер и уменьшить токопотребление из-за того, что процессор не будет просыпаться 100 раз в секунду для обновления ЖКИ.
                                                          Правильное батареечное устройство с постоянной работой ЖКИ должно работать минимум полгода от одного комплекта батарей. Это единицы микроампер. Предложенный HT1621 плохо для этого годится, потому что только он потребляет в районе 20-30 мкА.
                                                          • 0
                                                            Ну единиц микроампер в домашних условиях наверное сложно добиться. А при 100 — 200 мкА и комплекте хороших пальчиковых батареек думаю пол года проработать может.
                                                            • 0
                                                              Ну единиц микроампер в домашних условиях наверное сложно добиться


                                                              И что же в домашних условиях этому мешает?
                                                              • 0
                                                                Большинство поделок лепится из того что под рукой) Иногда нет экономичного контроллера, иногда подходящих батареек или стабилизатора. Банально большинство самодельщиков скорее всего не имеют профильного образования или желания глубоко закапываться в даташиты. Одни могут написать экономичное ПО но у них проблемы с железом, у других обвязка почти ничего не жрет но не оптимальное ПО контроллера потребляет как паровоз.
                                                                • 0
                                                                  Так это не сложно, а не охота.
                                                                  • 0
                                                                    Эх, если бы это была проблема самодельщиков… Сколько статей о том, как вмонтировать в мышку аккумулятор на 100500 мАч, чтобы проработала хоть месяц без зарядки, хотя у того же Logitech мыша работает год(!) на одной батарейке, соответственно два — на двух.
                                                                    • 0
                                                                      Это смотря какие.
                                                                      image
                                                                      Logitech Performance MX — офигенная мышь. Но аккумулятора там хватает на 3-5 дней. Причем от рождения так было.
                                                                    • 0
                                                                      То есть в домашних условиях возникает какая-то непреодолимая сила, не позволяющая прочитать даташит на контроллер и написать прошивку нормально?
                                                                      • 0
                                                                        В домашних условиях делают устройства не только те кто могут осмыслить даташит. Часто просто дергают примеры из инета, поправляют по месту и вперед. Кому то может интереснее процесс пайки и непосредственно сборки, а к ПО отношение «лишь бы было». Это же просто хобби) Это как добиваться рекордных урожаев на домашней картофельной грядке: есть энтузиасты, а есть те кому «как то растет и ладно».
                                                                        • 0
                                                                          То есть оригинальную фразу «в домашних условиях сложно добиться единиц микроампер» надо читать как «лично мне в домашних условиях сложно добиться единиц микроампер, потому что лень этим заниматься, а хочется побыстрее сляпать на коленке»?
                                                                          • 0
                                                                            Можно и так. Хотя нет все немного сложнее. Например я могу хорошо развести плату, сделать или подобрать приличный корпус, все красиво спаять и собрать, но вот с ПО проблемы. Глядя на творения людей на проводах и скотче залитые из «соплемета» называть свои устройства сделанными «на коленке» я не хочу. Причем некоторые сопливые поделия реально жрут микроамперы, потому что создатели хорошо пишут ПО, чего я не могу. Каждому свое как говориться) Не отрицаю что есть те у кого все получается цивилизованно: и прошивка, и плата, и корпус.
                                                              • +3
                                                                Как вы руками такие пучки проводов паяете? Чисто субъективно гораздо меньше вариантов ошибок при проектировании в чем-то вроде Eagle. Хотя, вероятно, тут моей недостаток опыта сказывается.
                                                                • 0
                                                                  Тоже всегда удивлялся такому терпению) Мне проще сразу развести плату, попробовать собрать, потом в случае ошибок еще раз вытравить, чем напаивать проводок за проводком. Но обилие поклонников вот такого способа сборки говорит о том, что не все такие нетерпеливые.
                                                                  • 0
                                                                    Как раз нетерпеливые :-)

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

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

                                                                      Ваш недостаток опыта вполне дополняется достатком здравого смысла :)
                                                                      Плату сделать действительно проще, быстрее, и с меньшим количеством ошибок. Просто под ЛУТ, дома.
                                                                      • +2
                                                                        Лут у меня получается, но не очень стабильно. Сейчас жду фабричные платы. Первый раз пробую. Хочу как белый человек нормальные использовать с шелкографией и маской.
                                                                        image
                                                                        • 0
                                                                          ЛУТ для макета самое то. И то не всякого, если сложная двухслойная плата приходится и макеты заказывать на производстве.
                                                                          А так да, впервые держать в руках заводскую плату собственной разводки нереально круто!
                                                                          • 0
                                                                            Лут я делал) только бумага из журнала медицинского оказалась неправильной. Тонер слишком тонким слоем перенёсся, хотя и отклеилась бумага сама без следов. В итоге вытравило сильно дорожки. Впрочем, для прототипа норм. Один чип я тупо сжёг перегрузкой) но это уже я проступил и ошибка была не в плате, а в коммутации гнезда наушников.
                                                                            • 0
                                                                              Дорожки после травления хорошо бы залудить под паяльной кислотой и тщательно смыть (это если плата очень давно лежит и вся покрылась окислами, гидрокислами и прочей гадостью). Ну и попробовать сменить флюс и припой.
                                                                              • 0
                                                                                Зачем паяльной кислотой издеваться над жалом паяльника, дорожками, легкими и глазами? Пемолюкс на жесткую сторону губки, чуть воды и натереть плату этой кашей. Даже после сильного окисления медь становится как новой. Да и остатки тонера хорошо стираются.
                                                                                • 0
                                                                                  Я до травления и тонера поверхность платы обрабатывал алмазом на 2000 Grit. Вроде все снялось. Тут проблема в том, что после травления дорожка в мелкую сеточку. По факту даже участок обрыва был. Реально перетравлено сильно. Но на руках не было других материалов — работал с тем, что было. Флюс активный спирто-канифольный. Вроде смылся без остатков в изопропаноле. Дал полежать полчаса в нем, а потом хорошо потряс.

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

                                                                                    Вот такая грусть из-за плохого трансфера получилась. Причем там даже обрыв есть по питанию. В районе посадочной площадки конденсатора слева вверху. Что есть) Переделывать некогда было. Прототип, однако.
                                                                                  • 0
                                                                                    ЛУТ требует навыка, «набивки руки» — именно в привязке к конкретному принтеру, утюгу и бумаге. Но при «набитой руке» крайне быстр. Фоторезист — более стабилен, хотя привычки тоже требует. Ну и чуть медленнее. ну а изготовление плат под заказ — медленно, но крайне качественно
                                                                                    • 0
                                                                                      Мне очень редко нужно, поэтому привычки особо нет)
                                                                                      • 0
                                                                                        Фоторезист требует ещё и некоторого оборудования — как минимум самого резиста, лампы, плёнки для шаблонов. А для ЛУТа утюг, принтер и журнал с сиськами, то есть порог вхождения ниже, можно начать прям вот когда загорелось.
                                                                                        • 0
                                                                                          Я смотрел на фоторезист. Но там реально порог для единичных экземпляров уже такой, что проще на заводе заказать.
                                                                                          • 0
                                                                                            Попробуйте ЛУТ на фольге.
                                                                                            Я когда активно сам платы делал, фольга очень выручила. Даже двухсторонние делал, правда, с особым подходом к проектированию таких изделий.
                                                                                          • 0
                                                                                            абсолютно согласен. ЛУТ — это вотпрямщазз с нуля, фоторезист — следующий шаг, ибо надо заранее купить фоторезист (рублей 200), лампу (еще 200), пленку (еще 200). Зато когда это есть — оно по «старту» уже не отличается, но тут уже и качество выше, и повторяемость.
                                                                                            То же касается и паяльника — первый детекторный приемник можно и на скрутках, затем — дедовским стоваттником, потом хочется что-то нормально лежащего в руке и не перегреавющегося — ну а затем и станцию можно прикупить. То же касается и измерений. И отладки софта. Предела совершенству нет, но каждый останавливается на своем уровне.
                                                                                            • 0
                                                                                              где Вы его за 200 видели? Давече покупал позитив 20 — 1000 р. Лампа — 2500 для ногтей, пленка может и 200, но лазерный принтер хорошо бы в смету добавить
                                                                                              • 0
                                                                                                видел.

                                                                                                Лампы — я засвечиваю энергосберегайкой, извиняюсь, «черного света» :-), цена 180 рублей.
                                                                                                • 0
                                                                                                  пленка тоже есть, но у меня с ней не заладилось, как-то грубо выходит, шаг 0.5 не протравливается. С позитивом лучше, там 0.5 не проблема. А черную лампу так и не нашел в продаже, пришлось купить косметическую лампу для полимеризации лака
                                                                                                  • 0
                                                                                                    это уже нюансы. но главное то, что сейчас окромя древних методов а-ля стеклянный рейсфедер и цапон-лак (а то и резака из ножовочного полотна ) — вполне доступны и ЛУТ, и фоторезист (не из «белка куриного яйца и еще чего-то», как в рецептуре книги «радиолюбительские технологии», а вполне заводской ), причем фоторезисты еще можно выбирать.
                                                                                                    плюс smd. Это ж по радиокружковым меркам — просто рай :-)
                                                                                                    • 0
                                                                                                      о да, молодежь наверное о рейсфедерах не в курсе… особо было сложно степень разведения лака ацетоном подобрать чтобы нормально наносились дорожки. А еще вариант был в стержень шариковой ручки лак заливать, а из наконечника выдавить шарик. Эх время
                                                                                                      • 0
                                                                                                        мы предпочитали «растягивать» стержень над спичкой и обрезать — поручившийся аналог рейсфедера ходил по фольге гораздо мягче, и не издавал скрипа…
                                                                                        • 0
                                                                                          Купите у китайцев бумагу для ЛУТ. Очень удобная вещь. Желтенькие такие листы:
                                                                                          www.ebay.com/itm/10PCS-A4-Sheets-Heat-Toner-Transfer-Paper-For-DIY-PCB-Electronic-Prototype-Mak-/400505239086?hash=item5d3ff8f62e
                                                                                          • 0
                                                                                            Я видел. Во всех комментариях стоят маты по поводу того, что китайцы не упаковывают в жесткий картон. В итоге все скомканное приходит.
                                                                                            • 0
                                                                                              у нас в городе в радиолюбительских ее магазинах продают (хотя я не пробовал). Ну и фоторезист (которого тоже надолго хватает при хранении в прохладном месте) там же.
                                                                                              • 0
                                                                                                Надо Чип и Дип глянуть. На радиорынке не видел точно.
                                                                                              • 0
                                                                                                Это да) Мне вообще в трубочку свернули пачку листов. Поставил под стопку книг чтоб выровнялись. Я потом режу лист на четыре и приклеиваю клейкими ценниками к обычной бумаге. Так экономичнее выходит и неровность не так сильно сказывается.
                                                                                    • +1
                                                                                      О, это ещё не пучки совсем :)
                                                                                      Там их меньше сотни даже.
                                                                                      • 0
                                                                                        Нафиг-нафиг) я и на более простых вариантах сжигал детали)
                                                                                      • +4
                                                                                        Чисто субъективно гораздо меньше вариантов ошибок при проектировании в чем-то вроде Eagle


                                                                                        Всё абсолютно правильно делаете. Время, потраченное на спагетти из проводов, ЛУТ и Sprint Layout — это время, потраченное впустую.
                                                                                        • 0
                                                                                          Про Sprint Layout не пойму, чем он плох для любительских устройств низкой сложности?
                                                                                          • +1
                                                                                            Да ничем не плох на самом деле. Да и провода не плохи. Это же для себя, развлечение типо. Если говорить про потраченное впустую время, то и часы можно за 50 рублей купить в ларьке ближайшем)
                                                                                            • 0
                                                                                              Имхо, надо с самого начала приучаться делать всё по технологии.
                                                                                              Гляньте в сторону KiCad.
                                                                                              • 0
                                                                                                Заводить комбайн из-за трёх колосков тоже не вариант. Если требуется развести диодный мост, гораздо быстрее это сделать в SL.
                                                                                                • 0
                                                                                                  Скорее не вариант иметь SL если делаешь хоть что-нибудь кроме диодного моста в течение года.
                                                                                              • 0
                                                                                                Нет сквозного проектирования, соответственно, непригоден для сколь-нибудь сложного устройства.

                                                                                                Зачем тратить на него время, если тот же DipTrace бесплатен и осваивается за полчаса?
                                                                                                • 0
                                                                                                  Eagle для двухслойных тоже бесплатен. Более чем достаточно.
                                                                                                  • 0
                                                                                                    Не бесплатен, у него ограничение на размеры. Вроде для большинства поделок и достаточные (100х100мм ЕМНИП, лень точно искать), но иногда можно упереться по одному габариту, т.е. например узенькую линеечку на 150 уже не сделаешь.
                                                                                                    • 0
                                                                                                      Это согласен. На большинство хобби-проектов не влияет. Ну KiCad есть, в конце концов. Хотя я и к Eagle-то мучительно привыкал с нуля. До него цапонлаком рисовал кривулины на текстолите руками.
                                                                                                      • 0
                                                                                                        запах цапонлака, хлорного железа и канифоли — прям картин «детство в радиокружке».
                                                                                                        • 0
                                                                                                          Ага) Но оно было фантастически кривым. И еще все элементы выводные. Я сейчас прям не могу нарадоваться SMD. Сверлить не надо, места мало занимают.
                                                                                                          • 0
                                                                                                            «и ведь всего-то — просто НЕ НАДО БЫЛО приделывать выводы к деталям»© :-0
                                                                                                            • 0
                                                                                                              Самое интересное ведь эти детали и раньше существовали. Помню в институте были древние советские гибридки с вполне себе современно выглядящими SMD конденсаторами. Почему их в обычных схемах не применяли непонятно… Видимо у нас эффект послезнания) Додуматься не приделывать ноги наверное было не так просто
                                                                                                              • 0
                                                                                                                вспоминаются даже «бескорпусные транзисторы со сферическми выводами» — нечто типа BGA, только 2х2 вывода :-) для этих гибридок.
                                                                                                                говорили, что были проблемы с техпроцессом пайки на больших площадях текстолита.
                                                                                                                • 0
                                                                                                                  Видимо боялись бунта монтажниц на заводах)
                                                                                            • 0
                                                                                              На самом деле, пайка пучка проводов на плате индикатора, вдумчиво и размеренно, заняла только около двух часов. Не то что бы это меня совсем не достало, но все же оказалось не так и страшно. В паре мест недопаял, в паре мест перепаял, но это легко удалось исправить. Где-то паяльником, а где-то кодом. Да, было бы здорово немного переделать, вывести линию RCLK на контроллер, но этим я вряд ли займусь :-)

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

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

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

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

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