Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

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

Итак, если вы следили за предыдущими статьями, то с легкостью сможете создать форму в Visual C#, прицепить к ней кнопочки, вывести текст. В идеале вы в состоянии поймать байтик из юарта и вывести полученный текст на форму.

Если вы не знакомы с предыдущими статьями, то основные моменты: если вы хотите сделать что то, то это действие должно быть привязано некому другому действию. Например, хотим чтобы изменился текст надписи, значит изменение текста нужно привязать к щелчку по кнопке, поэтому именно в обработке щелчка по кнопке следует писать свой код. Хотите вывести полученный по UART байт на форму — поместите компонент serialPort на форму, ведь именно он отвечает за ком порт и при событии DataReceived (получение данных) изменяйте надпись.

Не забываем! Чтобы вывести текст — принимаете байты в массив, выводите в надпись. Передать переменную состоящую из нескольких байт за один раз нельзя — передаете по байтно, собираете в массив — выводите. Чтобы узнать что начали передаваться данные — используйте спецсимволы, означающие начало и конец передачи — не путать со старт и стоп битами!

Все это круто, кнопки на форме рисовать умеем, текст писать и выводить переменные умеем, теперь неплохо бы еще научиться рисовать. Для этого заюзаем GDI+, он вполне сгодится. Чтобы его использовать в WindowsForm существует класс Graphics из пространства имен System.Drawing. Он позволяет рисовать изображения, многоугольники, дуги, линии, заливки областей, в общем то что нужно.

Главным образом нас интересует как рисовать прямые линии, с остальным, при желании, можно разобраться самостоятельно. Создаем проект WindowsForm. Придадим более культурный вид, например залить форму цветом WhiteSmoke, поместить кнопку и соответственно создать обработчик ее нажатия. В обработчике создадим переменную graphics, выберем цвет карандаша и нарисуем линию. Для наглядности, я привел полный исходник который должен
у вас получиться.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace plot
{
    public partial class Form1 : Form
    {
        public Form1(){InitializeComponent();}

        private void button1_Click(object sender, EventArgs e)
        {
            Graphics gr = CreateGraphics();    //создаем переменную класса graphics 
            Pen penc = new Pen(Color.Black);   //выбираем цвет карандаша,которым будем рисовать
            gr.DrawLine(penc, 0, 0, 100, 200);   //рисуем линию начальная точка x1=0 y1=0
        }                                      //конечная точка x2=100 y2=200
    }
}

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

draw_line1

Вернемся к изначальной задаче. Допустим микроконтроллер измеряет с некой периодичностью и шлет нам байты по последовательному порту. Кидаем на форму компонент serialPort1, задаем скорость и номер порта(!), с которого будем считывать информацию. Для теста я взял два виртуальных порта 4 и 5, т.е. через com4 терминалом передаются байты, а com5 читается программой. В событиях serialPort1 ищем обработчик DataReceived — туда пишем код, который рисует линии. С каждым приходящим байтом наш график будет дорисовывать линию к предыдущей, со смещением 5(переменная х2).

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{         
     Graphics gr = CreateGraphics();     //создаем переменную 
     Pen penc = new Pen(Color.Black);    //задаем цвет карандаша
     y2 = serialPort1.ReadChar();        //читаем полученный байт
     x2+=5;                              //следующая точка по координате х будет на 5 больше
     if (x2 > 300)                       //если мы достигли края формы, то очищаем форму и 
     {                                   //обнуляем переменные
         gr.Clear(Color.WhiteSmoke);
         x2 = 0; y2 = 0; x1 = 0; y1 = 0;
     }            
     gr.DrawLine(penc, x1, y1, x2, y2);  //рисуем линию по координатам
     x1 = x2;                            //запоминаем конец линии
     y1 = y2;
}

Не забываем, что перед использованием порт нужно открыть, а перед закрытием программы — закрыть. Теперь мы можем послать пару байтов, например при помощи терминала. Вроде работает.

draw_line2

Ну и на закуску — измеряем АЦП микроконтроллера, кидаем в юарт, смотрим на ПК. Только я внесем небольшое изменение в программу, чтобы график рисовался не от верхнего левого угла, а относительно центра. Для этого, нужно из половины высоты формы вычитать наш результат. И кнопку можно в принципе убрать с формы. В качестве схемы крутилка потенциометра. Прошивка микроконтроллера в комментариях думаю не нуждается — все есть в 8 и 10 уроках.

draw_sch

