看到大神们用Arduino、AVR做示波器,感觉很好玩,手头的pcDuino能不能做呢?一不做二不休,现在我们就自己用pcDuino做一个。

硬件清单:
pcDuino一块
杜邦线若干
软件环境:
1、pcDuino板载ubuntu
2、GCC 4.6
4、OpenGL:qt library自带
5、Arduino SDK(c_enviroment):https://github.com/pcduino/c_enviroment
 
照例先来捋一下思路,由于手头没有LCD模块,只能用显示器来充当示波器的屏幕了(27寸的示波器,哇咔咔~)。因为涉及到绘图,这里我使用OpenGL作为绘图工具,虽然有点炮打蚊子的感觉,但是。。。还有什么比OpenGL更好的跨平台图形库呢?同时逼格也得到提升,何了乐而不为。嘿嘿~
实现原理很简单,通过pcDuino的analogRead函数读取信号源的电压变化,再用OpenGL构建一个坐标系,X轴代表时间,Y轴代表电压,持续绘制电压随时间的变化曲线,就得到我们需要的波形图像了。
QT和OpenGL的环境搭建请参照这个帖子,这里不再赘述:http://www.oschina.net/question/1174645_121352
下面来看关键的GLWidget类代码,完整的QT项目源码稍后奉上,或通过邮件和微信与我联系索取:)。 
#include "OpenGLwidget.h"
#include <QTimer>
#include <QKeyEvent>
#include <math.h>
#include <iostream>
#include <GL/glu.h>
#include <Arduino.h>
#include <Serial.h>
#include <wiring_private.h>
 
//出于性能考虑宏定义一些必要的常量计算
//step定义opengl的x轴步长,即把x轴的-1到1均分成窗口的宽度(像素)
#define STEP 2/800.0
//units定义了窗口的x轴有800个点
#define UNITS 800
//pcduino的12bits ADC范围是0~4095,正负各4095
#define ANALOGVALUE 4095*2
 
//定义opengl的顶点二维数组,800个点,每个点由两个float组成
GLfloat ver[UNITS][2];
//定义了x轴的起步值,-1.0即屏幕的最左边
GLfloat xstep = -1.0;
 
//openglwidget的构造器,设置了窗口大小、窗口标题和更新opengl画布的signal
OpenGLWidget::OpenGLWidget( QWidget* parent)
    : QGLWidget(parent){
    setGeometry( 0, 30, 800, 600 );
    setWindowTitle("Joker's OpenGL Framework");
    t = new QTimer(this);
    connect(t, SIGNAL(timeout()), this, SLOT(updateGL()));
    t->start(0);
}
 
OpenGLWidget::~OpenGLWidget(){
 
}
 
//opengl的初始化函数
void OpenGLWidget::initializeGL(){
    glShadeModel( GL_SMOOTH );
    //设置颜色清空颜色,参数依次为RGBA,这里是一个我觉得比较帅气的灰色:)
    glClearColor( 0.3, 0.3, 0.3, 1.0 );
    glClearDepth( 1.0 );
    //开启深度测试
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    //开启opengl的反锯齿
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glEnable(GL_POINT_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_POLYGON_SMOOTH);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
 
}
 
//opengl的绘制函数,调用一次绘制一帧画面
void OpenGLWidget::paintGL(){
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLoadIdentity();
     //清空颜色缓冲区
     glClear(GL_COLOR_BUFFER_BIT);
     //定义视点、原点和视角俯仰,由于这个例子只是2d绘图,可以忽略
     gluLookAt (0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
     //绘制两条直线代表x和y坐标轴
     glBegin(GL_LINES);
     glColor3f(0.5,0.5,0.5);
     //这两个点可以画x轴
     glVertex2f(-1.0f, 0.0f);
     glVertex2f(1.0f, 0.0f);
     //这两个点可以画y轴
     glVertex2f(0.0f, -1.0f);
     glVertex2f(0.0f, 1.0f);
     glEnd();
     //绘制波形,用opengl的一个line strip定义,line strip其实就是一组点连成的线
     glBegin(GL_LINE_STRIP);
     //定义line strip的颜色,这里也是我认为比较帅气的绿色,哈哈
     glColor3f(0.0,1.0,0.0);
     //这个循环会通过analogRead取得电压数值,并把这个电压值转换成波形的y值,写入顶点数组
     for(int i=0;i<UNITS;i++){
         *(ver[i]) = xstep+=STEP;
         *(ver[i]+1) = analogRead(5)/ANALOGVALUE;
         glVertex2fv(ver[i]);
     }
     //std::cout<<analogRead(5)/4095.0*2<<std::endl;
     glEnd();
     //把顶点数据压入opengl的渲染管道,开始绘图
     glFlush();
}
//窗口大小变化的回调函数
void OpenGLWidget::resizeGL( int width, int height ){
    //std::cout<<width<<"*"<<height<<std::endl;
    if ( height == 0 )
    {
        height = 1;
    }
    glViewport(0,0,(GLint)width,(GLint)height );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    //gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}
//键盘按键的回调函数,按esc退出
void OpenGLWidget::keyPressEvent(QKeyEvent *e){
    switch ( e->key() ){
      case Qt::Key_Escape:
        close();
    }
}

编译运行,由于手头没有信号发生器,我就拿pcduino的PWM信号简单测试一下:

PWM输出的200Hz的方波,似乎很工整
 
 
我们加快频率到800,缩短占空比
 
实测我的写法只能支持2kHz左右的带宽,求大神优化:)
看腻了方波工整的信号,我索性输入一个音频信号,大家猜猜是哪首歌?猜对有奖:) 

