Часы-будильник со случайным временем срабатывания на базе ЭКВМ


Главная / ЭКВМ / Программы для ЭКВМ / Прикладные задачи

Если не считать биологических будильников, первые конструкции для подачи сигналов в определенный момент времени были сделаны тысячи лет назад на основе свечей и водяных часов. Первый механический будильник был изобретен в 1787 году. Он отличался тем, что звонил в строго определенное время - в четыре часа утра. Будильник, который можно настраивать на нужное время пробуждения запатентовал в 1847 году француз Антуан Радье.

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

Но исследования в этой области продолжаются. Антинобелевская премия (Ig Nobel Prize) по экономике за 2005 г принадлежит Гаури Нанда из Массачусетского технологического института за изобретение будильника, который убегает и прячется от выключения, заставляя людей просыпаться, что, по задумке изобретателя, должно помочь хотя бы частично устранить проблему опоздания на работу, увеличив фактическую продолжительность рабочего времени.

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

Интересно сделать будильник не с равномерным, а с нормальным (Гаусса) распределением времени срабатывания. В качестве параметров при этом передается не время начала и окончания периода срабатывания, а математическое ожидание Tm и стандартное отклонение σ.

Как известно из теории вероятностей, в момент Tm плотность вероятности пробуждения будет максимальна - около 0,39894. Среднее абсолютное отклонение составляет 0,798σ, вероятное отклонение 0,674σ. Из последнего значения следует, что в половине случаев будильник подаст сигнал в границах ±0,674σ

Границы 95% вероятности срабатывания составляют приблизительно ±1,96σ, 99% - ±2,58σ и 99,9% - ±3,29σ.

Вероятность пробуждения в пределах, кратных стандартному отклонению составит для ±1σ - 68,268%; для ±2σ - 95,45% и ±3σ - 99,73%. То есть вероятность того, что устройство не подаст сигнал в пределах 3σ от Tm составляет всего 0,27%. Для будильника это будет происходить примерно раз в год при ежедневном использовании. Вероятность того, что будильник не зазвонит в пределах ±5σ будет примерно один раз в 50 лет. Для любого конечного значения U будет существовать ненулевая вероятность того, что будильник не подаст сигнал. Хотя вряд ли это может быть хорошим оправданием в случае опоздания на службу или место учебы.

Значения интеграла вероятности для других пределов приведены в таблице.

U Ф (U)
0 0
0,1 0,03983
0,2 0,07926
0,3 0,11791
0,4 0,15542
0,5 0,19146
0,6 0,22575
0,7 0,25804
0,8 0,28814
0,9 0,31594
1,0 0,34134
1,1 0,36433
1,2 0,38493
1,3 0,40320
1,4 0,41924
1,5 0,43319
1,6 0,44520
1,7 0,45543
1,8 0,46407
1,9 0,47128
U Ф (U)
2,0 0,47725
2,1 0,48214
2,2 0,48610
2,3 0,48928
2,4 0,49180
2,5 0,49379
2,6 0,49534
2,7 0,49653
2,8 0,49744
2,9 0,49813
3,0 0,49865
3,5 0,4997674
4,0 0,4999683
4,5 0,4999966
5,0 0,4999997133



Далее приведена программа для ЭКВМ "Электроника МК", реализующая алгоритм часов с будильником. Длина программы - 626 байт. В связи с изменением механизма определения вектора прерываний с версии 1.09 ПО МК-152 - размещена новая версия программы.

Файлы программы версии 2.3 с исходным текстом и для записи в память ЭКВМ:

clock_v23.mkl - исходный текст программы с комментариями;
clock_v23.mkp - файл для записи в память ЭКВМ.

Программа загружается с нулевой страницы. Перед запуском следует записать в регистр R0 установленное время срабатывания будильника (мат. ожидание Tm) в формате "ЧЧ.ММ", в регистр R1 - стандартное отклонение σ в минутах. Для запуска программы нажать "В/О", "С/П"; для останова - "С/П".

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

Для включения или отключения будильника во время работы программы нажать любую клавишу (кроме "С/П"). При включенном будильнике на экран внизу слева будет выведен знак колокольчика.

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

В таблице приведена программа на языке МК.

  0 1 2 3 4 5 6 7 8 9
