Для этого будем считывать данные с аналогового порта Arduino/Freeduino и записывать их в последовательный (COM) порт. А уже из последовательно порта их будет принимать наша программа и строить график сигнала
Итак, скетч для Arduino/Freeduino будет совсем простой:
// // Oscilloscope // #define ANALOGA_IN 0 void setup() < Serial.begin(38400); // указываем скорость работы с COM-портом >void loop() < int val; val = analogRead(ANALOGA_IN); // считываем данные Serial.println( val); // записываем данные в порт >
Подключившись к порту мы увидим что-то вроде:
403 401 384 361 346 341 341 358 376 386
Осталось только написать программу для превращения данных из последовательного порта в красивый график
На основе программы построения графиков функций
Graph.pyw (http://purepython.narod.ru/tkinter.html)
я набросал программу для отображения данных из COM-порта.
Для работы потребуется Python и библиотека:
pySerial – собственно сама библиотека для работы с COM-портом (для её работы под Windows требуется pyWin32)
Как научиться пользоваться Осциллографом
собственно работа с COM-портом из данной библиотеки крайне проста:
# # для работы с COM-портом нужна библиотека # pySerial, кроме того, под винду понадобится еще pyWin32 # import serial SERIAL_PORT = ‘COM1’ SERIAL_SPEED = 38400 ser = serial.Serial(SERIAL_PORT, SERIAL_SPEED) while 1: #s = ser.read() # считывается один байт s = ser.readline().strip() # считывается строка и убираются символы “rn” print s # печатаем на экран
Весь остальной код нужен для работы с графикой Tkinter и отображения линий графика с помощью
create_line(x1,y1,x2,y2,….,xn,yn)
Однако, у меня пока не получилось заставить работать программу в системе real-time –
поэтому бесконечный цикл заменил на конечный
for i in range(0,200):

В итоге, получается, что при нажатии на кнопку «Serial» скрипт считывает 200 значений с COM-порта и строит по ним график:

Другие примеры осциллографов на ардуине:
для проекта Carduino
Запустив это приложение увидим красивую картинку
![]()
Собственно – остаётся:— научиться определять уровень напряжения сигнала
уровень напряжения можно получить из простой формулы
5V/1024 значений = 0,004883 В/значение (4,883 мВ).— и определять частоту сигнала
NB
Если посмотреть код скетча — увидим, что Arduino работает с COM-портом на скорости 38400 бод (бит/сек http://ru.wikipedia.org/wiki/Бод)
для передачи байта по протоколу RS-232 используется 10 бит (стартовый бит, 8 бит данных, бит чётности (не используется), стоповый бит)
38400/10 = 3840 байт/сек
т.к. на один отсчёт идёт 3 байта (4-5) получаем
3840/3 = 1280 (960-768) отсчётов в секундуОсциллограф из компьютера!
читать далее: 5. Генерация звука – пьезоизлучатель
По теме
Processing и Arduino
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)analogRead, Arduino, COM-порт, Processing, Python, осциллограф10 августа, 2009
admin
Arduino
9 комментариев на «“Практическое программирование Arduino/CraftDuino — Аналоговый ввод – осциллограф”»
Alexandr: 2010-12-19 в 15:38
Установил Processing 1.2, загрузил программу, но появляются ошибки на эту строчку:
port = new Serial(this,’COM1′, 38400); // Serial.list()[0]пишет: Badly formated character constant
Что бы это значило?
Прежде, чем двигаться дальше, хочу понять как это работает.
Войдите, чтобы ответить
admin: 2010-12-19 в 16:04 <
div >
в коде скетча была опечатка (одинарные кавычки), а правильно двойные:
port = new Serial(this,»COM1″, 38400);
Alexandr :Эту проблему решил (вместо одинарных кавычек нужно писать двойные). Проблема другого плана: загружаю скетч в Ардуино и запускаю программу на Питоне. Значение порта считывается. При этом Ардуино больше не может посылать в этот порт какие-либо значения, так как порт занят программой на Питоне.
Может какая фишка есть на Питоне чтобы не занимать порт, а только слушать его?Alexandr :
Ещё вопрос. Запустил программу на Процессинге 1.2. Значения для графика очень долго читаются. В чем причина? (В моём компе, характерной заторможенностью или чем-то ещё)
Alexandr :
Прикольно. Оказывается сигнал на порте № 0 (к примеру) влияет на все остальные 5 портов — согласно графикам, полученным программой.
Zoltberg :
наводки=
если оч мешает и нужно только как показометр(форму наблюдать а не точные измерения проводить) можно повесить резисторы по 1к на землю.
Должно помочь=)Alexandr :
А теперь мне нужно описание языка программирования, на котором пишутся скечи для Processing, на русском языке.
Alexandr :
Не правиьлновыразился. Не языка, а основных функций для работы со строками, портами, графикой, текстом.
называть это «осциллографом» как-то язык не поворачивается. У реальных осциллографов частота семплирования обычно порядка гигасемпл/сек. А это так, рисовалка.
Источник: robocraft.ru
Осциллограф реального времени на Arduino
Осциллограф – это один из самых необходимых инструментов для всех электронщиков. Он используется для определения формы колебания, уровней напряжения, частоты, шума и других параметров сигнала. Его часто используют для отладки работы или ремонта какого-нибудь электронного устройства. К сожалению, современные осциллографы могут достаточно дорого стоить – примерно $45-$100 за осциллографы, которые могут выполнять только базовые функции, а более продвинутые версии этих устройств могут стоит более $150.
В этом проекте мы рассмотрим создание на основе платы Arduino 4-х канального осциллографа, способного выполнять все основные функции данного устройства и при этом отличающегося невысокой стоимостью изготовления. Осциллограмма будет показываться на экране компьютера – для ее построения будет использоваться программа на языке Python. Также на нашем сайте вы можете посмотреть проект осциллографа на основе платы Arduino с выводом изображения на ЖК дисплей.
Общие принципы работы проекта
Наш проект состоит из двух основных частей:
- Конвертер данных.
- Плоттер.
Осциллограф, по своей сути, должен формировать визуальное отображение аналогового сигнала, поданного на его вход. Для осуществления этого мы сначала должны преобразовать сигнал из аналоговой в цифровую форму и затем построить его график. Для этого мы будем использовать один из имеющихся в плате Arduino аналогово-цифровых преобразователей (АЦП). После проведения преобразования в цифровую форму сигнал передается через последовательный порт связи в компьютер, где специальное программное обеспечение, написанное на языке Python, будет строить его график на экране компьютера.
Необходимые компоненты
Аппаратное обеспечение
- Плата Arduino Uno (или любая другая) (купить на Aliexpress).
- Фоторезистор (купить на Aliexpress).
- Резистор 10 кОм (купить на Aliexpress).
- Макетная плата.
- Соединительные провода.
Программное обеспечение
1. Arduino IDE
2. Python
3. Python Libraries: Pyserial, Matplotlib, DrawnowРабота схемы
Схема осциллографа на основе платы Arduino представлена на следующем рисунке.
Как видите, она достаточно простая. Все, что нам нужно сделать, это подсоединить анализируемый сигнал к заданному аналоговому контакту платы Arduino. В качестве источника тестового сигнала в нашем проекте мы будем использовать фоторезистор (LDR), включенный в цепь простого делителя напряжения. Таким образом, напряжение сигнала, подаваемого на вход нашего осциллографа, будет зависеть от интенсивности света, падающего на фоторезистор.
После сборки схемы на макетной плате у вас должна получиться примерно следующая конструкция:
Объяснение кода программы
Для построения графика анализируемого сигнала мы, как уже указывалось ранее, будем использовать скрипт на языке python, который будет принимать данные от платы Arduino через последовательный порт связи (UART) и на их основе строить график на экране компьютера. Программа (скетч) же для Arduino будет считывать данные с выхода АЦП своего аналогового порта и передавать их скрипту на python.
Объяснение программы для Python
Для нашего проекта мы будем использовать следующие библиотеки Python: drawnow, Matplotlib и Pyserial. Библиотека Pyserial позволяет нам считывать данные из последовательного порта связи, Matplotlib обеспечивает нам возможность построения графиков, а drawnow дает нам возможность рисовать эти графики в режиме реального времени. Более подробно об использовании языка Python вместе с Arduino вы можете прочитать в следующей статье.
Существует несколько способов установки этих библиотек, самый простой из них – это через pip. Pip может быть установлен из командной строки в windows или linux. PIP поставляется вместе с пакетом python3 поэтому при установке вам просто нужно отметить галочкой нужную опцию чтобы он установился.
После того как pip будет установлен можно начинать установку всех других необходимых нам библиотек. Если у вас windows, то откройте командную строку, в linux’е откройте терминал и введите там следующую команду:
Источник: microkontroller.ru
Блог программистов
Я решил сделать кроссплатформенную версию этого импровизированного осциллографа и полностью переписал программу на GTK+. Данная статья может быть полезна всем, кто только начал или собирается изучать этот тулкит. Параллельно в уроке рассматривается использование некоторых функций мощной библиотеки двухмерной графики Cairo.
В примере показана компиляция программы в Linux, пользователи Windows могу скомпилировать программу, например, с помощью MinGW, так же скомпилировать программу могут и пользователи Mac OS X. Вопросы компиляции на платформах, отличных от Linux выходят за рамки данной статьи и рассматриваться не будут. Те кто желает — всегда сможет разобраться самостоятельно, используя поиск.Но в начале немного теории.
GTK+ — это кроссплатформенная библиотека, предназначенная для создания приложений с графическим интерфейсом пользователя, предоставляет богатый набор функций на все случаи жизни. Изначально библиотека разрабатывалась для программы Gimp. Библиотека написана на языке С, но тем не менее сохраняет принципы объектно-ориентированного программирования.
Для использования возможностей библиотеки, в Вашей системе, должна быть установлена как сама библиотека, так и заголовочные файлы (dev, devel пакеты) к ней, все это Вы можете сделать с помощью менеджера пакетов Вашего дистрибутива.
После установки всех недостающих компонентов можно подключать заголовочные файлы библиотеки в свою программу#include
Основными объектами библиотеки, с которыми нам придется иметь дело, являются так называемые виджеты. Каждый элемент управления (кнопка, метка, поле ввода) является виджетом. Само окно так же является виджетом. Еще одно очень важное понятие GTK+ — сигналы. Их можно считать, своего рода, аналогами сообщений в Windows.
Сигналы посылают различные элементы управления (нажата кнопка, передвинуто окно), а так же функции, при наступлении некоторого события (сработал таймер). Для обработки сигналов необходимо создавать функции-обработчики. Но функция-обработчик не будет взаимодействовать с сигналом сама по себе, для этого их необходимо связать. Это делается с помощью специальных методов GTK+. Обратите, так же, внимание на явное приведение типов аргументов функций.
Настало время рассмотрения программы.В самом начале программы подключаем необходимые заголовочные файлы, объявляем необходимые переменные и функции. Комментарии, думаю, все поясняют.
#include #include #include //объявляем функцию, обработчик сигнала закрытия окна static void destroy(GtkWidget*, gpointer); //объявляем функцию, обработчки сигнала перерисовки окна static void draw(GtkWidget*, GdkEventExpose*, gpointer); //объявляем функцию, объявляющую область перерисовки недействительной static gboolean time_handler(GtkWidget*); //две переменные, смещение синусоиды и текущее положение точки графика gint count = 0, t = 0; double radianPerx = 2 * 3.14 / 90; //угол радиан, определяет расстояние между гребнями волн const double uAmplit = 900; //амплитуда синусоиды
После объявлений — главная функция main, в самом объявлении функции нет ничего необычного. Рассмотрим что твориться в ней.
Первым делом мы должны объявить два виджета, это наше будущее окно и область, в которой мы будем рисоватьGtkWidget *window, *drawing;
Пока что это просто виджеты, объекты, без указания конкретного типа.
Далее — инициализация gtkgtk_init(argv);
функции передаются два аргумента — аргументы функции main.
Теперь создаем новое окно и задаем ему необходимые параметры.//создаем новое, обычное окно window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //задаем текст заголовка окна gtk_window_set_title(GTK_WINDOW(window), «Осциллограф»); //запрещаем изменение размеров окна gtk_window_set_resizable(GTK_WINDOW(window), FALSE); //задаем размер окна gtk_widget_set_size_request(window, 600, 400); //задаем стартовую позицию — центр экрана gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); //задаем отступы контейнера окна gtk_container_set_border_width(GTK_CONTAINER(window), 10);
Тут стоит сказать, что в Gtk, элемент управления не может существовать произвольно, в любом месте.
Его может содержать в себе некий невизуальный объект-контейнер. Окно приложения может выполнять функцию контейнера, но может содержать только один объект, для расположения в окне множества элементов в окне — следует расположить в контейнера окна другой контейнер. Сам контейнер может содержать сколь угодно много элементов. Функция gtk_container_set_border_width задает «поля» контейнера окна. Если не вызывать эту функцию — контейнер, содержащий в себе, в данном случае, поле рисования, будет равен размеру самого окна, без заголовка.
Следующей функцией мы создаем новый таймер, с интервалом срабатывания — 100 миллисекунд и привязываем к таким срабатываниями функцию time_handler.
g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
Далее мы создаем новую область для рисования и помещаем ее в контейнер окна
//создаем новую область для рисования drawing = gtk_drawing_area_new(); //помещаем ее в контейнер окна gtk_container_add(GTK_CONTAINER(window), drawing);
И самое интересное, в главной функции — связывание сигналов с обработчиками, это делается с помощью функции g_signal_connect.
//связываем сигнал уничтожения окна и функцию-обработчик g_signal_connect(GTK_OBJECT(window), «destroy», G_CALLBACK(destroy), NULL); //связываем сигнал перерисовки области рисования и функцию-обработчик g_signal_connect(G_OBJECT(drawing), «expose_event», G_CALLBACK(draw), NULL);
Первым параметром функции является объект, который мониторится, следующий параметр — название сигнала, третий параметр — функция-обработчик сигнала. Последний параметр, который мы не используем, в данном случае — дополнительный параметр, который может быть передан в функцию-обработчик.
Оставшиеся две функции выполняют отображение всех виджетов на экране и запуск основного цикла программы.
gtk_widget_show_all(window); gtk_main();
Теперь рассмотрим собственно функции-обработчики сигналов. Пойдем от простого к сложному.
Функция-обработчик сигнала закрытия окна
static void destroy(GtkWidget* window, gpointer data) < //завершаем главный цикл приложения gtk_main_quit(); >
Здесь все просто, при вызове этой функции происходит вызов gtk_main_quit() и завершение работы программы. Стоит заметить, что если не написать этот обработчик — после закрытия окна, процесс бы оставался висеть в памяти и ожидать сигналов.
Функция-обработчик сигнала таймера
static gboolean time_handler(GtkWidget* widget) < //если передан нулевой параметр — возвращаем ложь if (widget->window == NULL) return FALSE; //увеличиваем значение переменной смещения графика count++; //обнуляем точку положения на графике t = 0; //заставляем окно перерисоваться gtk_widget_queue_draw(widget); return TRUE; >
Здес так же нет ничего замудренного. Сначала выполняется корректность переданного параметра, если он нулевой — функция завершается, вернув FALSE;
Если функция не завершилась — происходит увеление значения переменной, задающей смещение рисуемого графика. Так же обнуляется вспомогательная переменная, указывающая текущую точку на графике. Следующий вызов gtk_widget_queue_draw(widget) объявляет, переданный ему виджет, визуально недействительным и требующим перерисовки.И наконец самое интересное — функция, выполняющая отрисовку координатной сетки и синусоиды. Для рисования используется библиотека Cairo, «встроенная» в Gtk. Мы будем использовать следующие методы:
gdk_cairo_create(GtkWidget* ) — данная функция создает, на основе переданного ей виджета, новый контекст рисования Cairo.
cairo_rectangle (cr, x1, y1, x2, y2) — данная функция рисует, в контексте рисования Cairo прямоугольник по заданным координатам.
cairo_set_line_width (cr, 3) — данная функция задает ширину линии, которой производится рисования в указанном контексте
cairo_set_source_rgb (cr, r, g, b) — данная функция задает цвет линии, которой производится рисования в указанном контексте, параметры r, g, b определяют, соответственно, интенсивность красного, зеленого и синего цветов.
cairo_move_to(cr, x, y) — с помощью этой функции мы переходим в новую исходную точку, из которой будем рисовать.
cairo_line_to (cr, x, y) — задаем точку, куда следует нарисовать линию.
cairo_stroke (cr) — собственно выполнение рисования в контексте.
cairo_show_text(cr, buf*) — рисование текста в заданном контексте, в точке, предварительно заданной cairo_move_to.Собственно это все функции, которые выполняют всю работу в данном обработчике. Рисование самой синусоиды производится методом, знакомым по предидущему уроку. Ниже приведен полный исходный код функции, с комментариями
static void draw(GtkWidget* drawarea, GdkEventExpose* event, gpointer data) < int ya, xa; //переменные для хранения X и Y координат рисования char *buf; //текстовый буфер для хранения текста метки //создаем область для рисования Cairo cairo_t *cr = gdk_cairo_create(drawarea->window); //рисуем рамку, размером с область рисования cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height); //задаем толщину линии cairo_set_line_width (cr, 3); //задачем черный цвет cairo_set_source_rgb (cr, 0, 0, 0); //рисуем линию оси Y cairo_move_to(cr, 40, 0); cairo_line_to (cr, 40, 350); cairo_stroke (cr); //рисуем линию оси X cairo_move_to (cr, 30, 340); cairo_line_to (cr, 600, 340); cairo_stroke (cr); //задаем толщину линии cairo_set_line_width (cr, 0.7); //рисуем риски на оси X, линии сетки и текстовые метки xa = 40; while(xa < 600) < //задаем черный цвет cairo_set_source_rgb (cr, 0, 0, 0); //рисуем риски cairo_move_to (cr, xa, 333); cairo_line_to (cr, xa, 347); cairo_stroke (cr); //преобразовывем значение координаты риски в строку sprintf(buf, «%i», xa-40); //рисуем текст метки в нужной точке cairo_move_to (cr, xa-2, 360); cairo_show_text(cr, buf); //задаем зеленый цвет cairo_set_source_rgb (cr, 0, 0.5, 0); //рисуем линии сетки cairo_move_to (cr, xa+40, 333); cairo_line_to (cr, xa+40, 0); cairo_stroke (cr); xa += 40; > //рисуем риски на оси Y, линии сетки и текстовые метки ya = 340; while(ya > 0) < //задаем черный цвет cairo_set_source_rgb (cr, 0, 0, 0); cairo_move_to (cr, 33, ya); cairo_line_to (cr, 47, ya); cairo_stroke (cr); //преобразовывем значение координаты риски в строку sprintf(buf, «%i», 340-ya); //рисуем текст метки в нужной точке cairo_move_to (cr, 12, ya+2); cairo_show_text(cr, buf); //задаем зеленый цвет cairo_set_source_rgb (cr, 0, 0.5, 0); //рисуем линии сетки cairo_move_to (cr, 47, ya-40); cairo_line_to (cr, 600, ya-40); cairo_stroke (cr); ya -= 40; > //рисуем синусоиду //задаем красный цвет и толщину линии cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width (cr, 4); //устонавливаем начальную точку синусоиды cairo_move_to(cr, t+40, ((uAmplit * sin(t * radianPerx + count)) * 0.1 + 160)); //рисуем синусоиду while(t < 600) < cairo_line_to(cr, t+40, ((uAmplit * sin(t * radianPerx + count)) * 0.1 + 160)); t++; > cairo_stroke (cr); >
Компиляция исходного текста в файле osc.c выполняется командой
gcc -Wall -g osc.c -o osc `pkg-config —cflags gtk+-2.0` `pkg-config —libs gtk+-2.0`
Здесь просходит подключение всех необходимых библиотек, с помощью pkg-config (у вас должен быть установлена эта утилита). Если компилятор будет ругаться — значит у вас не установлены необходимые пакеты с заголовочными файлами.
Скриншот итогового приложения:
Источник: pblog.ru



