Chinaunix首页 | 论坛 | 博客
  • 博客访问: 358368
  • 博文数量: 76
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-21 22:30
文章分类
文章存档

2014年(38)

2013年(38)

分类: C/C++

2014-01-02 17:41:15

看到大神们用Arduino、AVR做示波器,感觉很好玩,手头的pcDuino能不能做呢?一不做二不休,现在我们就自己用pcDuino做一个。
硬件清单:
pcDuino一块
杜邦线若干
软件环境:
1、pcDuino板载ubuntu
2、GCC 4.6
3、QT 4.8.5:
4、OpenGL:qt library自带
5、Arduino SDK(c_enviroment):
照例先来捋一下思路,由于手头没有LCD模块,只能用显示器来充当示波器的屏幕了(27寸的示波器,哇咔咔~)。因为涉及到绘图,这里我使用OpenGL作为绘图工具,虽然有点炮打蚊子的感觉,但是。。。还有什么比OpenGL更好的跨平台图形库呢?同时逼格也得到提升,何了乐而不为。嘿嘿~
实现原理很简单,通过pcDuino的analogRead函数读取信号源的电压变化,再用OpenGL构建一个坐标系,X轴代表时间,Y轴代表电压,持续绘制电压随时间的变化曲线,就得到我们需要的波形图像了。
QT和OpenGL的环境搭建请参照这个帖子,这里不再赘述:
下面来看关键的GLWidget类代码,完整的QT项目源码稍后奉上,或通过邮件和微信与我联系索取:)。
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    
#include "OpenGLwidget.h"
#include
#include
#include
#include
#include
#include
#include
#include
            
//出于性能考虑宏定义一些必要的常量计算
//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          *(ver[i]) = xstep+=STEP;
         *(ver[i]+1) = analogRead(5)/ANALOGVALUE;
         glVertex2fv(ver[i]);
     }
     //std::cout<      glEnd();
     //把顶点数据压入opengl的渲染管道,开始绘图
     glFlush();
}
//窗口大小变化的回调函数
void OpenGLWidget::resizeGL( int width, int height ){
    //std::cout<     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的方波,似乎很工整
opengl joker pcduino
我们加快频率到800,缩短占空比
opengl joker pcduino
实测我的写法只能支持2kHz左右的带宽,求大神优化:)
看腻了方波工整的信号,我索性输入一个音频信号,大家猜猜是哪首歌?猜对有奖:)
opengl


阅读(2056) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~