000 Cx 1 P П 20 PP П 91 48 PP П 91 30
010 9 ВП 3 П 7 0 6 0 7 B↑ 2
020 PP П 91 32 PP П 91 53 PP П 90 10 F 10x
030 П 3 П A П B П C P ПП 04 29 P ПП 01 64
040 P ПП 02 53 Cx П 4 PP ИП 90 55 П E K [x]
050 П 9 ИП A - F x≠0 61 ИП 9 П A K ИП 4 P ПП 01
060 02 ИП E K {x} ИП 3 × П 8 K [x] П 9 ИП B -
070 F x≠0 78 ИП 9 П B K ИП 4 P ПП 01 33 ИП 8 K {x}
080 ИП 3 × K [x] П 9 ИП C - F x≠0 94 ИП 9 П C
090 K ИП 4 P ПП 01 50 ИП 4 P x≠0 00 45 K ГРФ P БП
100 00 43 2 0 B↑ 3 0 K П 7 2 PP П
110 90 03 ИП A P ПП 03 67 2 0 B↑ 5
120 6 K П 7 5 8 PP П 90 20 ИП A F x=0 32
130 БП 64 В/О 2 0 B↑ 6 4 K П 7 2
140 PP П 90 03 ИП B P ПП 03 67 P БП 03 92
150 2 7 B↑ 9 2 K П 7 1 PP П 90 03
160 ИП C P БП 03 67 0 B↑ K П 7 PP П 90 03
170 PP ИП 90 56 P ПП 03 67 4 6 PP П 90
180 20 PP ИП 90 57 P ПП 03 67 4 6 PP П
190 90 20 PP ИП 90 58 ИП 3 ÷ P П 21 K [x]
200 P ПП 03 67 P ИП 21 K {x} ИП 3 × P ПП 03
210 67 0 B↑ 7 0 K П 7 PP ИП 90 59 2
220 × 0 5 9 1 + B↑ K ИПРГ ИП 3 ×
230 1 + K ИПРГ + PP П 90 21 1 0
240 B↑ 0 K П 7 1 0 B↑ 1 2 7 PP П
250 90 12 В/О 5 2 B↑ 0 K П 7 B↑
260 1 2 7 PP П 90 12 P ИП 20 F x=0 92
270 5 4 B↑ 0 K П 7 4 PP П 90 01 8
280 B↑ 1 2 8 PP П 90 13 0 PP П 90
290 01 В/О 5 5 B↑ 0 K П 7 0 4 9
300 0 PP П 90 15 5 4 B↑ 1 0 K П 7
310 0 PP П 90 03 ИП 0 K [x] ПП 67 5 8
320 PP П 90 20 ИП 0 K {x} ИП 3 × ПП 67 5
330 5 B↑ 7 0 K П 7 0 4 9 7 PP П
340 90 15 5 4 B↑ 7 8 K П 7 0 5
350 0 4 PP П 90 21 ИП 1 PP П 90 23 0
360 5 0 7 PP П 90 21 В/О 1 0 ÷
370 П 8 K {x} 1 0 × 4 8 + П 9 ИП 8
380 K [x] 4 8 + PP П 90 20 ИП 9 PP П 90
390 20 В/О P ИП 20 P x≠0 04 13 ИП 6 ИП 3 ×
400 K [x] ИП A ИП 3 × ИП B + - F x≠0 14 Cx
410 PP П 91 50 В/О 0 5 1 3 B↑ 1
420 PP П 91 31 PP П 91 50 PP П 91 49 1
430 PP П 90 45 K СЧ F x≠0 33 F 1/x F ln 2 ×
440 F √ K СЧ 2 × F π × F cos × ИП 1 6
450 0 ÷ × П 8 K |x| 2 4 - F x≥0 62
460 Cx П 8 ИП 8 ИП 0 K М→Г + F x<0 71 2 4
470 + П 9 2 4 - F x<0 78 ИП 9 K Г→М ИП 3
480 × 0 , 5 + K [x] ИП 3 ÷ П 6 В/О
490 05h 08h 20h 3Eh 7Fh 3Eh 20h 05h 08h 1Ch
500 22h 22h 1Ah 01h 3Dh 20h 00h 20h ACh A8h
510 ADh 2Eh 00h 5 0 PP П 90 50 2 0
520 0 0 B↑ 2 5 PP П 90 52 PP В/О 8Fh
530 AEh ADh A5h A4h A5h ABh ECh ADh A8h AAh
540 00h 82h E2h AEh E0h ADh A8h AAh 00h 91h
550 E0h A5h A4h A0h 00h 97h A5h E2h A2h A5h
560 E0h A3h 00h 8Fh EFh E2h ADh A8h E6h A0h
570 00h 91h E3h A1h A1h AEh E2h A0h 00h 82h
580 AEh E1h AAh E0h A5h E1h A5h ADh ECh A5h
590 00h 00h 00h 05h 1Dh 05h 29h 05h 31h 05h
600 37h 05h 3Fh 05h 47h 05h 4Fh P ИП 20 F x=0
610 16 1 P П 20 БП 22 Cx P П 20 PP П
620 91 50 P ПП 02 53 K ГРФ PP В/О      

Контрольная сумма ADD 68815, XOR 21, при условии, что остальные байты последней страницы содержат 0FFh.




Исходный текст программы для компилятора с комментариями.