作者博客原文:http://blog.jokerjewel.com/articles/2013/12/21/1387628153495.html

OpenGL和pcDuino搭建数字示波器的更多相关文章

  1. Android OpenGL ES 开发(二): OpenGL ES 环境搭建

    零:环境搭建目的 为了在Android应用程序中使用OpenGL ES绘制图形,必须要为他们创建一个视图容器.其中最直接或者最常用的方式就是实现一个GLSurfaceView和一个GLSurfaceV ...

  2. 【游戏开发】基于VS2017的OpenGL开发环境搭建

    一.简介 最近,马三买了两本有关于“计算机图形学”的书籍,准备在工作之余鼓捣鼓捣图形学和OpenGL编程,提升自己的价值(奔着学完能涨一波工资去的).俗话说得好,“工欲善其事,必先利其器”.想学习图形 ...

  3. OpenGL(1)-环境搭建

    写在前面 工作几年,开始沉心做技术,对自己的知识进行梳理. OpenGL是由khronos组织制定并维护的规范,并不是API. OpenGL在3.2之前采用的是立即渲染模式(固定渲染管线),3.2之后 ...

  4. OpenGL学习(1)—— 测试OpenGL环境是否搭建成功

    一个用来验证OpenGL(glfw + glad)环境是否搭建成功的测试代码 内容为生成一个小窗口 #include <glad/glad.h> #include <GLFW/glf ...

  5. Windows Opengl ES 环境搭建

    环境 OS:win7 专业版SP1 64位 编译器: VS 2013 express 的cl 软件 windows上运行OpenGL ES要用到第三方的头文件,库文件和dll.下载地址 http:// ...

  6. Linux OpenGL 实践篇-1 OpenGL环境搭建

    本次实践所使用环境为CentOS 7. 参考:http://www.xuebuyuan.com/1472808.html OpenGL开发环境搭建: 1.opengl库安装 opengl库使用mesa ...

  7. OpenGL搭建环境-VS2012【OpenGL】

    在学习cocos2dx时,其底层就用到了OpenGL,因此,想要能够精通cocos2dx,还是需要了解OpenGL的. 本着这个目的,开始搭建OpenGL的环境,并进行学习. OpenGL环境的搭建相 ...

  8. OpenGL ES之GLFW窗口搭建

    概述 本章节主要总结如何使用GLFW来创建Opengl窗口.主要包括如下内容: OpenGl窗口创建介绍 GLFW Window版编译介绍 GLFW简单工程源码介绍 OpenGL窗口创建介绍 能用于O ...

  9. vs2012搭建OpenGL环境

    1. 下载glut库 glut库地址为:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip glut全称为:OpenGL ...

随机推荐

  1. poj 2060 Taxi Cab Scheme (最小路径覆盖)

    http://poj.org/problem?id=2060 Taxi Cab Scheme Time Limit: 1000MS   Memory Limit: 30000K Total Submi ...

  2. storyboard 总结

    1.storyboard 布局时用代码实现页面跳转: a> 获取当前 storyboard : [self storyboard] b> 为将要跳转到的 viewController 添加 ...

  3. java第五课:方法

    方法交换位置的三个步骤:1.把第一个盒子里的东西拿出来,放到一边2.把第二个盒子里的东西放到第一个盒子里3.捡起刚刚放到一边的东西,放到第二个盒子里 值传递:实际参数将内部保存的值,复制给方法的参数. ...

  4. google protobuf 使用示例

    定义.proto接口文件 package tutorial; message Person { required ; required int32 id = ; //unique ID number ...

  5. ITQ迭代量化方法解析

    一.问题来源 来源于换关键字,从LSH转换为hash检索,这要感谢李某. 二.解析 笔者认为关键思想是数据降维后使用矩阵旋转优化,其他和LSH一样的. 2.1 PCA降维 先对原始空间的数据集 X∈R ...

  6. C语言itoa()函数和atoi()函数详解(整数转字符)

    http://c.biancheng.net/cpp/html/792.html C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. 以下是用itoa()函数将整 ...

  7. linux配置防火墙详细步骤(iptables命令使用方法)

    通过本教程操作,请确认您能使用linux本机.如果您使用的是ssh远程,而又不能直接操作本机,那么建议您慎重,慎重,再慎重! 通过iptables我们可以为我们的Linux服务器配置有动态的防火墙,能 ...

  8. 如何用DELPHI编程修改外部EXE文件的版本信

    右击里面有修改 点开直接修改就可以了吧. DELPHI 里程序的版本信息怎么是灰色的,无法更改 耐心读以下说明,应该能解决你的问题,如果不能解决,请Hi我~ 如何给自己的dll文件添加版本信息呢? 首 ...

  9. Magento学习

    Magento是一个php电子商务系统. 内部模块化. 创建模块流程 Magento系统模块 app/code/core/Mage 其中每一个子目录都是一个单独的模块 自己创建的模块放在下面路径 ap ...

  10. matlab 设置横纵坐标刻度的字体!!

    set(gca,'FontSize',16) %%设置横纵坐标字体的大小