ARV: мысли вслух

Флейм в чистом виде - все что угодно...
Но - в рамках закона :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

Во-первых, взять мегу для столь простой задачи, это не спортивно.
Во-вторых, у меня два десятка тинек скопилось, что с ними делать, если всякий раз меги покупать?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

снова подумываю о карьере управдома... в соседней теме про С/С++ задал вопрос, свидетельствующий о новом тупике...
возможно, конечно, что для меня настала пора чудес... у большинства она в раннем детстве, а у меня вот сейчас...
наверное, этому можно радоваться... :dont_know:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

вчера столкнулся с интересным эффектом: при включении LTO-оптимизации размер результирующей прошивки не уменьшается, как ожидается, а возрастает, и заметно возрастает... с базовой оптимизацией -O3 без LTO примерно 6,5К прошивка, с LTO почти 8К. это я все про проект своих ГРИ-часов.

всё-таки, я не зря ковыряюсь с ним: столько занятных моментов обнаружил...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

Использую следующие ключи оптимизации обычно:

Код: Выделить всё

-Os -std=gnu11 -flto -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wl,--warn-common -Wl,--gc-sections -Wl,-lm
Для использования с -flto желательно компилятору указать -ffunction-sections -fdata-sections, чтобы функции и данные в отдельные секции были положены, а линкеру соб-но указать --gc-sections, чтобы он неиспользуемые секции почистил (gc - garbage collection). Попробуйте.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

NStorm писал(а):желательно компилятору указать -ffunction-sections -fdata-sections,
именно так и делаю, эту фишку еще лет 10 назад разузнал и с тех пор всем начинающим советую сам. и раньше LTO всегда уменьшало прошивку, а вот тут... облом. но это просто результат эксперимента, не трагедия же...

Добавлено after 1 minute 27 seconds:
а вот с -Os мой проект не работает - слишком долго прерывания исполняются, динамическая индикация и стабилизация высокого напряжения ломаются. поэтому -O3
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

Так а --gc-sections линкера тоже используете? Не забыли?
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

NStorm писал(а): Не забыли?
абыжаиш, начальник!

Добавлено after 9 minutes 20 seconds:
вот прямо сейчас повторил эксперимент, чтобы не быть голословным.
без LTO:
AVR Memory Usage
----------------
Device: atmega328p

Program: 7506 bytes (22.9% Full)
(.text + .data + .bootloader)

Data: 102 bytes (5.0% Full)
(.data + .bss + .noinit)
с LTO:
AVR Memory Usage
----------------
Device: atmega328p

Program: 8626 bytes (26.3% Full)
(.text + .data + .bootloader)

Data: 103 bytes (5.0% Full)
(.data + .bss + .noinit)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

А версия компилятора какая? Я заметил, что версии новее 5.4.0 от микрочипа генерят больший код.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

версия avr-gcc в текущий момент у меня 6.3.0, беру не с сайта микрочипа, а с какого-то репозитория вроде как всё еще поддерживаемого какими-то энузиастами

из имеющихся у меня версий от 3.3.2 (WinAVR) до 10.1.0 версия 6.3.0 по моим опытам порождает наиболее оптимальный размер кода.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

Вот у меня реальный проект завершенный. 7 юнитов. На 5.4.0 (avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.2_1759) 5.4.0) с -flto (опции, которые я выше показал):

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    7184 bytes (87.7% Full)
(.text + .data + .bootloader)

Data:        218 bytes (21.3% Full)
(.data + .bss + .noinit)
Без него:

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    7482 bytes (91.3% Full)
(.text + .data + .bootloader)

Data:        224 bytes (21.9% Full)
(.data + .bss + .noinit)
Сейчас попробую 11.1 собрать.

Репозитарий от энтузиазистов куда более свежих сборок avr-gcc: https://blog.zakkemble.net/avr-gcc-builds/
Попробуйте отсюда. А вообще я на 5.4.0 от микрочипов остановился. По мне он самый стабильный и оптимальный код дает, несмотря на "старость". Тоже советую попробовать. Может в вашей версии кривой LTO.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

вот откуда беру - сам забыл, пришлось вспоминать: https://blog.zakkemble.net/avr-gcc-builds/
там уже и 11.1.0 есть...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