; Часы-будильник со случайным временем срабатывания
; Нормальное распределение

; Версия 2.3 от 22.12.08

; * - установить перед запуском программы

; * R0  - установленное время срабатывания будильника (мат. ожидание) "ЧЧ.ММ"
; * R1  - сигма, в минутах

; R3 = 100 (константа)
; R4 - признак изменений для перерисовки экрана >=1 -есть 0-нет
; R6 - рассчитанное время срабатывания будильника
; R7 = 9000 (константа) для использования "КП7" вместо "РР П 9000"
; R8,R9 - временное хранение
; RA - последнее значение часов
; RB - последнее значение минут
; RC - последнее значение секунд
; RD - последнее значение даты
; RE - текущее значение часов

; R 20 - будильник 1-включен, 0- выключен (используется в прерывании)
; R 21 - временное хранение года при выводе


; Версия ПО МК-152 - 1.09 и выше 
; Версия компилятора - 1.08 и выше


.CHARSET 1251
.ORG 0
	CX
	1
	P M 20		; Включить будильник
	PP M 9148	; Сброс регистров функций прерывания (ПО МК-152 v1.08)
	PP M 9130	; Общее разрешение прерываний
	9
	EE
	3
	M 7		; R7=9000
	.NUM KLAVA	; Вектор прерывания - полный адрес (ПО МК-152 v1.09)
	ENT
	2
	PP M 9132	; Прерывание 2 - вектор KLAVA, приоритет 2
	PP M 9153	; Прерывание клавиатуры 
	PP M 9010	; Очистка экрана
	F 10^X
	M 3		; R3=100
	MA		; Значения часов, минут и секунд - для перерисовки
	MB
	MC
	P GSB VREMJA
	P GSB RIS_D	
	P GSB RIS_B	
A0:
	CX
	M 4		
A00:
	PP RM 9055	; Время 
	M E
	K INT
	M 9
	RM A
	-
	F X!=0 A1
	RM 9
	M A
	K RM 4		; инкремент R4 - признак перерисовки
	P GSB RIS_H
A1:
	RM E
	K FRAC
	RM3		;100
	*
	M 8
	K INT
	M 9
	RM B
	-
	F X!=0 A2
	RM 9
	M B
	K RM 4		; инкремент R4 - признак перерисовки
	P GSB RIS_M
A2:
	RM 8
	K FRAC
	RM3		;100
	*
	K INT
	M 9
	RM C
	-
	F X!=0 A3
	RM 9
	M C
	K RM 4		; инкремент R4 - признак перерисовки
	P GSB RIS_S
A3:	 
	RM 4
	P X!=0 A00
	K GRPH
	P GOTO A0

; Отрисовка часов
RIS_H:
	20
	ENT
	30
	K M 7		;PP M 9000 - Начальные координаты 
	2
	PP M 9003	; Номер шрифта 
	RM A
	P GSB RIS
	20
	ENT
	56
	K M 7		;PP M 9000 - Начальные координаты
	58
	PP M 9020	; двоеточие
	RM A
	F X=0 RISH1
	GOTO RIS_D	
RISH1:	RTN

; Отрисовка минут
RIS_M:
	20
	ENT
	64
	K M 7		;PP M 9000 - Начальные координаты
	2
	PP M 9003	; Номер шрифта
	RM B
	P GSB RIS		
	P GOTO BUDIL		

; Отрисовка секунд
RIS_S:
	27
	ENT
	92
	K M 7		;PP M 9000 - Начальные координаты
	1
	PP M 9003	; Номер шрифта
	RM C
	P GOTO RIS	

; Отрисовка даты и дня недели
RIS_D:
	0
	ENT
	K M 7		;PP M 9000 - Начальные координаты
	PP M 9003
	PP RM 9056	; число
	P GSB RIS	
	46
	PP M 9020	; точка
	PP RM 9057	; месяц 
	P GSB RIS	
	46
	PP M 9020	; точка
	PP RM 9058	; год - полное значение (ПО МК-152 v1.09)
	RM3		; 100
	/
	P M 21
	K INT		; век
	P GSB RIS	
	P RM 21
	K FRAC
	RM3		; 100
	*		; год - две цифры
	P GSB RIS
	0
	ENT
	70
	K M 7		;PP M 9000 - начальные координаты
	PP RM 9059	; день недели

	; Выбор текста из таблицы
	2
	*
	.NUM DAYX
	+
	ENT
	K PRGM
	RM3		; 100
	*
	<->
	1
	+
	K PRGM
	+			; в RX - начало текста дня недели
	PP M 9021	
	10
	ENT
	0
	K M 7		;PP M 9000  - Начальные координаты
	10
	ENT
	127
	PP M 9012	; Вывод линии
	RTN

