Давненько мы не задавали жару в виде наших хитрых задачек готовым "бонусным" роботам. Одной из интереснейших "домашних" EV3-моделей является BANNER PRINT3R, инструкцию по сборке и базовую программу для нее подготовил Ральф Хемпел. Этот робот умеет писать EV3 LEGO MINDSTORMS на чековой ленте, ловко доставая ее из рулона.
Мы долго думали, чем бы озадачить данного робота, какие интересные дополнения внести в конструкцию и вспомнили об одном из наших ранних проектов в цикле "Строим из микроконтроллеров" под названием "Азбука Морзе на базе Arduino":
Нам показалось, что будет очень интересно совместить распознавание кода Морзе с печатью распознанных букв на ленте - получится телеграф.
Конструкцию печатающего узла мы оставили практически без изменений, немного доработав ее под более широкую ленту (именно такая попалась нам в магазине). Блок EV3 разместили таким образом, чтобы хорошо был виден экран, добавили датчик-кнопку для ввода точек и тире. Исходную инструкцию по сборке BANNER PRINT3R можно посмотреть в разделе "Больше роботов" в домашней версии ПО или скачать здесь.
Мы нигде не нашли как заправляется бумага в данный аппарат, но методом проб и ошибок выяснили, что наиболее оптимальной схемой выглядит следующая:
Если вы помните, то мы потихоньку перебрались с EV3-G на текстовое программирование, это связано с тем что проекты становятся все сложнее и реализовать все задумки в EV3-G оказывается если и возможно, то крайне трудоемко. Поэтому программировать в данном проекте мы будем на языке EV3 Basic.
Скачать нашу программу можно по ссылке.
Общую схему работы нашего "EV3 Телеграфа" вы можете посмотреть на картинке ниже.
Распознаватель кода Морзе анализирует нажатия на датчик-кнопку, выделяет короткие и длинные нажатия, короткие паузы между элементами кода в буксе и длинные паузы между буквами. Далее приведен код распознавателя:
While "True"
m[0] = 0
m[1] = 0
m[2] = 0
m[3] = 0
m[4] = 0
m[5] = 0
X = 0
P = EV3.Time
While next_letter
If Sensor.ReadPercent(1) > 50 Then
If A = 0 Then
A = EV3.Time
Speaker.Note(100,"E5",10000)
Program.Delay(50)
EndIf
P = EV3.Time
EndIf
If Sensor.ReadPercent(1) = 0 And A > 0 Then
If B = 0 Then
B = EV3.Time
Speaker.Stop()
Program.Delay(50)
EndIf
P = EV3.Time
EndIf
If A > 0 And B > 0 Then
T = B - A
If T > 500 Then
m[X] = 2
Else
m[X] = 1
EndIf
A = 0
B = 0
X = X+1
P = EV3.Time
EndIf
If EV3.Time - P >= 2000 Or X > 5 Then
next_letter = "False"
EndIf
EndWhile
В массив m мы записываем 1 для точек и 2 для тире. Остальные, невостребованные в букве элементы заполняются нулями.
Руководствуясь кодом Морзе для русского алфавита
мы закодировали коды Морзе для всех русских букв в массивы b1 .. b33
'a
b1[0] = 1
b1[1] = 2
b1[2] = 0
b1[3] = 0
b1[4] = 0
b1[5] = 0
'б
b2[0] = 2
b2[1] = 1
b2[2] = 1
b2[3] = 1
b2[4] = 0
b2[5] = 0
После того, как получена длинная пауза или ведены все 6 символов кода буквы анализируем совпадение элементов массива m (буфера) с элементами массивов b1 .. b33 используя конструкцию вида
h = "True"
For I = 0 To 5
If m[i] <> b1[i] Then
h = "False"
EndIf
EndFor
If h = "True" Then
Speaker.Play(100,"EV3Telegraph/b1")
LCD.BmpFile(1,0,0,"EV3Telegraph/b1")
BO = 1
BOprint()
EndIf
Данный код при совпадении массивов выводит на экран распознанную букву, произносит ее и запускает процедуру добавления в очередь печати:
Sub BOprint
i = 0
While O[i] <> 0
If O[i] <> 0 Then
i = i + 1
EndIf
EndWhile
O[i] = BO
EndSub
Блок "драйвера" принтера работает с очередью печати, забирая первую букву, если очередь не пустая и выводит ее на печать
Sub Printer
While "True"
If O[0] = 1 Then
b1()
Clear()
EndIf
...
If O[0] = 32 Then
b32()
Clear()
EndIf
EndWhile
EndSub
После печати буквы она удаляется из очереди, а вся очередь сдвигается после этого влево, чтобы "драйвер печати".обработал следующую букву в очереди:
Sub Clear
i = 0
While O[i] <> 0
O[i] = O[i+1]
i = i + 1
EndWhile
EndSub
Для печати буквы используем процедуры движения по осям MoveX() и MoveY()
Sub MoveX
If XM > 0 Then
Motor.Move("C",-50,XM,"True")
Else
Motor.Move("C",50,-1 * XM,"True")
EndIf
EndSub
Sub MoveY
If YM > 0 Then
Motor.Move("A",50,YM,"True")
Else
Motor.Move("A",-50,-1 * YM,"True")
EndIf
EndSub
Процедура MoveXY() позволяет рисовать наклонные линии
Sub MoveXY
If YM > 0 Then
For j = 1 To XM / 5
Motor.Move("A",50,5,"True")
Motor.Move("C",-50,-5,"True")
EndFor
Else
For j = 1 To XM / 5
Motor.Move("A",-50,-5,"True")
Motor.Move("C",-50,-5,"True")
EndFor
EndIf
EndSub
Для поднимания и опускания маркера (ручки) используем процедуру PenMotor()
Sub PenMotor
tM = EV3.Time
regulator = "True"
If pen = "True" Then
PM = 150
Else
PM = 0
EndIf
While regulator
eM = PM - Motor.GetCount("B")
vM = eM * kM
Motor.Start("B",vM)
If Math.Abs(Motor.GetCount("B") - PM) < 5 Then
regulator = "False"
EndIf
If EV3.Time - tM > 1000 Then
regulator = "False"
EndIf
EndWhile
Motor.Stop("B","True")
EndSub
В качестве примера, чтобы нарисовать букву "И" требуется выполнить следующую последовательность вызова процедур:
Sub b9
Y = 300
MoveY()
pen = "True"
PenMotor()
Y = -300
MoveY()
Y = 300
X = 300
MoveXY()
Y = -300
MoveY()
pen = "False"
PenMotor()
X = 100
MoveX()
EndSub
Многие задают нам вопрос - почему наши видео выходят все реже. Дело в том что проекты становятся все сложнее и требуют больше времени на их подготовку. Кстати, если у вас возникнут интересные идеи по новым проектам - пишите, мы открыты к реализации интересных идей.
Мы долго думали, чем бы озадачить данного робота, какие интересные дополнения внести в конструкцию и вспомнили об одном из наших ранних проектов в цикле "Строим из микроконтроллеров" под названием "Азбука Морзе на базе Arduino":
Конструкцию печатающего узла мы оставили практически без изменений, немного доработав ее под более широкую ленту (именно такая попалась нам в магазине). Блок EV3 разместили таким образом, чтобы хорошо был виден экран, добавили датчик-кнопку для ввода точек и тире. Исходную инструкцию по сборке BANNER PRINT3R можно посмотреть в разделе "Больше роботов" в домашней версии ПО или скачать здесь.
Мы нигде не нашли как заправляется бумага в данный аппарат, но методом проб и ошибок выяснили, что наиболее оптимальной схемой выглядит следующая:
Если вы помните, то мы потихоньку перебрались с EV3-G на текстовое программирование, это связано с тем что проекты становятся все сложнее и реализовать все задумки в EV3-G оказывается если и возможно, то крайне трудоемко. Поэтому программировать в данном проекте мы будем на языке EV3 Basic.
Скачать нашу программу можно по ссылке.
Общую схему работы нашего "EV3 Телеграфа" вы можете посмотреть на картинке ниже.
Распознаватель кода Морзе анализирует нажатия на датчик-кнопку, выделяет короткие и длинные нажатия, короткие паузы между элементами кода в буксе и длинные паузы между буквами. Далее приведен код распознавателя:
While "True"
m[0] = 0
m[1] = 0
m[2] = 0
m[3] = 0
m[4] = 0
m[5] = 0
X = 0
P = EV3.Time
While next_letter
If Sensor.ReadPercent(1) > 50 Then
If A = 0 Then
A = EV3.Time
Speaker.Note(100,"E5",10000)
Program.Delay(50)
EndIf
P = EV3.Time
EndIf
If Sensor.ReadPercent(1) = 0 And A > 0 Then
If B = 0 Then
B = EV3.Time
Speaker.Stop()
Program.Delay(50)
EndIf
P = EV3.Time
EndIf
If A > 0 And B > 0 Then
T = B - A
If T > 500 Then
m[X] = 2
Else
m[X] = 1
EndIf
A = 0
B = 0
X = X+1
P = EV3.Time
EndIf
If EV3.Time - P >= 2000 Or X > 5 Then
next_letter = "False"
EndIf
EndWhile
В массив m мы записываем 1 для точек и 2 для тире. Остальные, невостребованные в букве элементы заполняются нулями.
Руководствуясь кодом Морзе для русского алфавита
мы закодировали коды Морзе для всех русских букв в массивы b1 .. b33
'a
b1[0] = 1
b1[1] = 2
b1[2] = 0
b1[3] = 0
b1[4] = 0
b1[5] = 0
'б
b2[0] = 2
b2[1] = 1
b2[2] = 1
b2[3] = 1
b2[4] = 0
b2[5] = 0
После того, как получена длинная пауза или ведены все 6 символов кода буквы анализируем совпадение элементов массива m (буфера) с элементами массивов b1 .. b33 используя конструкцию вида
h = "True"
For I = 0 To 5
If m[i] <> b1[i] Then
h = "False"
EndIf
EndFor
If h = "True" Then
Speaker.Play(100,"EV3Telegraph/b1")
LCD.BmpFile(1,0,0,"EV3Telegraph/b1")
BO = 1
BOprint()
EndIf
Данный код при совпадении массивов выводит на экран распознанную букву, произносит ее и запускает процедуру добавления в очередь печати:
Sub BOprint
i = 0
While O[i] <> 0
If O[i] <> 0 Then
i = i + 1
EndIf
EndWhile
O[i] = BO
EndSub
Блок "драйвера" принтера работает с очередью печати, забирая первую букву, если очередь не пустая и выводит ее на печать
Sub Printer
While "True"
If O[0] = 1 Then
b1()
Clear()
EndIf
...
If O[0] = 32 Then
b32()
Clear()
EndIf
EndWhile
EndSub
После печати буквы она удаляется из очереди, а вся очередь сдвигается после этого влево, чтобы "драйвер печати".обработал следующую букву в очереди:
Sub Clear
i = 0
While O[i] <> 0
O[i] = O[i+1]
i = i + 1
EndWhile
EndSub
Для печати буквы используем процедуры движения по осям MoveX() и MoveY()
Sub MoveX
If XM > 0 Then
Motor.Move("C",-50,XM,"True")
Else
Motor.Move("C",50,-1 * XM,"True")
EndIf
EndSub
Sub MoveY
If YM > 0 Then
Motor.Move("A",50,YM,"True")
Else
Motor.Move("A",-50,-1 * YM,"True")
EndIf
EndSub
Процедура MoveXY() позволяет рисовать наклонные линии
Sub MoveXY
If YM > 0 Then
For j = 1 To XM / 5
Motor.Move("A",50,5,"True")
Motor.Move("C",-50,-5,"True")
EndFor
Else
For j = 1 To XM / 5
Motor.Move("A",-50,-5,"True")
Motor.Move("C",-50,-5,"True")
EndFor
EndIf
EndSub
Для поднимания и опускания маркера (ручки) используем процедуру PenMotor()
Sub PenMotor
tM = EV3.Time
regulator = "True"
If pen = "True" Then
PM = 150
Else
PM = 0
EndIf
While regulator
eM = PM - Motor.GetCount("B")
vM = eM * kM
Motor.Start("B",vM)
If Math.Abs(Motor.GetCount("B") - PM) < 5 Then
regulator = "False"
EndIf
If EV3.Time - tM > 1000 Then
regulator = "False"
EndIf
EndWhile
Motor.Stop("B","True")
EndSub
В качестве примера, чтобы нарисовать букву "И" требуется выполнить следующую последовательность вызова процедур:
Sub b9
Y = 300
MoveY()
pen = "True"
PenMotor()
Y = -300
MoveY()
Y = 300
X = 300
MoveXY()
Y = -300
MoveY()
pen = "False"
PenMotor()
X = 100
MoveX()
EndSub
Многие задают нам вопрос - почему наши видео выходят все реже. Дело в том что проекты становятся все сложнее и требуют больше времени на их подготовку. Кстати, если у вас возникнут интересные идеи по новым проектам - пишите, мы открыты к реализации интересных идей.
Комментариев нет:
Отправить комментарий