Протестировано — работает, такая вот приставка-осциллограф к компьютеру, всего на одном микроконтроллере и преобразователе usb-uart.

draw_real

Проект Visual C#

Проект Atmel studio

Вопросы по прошивкам на форум, по статье в комменты.

24 комментария: Простой UART Осциллограф.

  • Сергей:

    подскажите, а какую макс частоту сигнала можно измерять таким осциллографом?

  • admin:

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

  • Сергей:

    т.е. если скорость UARТ 9600 бит/с, а АЦП в МК стоит 8-битный, то UART должен успевать передавать эти 8 бит, соответствующие амплитуде измеряемого сигнала в данный момент времени, т.е. 9600/8=1200 Гц, а на практике только 600 Гц успеет реально отослаться по UART. правильно ли я размышляю?

  • ether:

    Там ограничение еще будет и за счет частоты выборок самого АЦП. Она у мег, кажись, не выше 15 тыс. выборок в сек.

  • admin:

    в идеале — внешний ацп и передача по usb

  • iEugene0x7CA:

    В правильных осциллографах конкретно выборки делает очень быстрый АЦП, а логика(обычно на ПЛИС) принимает значения и записывает их во внешнюю быструю оперативную память в обход МК… После чего МК может медленно эту память прочитать, обработать, и медленно отослать на компьютер.
    Осциллографу важно быстро кусочек сигнала записать, которого будет достаточно для отрисовки картинки, обновлять которую очень часто вовсе не нужно, ибо сигнал все равно обычно повторяется и к нему по срабатыванию триггера можно будет вернутся в любой момент. 😉

    Проект в статье скорее концептуальный, примерный, и если кому нужна скорость- думаю он вполне сумеет напрячь моск и улучшить алгоритм. Кстати иногда напрягать моск очень полезно, говорят. 😀

  • Денис:

    Артур, спасибо за статью. Давно замышлял замутить нечто подобное для смартфона. Начну с компа.

  • constanta:

    добрый день! интересная статья но может вы знаете как прикрепить контроллер атмега к юсб без фт232 чтобы из него считать аналоговый сигнал, с цифровыми разобрался а аналоговый не могу понять, или как байт с контроллера передать тоже не могу понять !!! может у вас есть какие примеры на С ++!

    СПАСИБО!!!!

  • admin:

    гуглите V-USB, статьи еще пока нет, хотя она в ближайших планах

  • constanta:

    гуглил,просто невсьо понятно!!! спасибо!!!будем ждать!

  • KNPS:

    За статью спасибо
    У меня такой вопрос … Есть контроллер Atmega 8 в нём мы скажем измеряем температуру по уровню АЦП .. илиже просто меряем АЦП на двух портах .. как можно реализовать вывод этих данных в С#, кажем на label1 и label2. Я примерно разобрался как зажигать светодиоды как запрашивать данные с МК .. но проблема в том что оно всё какбы в одной переменной. И как можно реализовать опрос .. зажжен ли светодиод или нет.

  • Вениамин Кейвер:

    Доброго дня! А есть возможность по окончании каждого сеанса построения графика сохранять его в jpg или в другом формате?

  • admin:

    Конечно, если допишите :mrgreen: Если серьезно, то это пример-заготовка, а не готовое решение.

  • Михаил:

    Проверил. Работает. Спасибо.

  • Максим:

    Посоветуйте хорошую информацию по написанию портативного осциллографа на СИ, может книги какие или журналы, с основ желательно

  • admin:

    По аналоговой части лучше почитать хоровиц хила. Информацию о том как работает ацп, лучше гуглить. Си тут собственно не причем.

  • Денис:

    Это круто, только как подключать к компьютеру все это дело?

  • admin:

    через переходник usb/uart

  • Толя:

    Спасибо за статью! Подскажите, а как по оси х задать время?

  • Мешок:

    В идеале вы в состоянии поймать байтик из юарта и вывести полученный текст на форму.
    Вот с этим могут быть у новичков проблемы, не было же такого урока.
    Хотите вывести полученный по UART байт на форму — поместите компонент serialPort на форму, ведь именно он отвечает за ком порт и при событии DataReceived (получение данных) изменяйте надпись.
    Не все так просто, ведь событие DataReceived генерируется в дополнительном потоке. Хотелось бы урок и на эту тему)

  • admin:

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

  • pavletko:

    Добрый день! Будет ли такое работать с ATSAM4E16C? От чего он у вас питается и что значит «В качестве схемы крутилка потенциометра» ?

  • admin:

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Счетчик
Яндекс.Метрика