Как подключить светодиод к Arduino
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Подключение кнопки

Для сборки модели нам потребуется:

· плата Arduino

· Breadboard

· 5 проводов и/или перемычек «папа-папа»

· светодиод

· кнопка

· резисторы на 10 кОм и 220 Ом.

Что понадобится для подключения кнопки на Arduino?

Схема подключения модели Arduino с кнопкой и светодиодом:

Схема подключения кнопки и светодиода на Arduino

Для работы этой модели подойдет следующая программа (программу вы можете просто скопировать в Arduino IDE):


int button = 2;
int led = 8;
void setup() {
pinMode(led, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
if (digitalRead(button) == HIGH) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}

 

Так выглядит собранная модель Arduino кнопки со светодиодом:

Готовая модель с кнопкой и светодиодом на Arduino

 















Простая пищалка с кнопкой

 

Из схемы мигалки с кнопкой, что осталась от предыдущего примера,

удалим внешний светодиод и вместо него к выводу 13 подключим пье-

зоизлучатель звука (пьезозвонок). Второй вывод звонка подключим к

свободному выводу «земли» GND, на противоположной стороне платы

Uno (см. рисунок вверху).

Теперь загрузим Arduino IDE и создадим новый проект (Файл | Новый).

Сохраним его под названием, например, pischalka. В начале программы

определим два вывода:

#define BUZZER_PIN 13 // вывод для пищалки (англ. «buzzer»)

#define BUTTON_PIN 3 //вывод подключения кнопки

В функции setup определяем назначение этих выводов: BUZZER_

PIN – на выход, BUTTON_PIN, как и ранее, на вход с подтягивающим

резистором:

void setup() {

pinMode(BUZZER_PIN, OUTPUT); // на выход

pinMode(BUTTON_PIN, INPUT_PULLUP); // вывод кнопки на вход

}

И, наконец, в основном цикле отслеживаем состояние кнопки и

в зависимости от этого включаем или останавливаем звук:

void loop() {

 if (digitalRead(BUTTON_PIN) == LOW) { // кнопка нажата

tone(BUZZER_PIN, 1000); //частота 1000 Гц на пищалку

}

 else { //кнопка отпущена

 noTone(BUZZER_PIN);//прекращаем генерацию;

}

}

Загрузите программу в контроллер и проверьте ее работу. Простейшие
пьезоизлучатели, вроде пьезозвонка, который мы здесь используем, формально говоря, имеют довольно узкий диапазон рабочих частот -
от 1 до 3–4 кГц, и хотя схема будет работать с практически любой
заданной частотой в пределах звукового диапазона, но наиболее разборчивый звук вы получите именно при таких частотах (они соответствуют второй-третьей октавам музыкального ряда).

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

void loop() {

if (digitalRead(BUTTON_PIN) == LOW) { // кнопка нажата

tone(BUZZER_PIN, 1000); //частота 1000 Гц на пищалку




ОБЗОР МОДУЛЯ

Модуль представляет собой небольшую плату, на которой установлен LED 4-х разрядный семисегментный дисплей на основе одноименного i2c драйвера TM1637.

Внешне конструкция довольно простая, и на этом останавливаться сильно не будем. Разве что, можно отметить, что продается модуль иногда и в качестве 8-разрядной версии, которая будет занимать больше выводов для подключения к Arduino.

Также на некоторых дисплеях, например от RobotDyn, на дисплее имеется также и часовой разделитель в виде двоеточия. Именно поэтому очень широкое применение индикатор TM1637 нашел в DIY часах на Arduino.

СХЕМА ПОДКЛЮЧЕНИЯ

Благодаря наличию i2c интерфейса на борту, подключается модуль очень просто – с помощью четырех контактов. Два из них отвечают за питание и подключаются к выводам 5V и Gnd на панели Power нашего контроллера; два других, называются они CLK и DIO, подключатся к цифровым выводам, например 3 и 2, соответственно.

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

ПОДКЛЮЧЕНИЕ В ARDUINO IDE

Перед тем, как начинать писать программный код, а затем уже и ломать голову над более сложными проектами, необходимо загрузить специализированную библиотеку для нашего дисплея – tm1637.h: СКАЧАТЬ

Одновременно с загруженной библиотекой в папке «примеры» появятся три новых кода для ознакомления и проверки работоспособности. Познакомимся с одним из них.

Приведенный ниже код выводит на дисплей любые 4 символа, которые мы пропишем перед компиляцией, а также включает и выключает часовой разделитель с задержкой в 1 секунду (1000 миллисекунд):

Код для вывода на дисплей любых 4 символов

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include "TM1637.h" // Подключаем библиотеку для работы с модулем int8_t DispMSG[] = {1, 2, 3, 4}; // Настройка символов для последующего вывода на дислей //Определяем пины для подключения к плате Arduino #define CLK 3 #define DIO 2 //Создаём объект класса TM1637, в качестве параметров //передаём номера пинов подключения TM1637 tm1637(CLK, DIO); void setup() { //Инициализация модуля tm1637.init(); //Установка яркости горения сегментов /* BRIGHT_TYPICAL = 2 Средний BRIGHT_DARKEST = 0 Тёмный BRIGHTEST = 7 Яркий */ tm1637.set(BRIGHT_TYPICAL); } void loop() { //Задание на включение разделителя tm1637.point(true); //Выводим массив на дисплей tm1637.display(DispMSG); //Задержка delay(1000); //Задание на выключение разделителя tm1637.point(false); //Выводим массив на дисплей tm1637.display(DispMSG); //Задержка delay(1000); }

После загрузки и успешной компиляции данного кода, мы увидим цифры 1, 2, 3, 4 на LED экране.

Функции работы с АЦП

На этом уроке изучать работу АЦП мы будем с помощью платформы Arduino. В используемой нами модели Arduino Uno, наряду с обычными выводами общего назначения (к которым мы уже подключали светодиоды и кнопки) есть целых шесть аналоговых входов. В других версиях Arduino таких входов может быть и больше, например, у Arduino Mega их 16.

На карте Arduino Uno аналоговые входы имеют буквенно-цифровые обозначения A0, A1, …, A5 (снизу слева).

Во время работы всё с теми же кнопками, мы познакомились с функцией digitalRead, которая умеет считывать цифровой сигнал с определенного входа контроллера. У этой функции существует аналоговая версия analogRead, которая может делать то же самое, но только для аналогового сигнала.

результат = analogRead( номер_контакта );

после вызова этой функции, микроконтроллер измерит уровень аналогового сигнала на заданном контакте, и сохранит результат работы АЦП в переменную «результат». При этом результатом функции analogRead будет число от 0 до 1023.

Разрядность АЦП

Надо заметить, что число 1023 здесь появилось неспроста. Дело в том, что у каждого устройства АЦП есть такой важный параметр как разрядность. Чем больше значение этого параметра, тем точнее работает прибор. Предположим, что у нас есть АЦП с разрядностью 1. Подавая на вход любое напряжения от 0 до 2,5 Вольт, на выходе мы получим 0. Любое же напряжение от 2,5 до 5 вольт даст нам единицу. То есть 1-битный АЦП сможет распознать только два уровня напряжения. Графически это можно изобразить следующим образом:

АЦП с разрядностью 2 распознает уже четыре уровня напряжения:

§ от 0 до 1,25 — это 0;

§ от 1,25 до 2,5 — это 1;

§ от 2,5 до 3,75 — это 2;

§ наконец, от 3,75 до 5 — это 3.

На следующих двух картинках изображена работа АЦП с разрядностью 2 и 3 бит:

В Arduino Uno установлен 10-битный АЦП, и это значит, что любое напряжение на аналоговом входе в диапазоне от 0 до 5 вольт будет преобразовано в число с точностью 1/1024 вольта. На графике будет сложно изобразить столько ступенек. Имея такую точность, 10-битный АЦП может «почувствовать» изменение напряжение на входе величиной всего 5 милливольт.

3. Опорное напряжение
Есть нюанс, который может стать причиной ошибки измерения с помощью АПЦ. Помните тот диапазон от 0 до 5 вольт в котором работает устройство? В общем случае этот диапазон выглядит иначе:
от 0 до опорного напряжения
Это изменение повлечет за собой изменение формулы расчет точности АЦП:
точность = опорное напряжение/1024
Опорное напряжение определяет границу диапазона, с которым будет работать АЦП.
В нашем примере опорное напряжение будет равно напряжению питания Arduino Uno, которое дал USB порт компьютера. В конкретном случае это напряжение было 5.02 Вольта, и можно сказать, что измерили заряд батарейки с высокой точностью.
Что если вы питаете микроконтроллер от другого источника? Допустим у вас есть четыре NiMh аккумулятора на 1.2 Вольта. В сумме они дадут 4.8 Вольта (пусть они немного разряжены, ведь в действительности их заряжают до 1.4 Вольта). Точность измерения будет равна 4.8/1024. Это следует учесть в нашей программе.
Наконец рассмотрим случай, когда мы питаем Arduino Uno одним напряжением, а в качестве опорного хотим установить совсем другое, например, 3.3 Вольта. Что делать? Для такого варианта на Arduino Uno есть специальный вывод Vref. Чтобы решить проблему, нам нужно подать на этот контакт напряжение 3.3 Вольта, и разрешить использование внешнего источника опорного напряжения функцией:

analogReference(EXTERNAL);

которую следует вызвать внутри функции setup нашей программы.
Также следует учитывать, что результат измерения значения напряжения не может превышать границы диапазона. Если мы выбираем в качестве опорного напряжения 3.3 Вольта, а поступающий сигнал будет с большим напряжением, то мы получим неправильное значение напряжения, поскольку АЦП «не знает» о наличии более высокого напряжения.










Программа

Наша первая программа с использованием АЦП будет крайне простой: каждую секунду мы будем измерять аналоговое значение на входе A0, и передавать его в последовательный порт.

int val = 0;

void setup() {

Serial.begin(9600);

pinMode(A0, INPUT);

}

void loop() {

val = analogRead(A0);

Serial.println(val);

delay(1000);

}

Теперь загружаем программу на Arduino, и переходим к измерениям.

Подключение

Чтобы измерить напряжение на батарейке, мы должны подключить её к нашей Arduino всего двумя контактами. Для примера используем щелочную батарейку на 1.5 Вольта.

Теперь откроем окно COM-монитора в Arduino IDE, и посмотрим какие значение выдает нам АЦП:

 

Что означает число 314? Вспомним, что 10-битный АЦП разбивает диапазон от 0 до 5 вольт на 1024 части. Значит точность 10-битного АЦП — 5/1024. Зная точность, мы можем записать формулу для преобразования показаний АЦП к вольтам:
V = (5/1024)*ADC
где V — измеренное напряжение на батарейке;
ADC — результат работы функции analogRead.
Подставим эту формулу в программу и снова попробуем измерить заряд батарейки!

int val = 0;

void setup() {

Serial.begin(9600);

pinMode(A0, INPUT);

}

void loop() {

val = analogRead(A0);

Serial.println((5/1024.0)*val);

delay(1000);

}

Результат измерений:

Этот результат выглядит уже более понятно1.





Класс Tk

Tk является базовым классом любого Tkinter приложения. При создании объекта этого класса запускается интерпретатор tcl/tk и создаётся базовое окно приложения.
Tkinter является событийно-ориентированной библиотекой. В приложениях такого типа имеется главный цикл обработки событий. В Tkinter такой цикл запускается методом mainloop. Для явного выхода из интерпретатора и завершения цикла обработки событий используется метод quit.
Таким образом минимальное приложение на Tkinter будет таким:

from tkinter import *
root = Tk()
root . mainloop ()

  





Button

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

 

from Tkinter import *

root=Tk()

button1=Button(root,text='ok',14')

Button1.pack()

Root.mainloop()

 

Разберем этот небольшой код. За создание, собственно, окна, отвечает класс Tk(), и первым делом нужно создать экземпляр

этого класса. Этот экземпляр принято называть root, хотя вы можете назвать его как угодно. Далее создаётся кнопка, при

этом мы указываем её свойства (начинать нужно с указания окна, в примере - root). Здесь перечислены некоторые из них:

text - какой текст будет отображён на кнопке (в примере - ок)

width,height - соответственно, ширина и длина кнопки.

bg - цвет кнопки (сокращенно от background, в примере цвет - чёрный)

fg - цвет текста на кнопке (сокращённо от foreground, в примере цвет - красный)

font - шрифт и его размер (в примере - arial, размер - 14)

Далее, нашу кнопку необходимо разместить на окне. Для этого, в Tkinter используются специальные упаковщики( pack(),

place(), grid() ). Поподробнее об упаковщиках узнаем позже. Пока, чтобы разместить несколько виджетов на окне, будем

применять самый простой упаковщик pack(). В конце программы, нужно использовать функцию mainloop (см. пример),

иначе окно не будет создано.

 

Label

Label - это виджет, предназначенный для отображения какой-либо надписи без возможности редактирования пользователем.

Имеет те же свойства, что и перечисленные свойства кнопки.

 

Entry

Entry - это виджет, позволяющий пользователю ввести одну строку текста. Имеет дополнительное свойство bd (сокращённо от borderwidth), позволяющее регулировать ширину границы.

borderwidth - ширина бордюра элемента

bd - сокращение от borderwidth

width - задаёт длину элемента в знакоместах.

show - задает отображаемый символ.

 

Text

Text - это виджет, который позволяет пользователю ввести любое количество текста. Имеет дополнительное свойство wrap,

отвечающее за перенос (чтобы, например, переносить по словам, нужно использовать значение WORD). Например:

 

from Tkinter import *

root=Tk()

text1=Text(root,height=7,14',wrap=WORD)

Text1.pack()

Root.mainloop()

 

Методы insert, delete и get добавляют, удаляют или извлекают текcт. Первый аргумент - место вставки в виде 'x.y', где x – это

строка, а y – столбец. Например:

 

text 1. insert (1.0,'Добавить Текст \ n \ в начало первой строки' )

Text1.delete('1.0', END) # Удалить все

Text1.get('1.0', END) # Извлечь все

 

Listbox

Listbox - это виджет, который представляет собой список, из элементов которого пользователь может выбирать один или

несколько пунктов. Имеет дополнительное свойство selectmode, которое, при значении SINGLE, позволяет пользователю

выбрать только один элемент списка, а при значении EXTENDED - любое количество. Пример:

 

from Tkinter import *

root=Tk()

listbox1=Listbox(root,height=5,

listbox2=Listbox(root,height=5,

list1=[u"Москва",u"Санкт-Петербург" ,u"Саратов",u"Омск"]

list2=[u"Канберра",u"Сидней",u"Мельбурн",u"Аделаида"]

For i in list1:

listbox1.insert(END,i)

For i in list2:

listbox2.insert(END,i)

Listbox1.pack()

Listbox2.pack()

Root.mainloop()

 

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

строки. В Python 2.x для этого нужно перед строкой поставить букву u, в Python 3.x этого делать вообще не требуется, т.к.

все строки в нем изначально Unicode. Кроме того в первой или второй строке файла необходимо указать кодировку файла (в комментарии): coding: utf-8. Чаще всего используется формат в стиле текстового редактора emacs:

# encoding : utf -8

В Python 3.x кодировку файла можно не указывать, в этом случае по умолчанию предполагается utf-8.

 

Frame

Виджет Frame (рамка) предназначен для организации виджетов внутри окна. Рассмотрим пример:

 

from tkinter import *

root=Tk()

frame1=Frame(root,bg='green',bd=5)

frame2=Frame(root,bg='red',bd=5)

button1=Button(frame1,text=u'Первая кнопка' )

button2=Button(frame2,text=u'Вторая кнопка' )

Frame1.pack()

Frame2.pack()

Button1.pack()

Button2.pack()

Root.mainloop()

Свойство bd отвечает за толщину края рамки.

 

Checkbutton

Checkbutton - это виджет, который позволяет отметить „галочкой“ определенный пункт в окне. При использовании

нескольких пунктов нужно каждому присвоить свою переменную. Разберем пример:

 

from tkinter import *

root=Tk()

var1=IntVar()

var2=IntVar()

check1=Checkbutton(root,text=u'1 пункт',variable=var1,onvalue=1,offvalue=0)

check2=Checkbutton(root,text=u'2 пункт',variable=var2,onvalue=1,offvalue=0)

Check1.pack()

Check2.pack()

Root.mainloop()

 

IntVar() - специальный класс библиотеки для работы с целыми числами. variable - свойство, отвечающее за прикрепление к

виджету переменной. onvalue, offvalue - свойства, которые присваивают прикреплённой к виджету переменной значение,

которое зависит от состояния(onvalue - при выбранном пункте, offvalue - при невыбранном пункте).

 

Radiobutton

Виджет Radiobutton выполняет функцию, схожую с функцией виджета Checkbutton. Разница в том, что в виджете Radiobutton

пользователь может выбрать лишь один из пунктов. Реализация этого виджета несколько иная, чем виджета Checkbutton:

 

from tkinter import *

root=Tk()

var=IntVar()

rbutton1=Radiobutton(root,text='1',variable=var,value=1)

rbutton2=Radiobutton(root,text='2',variable=var,value=2)

rbutton3=Radiobutton(root,text='3',variable=var,value=3)

Rbutton1.pack()

Rbutton2.pack()

Rbutton3.pack()

Root.mainloop()

 

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

Самое интересное, что если присвоить этой переменной какое-либо значение, поменяется и выбранный виджет. На этом мы

прервём изучение типов виджетов (потом мы к ним обязательно вернёмся).

 

Scale

Scale (шкала) - это виджет, позволяющий выбрать какое-либо значение из заданного диапазона. Свойства:

orient - как расположена шкала на окне. Возможные значения: HORIZONTAL, VERTICAL (горизонтально,

вертикально).

length - длина шкалы.

from_ - с какого значения начинается шкала.

to - каким значением заканчивается шкала.

tickinterval - интервал, через который отображаются метки шкалы.

resolution - шаг передвижения (минимальная длина, на которую можно передвинуть движок)

Пример кода:

 

from tkinter import *

root = Tk()

Def getV(root):

a = scale1.get()

print "Значение", a

scale1 = Scale(root,orient=HORIZONTAL,length=300,from_=50,to=80,tickinterval=5,

 resolution=5)

button1 = Button(root,text=u"Получить значение" )

Scale1.pack()

Button1.pack()

button1.bind("<Button-1>",getV)

Root.mainloop()

 

Здесь используется специальный метод get(), который позволяет снять с виджета определенное значение, и используется не только в Scale.

 

Scrollbar

Scrollbar – этот виджет даёт возможность пользователю "прокрутить" другой виджет (например текстовое поле) и часто бывает

полезен. Использование этого виджета достаточно нетривиально. Необходимо сделать две привязки: command полосы

прокрутки привязываем к методу xview/yview виджета, а xscrollcommand/yscrollcommand виджета привязываем к методу set

полосы прокрутки.

Рассмотрим на примере:

from tkinter import *

root = Tk()

text = Text(root, height=3,

text.pack(side='left')

scrollbar = Scrollbar(root)

scrollbar.pack(side='left')

# первая привязка

scrollbar['command'] = text.yview

# вторая привязка

text['yscrollcommand' ] = scrollbar.set

Root.mainloop()

 

Упаковщики

Упаковщик (менеджер геометрии, менеджер расположения) это специальный механизм, который размещает (упаковывает)виджеты на окне. В Tkinter есть три упаковщика: pack, place, grid. Обратите внимание, что в одном виджете можно использовать только один тип упаковки, при смешивании разных типов упаковки программа, скорее всего, не будет работать.

Разберем каждый из них по порядку:

Pack()

Упаковщик pack() является самым интеллектуальным (и самым непредсказуемым). При использовании этого упаковщика с

помощью свойства side нужно указать к какой стороне родительского виджета он должен примыкать. Как правило этот

упаковщик используют для размещения виджетов друг за другом (слева направо или сверху вниз). Пример:

from tkinter import *

root=Tk()

button1 = Button(text="1")

button2 = Button(text="2")

button3 = Button(text="3")

button4 = Button(text="4")

button5 = Button(text="5")

button1.pack(side='left')

button2.pack(side='top')

button3.pack(side='left')

button4.pack(side='bottom')

button5.pack(side='right')

Root.mainloop()

 

Результат работы можно увидеть на скриншоте справа.

Для создания сложной структуры с использованием этого упаковщика обычно используют Frame,

вложенные друг в друга.

Аргументы:

При применении этого упаковщика можно указать следующие аргументы:

side ("left"/"right"/"top"/"bottom") - к какой стороне должен примыкать размещаемый виджет.

fill (None/"x"/"y"/"both") - необходимо ли расширять пространство предоставляемое виджету.

expand (True/False) - необходимо ли расширять сам виджет, чтобы он занял всё предоставляемое ему

пространство.

in_ - явное указание в какой родительский виджет должен быть помещён.

Дополнительные функции

Кроме основной функции у виджетов есть дополнительные методы для работы с упаковщиками.

pack_configure - синоним для pack.

pack_slaves (синоним slaves) - возвращает список всех дочерних упакованных виджетов.

pack_info - возвращает информацию о конфигурации упаковки.

pack_propagate (синоним propagate) (True/False) - включает/отключает распространении информации о

геометрии дочерних виджетов. По умолчанию виджет изменяет свой размер в соответствии с размером своих

потомков. Этот метод может отключить такое поведение (pack_propagate(False)). Это может быть полезно,

если необходимо, чтобы виджет имел фиксированный размер и не изменял его по прихоти потомков.[7]

pack_forget (синоним forget) - удаляет виджет и всю информацию о его расположении из упаковщика.

Позднее этот виджет может быть снова размещён.

 

Grid()

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

Аргументы:

row - номер строки, в который помещаем виджет.

rowspan - сколько строк занимает виджет

column - номер столбца, в который помещаем виджет.

columnspan - сколько столбцов занимает виджет.

padx / pady - размер внешней границы (бордюра) по горизонтали и вертикали.

ipadx / ipady - размер внутренней границы (бордюра) по горизонтали и вертикали. Разница между pad и ipad

в том, что при указании pad расширяется свободное пространство, а при ipad расширяется помещаемый

виджет.

sticky ("n", "s", "e", "w" или их комбинация) - указывает к какой границе "приклеивать" виджет. Позволяет

расширять виджет в указанном направлении. Границы названы в соответствии со сторонами света. "n"

(север) - верхняя граница, "s" (юг) - нижняя, "w" (запад) - левая, "e" (восток) - правая.

in_ - явное указание в какой родительский виджет должен быть помещён.

 

Для каждого виджета указываем, в какой он находится строке, и в каком столбце. Если нужно, указываем, сколько ячеек он

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

Пример:

 

entry1.grid(row=0,column=0,columnspan=3)

button1.grid(row=1,column=0)

button2.grid(row=1,column=1)

button3.grid(row=1,column=2)

 

Дополнительные функции

grid_configure - синоним для grid.

grid_slaves (синоним slaves) - см. pack_slaves.

grid_info - см. pack_info.

grid_propagate (синоним propagate) - см. pack_propagate.

grid_forget (синоним forget) - см. pack_forget.

grid_remove - удаляет виджет из-под управления упаковщиком, но сохраняет информацию об упаковке. Этот

метод удобно использовать для временного удаления виджета (см. пример в описании метода destroy).

grid_bbox (синоним bbox) - возвращает координаты (в пикселях) указанных столбцов и строк.[9]

grid_location (синоним location) - принимает два аргумента: x и y (в пикселях). Возвращает номер строки и

столбца в которые попадают указанные координаты, либо -1 если координаты попали вне виджета.

grid_size (синоним size) - возвращает размер таблицы в строках и столбцах.

grid_columnconfigure (синоним columnconfigure) и grid_rowconfigure (синоним rowconfigure) - важные

функции для конфигурирования упаковщика. Методы принимают номер строки/столбца и аргументы

конфигурации. Список возможных аргументов:

minsize - минимальная ширина/высота строки/столбца.

weight - "вес" строки/столбца при увеличении размера виджета. 0 означает, что строка/столбец не будет

расширяться. Строка/столбец с "весом" равным 2 будет расширяться вдвое быстрее, чем с весом 1.

uniform - объединение строк/столбцов в группы. Строки/столбцы имеющие одинаковый параметр uniform

будут расширяться строго в соответствии со своим весом.

pad - размер бордюра. Указывает, сколько пространства будет добавлено к самому большому виджету в

строке/столбце.

 

Пример, текстовый виджет с двумя полосами прокрутки:

 

from tkinter import *

root=Tk()

text = Text(wrap=NONE)

vscrollbar = Scrollbar(orient='vert', command=text.yview)

text['yscrollcommand' ] = vscrollbar.set

hscrollbar = Scrollbar(orient='hor', command=text.xview)

text['xscrollcommand' ] = hscrollbar.set

# размещаем виджеты

text.grid(row=0, column=0, sticky='nsew')

vscrollbar.grid(row=0, column=1, sticky='ns')

hscrollbar.grid(row=1, column=0, sticky='ew')

# конфигурируем упаковщик, чтобы текстовый виджет расширялся

root.rowconfigure(0, weight=1)

root.columnconfigure (0, weight=1)

Root.mainloop()

 

Place()

place представляет собой простой упаковщик, позволяющий размещать виджет в фиксированном месте с фиксированным

размером. Также он позволяет указывать координаты размещения в относительных единицах для реализации "резинового"

размещения. При использовании этого упаковщика, нам необходимо указывать координаты каждого виджета. Например:

 

button1.place(x=0,y=0)

 

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

Аргументы:

anchor ("n", "s", "e", "w", "ne", "nw", "se", "sw" или "center") - какой угол или сторона размещаемого виджета будет указана в аргументах x/y/relx/rely. По умолчанию "nw" - левый верхний

bordermode ("inside", "outside", "ignore") - определяет в какой степени будут учитываться границы при размещении виджета.

in_ - явное указание в какой родительский виджет должен быть помещён.

x и y - абсолютные координаты (в пикселях) размещения виджета.

width и height - абсолютные ширина и высота виджета.

relx и rely - относительные координаты (от 0.0 до 1.0) размещения виджета.

relwidth и relheight - относительные ширина и высота виджета.

 

Относительные и абсолютные координаты (а также ширину и высоту) можно комбинировать. Так например, relx=0.5,

x=-2 означает размещение виджета в двух пикселях слева от центра родительского виджета, relheight=1.0,

height=-2 - высота виджета на два пикселя меньше высоты родительского виджета.

Дополнительные функции:

place_slaves, place_forget, place_info - см. описание аналогичных методов упаковщика pack.

 

Привязка событий

Command

Для большинства виджетов, реагирующих на действие пользователя, активацию виджета (например нажатие кнопки) можно
привязать с использованием опции command. К таким виджетам относятся: Button, Checkbutton, Radiobutton, Spinbox,
Scrollbar, Scale. Выше мы уже неоднократно пользовались этим способом:
button = Button(command=callback )
Такой способ является предпочтительным и наиболее удобным способом привязки.


bind()

Метод bind[1] привязывает событие к какому-либо действию (нажатие кнопки мыши, нажатие клавиши на клавиатуре и т.д.).
bind принимает три аргумента:
название события
функцию, которая будет вызвана при наступлении события
третий аргумент (необязательный) - строка "+" - означает, что эта привязка добавляется к уже существующим.
Если третий аргумент опущен или равен пустой строке - привязка замещает все другие привязки данного
события к виджету.
Метод bind возвращает идентификатор привязки, который может быть использован в функции unbind.
Обратите внимание, что если bind привязан к окну верхнего уровня, то Tkinter будет обрабатывать события всех виджетов
этого окна (см. также bind_all ниже).
Функция, которая вызывается при наступлении события, должна принимать один аргумент. Это объект класса Event, в котором описано наступившее событие. Объект класса Event имеет следующие атрибуты (в скобках указаны события, для которых этот атрибут установлен):
serial - серийный номер события (все события)
num - номер кнопки мыши (ButtonPress, ButtonRelease)
focus - имеет ли окно фокус (Enter, Leave)
height и width - ширина и высота окна (Configure, Expose)
keycode - код нажатой клавиши (KeyPress, KeyRelease)
state - состояние события (для ButtonPress, ButonRelease, Enter, KeyPress, КeyRelease, Leave, Motion - в
виде числа; для Visibility - в виде строки)
time - время наступления события (все события)
x и y - координаты мыши
x _ root и y _ root - координаты мыши на экране (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
char - набранный на клавиатуре символ (KeyPress, KeyRelease)
send _ event - см. документацию по X/Windows
keysym - набранный на клавиатуре символ (KeyPress, KeyRelease)
keysym _ num- набранный на клавиатуре символ в виде числа (KeyPress, KeyRelease)
type - тип события в виде числа (все события)
widget - виджет, который получил событие (все события)
delta - изменение при вращении колеса мыши (MouseWheel)
Эта функция может возвращать строки "continue" и "break". Если функция возвращает "continue" то Tkinter продолжит обработку других привязок этого события, если "break" - обработка этого события прекращается. Если функция ничего не возвращает (если возвращает None), то обработка событий продолжается (т.е. это эквивалентно возвращению "continue").

Названия событий
Есть три формы названия событий. Самый простой случай это символ ASCII. Так описываются события нажатия клавиш на
клавиатуре:
widget . bind( "z" , callback )


callback вызывается каждый раз, когда будет нажата клавиша "z".
Второй способ длиннее, но позволяет описать больше событий. Он имеет следующий синтаксис: <modifier-modifier-type-detail>
Название события заключено в угловые скобки. Внутри имеются ноль или более модификаторов, тип события и дополнительная информация (номер нажатой клавиши мыши или символ клавиатуры) Поля разделяются дефисом или пробелом. Пример (привязываем одновременное нажатие Ctrl+Shift+q):
widget.bind("<Control-Shift-KeyPress-q>" , callback ) (в данном примереKeyPress можно убрать).
Третий способ позволяет привязывать виртуальные события - события, которые генерируются самим приложением. Такие события можно создавать самим, а потом привязывать их. Имена таких событий помещаются в двойные угловые скобки: <<Paste>>. Есть некоторое количество уже определённых виртуальных событий.


Список модификаторов
Return
- Enter
Escape - Esc
Control - Ctrl
Alt
Shift
Lock
Extended

Prior - PgUp
Next - PgDown
Button1, B1 - нажата первая (левая) кнопка мыши
Button2, B2 - вторая (средняя) кнопка мыши
Button3, B3 - третья (правая)
Button4, B4 - четвёртая
Button5, B5 - пятая
Mod1, M1, Command
Mod2, M2, Option
Mod3, M3
Mod4, M4
Mod5, M5
Meta, M
Double
- двойной щелчок мыши (например, <Double-Button-1>)
Triple - тройной
Quadruple - четверной

Типы событий
Здесь перечислены все возможные типы событий, для самых часто используемых дано описание. Более подробно см. man bind.
Activate, Deactivate
MouseWheel
- прокрутка колесом мыши
KeyPress, KeyRelease- нажатие и отпускание клавиши на клавиатуре
ButtonPress, ButtonRelease, Motion- нажатие, отпускание клавиши мыши, движение мышью
Configure - изменение положения или размера окна
Map, Unmap- показывание или сокрытие окна (например, в случае сворачивания/разворачивания окна пользователем)
Visibility
Expose
- событие генерируется, когда необходимо всё окно или его часть перерисовать
Destroy - закрытие окна
FocusIn, FocusOut- получение или лишение фокуса
Enter, Leave - Enter генерируется когда курсор мыши "входит" в окно, Leave - когда "уходит" из окна
Property
Colormap
MapRequest, CirculateRequest, ResizeRequest, ConfigureRequest, Create
Gravity, Reparent, Circulate

Клавиатурные символы
Полный список см.man keysyms.
Примеры
<Button-1>или <1> - нажата левая клавиша мыши.
<Alt-Motion>- движение мышью с нажатой на клавиатуре клавишей Alt.
<Key> - нажатие любой клавиши на клавиатуре.
Пример:

from Tkinter import *
root = Tk()
def leftclick (event):
print u'Вы нажали левую кнопку мыши'
def rightclick (event):
print u'Вы нажали правую кнопку мыши'
button1=Button(root, text=u'Нажми')
button1.pack()
button1.bind('<Button-1>' , leftclick )
button1.bind('<Button-3>' , rightclick )
root.mainloop ()

Дополнительные методы
bind_all
- создаёт привязку для всех виджетов приложения. Отличие от привязки к окну верхнего уровня
заключается в том, что в случае привязки к окну привязываются все виджеты этого окна, а этот метод
привязывает все виджеты приложения (у приложения может быть несколько окон).
bind_class - создаёт привязку для всех виджетов данного класса

 

Пример:
from Tkinter import *
def callback (e):
print u'Нажата кнопка' , e . widget[ 'text' ]
root = Tk()
button1 = Button(root, text = '1' )
button1 . pack()
button2 = Button(root, text = '2' )
button2 . pack()
root . bind_class ( 'Button' , '<1>' , callback )
root . mainloop ()

bindtags - позволяет изменить порядок обработки привязок. По умолчанию порядок следующий: виджет,
класс, окно, all; где виджет - привязка к виджету (bind), класс - привязка к классу (bind_class), окно - привязка к
окну (root.bind), all - привязка всех виджетов (bind_all).

 

Пример, меняем порядок обработки привязок на обратный:

from Tkinter import *
def callback1 (e): print 'callback1'
def callback2 (e): print 'callback2'
def callback3 (e): print 'callback3'
def callback4 (e): print 'callback4'
root = Tk()
button = Button(root)
button . pack()
button . bind( '<1>' , callback1 )
root . bind_class ( 'Button' , '<1>' , callback2 )
root . bind( '<1>' , callback3 )
root . bind_all ( '<1>' , callback4 )
button . bindtags (( 'all' , root, 'Button' , button))
root . mainloop ()

unbind - отвязать виджет от события. В качестве аргумента принимает идентификатор, полученный от
метода bind.
unbind_all - то же, что и unbind, только для метода bind_all.
unbind_class- то же, что и unbind, только для метода bind_class

 

****************************************************************

Лаб_6 - Программирование Питон PyGame . Классы

Познакомимся с основами ООП - использованием с классов в Python, на примере собственной игры «Wild West». Игра создана на основе кода игры «Alien» подробно описанной в этой книге - Эрик Мэтиз. Изучаем Питон. Программирование игр, визуализация данных, веб-приложения. Питер. 2017.  

Для создание игровых аудио и видео эффектов, которых нет в исходном примере, используем собственные аудио и видео образы:

         

 

Код программы

----------------------------------------------------------------------------------------------------------

alien_invasion.py

 

import pygame

from pygame.sprite import Group

from pygame.sprite import GroupSingle

import myvar

 

from settings import Settings

from game_stats import GameStats

from scoreboard import Scoreboard

from button import Button

from ship import Ship

import game_functions as gf

 

pygame.mixer.music.load('audio/music.wav')

pygame.mixer.music.set_volume(0.3)

pygame.mixer.music.play(-1)

 

def run_game():

# Initialize pygame, settings, and screen object.

pygame.init()

ai_settings = Settings()

screen = pygame.display.set_mode(

   (ai_settings.screen_width, ai_settings.screen_height))

clock = pygame.time.Clock()

   

# впишем фон игры и название огры

screen.blit(myvar.my_image, (0, 0))    ##   

pygame.display.set_caption("Western 1.0")

   

# Make the Play button.

play_button = Button(ai_settings, screen, "Play")

   

# Create an instance to store game statistics, and a scoreboard.

stats = GameStats(ai_settings)

sb = Scoreboard(ai_settings, screen, stats)

    

   

# Make a ship, a group of bullets, and a group of aliens.

ship = Ship(ai_settings, screen)

bullets = Group()

aliens = Group()

gbullets = Group()

# создадим группу основного игрового ship   

m_ships = GroupSingle()

m_ships.add(ship)

   

   

# Create the fleet of aliens.

gf.create_fleet(ai_settings, screen, aliens)

 

# Start the main loop for the game.

while True:

   gf.check_events(ai_settings, screen, stats, sb, play_button, m_ships,

       aliens, bullets)

       

   if stats.game_active:           

       gf.update_ships(m_ships)        

       bullets.clear(screen, myvar.my_image)

       gf.update_bullets(ai_settings, screen, stats, sb, m_ships, aliens,

                        bullets)

       gbullets.clear(screen, myvar.my_image)

       gf.update_gbullets(ai_settings, screen, stats, sb, m_ships, aliens,

                          gbullets)

       gf.update_aliens(ai_settings, screen, stats, sb, m_ships, aliens,

           bullets, gbullets)

       

   gf.update_screen(ai_settings, screen, stats, sb, m_ships, aliens,

       bullets, gbullets, play_button)

 

   clock.tick(200)

 

run_game()

 

----------------------------------------------------------------------------------------------------------

game_functions.py

 

import sys

from time import sleep

import pygame

import myvar

 

 

from bullet import Bullet

from gbullet import Gbullet

from alien import Alien

from ship import Ship

 

pygame.init() ##

bgr_img = myvar.my_image

shoot_sound1 = pygame.mixer.Sound('audio/shooter.wav') ## звук выстрела ship

shoot_sound2 = pygame.mixer.Sound('audio/sh_reload.wav') ## звук перезарядки ship

shoot_sound3 = pygame.mixer.Sound('audio/alien.wav') ## звук крика alien

shoot_sound4 = pygame.mixer.Sound('audio/ship.wav') ## звук крика ship

shoot_sound5 = pygame.mixer.Sound('audio/guns.wav') ## звук выстрела alien

 

def check_keydown_events(event, ai_settings, screen, m_ships, bullets):

"""Respond to keypresses."""

if event.key == pygame.K_RIGHT:

   for ship in m_ships:

       ship.moving_right = True

elif event.key == pygame.K_LEFT:

   for ship in m_ships:

       ship.moving_left = True

elif event.key == pygame.K_SPACE:

   fire_bullet(ai_settings, screen, m_ships, bullets)

elif event.key == pygame.K_q:

   pygame.quit()

   sys.exit()       

       

def check_keyup_events(event, m_ships):

"""Respond to key releases."""

if event.key == pygame.K_RIGHT:

   for ship in m_ships:

       ship.moving_right = False

elif event.key == pygame.K_LEFT:

   for ship in m_ships:

       ship.moving_left = False

 

def check_events(ai_settings, screen, stats, sb, play_button, m_ships, aliens,

   bullets):

"""Respond to keypresses and mouse events."""

for event in pygame.event.get():

   if event.type == pygame.QUIT:

       sys.exit()

   elif event.type == pygame.KEYDOWN:

       check_keydown_events(event, ai_settings, screen, m_ships, bullets)

   elif event.type == pygame.KEYUP:

       check_keyup_events(event, m_ships)

   elif event.type == pygame.MOUSEBUTTONDOWN:

       mouse_x, mouse_y = pygame.mouse.get_pos()

       check_play_button(ai_settings, screen, stats, sb, play_button,

           m_ships, aliens, bullets, mouse_x, mouse_y)

           

def check_play_button(ai_settings, screen, stats, sb, play_button, m_ships,

   aliens, bullets, mouse_x, mouse_y):

"""Start a new game when the player clicks Play."""

button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)

if button_clicked and not stats.game_active:

   # Reset the game settings.

   ai_settings.initialize_dynamic_settings()

       

   # Hide the mouse cursor.

   pygame.mouse.set_visible(False)

       

   # Reset the game statistics.

   stats.reset_stats()

   stats.game_active = True

   # Установим флаг активации кнопки для погашения

   stats.game_button_pressed = True 

       

   # Reset the scoreboard images.

   sb.prep_score()

   sb.prep_high_score()

   sb.prep_level()

   sb.prep_ships()

       

   # Empty the list of aliens and bullets.

   aliens.empty()

   bullets.empty()

   m_ships.empty()

       

   # Create a new fleet and center the ship.

   create_fleet(ai_settings, screen, aliens)

   # создаем новый объект ship

   ship = Ship(ai_settings, screen)

   ship.center_ship()

   m_ships.add(ship)       

 

def fire_bullet(ai_settings, screen, m_ships, bullets):

"""Fire a bullet, if limit not reached yet."""

# Create a new bullet, add to bullets group.

if len(bullets) < ai_settings.bullets_allowed:

   for ship in m_ships:

       new_bullet = Bullet(ai_settings, screen, ship)

       ship.aliene_fight = True # Установить флаг ответного огня противника

   bullets.add(new_bullet)       

   shoot_sound1.play() ## выстрел

   sleep(0.3)      ##

   shoot_sound2.play() ## перезарядка

   sleep(0.3)

 

   

def fire_gbullet(ai_settings, screen, m_ships, bullets, aliens, gbullets):

""" ответный огонь alien в зоне поражения ship """

if len(gbullets) < ai_settings.gbullets_allowed:

   for alien in aliens:

       for ship in m_ships:

           if (alien.rect.x > ship.zonx_min) and (alien.rect.x < ship.zonx_max):

               new_gbullet = Gbullet(ai_settings, screen, alien)

               gbullets.add(new_gbullet)

               shoot_sound5.play() ##

               sleep(0.3)      ##

               ship.aliene_fight = False

 

 

def update_screen(ai_settings, screen, stats, sb, m_ships, aliens, bullets,

   gbullets, play_button):

"""Update images on the screen, and flip to the new screen."""

# Redraw the screen, только один раз для удаления кнопки

if stats.game_button_pressed:

   screen.blit(bgr_img, (0, 0))

   stats.game_button_pressed = False

 

bullets.draw(screen)

gbullets.draw(screen)

 

m_ships.clear(screen, bgr_img)  

m_ships.draw(screen)

   

aliens.clear(screen, bgr_img) 

aliens.draw(screen)

   

# Draw the score information.

sb.show_score()

   

# Draw the play button if the game is inactive.

if not stats.game_active:

   play_button.draw_button()

 

# Make the most recently drawn screen visible.

pygame.display.flip()

   

def update_bullets(ai_settings, screen, stats, sb, m_ships, aliens, bullets):

"""Update position of bullets, and get rid of old bullets."""

# Update bullet positions.

bullets.update()

 

# Get rid of bullets that have disappeared.

for bullet in bullets.copy():

   if bullet.rect.bottom <= 0:

       bullets.remove(bullet)

           

check_bullet_alien_collisions(ai_settings, screen, stats, sb, m_ships,

   aliens, bullets)

 

def update_gbullets(ai_settings, screen, stats, sb, m_ships, aliens,

               gbullets):

"""Update position of bullets, and get rid of old bullets."""

# Update gbullet positions.

gbullets.update()

 

# Get rid of bullets that have disappeared.

for gbullet in gbullets.copy():

   if gbullet.rect.bottom >= ai_settings.screen_height:

       gbullets.remove(gbullet)

           

#check_g_bullet_ship_collisions(ai_settings, screen, stats, sb, ship,

# aliens, g_bullets)

 

 

def update_ships(m_ships):

""" обновление Group m_ships """

for ship in m_ships:

   ship.update()

 

       

def check_high_score(stats, sb):

"""Check to see if there's a new high score."""

if stats.score > stats.high_score:

   stats.high_score = stats.score

   sb.prep_high_score()

           

def check_bullet_alien_collisions(ai_settings, screen, stats, sb, m_ships,

                             aliens, bullets):

"""Respond to bullet-alien collisions."""

# Remove any bullets and aliens that have collided.

collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)

   

if collisions:

   for aliens in collisions.values():

       stats.score += ai_settings.alien_points * len(aliens)

       sb.prep_score()

   check_high_score(stats, sb)

   shoot_sound3.play() ## звук попадания в противника

   

if len(aliens) == 0:

   # If the entire fleet is destroyed, start a new level.

   bullets.empty()

   ai_settings.increase_speed()

       

   # Increase level.

   stats.level += 1

   sb.prep_level()

       

   create_fleet(ai_settings, screen, aliens)

   

def check_fleet_edges(ai_settings, aliens):

"""Respond appropriately if any aliens have reached an edge."""

for alien in aliens.sprites():

   if alien.check_edges():

       change_fleet_direction(ai_settings, aliens)

       break

       

def change_fleet_direction(ai_settings, aliens):

"""Drop the entire fleet, and change the fleet's direction."""

for alien in aliens.sprites():

   alien.rect.y += ai_settings.fleet_drop_speed

ai_settings.fleet_direction *= -1

   

def ship_hit(ai_settings, screen, stats, sb, ship, m_ships, aliens, bullets):

"""Respond to ship being hit by alien."""

if stats.ships_left > 0:

   # Decrement ships_left.

   stats.ships_left -= 1       

   # Update scoreboard.

   sb.prep_ships()

       

else:

   stats.game_active = False

   pygame.mouse.set_visible(True)

   

# Empty the list of aliens and bullets.

aliens.empty()

bullets.empty()

# m_ships.empty()

   

# Create a new fleet, and center the ship.

create_fleet(ai_settings, screen, aliens)

ship.center_ship()

m_ships.add(ship)

   

# Pause.

sleep(0.5)

   

def check_aliens_bottom(ai_settings, screen, stats, sb, ship, m_ships, aliens,

   bullets):

"""Check if any aliens have reached the bottom of the screen."""

screen_rect = screen.get_rect()

for alien in aliens.sprites():

   if alien.rect.bottom >= screen_rect.bottom:

       stats.game_button_pressed = True  # для перезаписи полностью экрана (ships_left)

       # Treat this the same as if the ship got hit.

       ship_hit(ai_settings, screen, stats, sb, ship, m_ships, aliens, bullets)

       shoot_sound4.play() ## звук крушения корабля

       break

           

def update_aliens(ai_settings, screen, stats, sb, m_ships, aliens, bullets,

   gbullets):

"""

Check if the fleet is at an edge,

then update the postions of all aliens in the fleet.

"""

check_fleet_edges(ai_settings, aliens)

aliens.update()

# при флаге ответного огня начать стрелять противнику

for ship in m_ships :

   if ship.aliene_fight == True :

       fire_gbullet(ai_settings, screen, m_ships, bullets, aliens, gbullets)       

   

# Look for alien-ship collisions.

for ship in m_ships:

   if pygame.sprite.spritecollideany(ship, aliens):

       ship_hit(ai_settings, screen, stats, sb, ship, m_ships, aliens, bullets)

       shoot_sound4.play() ## звук крушения корабля

       stats.game_button_pressed = True # для перезаписи полностью экрана (ships_left)

   # Look for aliens hitting the bottom of the screen.

   check_aliens_bottom(ai_settings, screen, stats, sb, ship, m_ships, aliens, bullets)

           

def get_number_aliens_x(ai_settings, alien_width):

"""Determine the number of aliens that fit in a row."""

available_space_x = ai_settings.screen_width - 4 * alien_width ##

number_aliens_x = int(available_space_x / (6 * alien_width)) ##

return number_aliens_x

 

def create_alien(ai_settings, screen, aliens, alien_number, row_number):

"""Create an alien, and place it in the row."""

alien = Alien(ai_settings, screen)

alien_width = alien.rect.width

alien.x = 4*alien_width + 6 * alien_width * alien_number ##

alien.rect.x = alien.x

alien.rect.y = 2*alien.rect.height + 6 * alien.rect.height * row_number ##

aliens.add(alien)

 

def create_fleet(ai_settings, screen, aliens):

"""Create a full fleet of aliens."""

# Create an alien, and find number of aliens in a row.

alien = Alien(ai_settings, screen)

number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)

number_rows = int(1) # get_number_rows(ai_settings, ship.rect.height,

   # alien.rect.height)

   

# Create the fleet of aliens.

for row_number in range(number_rows):

   for alien_number in range(number_aliens_x):

       create_alien(ai_settings, screen, aliens, alien_number, row_number)

 

----------------------------------------------------------------------------------------------------------


































































































































Ship.py

 

import pygame

from pygame.sprite import Sprite

 

class Ship(Sprite):

 

def __init__(self, ai_settings, screen):

   """Initialize the ship, and set its starting position."""

   super(Ship, self).__init__()

   self.screen = screen

   self.ai_settings = ai_settings

 

   # Load the ship image, and get its rect.

   self.image = pygame.image.load('images/shooter.bmp')

   self.rect = self.image.get_rect()

   self.screen_rect = screen.get_rect()

 

   # Start each new ship at the bottom center of the screen.

   self.rect.centerx = self.screen_rect.centerx

   self.rect.bottom = self.screen_rect.bottom

       

   # Store a decimal value for the ship's center.

   self.center = float(self.rect.centerx)

       

   # Movement flags.

   self.moving_right = False

   self.moving_left = False

   # Добавим флаг разрешения на ответ враж. огонь

   self.aliene_fight = False

       

def center_ship(self):

   """Center the ship on the screen."""

   self.center = self.screen_rect.centerx

       

def update(self):

   """Update the ship's position, based on movement flags."""

   # Update the ship's center value, not the rect.

   if self.moving_right and self.rect.right < self.screen_rect.right:

       self.center += self.ai_settings.ship_speed_factor           

   if self.moving_left and self.rect.left > 0:

       self.center -= self.ai_settings.ship_speed_factor

   # определим зону вражеского обстрела ship (x_min и x_max)

   self.zonx_min = self.center - self.ai_settings.ship_zonx

   self.zonx_max = self.center + self.ai_settings.ship_zonx

 

   # Update rect object from self.center.

   self.rect.centerx = self.center

 

def blitme(self):

   """Draw the ship at its current location."""

   self.screen.blit(self.image, self.rect)

 

----------------------------------------------------------------------------------------------------------

Alien.py

 

import pygame

from pygame.sprite import Sprite

import myvar 

 

class Alien(Sprite):

"""A class to represent a single alien in the fleet."""

 

def __init__(self, ai_settings, screen):

   """Initialize the alien, and set its starting position."""

   super(Alien, self).__init__()

   self.screen = screen

   self.ai_settings = ai_settings

 

   # Load the alien image, and set its rect attribute.

   self.image = pygame.image.load('images/gans.bmp')

   self.rect = self.image.get_rect()

 

   # Start each new alien near the top left of the screen.

   self.rect.x = self.rect.width

   self.rect.y = self.rect.height

 

   # Store the alien's exact position.

   self.x = float(self.rect.x)

       

def check_edges(self):

   """Return True if alien is at edge of screen."""

    screen_rect = self.screen.get_rect()

   if self.rect.right >= screen_rect.right:

       return True

   elif self.rect.left <= 0:

       return True

       

def update(self):

   """Move the alien right or left."""

   self.x += (self.ai_settings.alien_speed_factor *

                   self.ai_settings.fleet_direction)

   self.rect.x = self.x

 

def blitme(self):

   """Draw the alien at its current location."""

   self.screen.blit(self.image, self.rect)

 

----------------------------------------------------------------------------------------------------------

Bullet.py

 

import pygame

from pygame.sprite import Sprite

 

class Bullet(Sprite):

"""A class to manage bullets fired from the ship."""

 

def __init__(self, ai_settings, screen, ship):

   """Create a bullet object, at the ship's current position."""

   super(Bullet, self).__init__()

   self.screen = screen

 

   # Load the bullit image, and set its rect attribute.

     self.image = pygame.image.load('images/bullet.bmp')

   self.rect = self.image.get_rect()

   self.rect.x = self.rect.width

   self.rect.y = self.rect.height

 

   # Create bullet rect at (0, 0), then set correct position.

   # self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,

   # ai_settings.bullet_height)

   self.rect.centerx = ship.rect.centerx

   self.rect.top = ship.rect.top

       

   # Store a decimal value for the bullet's position.

   self.y = float(self.rect.y)

 

   # self.color = ai_settings.bullet_color

   self.speed_factor = ai_settings.bullet_speed_factor

 

def update(self):

   """Move the bullet up the screen."""

   # Update the decimal position of the bullet.

   self.y -= self.speed_factor

   # Update the rect position.

   self.rect.y = self.y

 

def draw_bullet(self):

   """Draw the bullet to the screen."""

   # pygame.draw.rect(self.screen, self.color, self.rect)

 

   self.screen.blit(self.image, self.rect)

 

----------------------------------------------------------------------------------------------------------

Button.py

 

import pygame.font

 

class Button():

 

def __init__(self, ai_settings, screen, msg):

   """Initialize button attributes."""

   self.screen = screen

   self.screen_rect = screen.get_rect()

       

   # Set the dimensions and properties of the button.

   self.width, self.height = 200, 50

   self.button_color = (0, 255, 0)

   self.text_color = (255, 255, 255)

   self.font = pygame.font.SysFont(None, 48)

       

   # Build the button's rect object, and center it.

   self.rect = pygame.Rect(0, 0, self.width, self.height)

   self.rect.center = self.screen_rect.center

       

   # The button message only needs to be prepped once.

   self.prep_msg(msg)

 

def prep_msg(self, msg):

   """Turn msg into a rendered image, and center text on the button."""

   self.msg_image = self.font.render(msg, True, self.text_color,

       self.button_color)

   self.msg_image_rect = self.msg_image.get_rect()

   self.msg_image_rect.center = self.rect.center

       

def draw_button(self):

   # Draw blank button, then draw message.

   self.screen.fill(self.button_color, self.rect)

   self.screen.blit(self.msg_image, self.msg_image_rect)

 

----------------------------------------------------------------------------------------------------------

Settings.py

 

class Settings():

"""A class to store all settings for Alien Invasion."""

 

def __init__(self):

   """Initialize the game's static settings."""

   # Screen settings.

   self.screen_width = 1423 #1200

   self.screen_height = 800

  

   self.bg_color = (230, 230, 230)

       

   # Ship settings.

   self.ship_limit = 3

   # добавим размер зоны ответного враж. огня

   self.ship_zonx = 50

           

   # Bullet settings.

   self.bullet_width = 3

   self.bullet_height = 10 #15

   self.bullet_color = 60, 60, 60

   self.bullets_allowed = 3

   # Добавим колв-о ответного огня

   self.gbullets_allowed = 5

               

   # Alien settings.

   self.fleet_drop_speed = 10

           

   # How quickly the game speeds up.

   self.speedup_scale = 1.1

   # How quickly the alien point values increase.

   self.score_scale = 1.5

   

   self.initialize_dynamic_settings()

 

def initialize_dynamic_settings(self):

   """Initialize settings that change throughout the game."""

   self.ship_speed_factor = 1.5

   self.bullet_speed_factor = 2

   self.alien_speed_factor = 1

       

   # Scoring.

   self.alien_points = 50

   

   # fleet_direction of 1 represents right, -1 represents left.

   self.fleet_direction = 1

       

def increase_speed(self):

   """Increase speed settings and alien point values."""

   self.ship_speed_factor *= self.speedup_scale

   self.bullet_speed_factor *= self.speedup_scale

   self.alien_speed_factor *= self.speedup_scale

       

   self.alien_points = int(self.alien_points * self.score_scale)

 

----------------------------------------------------------------------------------------------------------

game_stats.py

 

class GameStats():

"""Track statistics for Alien Invasion."""

   

def __init__(self, ai_settings):

   """Initialize statistics."""

   self.ai_settings = ai_settings

   self.reset_stats()

       

   # Start game in an inactive state.

   self.game_active = False

   self.game_button_pressed = False

       

   # High score should never be reset.

   self.high_score = 0

       

def reset_stats(self):

   """Initialize statistics that can change during the game."""

   self.ships_left = self.ai_settings.ship_limit

   self.score = 0

   self.level = 1

 

----------------------------------------------------------------------------------------------------------

Scoreboard.py

 

import pygame.font

from pygame.sprite import Group

 

from ship import Ship

 

class Scoreboard():

"""A class to report scoring information."""

 

def __init__(self, ai_settings, screen, stats):

   """Initialize scorekeeping attributes."""

   self.screen = screen

   self.screen_rect = screen.get_rect()

   self.ai_settings = ai_settings

   self.stats = stats

       

   # Font settings for scoring information.

   self.text_color = (30, 30, 30)

   self.font = pygame.font.SysFont(None, 48)

 

   # Prepare the initial score images.

   self.prep_score()

   self.prep_high_score()

   self.prep_level()

   self.prep_ships()

 

def prep_score(self):

   """Turn the score into a rendered image."""

   rounded_score = int(round(self.stats.score, -1))

   score_str = "{:,}".format(rounded_score)

   self.score_image = self.font.render(score_str, True, self.text_color,

       self.ai_settings.bg_color)

           

   # Display the score at the top right of the screen.

   self.score_rect = self.score_image.get_rect()

   self.score_rect.right = self.screen_rect.right - 20

   self.score_rect.top = 20

       

def prep_high_score(self):

   """Turn the high score into a rendered image."""

   high_score = int(round(self.stats.high_score, -1))

   high_score_str = "{:,}".format(high_score)

   self.high_score_image = self.font.render(high_score_str, True,

       self.text_color, self.ai_settings.bg_color)

               

   # Center the high score at the top of the screen.

   self.high_score_rect = self.high_score_image.get_rect()

      self.high_score_rect.centerx = self.screen_rect.centerx

   self.high_score_rect.top = self.score_rect.top

       

def prep_level(self):

   """Turn the level into a rendered image."""

   self.level_image = self.font.render(str(self.stats.level), True,

           self.text_color, self.ai_settings.bg_color)

       

   # Position the level below the score.

   self.level_rect = self.level_image.get_rect()

   self.level_rect.right = self.score_rect.right

   self.level_rect.top = self.score_rect.bottom + 10

       

def prep_ships(self):

   """Show how many ships are left."""

   self.ships = Group()

   for ship_number in range(self.stats.ships_left):

       ship = Ship(self.ai_settings, self.screen)

       ship.rect.x = 10 + ship_number * ship.rect.width

       ship.rect.y = 10

       self.ships.add(ship)

       

def show_score(self):

   """Draw score to the screen."""

   self.screen.blit(self.score_image, self.score_rect)

   self.screen.blit(self.high_score_image, self.high_score_rect)

   self.screen.blit(self.level_image, self.level_rect)

   # Draw ships.

   self.ships.draw(self.screen)

 

----------------------------------------------------------------------------------------------------------

Myvar.py

 

import pygame

 

my_image = pygame.image.load('images/land.bmp')

 

 

----------------------------------------------------------------------------------------------------------

Gbullet.py

 

 

import pygame

from pygame.sprite import Sprite

 

class Gbullet(Sprite):

"""A class to manage bullets fired from the alien."""

 

def __init__(self, ai_settings, screen, alien):

   """Create a bullet object, at the ship's current position."""

    super(Gbullet, self).__init__()

   self.screen = screen

 

   # Load the bullit image, and set its rect attribute.

   self.image = pygame.image.load('images/bullet.bmp')

   self.rect = self.image.get_rect()

   self.rect.x = self.rect.width

   self.rect.y = self.rect.height

 

   # Create bullet rect at (0, 0), then set correct position.

   # self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,

   # ai_settings.bullet_height)

   self.rect.centerx = alien.rect.centerx

   self.rect.top = alien.rect.top

       

   # Store a decimal value for the bullet's position.

   self.y = float(self.rect.y)

 

   # self.color = ai_settings.bullet_color

   self.speed_factor = ai_settings.bullet_speed_factor

 

def update(self):

   """Move the bullet down the screen."""

   # Update the decimal position of the bullet.

   self.y += self.speed_factor

   # Update the rect position.

   self.rect.y = self.y

 

def draw_bullet(self):

   """Draw the bullet to the screen."""

   # pygame.draw.rect(self.screen, self.color, self.rect)

 

   self.screen.blit(self.image, self.rect)

 

****************************************************************

Лаб_7 - Подключение, USB передача сигналов сигналов трехкоординатного датчика с АЦП на PC осциллограф (Питон).

В качестве трехкоординатного датчика подключенного к Arduino используем три потенциометра подключенных по схеме приведенной в Лаб 4.( п.п. 4.2), при этом средний вывод потенциометров подключены соответственно к АЦП входам A0, A1, A2 соответственно. Передача данных переменных напряжений с потенциометров X,Y,Z по COM каналу связи на РС осуществляется в пакетном режиме.

Код Arduino:

#define PIN_LED 11
#define PIN_X A0
#define PIN_Y A1
#define PIN_Z A2
#define PIN_SOUND 3

int analogVal_X = 0;
int analogVal_Y = 0;
int analogVal_Z = 0;
int brightn = 0;

void setup() {

pinMode(PIN_LED, OUTPUT);
pinMode(PIN_X, INPUT);
pinMode(PIN_Y, INPUT);
pinMode(PIN_Z, INPUT);
pinMode(PIN_SOUND, OUTPUT);

Serial.begin(19200);

}

void loop() {

delay(200);
  analogVal_X = analogRead(PIN_X);
analogVal_Y = analogRead(PIN_Y);
analogVal_Z = analogRead(PIN_Z);
brightn = analogVal_X/4;
analogWrite(PIN_LED, brightn);

 

Serial.print(analogVal_X);
Serial.print(" ");
Serial.print(analogVal_Y);
Serial.print(" ");
Serial.print(analogVal_Z);
Serial.print("\n");

analogWrite(PIN_SOUND, 50);
delay(100);
analogWrite(PIN_SOUND, 0);

delay(200);

}

Для приема, визуализации, записи в файл получаемых на PC от Arduino данных напишем на Python программу.   

GUI программы приема и обработки данных

 

Код программа (serial_monitor&plot_tkinter_val3_TKinter_07.py ):

from serial import *

from tkinter import *

from tkinter import messagebox

from tkinter.filedialog import *

import fileinput

 

serialPort = "COM3" # ИЗМЕНИТЬ НА НОМЕР ИСПОЛЬЗУЕМОГО COM ПОРТА!!!

baudRate = 9600

ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0)

 

#make a TkInter Window

root = Tk()

root.wm_title("Reading Serial")

 

# строчные переменные для строчных потоков данных порта и

# окрытого файла 

ComStrData = ""

FileStrData = ""

 

#make our own buffer

serBuffer = ""

FileStrBuff = ""

# битовая переменная чтения данных из порта

dd = b"a"

# переменная текущего количества принятых строк данных XYZ

DStrNum = 0

FStrNum = 0

# переменная стартового номера строки для анимационного (онлайн) графика 

LGraph_StartStrNum = 0

 

StartMode = False

ContinueStartMode = False

LiveGraphMode = False

 

# массивы для получаемых данных COM порта

comX = []

comY = []

comZ = []

# массивы для данных открытого файла

fopX = []

fopY = []

fopZ = []

 

# переменная индикации графика данных - com(TRUE) file(False)

ComFile_PlotMod = True 

 

# создаем надписи и окна индкации GUI программы  

label_ComDataXYZ = Label(root, text="ComXYZ ", font='Arial 8')

label_ComStrNum = Label(root, text="CStrNum -", font='Arial 8')

label_FileStrNum = Label(root, text="FStrNum -", font='Arial 8')

label_SaveFNote = Label(root, text="SaveFNote -", font='Arial 8')

label_OpenFNote = Label(root, text="OpenFNote -", font='Arial 8')

 

txt_DataStr = Text(root, height=32, takefocus=0)

txt_X = Text(root, height=1, font='Arial 14', takefocus=0)

txt_Y = Text(root, height=1, font='Arial 14', takefocus=0)

txt_Z = Text(root, height=1, font='Arial 14', takefocus=0)

txt_N = Text(root, height=1, font='Arial 14', takefocus=0)

txt_FileStrN = Text(root, height=1, font='Arial 14', \

          takefocus=0)

 

txt_SaveFNote = Text(root, height=2, font='Arial 8', \

          takefocus=0)

txt_OpenFNote = Text(root, height=2, font='Arial 8', \

          takefocus=0)

 

def FnStopWarningMsg():

messagebox.showwarning("Предупреждение", "Нужно остановить чтение порта (кн.STOP)")

def FnStartWarningMsg():

messagebox.showwarning("Предупреждение", "Нужно запустить чтение порта (кн.START)")

 

# Функ инициализации запуска процесса чтения из сериал порта  

def FnButStart():

global StartMode

global ContinueStartMode

global DStrNum

global serBuffer

global comX, comY, comZ

# если ранее не установлен режима старта чтения из порта

# включаем флаги и стартовая инициализация переменных

if StartMode == False:

   StartMode = True

   ContinueStartMode = False

   DStrNum = 0

   txt_N.delete('0.0', END)

   txt_N.insert('0.0', DStrNum)

   ComStrData = ""

   serBuffer = ""

   txt_DataStr.delete('0.0',END)

   comX = []

   comY = []

   comZ = []   

 

# Функ остановки процесса чтения из сериал порта

def FnButStop():

global StartMode

# выключаем режим старта чтения из порта

if StartMode == True:

   StartMode = False

 

# Функ продолжения процесса чтения из сериал порта

def FnButContinue():

global StartMode

global ContinueStartMode

global ComStrData

# включаем режим старта без стартовой инициализации переменных

if StartMode == False:

   StartMode = True

   ContinueStartMode = True

       

# Функ сохранения в файл сериал данных

def FnButSAVE_FILE():

global StartMode

global ComStrData

#предупреждаем и выходим если идет чтение из порта

if StartMode == True:

   FnStopWarningMsg()

   return

sa = asksaveasfilename()

f = open(sa,"w")

f.write(ComStrData)

f.close()

 

# Функ чтения из файла ранее сохраненных сериал данных

def FnButOPEN_FILE():

global StartMode

global FileStrData

global fopX, fopY, fopZ

global FileStrBuff

global FStrNum

#предупреждаем и выходим если идет чтение из порта

if StartMode == True:

   FnStopWarningMsg()

   return

# читаем данные из файла и обрабатываем

FileStrBuff = ""

FStrNum = 0

op = askopenfilename()

FileStrData = ""

txt_DataStr.delete('0.0', END)       

for FileStrData in fileinput.input(op):

   txt_DataStr.insert('0.0', FileStrData)

   OpnFileData_list = list(map(int, FileStrData.split(' ')))

   fopX.append(OpnFileData_list[0])

   fopY.append(OpnFileData_list[1])

   fopZ.append(OpnFileData_list[2])

   FileStrData = ""

   FStrNum += 1

txt_FileStrN.delete('0.0', END)

txt_FileStrN.insert('0.0', FStrNum)

 

# Функ рисования осей O_X и O_Y координат для plot canvas (1008x520)

def PlotAxis():

plot.create_line(8,520,8,4, # ось O_Y (вертикал)

plot.create_line(4,518,1004,518,# ось O_X (горизонт)

 

   

# Функ графического отображения сериал данных полученных из порта

def FnButDATA_GRAPH():

global StartMode

global FStrNum

#предупреждаем и выходим если идет чтение из порта

if StartMode == True:

   FnStopWarningMsg()

   return

GraphPlot()

   

# Функ графического отображения сериал данных полученных из файла 

def FnButFILE_GRAPH():

global StartMode

 #предупреждаем и выходим если идет чтение из порта

if StartMode == True:

   FnStopWarningMsg()

   return

 

def FnButLIVE_GRAPH():

global StartMode, LiveGraphMode

# предупреждаем и выходим если не запущено чтение из порта (START)

if StartMode == False:

   FnStartWarningMsg()

   return

# если режим анимации не установлен, то запускаем, иначе останавливаем

# режим анимации графика

if LiveGraphMode == False:

   LiveGraphMode = True

else:

   LiveGraphMode = False

plot.delete("all")

PlotAxis()

 

# создаем управляющие элементы GUI программы   

plot = Canvas(root, width = 1008, height = 520, bg = "lightblue")

button1_START = Button(root, text='START', height=1, \

                 font='Arial 10', command=FnButStart)

button2_STOP = Button(root, text='STOP', height=1, \

                 font='Arial 10', command=FnButStop)

button3_CONTINUE = Button(root, text='CONTINUE', \

            height=1, font='Arial 10', command=FnButContinue)

button4_SAVE_FILE = Button(root, text='SAVE_FILE', \

        height=1, font='Arial 10', command=FnButSAVE_FILE)

button5_OPEN_FILE = Button(root, text='OPEN_FILE', \

        height=1, font='Arial 10', command=FnButOPEN_FILE)

button6_DATA_GRAPH = Button(root, text='COM_GRAPH', \

        height=1, font='Arial 10', command=FnButDATA_GRAPH)

button7_FILE_GRAPH = Button(root, text='FILE_GRAPH', \

        height=1, font='Arial 10', command=FnButFILE_GRAPH)

button8_LIVE_GRAPH = Button(root, text='LIVE_GRAPH', \

        height=1, font='Arial 10', command=FnButLIVE_GRAPH)

 

# make a scrollbar

scrollbar = Scrollbar(root, orient=VERTICAL)

 

# через grid размещаем элементы GUI в главном окне 

scrollbar.grid(row=1, column=0,columnspan = 1, sticky='ns', rowspan = 3)

# размещаем окна входных данных порта

label_ComDataXYZ.grid(row=0, column=0)

txt_X.grid(row=0, column=1)

txt_Y.grid(row=0, column=2)

txt_Z.grid(row=0, column=3)

# размещаем окно числа принятых строк

label_ComStrNum.grid(row=0, column=4)

txt_N.grid(row=0, column=5)

# размещаем окно индикации принятых строк и окно графика

txt_DataStr.grid(row=1, column=1,columnspan = 3)

plot.grid(row=1, column=4,columnspan = 12, rowspan = 2)

# размещаем кнопки управелния процессами

button1_START.grid(row=0, column=6)

button2_STOP.grid(row=0, column=7)

button3_CONTINUE.grid(row=0, column=8)

button4_SAVE_FILE.grid(row=0, column=9)

label_FileStrNum.grid(row=0, column=10)

txt_FileStrN.grid(row=0, column=11)

button5_OPEN_FILE.grid(row=0, column=12)

button6_DATA_GRAPH.grid(row=0, column=13)

button7_FILE_GRAPH.grid(row=0, column=14)

button8_LIVE_GRAPH.grid(row=0, column=15)

# размещаем окна примечаний для записываемомго и считанного файла

label_SaveFNote.grid(row=3, column=2)

txt_SaveFNote.grid(row=3, column=3, columnspan = 12)

label_OpenFNote.grid(row=4, column=2)

txt_OpenFNote.grid(row=4, column=3, columnspan = 12)

 

# attach text box to scrollbar

txt_DataStr.config(yscrollcommand=scrollbar.set)

scrollbar.config(command=txt_DataStr.yview)

 

# Функ воспроизведения статической графика

def GraphPlot():

global DStrNum

if ComFile_PlotMod == True:

   for i in range(2, 125):

       if i < DStrNum:

           px = 8+(i-1)*5

           pyX = 520 - comX[i-1]//2

           pyY = 520 - comY[i-1]//2

           pyZ = 520 - comZ[i-1]//2

 

           px_ = 8+i*5

           pyX_ = 520 - comX[i]//2

           pyY_ = 520 - comY[i]//2

           pyZ_ = 520 - comZ[i]//2

 

           plot.create_line(px,pyX,px_,pyX_,= 'black')

           plot.create_line(px,pyY,px_,pyY_,= 'red')

           plot.create_line(px,pyZ,px_,pyZ_,= 'blue')

               

       else:

           break

 

# Функ воспроизведения анимированной (онлайн) графика

def LiveGraphPlot():

global DStrNum, LGraph_StartStrNum

if LGraph_StartStrNum == 0:

   LGraph_StartStrNum = DStrNum

   index = 1

if ComFile_PlotMod == True:

   for i in range(2, 125):

       if i < DStrNum:

           px = 8+(i-1)*5

           pyX = 520 - comX[i-1+LGraph_StartStrNum]//2

           pyY = 520 - comY[i-1+LGraph_StartStrNum]//2

           pyZ = 520 - comZ[i-1+LGraph_StartStrNum]//2

 

           px_ = 8+i*5

           pyX_ = 520 - comX[i+LGraph_StartStrNum]//2

           pyY_ = 520 - comY[i+LGraph_StartStrNum]//2

           pyZ_ = 520 - comZ[i+LGraph_StartStrNum]//2

 

           plot.create_line(px,pyX,px_,pyX_,= 'black')

           plot.create_line(px,pyY,px_,pyY_,= 'red')

           plot.create_line(px,pyZ,px_,pyZ_,= 'blue')

               

       else:

           break

   # увеличиваем индекс воспроизводимого количества данных с начала

   # анимации но не более макс размерности графика по O_X (1000/шаг индикации)

   index += 1

        

# ФУНКЦИЯ чтения из сериал (COM_N) порта строчные данные и воспроизводим

# данные в индикаторных окнах

def readSerial():

while True:

   dd = ser.read() # attempt to read a character from Serial

   c=dd.decode("utf-8")

   #was anything read?

   if len(c) == 0:

       break

   # get the buffer from outside of this function

   global ComStrData

   global serBuffer

   global DStrNum

   global StartMode

   global comX, comY, comZ

   # после буферного набора данных очередной строки из строчного потока данных                  

   if c == '\n':

       serBuffer += "\n" # add the newline to the buffer

       # читаем из строки данных отдельные числа X,Y,Z                   

       numbers_list = list(map(int, serBuffer.split(' ')))

       X=numbers_list[0]

       Y=numbers_list[1]

       Z=numbers_list[2]

       DStrNum += 1

       comX.append(X)

       comY.append(Y)

       comZ.append(Z)           

       # перепишем полученные данные в соответствующие окна X,Y,Z

       txt_X.delete('0.0', END)

       txt_X.insert('0.0', X)

       txt_Y.delete('0.0', END)

       txt_Y.insert('0.0', Y)

       txt_Z.delete('0.0', END)

       txt_Z.insert('0.0', Z)

           

       if StartMode == True:

           #add the line to the TOP of the log

           txt_DataStr.insert('0.0', serBuffer)

           txt_N.delete('0.0', END)

           txt_N.insert('0.0', DStrNum)

           ComStrData += serBuffer

 

       if LiveGraphMode == True:

           plot.delete("all")

           PlotAxis()

           LiveGraphPlot()       

 

       serBuffer = "" # empty the buffer

   else: # набираем в буфер данные текущей отдельной строки(до символа \n)

       serBuffer += c # add to the buffer

root.after(10, readSerial) # check serial again soon

 

# пропишем в окна начальные значения переменных 

txt_N.delete('0.0', END)

txt_N.insert('0.0', DStrNum)

txt_FileStrN.delete('0.0', END)

txt_FileStrN.insert('0.0', FStrNum)

 

# Рисуем оси координат для plot canvas (1008x520)

PlotAxis()

# plot.create_line(8,520,8,4, # ось O_Y (вертикал)

# plot.create_line(4,518,1004,518,# ось O_X (горизонт)

 

# after initializing serial, an arduino may need a bit of time to reset

root.after(100, readSerial)

 

root.mainloop()

 

****************************************************************

Лаб_8 - Подключение, USB передача сигналов звукового модуля на PC осциллограф (Питон).

 

****************************************************************

Лаб_9 - Конфигурирование и программирование ультразвуковой системы измерения расстояния.

 

****************************************************************

Лаб_10 - Конфигурирование и программирование ультразвуковой системы измерения расстояния.

 


****************************************************************

Лаб_10 - Конфигурирование и программирование робокара

 

****************************************************************

Лаб_11 - Конфигурирование и программирование робокара

 

****************************************************************

Лаб_12 - Конфигурирование и программирование робота манипулятора

 

****************************************************************

Лаб_13 - Конфигурирование и программирование робота манипулятора

 

 

****************************************************************

Лаб_14 - Конфигурирование и программирование Интернет сети.

 

****************************************************************

Лаб_15 - Конфигурирование и программирование Интернет сети.

 

 

****************************************************************

 

****************************************************************

Приложение 1.
Устройство платы Arduino Uno R3

Плата Arduino Uno — центр большой империи Arduino, самое популярное и самое доступное устройство Arduino. В ее основе лежит чип ATmega — в последней ревизии Arduino Uno R3 это ATmega328 (хотя на рынке можно еще встретить варианты платы UNO с ATmega168). Arduino Uno является самым подходящим вариантом для начала работы с платформой: она имеет удобный размер (не слишком большой, как у Mega и не такой маленький, как у Nano), достаточно доступна из-за массового выпуска всевозможных клонов, под нее написано огромное количество бесплатных уроков и скетчей. В этой статье мы рассмотрим основные особенности, характеристики и устройство платы Arduino Uno R3, требования к питанию и возможности подключения внешних устройств.

1 Характеристики Arduino Uno R3

2 Изображения плат Ардуино Уно

3 Устройство Arduino Uno

3.1 Схема платы Arduino Uno

3.2 Описание элементов платы Arduino Uno R3

3.3 Распиновка микроконтроллера ATMega 328

4 Описание пинов Ардуино

4.1 Цифровые пины Arduino Uno

4.2 Аналоговые пины Arduino Uno

4.3 Дополнительные разъемы

5 Варианты питания Ардуино Уно

6 Память Arduino Uno R3

7 Отличие Arduino Uno от других плат

7.1 Отличия Arduino Uno от Arduino Nano

8 Краткие выводы


























Схема платы Arduino Uno

Принципиальная схема:

 

Описание элементов платы Arduino Uno R3

Распиновка микроконтроллера ATMega 328

Описание пинов Ардуино

Пины Ардуино используются для подключения внешних устройств и могут работать как в режиме входа (INPUT), так и в режиме выхода (OUTPUT). К каждому входу может быть подключен встроенный резистор 20-50 кОм с помощью выполнения команды pinMode () в режиме INPUT_PULLUP. Допустимый ток на каждом из выходов – 20 мА, не более 40 мА в пике.
Для удобства работы некоторые пины совмещают в себе несколько функций:

· Пины 0 и 1 — контакты UART (RХ и TX соответственно) .

· Пины c 10 по 13 – контакты SPI (SS, MOSI, MISO и SCK соответственно)

· Пины A4 и A5 – контакты I2C (SDA и SCL соответственно).

Цифровые пины Arduino Uno

Пины с номерами от 0 до 13 являются цифровыми. Это означает, что вы можете считывать и подавать на них только два вида сигналов: HIGH и LOW. С помощью ШИМ также можно использовать цифровые порты для управления мощностью подключенных устройств.

 

Пин ардуино Адресация в скетче Специальное назначение ШИМ
Цифровой пин 0 0 RX  
Цифровой пин 1 1 TX  
Цифровой пин 2 2 Вход для прерываний  
Цифровой пин 3 3 Вход для прерываний ШИМ
Цифровой пин 4 4    
Цифровой пин 5 5   ШИМ
Цифровой пин 6 6   ШИМ
Цифровой пин 7 7    
Цифровой пин 8 8    
Цифровой пин 9 9   ШИМ
Цифровой пин 10 10 SPI (SS) ШИМ
Цифровой пин 11 11 SPI (MOSI) ШИМ
Цифровой пин 12 12 SPI (MISO)  
Цифровой пин 13 13 SPI (SCK) К выходу также подсоединен встроенный светодиод (есть в большинстве плат Arduino)  

 

Аналоговые пины Arduino Uno

Аналоговые пины Arduino Uno предназначены для подключения аналоговых устройств и являются входами для встроенного аналого-цифрового преобразователя (АЦП), который в ардуино уно десятиразрядный.

Пин Адресация в скетче Специальное назначение
Аналоговый пин A0 A0 или 14  
Аналоговый пин A1 A1 или 15  
Аналоговый пин A2 A2 или 16  
Аналоговый пин A3 A3 или 17  
Аналоговый пин A4 A4 или 18 I2C (SCA)
Аналоговый пин A5 A5 или 19 I2C (SCL)

Дополнительные разъемы

· AREF – выдает опорное напряжения для встроенного АЦП. Может управляться функцией analogReference().

· RESET – подача низкого сигнала на этом входе приведет к перезагрузке устройства.

Варианты питания Ардуино Уно

Рабочее напряжение платы Ардуино Уно — 5 В. На плате установлен стабилизатор напряжения, поэтому на вход можно подавать питание с разных источников. Кроме этого, плату можно запитывать с USB — устройств. Источник питания выбирается автоматически.

· Питание от внешнего адаптера, рекомендуемое напряжение от 7 до 12 В. Максимальное напряжение 20 В, но значение выше 12 В с высокой долей вероятности быстро выведет плату из строя. Напряжение менее 7 В может привести к нестабильной работе, т.к. на входном каскаде может запросто теряться 1-2 В. Для подключения питания может использоваться встроенный разъем DC 2.1 мм или напрямую вход VIN для подключения источника с помощью проводов.

· Питание от USB-порта компьютера.

· Подача 5 В напрямую на пин 5V. В этом случае обходится стороной входной стабилизатор и даже малейшее превышение напряжения может привести к поломке устройства.

Пины питания

· 5V – на этот пин ардуино подает 5 В, его можно использовать для питания внешних устройств.

· 3.3V – на этот пин от внутреннего стабилизатора подается напряжение 3.3 В

· GND – вывод земли.

· VIN – пин для подачи внешнего напряжения.

· IREF – пин для информирования внешних устройств о рабочем напряжении платы.

Память Arduino Uno R3

В Arduino Uno три вариант памяти:

· FLASH – память объемом 32 кБ;

· Оперативная SRAM память объемом 2 кБ;

· Энергонезависимая память (EEPROM) объемом 1кБ.

 

 


Электрическая цепь

Предположим у нас есть один резистор, один светодиод и батарея «крона». Соединим их в цепь с помощью макетной платы.

Сначала ставим светодиод.

Затем ставим резистор таким образом, чтобы одна из его ног был под, либо над анодом светодиода (анод — это положительный вывод, он длиннее, чем катод). Используем резистор номиналом 1 кОм.

Зеленым цветом подсвечиваются скрытые проводники.

Теперь соединяем всё с батареей. Положительный контакт батареи подключаем ко второй ноге резистора, а отрицательный — к катоду светодиода (короткая нога).

Цепь замыкается и светодиод мгновенно вспыхивает!

Кнопка

Добавим в цепь тактовую кнопку.

Теперь чтобы замкнуть цепь необходимо нажать кнопку. Жмем кнопку — светодиод зажигается!

Шина питания

Для этого задания нам понадобятся дополнительные провода-перемычки. Это такие проводки, в обоих концов которых находится штырёк.

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

На заметку. Принято красной линией обозначать положительный контакт элемента питания, в синей — отрицательный.

Вставим кнопку в разрыв отрицательной линии питания.

Жмем кнопку — все три светодиода одновременно зажигаются.

Переменные и типы данных.

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

 

Тип данных Разрядность, бит Диапазон чисел
boolean 8 true, false
char 8 -128 … 127
unsigned char 8 0 … 255
byte 8 0 … 255
int 16 -32768 … 32767
unsigned int 16 0 … 65535
word 16 0 … 65535
long 32 -2147483648 … 2147483647
unsigned long 32 0 … 4294967295
short 16 -32768 … 32767
float 32 -3.4028235+38 … 3.4028235+38
double 32 -3.4028235+38 … 3.4028235+38

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

Объявление переменных.

Указывается тип данных, а затем имя переменной.
int x; // объявление переменной с именем x типа int
float widthBox; // объявление переменной с именем widthBox типа float

Все переменные должны быть объявлены до того как будут использоваться.

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

· Переменные, объявленные в начале программы, до функции void setup(), считаются глобальными и доступны в любом месте программы.

· Локальные переменные объявляются внутри функций или таких блоков, как цикл for, и могут использоваться только в объявленных блоках. Возможны несколько переменных с одним именем, но разными областями видимости.

int mode; // переменная доступна всем функциям

void setup() {
// пустой блок, начальные установки не требуются
}

void loop() {

long count; // переменная count доступна только в функции loop()

for ( int i=0; i < 10;) // переменная i доступна только внутри цикла
{
i++;
}
}

При объявлении переменной можно задать ее начальное значение (проинициализировать).

int x = 0; // объявляется переменная x с начальным значением 0
char d = ‘a’; // объявляется переменная d с начальным значением равным коду символа ”a”

При арифметических операциях с разными типами данных происходит автоматическое преобразование типов данных. Но лучше всегда использовать явное преобразование.

int x; // переменная int
char y; // переменная char
int z; // переменная int

z = x + (int) y; // переменная y явно преобразована в int












Арифметические операции.

= присваиваниее
+ сложение
- вычитание
* произведение
/ деление
% остаток от деления

Операции отношения.

== равно
!= не равно
< меньше
> больше
<= меньше или равно
>= больше или равно

Логические операции.

&& логическое И
|| логическое ИЛИ
! логическое НЕ

Операции над указателями.

* косвенная адресация
& получение адреса переменной

Битовые операции.

& И
| ИЛИ
^ ИСКЛЮЧАЮЩЕЕ ИЛИ
~ ИНВЕРСИЯ
<< СДВИГ ВЛЕВО
>> СДВИГ ВПРАВО

Массивы.

Массив это область памяти, где последовательно хранятся несколько переменных.

Объявляется массив так.

int ages[10]; // массив из 10 переменных типа int

float weight[100]; // массив из 100 переменных типа float

При объявлении массивы можно инициализировать:

int ages[10] = { 23, 54, 34, 24, 45, 56, 23, 23, 27, 28};

Обращаются к переменным массивов так:

x = ages[5]; // x присваивается значение из 5 элемента массива.
ages[9] = 32; // 9 элементу массива задается значение 32

Нумерация элементов массивов всегда с нуля.


Функции.

Функции позволяют выполнять одни и те же действия с разными данными. У функции есть:

· имя, по которому ее вызывают;

· аргументы – данные, которые функция использует для вычисления;

· тип данных, возвращаемый функцией.

Описывается пользовательская функция вне функций setup() и loop().

void setup() {
// код выполняется один раз при запуске программы
}

void loop() {
// основной код, выполняется в цикле
}

// объявление пользовательской функции с именем functionName
type functionName( type argument1, type argument1, … , type argument)
{
// тело функции
return();
}

Пример функции, вычисляющей сумму квадратов двух аргументов.

int sumQwadr (int x, int y)
{
return( x* x + y*y);
}

 

Вызов функции происходит так:
d= 2; b= 3;
z= sumQwadr(d, b); // в z будет сумма квадратов переменных d и b

Функции бывают встроенные, пользовательские, подключаемые.
Очень коротко, но этих данных должно хватить для того, чтобы начать писать программы на C для систем Ардуино.

Рекомендации по оформлению программ на языке C.

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

 
















Имена в языке C.

Имена, представляющие типы данных, должны быть написаны в смешанном регистре. Первая буква имени должна быть заглавная (верхний регистр).
Signal, TimeCount

Переменные должны быть записаны именами в смешанном регистре, первая буква строчная (нижний регистр).
signal, timeCount

Константы должны быть записаны в верхнем регистре. В качестве разделителя нижнее подчеркивание.
MAX_TEMP, RED

Методы и функции должны быть названы глаголами, записанными в смешанном регистре, первая буква в нижнем регистре.
getTime, setTime

 





Приложение 3.

Запуск программы.

Запустить нашу программу можно несколькими способами. Самый простой из них, выбрать меню «Run» в редакторе программ, далее «Run Module» или нажать клавишу «F5». Текст команды будет передан в интерпретатор, который проверит её на ошибки и незамедлительно приступит к выполнению:

Рисунок 3.1-5 Вид оболочки IDLE с запущенной программой.

В этот момент, работа программы останавливается. Компьютер ждет, пока пользователь не введет какие-либо данные и подтвердит их. Введите свое имя и нажмите «Enter»:

Рисунок 3.1-6 Программа закончила работу и оболочка IDLE готова к приему новых команд.

Чтобы запустить программу заново, нужно вернуться в редактор программ Python и снова нажать F5.

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

Также, программу можно запустить просто открыв папку, содержащую файл программы, и дважды кликнуть на её имени.

Если вам лень набирать текст программ, вы можете скачать готовый листинг из раздела «Загрузки». Но, все же, я настоятельно рекомендую набирать программы вручную — это способствует лучшей запоминаемости команд и облегчает понимание работы программы.

 

 

Приложение 4.

Строки

 

Строки в Python обособляются кавычками двойными «"» или одинарными «'». Внутри двойных ковычек могут присутствовать одинарные или наоборот. К примеру строка «Он сказал 'привет'!» будет выведена на экран как «Он сказал 'привет'!». Если нужно использовать строку из несколько строчек, то эту строку надо начинать и заканчивать тремя двойными кавычками «"""». Вы можете подставить в шаблон строки элементы из кортежа или словаря. Знак процента «%» между строкой и кортежем, заменяет в строке символы «%s» на элемент кортежа. Словари позволяют вставлять в строку элемент под заданным индексом. Для этого надо использовать в строке конструкцию «%(индекс)s». В этом случае вместо «%(индекс)s» будет подставлено значение словаря под заданным индексом.

 

>>>print «Name: %s\nNumber: %s\nString: %s» % (myclass.name, 3, 3 * "-")
Name: Poromenos
Number: 3
String: —
strString = ""« Этот текст расположен

на нескольких строках »""

>>> print «This %(verb)s a %(noun)s.» % {«noun»: «test», «verb»: «is»}
This is a test.

 









Операторы

 

Операторы while, if, for составляют операторы перемещения. Здесь нет аналога оператора select, так что придется обходиться if. В операторе for происходит сравнение переменной и списка. Чтобы получить список цифр до числа <number> — используйте функцию range(<number>). Вот пример использования операторов

rangelist = range(10) #Получаем список из десяти цифр (от 0 до 9)
>>> print rangelist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in rangelist: #Пока переменная number (которая каждый раз увеличивается на единицу) входит в список…
# Проверяем входит ли переменная
# numbers в кортеж чисел (3, 4, 7, 9)
if number in (3, 4, 7, 9): #Если переменная number входит в кортеж (3, 4, 7, 9)...
# Операция «break» обеспечивает
# выход из цикла в любой момент
break
else:
# «continue» осуществляет «прокрутку»
# цикла. Здесь это не требуется, так как после этой операции
# в любом случае программа переходит опять к обработке цикла
continue
else:
# «else» указывать необязательно. Условие выполняется
# если цикл не был прерван при помощи «break».
pass # Ничего не делать

if rangelist[1] == 2:
print «The second item (lists are 0-based) is 2»
elif rangelist[1] == 3:
print «The second item (lists are 0-based) is 3»
else:
print «Dunno»

while rangelist[1] == 1:
pass

 





























Функции

 

Для объявления функции служит ключевое слово «def». Аргументы функции задаются в скобках после названия функции. Можно задавать необязательные аргументы, присваивая им значение по умолчанию. Функции могут возвращать кортежи, в таком случае надо писать возвращаемые значения через запятую. Ключевое слово «lambda» служит для объявления элементарных функций .

# arg2 и arg3 — необязательые аргументы, принимают значение объявленное по умолчни,
# если не задать им другое значение при вызове функци.
def myfunction(arg1, arg2 = 100, arg3 = «test»):
return arg3, arg2, arg1
#Функция вызывается со значением первого аргумента — "Argument 1", второго — по умолчанию, и третьего — "Named argument".
>>>ret1, ret2, ret3 = myfunction(«Argument 1», arg3 = «Named argument»)
# ret1, ret2 и ret3 принимают значения "Named argument", 100, "Argument 1" соответственно
>>> print ret1, ret2, ret3
Named argument 100 Argument 1

# Следующая запись эквивалентна def f(x): return x + 1
functionvar = lambda x: x + 1
>>> print functionvar(1)
2

 














Классы

 

Язык Python ограничен в множественном наследовании в классах. Внутренние переменные и внутренние методы классов начинаются с двух знаков нижнего подчеркивания «__» (например «__myprivatevar»). Мы можем также присвоить значение переменной класса извне. Пример:

class Myclass:
common = 10
def __init__(self):
self.myvariable = 3
def myfunction(self, arg1, arg2):
return self.myvariable

# Здесь мы объявили класс Myclass. Функция __init__ вызывается автоматически при инициализации классов .
>>> classinstance = Myclass() # Мы инициализировали класс и переменная myvariable приобрела значение 3 как заявлено в методе инициализации
>>> classinstance.myfunction(1, 2) # Метод myfunction класса Myclass возвращает значение переменной myvariable
3
# Переменная common объявлена во всех классах
>>> classinstance2 = Myclass()
>>> classinstance.common
10
>>> classinstance2.common
10
# Поэтому , если мы изменим ее значение в классе Myclass изменятся
# и ее значения в объектах , инициализированных классом Myclass
>>> Myclass.common = 30
>>> classinstance.common
30
>>> classinstance2.common
30
# А здесь мы не изменяем переменную класса . Вместо этого
# мы объявляем оную в объекте и присваиваем ей новое значение
>>> classinstance.common = 10
>>> classinstance.common
10
>>> classinstance2.common
30
>>> Myclass.common = 50
# Теперь изменение переменной класса не коснется
# переменных объектов этого класса
>>> classinstance.common
10
>>> classinstance2.common
50

# Следующий класс является наследником класса Myclass
# наследуя его свойства и методы , ктому же класс может
# наследоваться из нескольких классов , в этом случае запись
# такая : class Otherclass(Myclass1, Myclass2, MyclassN)
class Otherclass(Myclass):
def __init__(self, arg1):
self.myvariable = 3
print arg1

>>> classinstance = Otherclass(«hello»)
hello
>>> classinstance.myfunction(1, 2)
3
# Этот класс не имеет совйтсва test, но мы можем
# объявить такую переменную для объекта . Причем
# t эта переменная будет членом только classinstance.
>>> classinstance.test = 10
>>> classinstance.test
10


Исключения

 

Исключения в Python имеют структуру try-except [exceptionname]:

def somefunction():
try:
# Деление на ноль вызывает ошибку
10 / 0
except ZeroDivisionError:
# Но программа не "Выполняет недопустимую операцию"
# А обрабатывает блок исключения соответствующий ошибке «ZeroDivisionError»
print «Oops, invalid.»

>>> fnexcept()
Oops, invalid.


Импорт

Внешние библиотеки можно подключить процедурой «import [libname]», где [libname] — название подключаемой библиотеки. Вы так же можете использовать команду «from [libname] import[funcname]», чтобы вы могли использовать функцию [funcname] из библиотеки [libname]

import random # Импортируем библиотеку «random»
from time import clock # И заодно функцию «clock» из библиотеки «time»

randomint = random.randint(1, 100)
>>> print randomint
64


Работа с файловой системой

 

Python имеет много встроенных библиотек. В этом примере мы попробуем сохранить в бинарном файле структуру списка, прочитать ее и сохраним строку в текстовом файле. Для преобразования структуры данных мы будем использовать стандартную библиотеку «pickle»

import pickle
mylist = [«This», «is», 4, 13327]
# Откроем файл C:\binary.dat для записи . Символ «r»
# предотвращает замену специальных сиволов (таких как \n, \t, \b и др.).
myfile = file(r«C:\binary.dat», «w»)
pickle.dump(mylist, myfile)
myfile.close()

myfile = file(r«C:\text.txt», «w»)
myfile.write(«This is a sample string»)
myfile.close()

myfile = file(r«C:\text.txt»)
>>> print myfile.read()
'This is a sample string'
myfile.close()

# Открываем файл для чтения
myfile = file(r«C:\binary.dat»)
loadedlist = pickle.load(myfile)
myfile.close()
>>> print loadedlist
['This', 'is', 4, 13327]

 


































































































Особенности

 

Условия могут комбинироваться. 1 < a < 3 выполняется тогда, когда а больше 1, но меньше 3.

Используйте операцию «del» чтобы очищать переменные или элементы массива.

Python предлагает большие возможности для работы со списками. Вы можете использовать операторы объявлении структуры списка. Оператор for позволяет задавать элементы списка в определенной последовательности, а if — позволяет выбирать элементы по условию.

>>> lst1 = [1, 2, 3]
>>> lst2 = [3, 4, 5]
>>> print [x * y for x in lst1 for y in lst2]
[3, 4, 5, 6, 8, 10, 9, 12, 15]
>>> print [x for x in lst1 if 4 > x > 1]
[2, 3]
# Оператор «any» возвращает true, если хотя
# бы одно из условий, входящих в него, выполняется.
>>> any(i % 3 for i in [3, 3, 4, 4, 3])
True
# Следующая процедура подсчитывает количество
# подходящих элементов в списке
>>> sum(1 for i in [3, 3, 4, 4, 3] if i == 3)
3
>>> del lst1[0]
>>> print lst1
[2, 3]
>>> del lst1


Глобальные переменные объявляются вне функций и могут быть прочитанны без каких либо объявлений. Но если вам необходимо изменить значение глобальной переменной из функции, то вам необходимо объявить ее в начале функции ключевым словом «global», если вы этого не сделаете, то Python объявит переменную, доступную только для этой функции.

number = 5

def myfunc():
# Выводит 5
print number

def anotherfunc():
# Это вызывает исключение, поскольку глобальная апеременная
# не была вызванна из функции. Python в этом случае создает
# одноименную переменную внутри этой функции и доступную
# только для операторов этой функции.
print number
number = 3

def yetanotherfunc():
global number
# И только из этой функции значение переменной изменяется.
number = 3

 




































Приложение 5. ( Фо рма отчета по лабораторной работе)

Федеральное агентство связи
Сибирский Государственный университет Телекоммуникаций и Информатики

 

ОТЧЕТ

к лабораторной работе №______
тема___________________________________

_______________________________________

по дисциплине: Электротехника и Электроника

 

Выполнил студент _________________________

группы ___________________

Дата отчета /_______/_______________2019 г.

Подпись студента __________________

 

Проверил преподаватель Шыырап Ю.М.

 Дата проверки /_______/_______________2019 г.

Оценка работы _________________________

Подпись преподавателя__________________

 

Новосибирск, 2019 г

Название лабораторной работы:______________________________________
__________________________________________________________________
__________________________________________________________________

Задание: __________________________________________________________
______________________________________________________________________________________________________________________________________________________________________________________________________
__________________________________________________________________

Выполнено:________________________________________________________
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Полученный результат:______________________________________________
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

к отчету прилагаются: _______________________________________________
____________________________________________________________________________________________________________________________________

ссылки на источники:________________________________________________
____________________________________________________________________________________________________________________________________
__________________________________________________________________

__________________________________________________________________













Как подключить светодиод к Arduino

В этом простом примере показано, как с помощью платформы Arduino заставить мигать светодиод. Для начала мы соберем простую схему на макетной плате, подключив светодиод к цифровому выходу микроконтроллера Ардуино (входы и выходы на плате еще называют Pin). Загрузив скетч (так называют программу для Ардуино), вы поймете, как пользоваться и работать с платой Arduino UNO.

Фото. Устройство светодиода и резистора в разрезе

Светодиоды — это полупроводниковые элементы, которые служат для индикации и освещения. Они имеют полярность (+ и ) и чувствуют направление движения постоянного тока. Если подключить светодиод неправильно, то постоянный ток не пройдет и прибор не засветится. Кроме того, светодиод может выйти из строя при неправильном подключении. Анод (длинная ножка светодиода) подключается к плюсу.

Для занятия нам понадобятся следующие детали:

§ плата Arduino Uno / Arduino Nano / Arduino Mega;

§ макетная плата;

§ 2 светодиода и 2 резистора 220 Ом;

§ провода «папа-папа».

Быстрая сборка схем на макетной плате

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

Одну и ту же схему можно собрать разными способами

Соберите схему подключения светодиода к Arduino, как на фото ниже

Длинная ножка светодиода — анод, она всегда подключается к плюсу

Для чего светодиод включают к Ардуино с резистором? Дело в том, что в светодиоде стоит кристалл который боится больших токов. Резистор призван ограничивать силу тока (Амперы), чтобы светодиод не перегорел. Большой ток губителен для светодиода, меньший ток (благодаря подключению резистора) обеспечивает длительную работу. Чтобы подключить светодиод к Ардуино без резистора, используйте 13 порт.

Подключите плату Arduino к компьютеру при помощи USB провода

Кабель с разъемами USB-A и USB-B для подключения принтера

Если у вас не установлена программа Arduino IDE, то скачайте последнюю версию на официальном сайте www.arduino.cc. С помощью USB кабеля производится запись программ, также плата получает питание от компьютера. Если требуется автономная работа электронного устройства, то плату можно запитать от батарейки или блока питания на 7-12 В. При подаче питания на плате загорится светодиод индикации.

Откройте программу Arduino IDE и проверьте подключение платы

 

Убедитесь, что программа определила ваш тип платы Ардуино

Шаг 1. Зайдите в основном меню «Инструменты -> Плата». Если плата Arduino определилась неправильно, то выберите необходимый тип, например, Arduino Uno.

Шаг 2. Установите порт (кроме COM1) подключения в меню «Инструменты -> Порт», так как при подключении Ардуино к ПК создается виртуальный COM-порт.

 

 

Убедитесь, что программа определила порт подключения Ардуино

 

Скетч мигающий светодиод Ардуино

 

void setup() // процедура setup

{

pinMode(13, OUTPUT); // объявляем пин 13 как выход

}

 

void loop() // процедура loop

{

digitalWrite(13, HIGH); // зажигаем светодиод

 

delay(1000); // ждем 1 секунду

 

digitalWrite(13, LOW); // выключаем светодиод

 

delay(1000); // ждем 1 секунду

}

Скопируйте код под фото и вставьте свой первый скетч в программу

 

Скопируйте код и вставьте скетч в программу Arduino IDE

Перед загрузкой программы в микроконтроллер можно выполнить проверку (компиляцию), на наличие ошибок в коде. В случае обнаружения ошибки — будет получено сообщение в нижнем окошке Arduino IDE. В любом случае, при загрузке скетча, сначала происходит проверка и компиляция программы. При компиляции происходит перевод программы в двоичный код, понятный микроконтроллеру.

Загрузите скетч в Arduino, нажав на кнопку «Вгрузить» (смотри фото)

Перед загрузкой программы в микроконтроллер, потребуется сохранить скетч на компьютере. Нажмите «Сохранить» в появившемся окне и начнется загрузка.

Перед загрузкой программы, потребуется сохранить скетч

Пояснения к коду:

1. процедура setup выполняется при запуске микроконтроллера один раз. Используется для конфигурации портов микроконтроллера и других настроек;

2. после выполнения setup запускается процедура loop, которая выполняется в бесконечном цикле. Это мы используем, чтобы светодиод мигал постоянно;

3. процедуры setup и loop должны присутствовать в любой программе (скетче), даже если вам не нужно ничего выполнять в них — пусть они будут пустые, просто не пишите ничего между фигурными скобками.

 

Подключение кнопки

Для сборки модели нам потребуется:

· плата Arduino

· Breadboard

· 5 проводов и/или перемычек «папа-папа»

· светодиод

· кнопка

· резисторы на 10 кОм и 220 Ом.

Что понадобится для подключения кнопки на Arduino?

Схема подключения модели Arduino с кнопкой и светодиодом:

Схема подключения кнопки и светодиода на Arduino

Для работы этой модели подойдет следующая программа (программу вы можете просто скопировать в Arduino IDE):


int button = 2;
int led = 8;
void setup() {
pinMode(led, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
if (digitalRead(button) == HIGH) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}

 

Так выглядит собранная модель Arduino кнопки со светодиодом:

Готовая модель с кнопкой и светодиодом на Arduino

 















Дата: 2019-05-28, просмотров: 213.