; Отрисовка строки будильника
RIS_B:
	52
	ENT
	0
	K M 7		;PP M 9000 - Начальные координаты
	<->		;52
	ENT
	127
	PP M 9012 	; линия

	P RM 20
	F X=0 RISB1
			; будильник выключен
	54
	ENT
	0
	K M 7		;PP M 9000 - Начальные координаты
	4
	PP M 9001	; Атрибуты вывода 4 - инверсия и замена
	8
	ENT
	128
	PP M 9013	; Вывод прямоугольника
	0
	PP M 9001	; Атрибуты вывода 0
	RTN

RISB1:
	; будильник включен
	55
	ENT
	0
	K M 7		;PP M 9000 - Начальные координаты
	.NUM KOLOK
	PP M 9015	; Вывод колокольчика
	54
	ENT
	10
	K M 7		;PP M 9000 - Начальные координаты
	0
	PP M 9003	; Номер шрифта 
	RM 0
	K INT
	GSB RIS
	58
	PP M 9020	; Вывод двоеточия
	RM 0
	K FRAC
	RM3		;100
	*
	GSB RIS
	55
	ENT
	70
	K M 7		;PP M 9000 - Начальные координаты
	.NUM SIGMA
	PP M 9015	; сигма
	54
	ENT
	78
	K M 7		;PP M 9000 - Начальные координаты
	.NUM RAVNO
	PP M 9021	; Вывод знака равенства
	RM 1
	PP M 9023	; Вывод значения сигмы
	.NUM MINUT
	PP M 9021	; Вывод размерности
	RTN

; Подпрограмма вывода двузначного числа из RX
RIS:
	10
	/
	M 8
	K FRAC
	10
	*
	48
	+
	M 9
	RM 8
	K INT
	48
	+
	PP M 9020	; Вывод символа
	RM 9
	PP M 9020	; Вывод символа
	RTN

; Проверка будильника
BUDIL:	 
	P RM 20
	P X!=0 BUDIL1

	; будильник включен
	RM 6
	RM3		;100
	*
	K INT
	RM A
	RM 3		;100
	*
	RM B
	+
	-
	F X!=0 BUDIL2
	CX
	PP M 9150	; Запретить прерывания таймера 0
BUDIL1:  RTN

BUDIL2:	 
	.NUM TIMER0		; Вектор прерывания - номер страницы
	ENT
	1
	PP M 9131	; Прерывание 1 - вектор TIMER0 приоритет 1
	PP M 9150	; Таймер 0 на прерывании 1
	PP M 9149	; Вызвать прерывание 1

; Установить реальное время срабатывания будильника 
VREMJA:	 
	1
	PP M 9045	; Размерность - радианы
VREMJA1:	 
	K RAN
	F X!=0 VREMJA1	; Исключить деление на 0
	F 1/X
	F LN
	2
	*
	F SQRT
	K RAN
	2
	*
	F PI
	*
	F COS
	*
	RM 1
	60
	/
	*
	M 8
	K ABS
	24
	-
	F X>=0 VREMJA2	; Отклонение не более суток
	CX
	M 8
VREMJA2:	
	RM 8
	RM 0
	K M->D
	+
	F X<=0 VREMJA3
	24
	+
VREMJA3:	
	M 9
	24
	-
	F X<=0 VREMJA4
	RM 9
VREMJA4:	
	K D->M
	RM 3		;100
	*
	0,5
	+
	K INT
	RM 3		;100
	/
	M 6
	RTN

; Строки
KOLOK: .DB 5, 8, 32, 62, 127, 62, 32 ; Символ колокольчика
SIGMA: .DB 5, 8, 28, 34, 34, 26, 1	; Сигма

RAVNO: .TEXT "= \0"
MINUT: .TEXT " мин.\0"


; Прерывание таймера
TIMER0:
	50
	PP M 9050	;  Переустановить таймер 0
	2000
	ENT
	25
	PP M 9052	; Звук
	PP RTN

; Строки
DAY1: 	.TEXT "Понедельник\0"
DAY2:  .TEXT "Вторник\0"
DAY3:  .TEXT "Среда\0"
DAY4:  .TEXT "Четверг\0"
DAY5:  .TEXT "Пятница\0"
DAY6:  .TEXT "Суббота\0"
DAY7:  .TEXT "Воскресенье\0"
DAYX:	.DA	0, DAY1, DAY2, DAY3, DAY4, DAY5, DAY6, DAY7	; Таблица адресов

; Прерывание клавиатуры
KLAVA:
	P RM 20
	F X=0 KLAVA1
	1
	P M 20
	GOTO KLAVA2
KLAVA1:
	CX
	P M 20
	PP M 9150	; Запретить таймер 0 (выключить будильник)
KLAVA2:	
	P GSB RIS_B
	K GRPH
	PP RTN
	.END 


НПП "СЕМИКО" (383) 271-01-25 (многоканальный)