Сжёг Arduino UNO, восстанавливаем....

Тема в разделе "Arduino & Shields", создана пользователем AlexU, 26 фев 2016.

Метки:
  1. AlexU

    AlexU Гуру

    Делюсь опытом восстановления Arduino UNO Rev.3 (итальянской, ATmega328P + ATmega16U2). Спалил её случайно, подав 12V на пин '+5V' -- сгорели оба контроллера, но сначала опишу способ восстановления, если сгорел только контроллер ATmega328P (тот самый, что можно вытащить и вставить без пайки), а контроллер ATnega16U2 остался живой.

    Небольшое отступление: все операции проводились в системе Linux (Kubuntu). Что касается пользователей Wndows, то последовательность шагов та же, но прийдётся устанавливать дополнительные драйверы, например, для DFU, какие ещё драйверы -- не знаю... Также у пользователей Windows будут проблемы со сборкой прошивки программатора, но вроде как они решаемы при помощи MinGW http://www.mingw.org/. Но с этими вопросами придётся разбираться самим.

    Первый способ (никаких устройств-программаторов не нужно, только Arduino UNO и USB шнурок):
    Итак заменили контроллер ATmega328P и встаёт вопрос -- как восстановить в нём бутлоадер? На оффициальном сайте https://www.arduino.cc/en/Hacking/Bootloader говориться, что нужно покупать программатор. Вот только зачем? Дело в том, что на плате Arduino UNO имеется второй контроллер ATmega16U2, который легко может быть превращён в программатор типа AVRISPmkII. Не большое отступление: на некоторых версиях вроде как может стоять ATmega8U2, что делать в этом случае -- не знаю -- прошивка программатора "весит" ~10kB.
    Что нужно, что бы второй контроллер превратить в программатор:
    1. качаем исходники LUFA (http://www.fourwalledcubicle.com/LUFA.php), распаковываем архив в какой-нибуть каталог, назовём его <LUFA>;
    2. переходим в подкаталог <LUFA>/Projects/AVRISP-MKII/Config, правим файл AppConfig.h:
    пропускаем комментарии с лицензионным соглашением и т.п. доходим до строк:
    Код (C++):
    #ifndef _APP_CONFIG_H_
    #define _APP_CONFIG_H_
    и далее нужно исправить на следующее:
    Код (C++):

       #define AUX_LINE_PORT  PORTD
       #define AUX_LINE_PIN  PIND
       #define AUX_LINE_DDR  DDRD
       #define AUX_LINE_MASK  0xFF
    //   #define AUX_LINE_MASK  (1 << 7)
    //   #if (BOARD == BOARD_U2S)
    //     #define AUX_LINE_MASK  (1 << 0)
    //   #else
    //     #define AUX_LINE_MASK  (1 << 4)
    //   #endif

       #define ENABLE_ISP_PROTOCOL
       #define ENABLE_XPROG_PROTOCOL
    а так же надо закоментировать определение LIBUSB_DRIVER_COMPAT:
    Код (C++):
    //    #define LIBUSB_DRIVER_COMPAT
    Остальное оставляем без изменений.

    3. переходим в подкаталог <LUFA>/Projects/AVRISP-MKII, правим файл makefile:
    опять же после комментариев правим следующие декларации:
    Код (C++):
    MCU  = atmega16u2
    F_CPU  = 16000000
    Остальное оставляем без изменений.

    4. Производим сборку: команда make. Побегут строки, но в конце должно появиться что-то вроде:
    Код (Bash):
    [SIZE]  : Determining size of "AVRISP-MKII.elf"

    avr-size --mcu=atmega16u2 --format=avr AVRISP-MKII.elf
    AVR Memory Usage
    ----------------
    Device: atmega16u2

    Program:  10366 bytes (63.3% Full)
    (.text + .data + .bootloader)

    Data:  179 bytes (35.0% Full)
    (.data + .bss + .noinit)

    EEPROM:  2 bytes (0.4% Full)
    (.eeprom)


    [INFO]  : Finished building project "AVRISP-MKII".
    Это значит, что всё хорошо собралось.
    5. Переводим Arduino UNO в режи DFU для чего: подключаем Arduino к USB порту и затем на короткое время замыкаем контакты (см. картинку).
    6. Проверяем, что Arduino в режиме DFU -- команда lsusb выдаст помимо прочего запись:
    Код (Bash):
    Bus 003 Device 003: ID 03eb:2fef Atmel Corp.
    7. Прошиваем прошивку программатора AVRISPmkII:
    первая команда -- очистка flash:
    Код (Bash):
    dfu-programmer atmega16u2 erase
    без очистки шиться не будет.
    вторая команда -- запись прошивки:
    Код (Bash):
    dfu-programmer atmega16u2 flash AVRISP-MKII.hex
    8. "Передёргиваем" USB (можно конечно дать команду dfu-programmer atmega16u2 start, которая запустит прошивку, но я переподключал устройство), смотрим список USB устройств (lsusb) и видим:
    Код (Bash):
    Bus 003 Device 005: ID 03eb:2104 Atmel Corp. AVR ISP mkII
     

    Вложения:

    Последнее редактирование: 28 сен 2016
    ИгорьК, Airbus и Unixon нравится это.
  2. AlexU

    AlexU Гуру

    9. Используя проводочки папа-мама, коммутируем наш "программатор" для прошивки ATmega328P (см. картинку), запускаем Arduino IDE (использовал версию 1.7.8 с сайта arduino.org) и настраиваем: 'Инструменты/Плата' -> Arduino UNO; 'Инструменты/Программатор' -> AVRISP mkII. После чего жмём 'Инструменты/Записать Загрузчик'.
    Вывод примерно следующий (в настройках Arduino IDE поставил галочку "Показать подробный вывод Загрузить":
    Код (Bash):
    ......../arduino-1.7.8-linux64/hardware/tools/avr/bin/avrdude -C......../arduino-1.7.8-linux64/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -cstk500v2 -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xDE:m -Ulfuse:w:0xFF:m

    avrdude: Version 6.0.1, compiled on Jan 15 2015 at 13:12:29
      Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
      Copyright (c) 2007-2009 Joerg Wunsch

      System wide configuration file is "......../arduino-1.7.8-linux64/hardware/tools/avr/etc/avrdude.conf"
      User configuration file is "/home/alexandr/.avrduderc"
      User configuration file does not exist or is not a regular file, skipping

      Using Port  : usb
      Using Programmer  : stk500v2
    avrdude: usbdev_open(): Found AVRISP mkII, serno: 000200212345
      AVR Part  : ATmega328P
      Chip Erase delay  : 9000 us
      PAGEL  : PD7
      BS2  : PC2
      RESET disposition  : dedicated
      RETRY pulse  : SCK
      serial program mode  : yes
      parallel program mode  : yes
      Timeout  : 200
      StabDelay  : 100
      CmdexeDelay  : 25
      SyncLoops  : 32
      ByteDelay  : 0
      PollIndex  : 3
      PollValue  : 0x53
      Memory Detail  :

      Block Poll  Page  Polled
      Memory Type Mode Delay Size  Indx Paged  Size  Size #Pages MinW  MaxW  ReadBack
      ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
      eeprom  65  20  4  0 no  1024  4  0  3600  3600 0xff 0xff
      flash  65  6  128  0 yes  32768  128  256  4500  4500 0xff 0xff
      lfuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      hfuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      efuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      lock  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      calibration  0  0  0  0 no  1  0  0  0  0 0x00 0x00
      signature  0  0  0  0 no  3  0  0  0  0 0x00 0x00

      Programmer Type : STK500V2
      Description  : Atmel STK500 Version 2.x firmware
      Programmer Model: AVRISP mkII
    avrdude: stk500v2_recv_mk2: error in USB receive
      Hardware Version: 0
      Firmware Version Master : 1.23
      Vtarget  : 3.3 V
      SCK period  : 8.00 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f
    avrdude: erasing chip
    avrdude: reading input file "0x3F"
    avrdude: writing lock (1 bytes):

    Writing | ################################################## | 100% 0.00s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x3F:
    avrdude: load data lock data from input file 0x3F:
    avrdude: input file 0x3F contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of lock verified
    avrdude: reading input file "0x05"
    avrdude: writing efuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of efuse written
    avrdude: verifying efuse memory against 0x05:
    avrdude: load data efuse data from input file 0x05:
    avrdude: input file 0x05 contains 1 bytes
    avrdude: reading on-chip efuse data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of efuse verified
    avrdude: reading input file "0xDE"
    avrdude: writing hfuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of hfuse written
    avrdude: verifying hfuse memory against 0xDE:
    avrdude: load data hfuse data from input file 0xDE:
    avrdude: input file 0xDE contains 1 bytes
    avrdude: reading on-chip hfuse data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of hfuse verified
    avrdude: reading input file "0xFF"
    avrdude: writing lfuse (1 bytes):

    Writing | ################################################## | 100% 0.00s

    avrdude: 1 bytes of lfuse written
    avrdude: verifying lfuse memory against 0xFF:
    avrdude: load data lfuse data from input file 0xFF:
    avrdude: input file 0xFF contains 1 bytes
    avrdude: reading on-chip lfuse data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of lfuse verified

    avrdude done.  Thank you.

    ......../arduino-1.7.8-linux64/hardware/tools/avr/bin/avrdude -C......../arduino-1.7.8-linux64/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -cstk500v2 -Pusb -Uflash:w:......../arduino-1.7.8-linux64/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex:i -Ulock:w:0x0F:m

    avrdude: Version 6.0.1, compiled on Jan 15 2015 at 13:12:29
      Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
      Copyright (c) 2007-2009 Joerg Wunsch

      System wide configuration file is "......../arduino-1.7.8-linux64/hardware/tools/avr/etc/avrdude.conf"
      User configuration file is "/home/alexandr/.avrduderc"
      User configuration file does not exist or is not a regular file, skipping

      Using Port  : usb
      Using Programmer  : stk500v2
    avrdude: usbdev_open(): Found AVRISP mkII, serno: 000200212345
      AVR Part  : ATmega328P
      Chip Erase delay  : 9000 us
      PAGEL  : PD7
      BS2  : PC2
      RESET disposition  : dedicated
      RETRY pulse  : SCK
      serial program mode  : yes
      parallel program mode  : yes
      Timeout  : 200
      StabDelay  : 100
      CmdexeDelay  : 25
      SyncLoops  : 32
      ByteDelay  : 0
      PollIndex  : 3
      PollValue  : 0x53
      Memory Detail  :

      Block Poll  Page  Polled
      Memory Type Mode Delay Size  Indx Paged  Size  Size #Pages MinW  MaxW  ReadBack
      ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
      eeprom  65  20  4  0 no  1024  4  0  3600  3600 0xff 0xff
      flash  65  6  128  0 yes  32768  128  256  4500  4500 0xff 0xff
      lfuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      hfuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      efuse  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      lock  0  0  0  0 no  1  0  0  4500  4500 0x00 0x00
      calibration  0  0  0  0 no  1  0  0  0  0 0x00 0x00
      signature  0  0  0  0 no  3  0  0  0  0 0x00 0x00

      Programmer Type : STK500V2
      Description  : Atmel STK500 Version 2.x firmware
      Programmer Model: AVRISP mkII
    avrdude: stk500v2_recv_mk2: error in USB receive
      Hardware Version: 0
      Firmware Version Master : 1.23
      Vtarget  : 3.3 V
      SCK period  : 8.00 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.00s

    avrdude: Device signature = 0x1e950f
    avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
      To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: reading input file "......../arduino-1.7.8-linux64/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex"
    avrdude: writing flash (32768 bytes):

    Writing | ################################################## | 100% 0.00s

    avrdude: 32768 bytes of flash written
    avrdude: verifying flash memory against ......../arduino-1.7.8-linux64/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex:
    avrdude: load data flash data from input file ......../arduino-1.7.8-linux64/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex:
    avrdude: input file ......./arduino-1.7.8-linux64/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex contains 32768 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 32768 bytes of flash verified
    avrdude: reading input file "0x0F"
    avrdude: writing lock (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x0F:
    avrdude: load data lock data from input file 0x0F:
    avrdude: input file 0x0F contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: 1 bytes of lock verified

    avrdude done.  Thank you.
    Бутлоадер прошит, осталось вернуть стандартную прошивку в контроллер ATmega16U2.
     
    ИгорьК, Airbus и Unixon нравится это.
  3. AlexU

    AlexU Гуру

    10. переводим в режим DFU (см. пункты 5 и 6);

    11. переходим в каталог <Arduino_IDE>/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial/ и прошиваем "Arduino-usbserial-atmega16u2-Uno-Rev3.hex':
    первая команда:
    Код (Bash):
    dfu-programmer atmega16u2 erase
    вторая команда:
    Код (Bash):
    dfu-programmer atmega16u2 flash Arduino-usbserial-atmega16u2-Uno-Rev3.hex
    12. "Передёргиваем" USB и, "вуа-ля", мы получили восстановленную Arduino UNO. Смотрим список устройств (команда lsusb):
    Код (Bash):
    Bus 003 Device 033: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)

    Второй спсособ -- сгорели оба контроллера (с экономической точки зрения дешевле купить китайский клон, чем восстанавливать оригинал):

    1. меняем контроллеры на исправные, ATmega16U2 придётся паять. Паять это пол-беды -- найти ATmega16U2-MU (обратите внимание на суффикс -MU) не так-то просто.

    2. И тут "засада" -- по умолчанию фьюзы ATmega16U2 выставлены так, что он будет работать от внешнего кварца, но с делением частоты на 8. В нашем случае (кварц 16МГц) частота работы -- 2МГц. А все прошивки рассчитаны на 16 МГц. Варианта решения два: пересобирать прошивку 'arduino-usbserial' на частоту 2 МГц для ATmega16U2 (см. подкаталог <Arduino_IDE>/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial/) или перепрошивать фьюзы. Я выбрал второй вариант -- перепрошил фьюзы с помощью программатора. (В режиме DFU фьюзы поменять нельзя).

    3. Остальные шаги такие же как и в первом способе.

    Надеюсь информация будет полезна....
     
    ИгорьК, Airbus и Unixon нравится это.
  4. Unixon

    Unixon Оракул Модератор

    Хм, интересный bootstrap через dfu. Менял как то дохлый 16u2 на чужой Uno, прошивал просто через ICSP.
     
  5. Airbus

    Airbus Радиохулиган Модератор

    Не ну круто конечно вот так из ничего сделать ВСЁ!Перепрошивать на плате ATnega16U2 туда-сюда и это чтоб загнать Лодыря в Мегу-328 в DIP корпусе.Плюс тр@хаться с линуксом.Мне так проще сразу загнать лодыря "на место" у меня дома пластиковое ведёрко разных программаторов стоит от пяти проводков до "DI Halt" на Меге8.Но я всю жизнь с программатором и паяльником по жизни а НУБ сможет?А если вместо ATnega16U2 СН341?Или FT232?Тода как?А второй способ
    Но в любом случае Автору Респект!
     
  6. Unixon

    Unixon Оракул Модератор

    Вы просто не умеете его готовить.

    Тогда инструкция становится, как минимум, вдвое короче. CH340 или FT232 достаточно просто перепаять.
     
  7. AlexU

    AlexU Гуру

    У самого есть программатор. Всё решалось двумя командами -- прошивкой бутлоадера в 328-й и прошивкой usbtoserial+DFU в 16U2.
    Но здесь преследовались две цели:
    1. Показать, что можно использовать второй контроллер, например, в связке с основным -- получаем "двух-процессорную" Arduino. Соответственно рассказывалось как его прошивать и восстанавливать в первоначальное состояние.
    2. Очень часто новички сжигают только один контроллер, подключая большую нагрузку. Точнее выводят из строя некоторые пины. Купить на замену 328-й -- проблем нет, поменять тоже. Остаётся восстановить бутлоадер. И тут "засада" -- кроме Arduino и USB шнурка больше ни чего нет, о офф-сайт говорит, что нужен программатор.
    А вобщем и целом, конечно, первое устройство, которое должен "слепить" ардуинщик, должен быть какой-либо программатор для AVR-ок ... А уже потом всё остальное....
     
    Airbus и ИгорьК нравится это.
  8. ИгорьК

    ИгорьК Гуру

    Три копейки... ИМХО - полезно сжечь и чтобы купили новый. Мне кажется, только так начинают думать.
    Много раз уже вижу, как 3-вольтовые входы вешают на 5-вольтовые выходы, как Вы правильно заметили - на один выход вешают запредельные нагрузки.
    И, главное, АГРЕССИВНО доказывают что "у меня, у друга это работает и надо так".
    В чем вред Вашей темы, наряду с красотой решения? Как раз в том, что она позволяет новичкам...
    Вы, как опытный товарищ, СЛУЧАЙНО подавший 12 вольт - и так знаете решение.
     
  9. Airbus

    Airbus Радиохулиган Модератор

    Так пытался же пробовал все его (её?)проявления в.т.ч и аМИГО Федоры итд.-не впечатлило и не красивее и не быстрее.ИМХО эйплы тоже на любителя (на Большого любителя) Я пользуюсь ХР именно потому что нет проблем с драйверами и все приложения для работы с AVR (AVR Studio CV AVR) и под ПИКи ею без проблем поддерживаются.С 7 а тем более с 8 больше траблов и это заметно на Форуме.
    100% согласен!Ну вот хоть убейте без него никак!Можно купить недорого можно спаять самому (но это не совсем для начинающих) Но способ от AlexU для меня например сложный (хотя теоретически правильный)надо очень аккуратно и правильно всё сделать и хотя я далеко не новичёк вряд ли взялся:
    1. качаем исходники LUFA
    2. правим файл AppConfig.h
    3. правим файл makefile:
    4. Производим сборку: команда make.
    5. Переводим Arduino UNO в режи DFU для чего: подключаем Arduino к USB порту и затем на короткое время замыкаем контакты
    7. Прошиваем прошивку программатора AVRISPmkII
    9. Используя проводочки папа-мама, коммутируем наш "программатор" для прошивки ATmega328P
    8. "Передёргиваем" USB (можно конечно дать команду dfu-programmer atmega16u2 start, которая запустит прошивку,
    10. переводим в режим DFU
    11. переходим в каталог <Arduino_IDE>/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial/ и прошиваем "Arduino-usbserial-atmega16u2-Uno-Rev3.hex':
    12. "Передёргиваем" USB и, "вуа-ля", мы получили восстановленную Arduino UNO
    Зачем столько ходов?Недавно шил Лодырей в Меги8 Высоковольтник шьёт за 3 секунды (вместе с фьюзами) "Громов" за 1 минуту + фьюзы 5 сек. USB ISP+"Дудка" за 25 сек+ фьюзы 5 сек.Да и вероятность ошибок сведена к минимуму.
     
    Последнее редактирование: 26 фев 2016
    Ariadna-on-Line и ИгорьК нравится это.
  10. vvr

    vvr Инженерище

    почитал.
    порадовался.
    проще, дешевле, быстрее и без геморррррра - погорельца в помойку, купить нового китайца (двух, один про запас):)
     
  11. Aragorn

    Aragorn Нуб

    Коллеги, приветствую. Попал в аналогичную ситуацию, atmega328p мини сгорела по питанию, на питающем входе +5В КЗ.
    Сектча нет, резервного дампа памяти тоже. Ест ли какие-то шансы достать прошивку из flash контроллера и прошить в новый?
     
  12. asam

    asam Гик

    В домашних условиях - нет. Есть конторы которые могут вскрыть чип и попытаться с хорошей вероятностью вытащить прошивку. Но стоит это будет столько....

    Что за аппарат? Может проще прошивку заново написать? Или купить новый?
     
    Aragorn нравится это.
  13. Aragorn

    Aragorn Нуб

    Кустарный контроллер параметров окружающей среды, с кучей датчиков... Если Атмега при превышении питания сгорает полностью и достать прошивку без вскрытия чипа нельзя - возиться смысла нет.
     
  14. Airbus

    Airbus Радиохулиган Модератор

    Нет.То есть совсем никаких.Даже вариант с распиливанием это у "них в Америках" да и то будет стоить как новый Ауди.А у нас такого нет-от слова совсем.Тоже недавно пальнул Нано.Поэтому оставляю копии как скетчей нак и НЕХ на всякий случай.Мегу-328 в DIP (для оперативной замены) да и прошиваю парочку-на всякий случай.
     
    Aragorn нравится это.
  15. Blackgeneral

    Blackgeneral Нерд

    А есть ли на форуме "инструкция" как провести полную диагностику ардуино УНО?
    P.S.:про предохранитель и линейный стабилизатор знаю, но проблема, как мне кажется, не в питании. Китайский клон ведет себя довольно странно: скетч может нормально прошится, а может зависнуть и постоянно гореть светодиодом "L". Иногда помогает "отлеживание" платы в течении нескольких часов.
     
  16. vvr

    vvr Инженерище

    выкидывайте её без сожаления.
    не такие уж и дорогие...
     
    b707 нравится это.
  17. SergeiL

    SergeiL Оракул Модератор

    А проблема не с питанием?
     
  18. Blackgeneral

    Blackgeneral Нерд

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

    parovoZZ Гуру

    Конечно, проходили. Выпаиваешь микру и в ведро ее,
     
    vvr нравится это.
  20. b707

    b707 Гуру

    зачем так много сложностей... сразу в ведро :)