Забавно. Попробовать 9.2.0 собрать и получаю ошибку:

Код: Выделить всё

<artificial>:(.text.startup.main+0xe): undefined reference to `WDT_off'
При этом WDT_off объявлено в main.c и оттуда же вызывается только:

Код: Выделить всё

void inline WDT_off(void) {
Убрал inline и собралось... странно. 9.2.0 с LTO:

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    7128 bytes (87.0% Full)
(.text + .data + .bootloader)

Data:        218 bytes (21.3% Full)
(.data + .bss + .noinit)
Без LTO:

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    7490 bytes (91.4% Full)
(.text + .data + .bootloader)

Data:        224 bytes (21.9% Full)
(.data + .bss + .noinit)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

:))) :))) :))) опередили :beer:

Добавлено after 1 minute 7 seconds:
ну, вы меня сподвигли на эксперименты.
ща стану проверять разные версии из имеющихся
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

11.1 у меня линкер не запускается, Зак собрал его на каком-то новом дистре Linux, требуется более новый GLIBC, чем у меня. Не буду заморачиваться.

EDIT: А хотя фиг с ним, самому интересно уже. Поставил собраться 11.1 скриптом Зака из исходников, посмотрим как соберется под мою систему.
Последний раз редактировалось NStorm Чт июн 17, 2021 09:37:42, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

9.2.0 без LTO:
AVR Memory Usage
----------------
Device: atmega328p

Program: 7414 bytes (22.6% Full)
(.text + .data + .bootloader)

Data: 102 bytes (5.0% Full)
(.data + .bss + .noinit)
с LTO:
AVR Memory Usage
----------------
Device: atmega328p

Program: 8812 bytes (26.9% Full)
(.text + .data + .bootloader)

Data: 103 bytes (5.0% Full)
(.data + .bss + .noinit)
Добавлено after 59 seconds:
9-ка еще хуже собрала :)))

Добавлено after 4 minutes 28 seconds:
10.1.0 с LTO:
AVR Memory Usage
----------------
Device: atmega328p

Program: 8846 bytes (27.0% Full)
(.text + .data + .bootloader)

Data: 103 bytes (5.0% Full)
(.data + .bss + .noinit)
без LTO смысла не вижу проверять

4.9.2 - не собралось

5.2.1:
AVR Memory Usage
----------------
Device: atmega328p

Program: 8456 bytes (25.8% Full)
(.text + .data + .bootloader)

Data: 103 bytes (5.0% Full)
(.data + .bss + .noinit)
короче, больше не буду, эффект налицо: мой проект с LTO получается больше, чем без :)))

учитесь, пока я жив! :))) :))) :)))

Добавлено after 1 minute 36 seconds:
NStorm, вы попробуйте ваши проекты с -O3 собрать с LTO и без. так будет корректнее сравнивать эффекты.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: ARV: мысли вслух

Сообщение NStorm »

С -O3 оно у меня просто не собирается, из-за того, что не влезает в мегу8 :)))
Дефайнами у меня часть функционала отключается. Значительная. Просто с -Os с отключенным функционалом у меня около 3500 байт занимает... а с -O3 (и LTO):

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    8152 bytes (99.5% Full)
(.text + .data + .bootloader)

Data:        186 bytes (18.2% Full)
(.data + .bss + .noinit)
А без LTO и правда сильно меньше:

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    5918 bytes (72.2% Full)
(.text + .data + .bootloader)

Data:        202 bytes (19.7% Full)
(.data + .bss + .noinit)
Вот значит в чем собака зарыта. Видимо LTO всё-таки не только место старается оптимизировать. Раз задан -O3 оптимизация идет в другую сторону, явно не в сторону места.

Тоже самое, без части функционала, с LTO и -Os просто вот так весит:

Код: Выделить всё

AVR Memory Usage
----------------
Device: atmega8

Program:    3720 bytes (45.4% Full)
(.text + .data + .bootloader)

Data:        198 bytes (19.3% Full)
(.data + .bss + .noinit)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

судя по тому, что с LTO прибавляется и расход ОЗУ, хотя все неиспользуемые переменные выброшены чисткой секций, и в самом деле LTO работает для размера так, а для скорости - этак...

интересное наблюдение, однако.

Добавлено after 2 hours 4 minutes 28 seconds:
начну-ка я помаленечку рассказывать о своем многотрудном проекте часов на ГРИ... в тему про ГРИ не буду, т.к. ничего нового я не внесу туда, а вот тут блуждания моих мыслей вполне уместны.

итак, вот такой код главной функции у меня вышел:

Код: Выделить всё

int main(void){
	show_mode_t show_mode = SHOW_SIMPLE;
	mode_t tm, mode = MODE_TIME;
	uint8_t sec = 255;

	mode_clock_init(mode);

	indication(false); // индикация отключается
	refresh = true;

	sei();

	while(1){
		// TODO проверка питания
		while(main_power_miss()){
			// пока питания нет
			indication(false); // индикация отключается
			sec = time.s;
			// уходим в сон
			do {
				set_sleep_mode(SLEEP_MODE_PWR_SAVE);
				sleep_mode();
				// пробуждение по прерыванию от таймера
				refresh = time.s != sec;
			} while (!refresh);
			continue;
		}
		// при наличии питания
		indication(mode != MODE_NIGHT); // индикация включена, если не ночной режим

		if(time.s != sec){
			refresh = true;
			sec = time.s;
		}

		// выводим режим
		if(modes[mode].show != NULL)
			modes[mode].show(show_mode);

		refresh = false;

		// проверки условий разных событий
		if(!played() && alarm.s && (time.h == alarm.h) && (time.m == alarm.m) && (time.s == 0))
			// принудительно включаем режим будильника, если наступило время
			tm = MODE_WAKE;
		else if(night_time() && (abs(time.s - night_sec) >= 3) && (mode != MODE_NIGHT))
			// принудительно включаем ночной режим, если условие соблюдено
			tm = MODE_NIGHT;
		else
			// иначе получаем и обрабатываем событие
			tm = modes[mode].exec(get_key_event());

		if(tm != mode){
			// если возможно - делаем инициализацию нового режима
			if(modes[tm].init != NULL)
				modes[tm].init(mode);
			mode = tm;
			refresh = true;
		}
	}
}
МК засыпает (POWER_SAVE), если функция main_power_miss вернет true. просыпается он по прерываниям переполнения второго таймера, работающего в асинхронном режиме от часового кварца. таймер настроен так, что переполняется он 16 раз в секунду, но проверка питания осуществляется только 1 раз в секунду, чтобы предельно снизить потребление. делается это вторым циклом внутри того, что с функцией проверки питания - надеюсь, по коду и комментам все понятно.

ну, а затем все более-менее просто:
- функция indication включает-выключает высоковольтный преобразователь и другие энергоёмкие периферийные компоненты МК;
- структура time (поля традиционные - час, минута и секунда) изменяется в обработчике прерывания второго таймера и хранит текущее время;
- переменная mode хранит текущий режим работы часов, а массив modes заполнен функциями, реализующими поведение того или иного режима.

таким образом, логика работы часов реализована в виде конечного автомата: состояние автомата задается переменной mode, а переходы между состояниями определены значением, возвращаемым функцией exec каждого состояния. если осуществляется переход в новое состояние, то, если существует, вызывается функция предварительной инициализации нового состояния. чем-то все это напоминает ООП с конструкторами.

вот, как-то так.

Добавлено after 37 minutes 43 seconds:
наверное, предыдущий текст я напрасно не сопроводил описанием типа и структуры массива modes:

Код: Выделить всё

/// структура методов режима часов
typedef struct {
	void (*init)(mode_t prev);		//!< инициализация
	mode_t (*exec)(event_t ev);		//!< обработчик событий
	void (*show)(show_mode_t sm);	//!< индикация
} mode_methods_t;

static const __flash mode_methods_t modes[MODE_CNT] = {
	//MODE_TIME
		{mode_clock_init, mode_clock_exec, mode_clock_show},
	//MODE_SEC
		{NULL, mode_sec_exec, mode_sec_show},
	//MODE_ALARM
		{mode_alarm_init, mode_alarm_exec, mode_alarm_show},
	//MODE_SETUP
		{mode_edit_init, mode_edit_exec, mode_edit_show},
	//MODE_WAKE
		{mode_wake_init, mode_wake_exec, mode_clock_show},
	//MODE_NIGHT_VIEW
		{mode_nview_init, mode_nview_exec, mode_nview_show},
	//MODE_NIGHT
		{mode_night_init, mode_night_exec, NULL},
	//MODE_NIGHT_EDIT
		{mode_edit_night_init, mode_edit_night_exec, mode_edit_night_show},
};
ну и заодно немного подробностей о состояниях конечного автомата часов:

Код: Выделить всё

/// возможные режимы работы
typedef enum{
	MODE_TIME,			//!< индикация времени
	MODE_SEC,			//!< индикация секунд
	MODE_ALARM,			//!< индикация будильника
	MODE_SETUP,			//!< настройка времени
	MODE_WAKE,			//!< срабатывание будильника
	MODE_NIGHT_VIEW,	//!< индикация настройки ночного режима
	MODE_NIGHT,			//!< ночной режим
	MODE_NIGHT_EDIT,	//!< изменение настроек ночного режима
	//
	MODE_CNT			//!< общее количество режимов
} mode_t;
ночной режим - это когда все ГРИ погашены большую часть времени, и только 1 раз в секунду минуту конечно же (или после нажатия любой кнопки) активируются на 3 секунды. лично меня на этапе засыпания выбешивает свечение во мраке чего-то электронного, даже индикатор зарядки телефона. вот и решил сделать такой режим, сведя к минимуму освещение от часов по ночам, но сохранив возможность, если мучает бессонница, все-таки контролировать время.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

не могу не процитировать сегодняшний Хабр:
Изображение
:)))

Добавлено after 3 hours 23 minutes 42 seconds:
продолжаю про ГРИ-часы

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

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

поскольку у меня 2 независимые (в смысле, независимо управляемые) разделительные точки, я решил сделать выделение режимов с их помощью:

1. если точки мигают - видим текущее время, независимо от подсветки
2. если обе точки светятся, не мигая - видим минуты и секунды, независимо от подсветки
3. если светится только одна точка - видим заданное время будильника
4. если точки не светятся - видим настройку ночного режима

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

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

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

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

теперь установка/коррекция времени/параметров.
для выделения этих режимов я принял решение использовать подсветку: то, что в текущий момент можно изменить, подсвечивается полной яркостью, остальное не подсвечивается.
настройку реализовал поразрядно, т.к. изменение, например, минут путем нажатия кнопки коррекции до 60 раз, меня не устраивает. когда активируется режим коррекции (длительным нажатием кнопки MODE), подсветка, если была включена, гаснет на всех лампах, кроме самой левой (это десятки часов). цвет подсветки в режиме коррекции всегда один и тот же (пока не определился, какой, пока красный). нажатие MODE переключает подсветку последовательно на единицы часов, десятки минут, единицы минут и снова на десятки часов и т.д. ну а кнопками +/- можно изменять подсвеченную цифру. реализовал и блокировку ввода недопустимого значения: если были показания часов 19 и нажимаем + в разряде десятков часов, то показания меняются на 23, а не на 29. это немного противоречит логике "меняется то, что подсвечено", зато соответствует логике показаний времени.
когда показания введены, надо нажать и удерживать MODE пару секунд для принятия изменений. если этого не сделать, то спустя 30 секунд отсутствия нажатий кнопок часы сбросят введенные показания и вернутся к тем, которые являются текущими.

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

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

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

вот, как-то так, пока что...
Вложения
хабр.PNG
(3.08 КБ) 696 скачиваний
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Upgrader
Друг Кота
Сообщения: 26671
Зарегистрирован: Пт май 18, 2007 22:56:58

Re: ARV: мысли вслух

Сообщение Upgrader »

[uquote="ARV",url="/forum/viewtopic.php?p=4049196#p4049196"]не могу не процитировать сегодняшний Хабр:
Изображение
:)))[/uquote]Не знаю, это наверное отдельная порода самодельщиков.
У меня наоборот никогда часы и погодные станции не получаются, вместо них всегда что-то совершенно другое получается. :)))
Не променяю медь на ржавую несгорайку!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ARV: мысли вслух

Сообщение ARV »

как бы ни старался Upgrader сделать часы или погодную станцию, все равно выходит что-то другое :)))
так?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «МЯЯЯУ!»