Arduino示波器(一)
Arduino示波器(一)
一、背景
自ADS1115被Arduino/ESP32/phyphox蓝牙实验开发组发掘,小伙伴们突然有了一个企图:开发一个极为便宜的示波器——真正的金钱上的投入少,因为phyphox实验主打可移动性和低成本——于是查阅了一些中外文献(当然是业余的挤出来的时间),发现大致思路有这么两种:一种是主张精确和准确,纷纷提出STM32、ADC采样等。我是不主张的,追求精确和准确干嘛不用专业的示波器?如果不是玩物丧志的沉溺于diy真的没有必要;另一种则是使用12864等显示波形,但是我们是在研究Arduino&phyphox示波器,最直接的显示途径,便是phyphox了。这样算下来,大致的可取路径有以下几个方向:
使用Arduino/ESP32采集数据,然后使用phyphox来充当显示屏。这个方案实在太过简单,略过了,不研究。
使用Arduino/ESP32采集数据,使用Arduino IDE自带的串口绘图器充当显示屏。这个方案当然极为方便,但是要在串口绘图器上调整div或者hold,以及显示数字,好象不太可能。可以粗略使用,仍然略过,不研究。
使用Arduino/ESP32采集数据,用其他应用程序来显示波形。这个方案,最优搭配绝对是processing莫属!于是到processing官网去查找示波器代码,果然有!简单改改,放在这里用了,是为(一).
这最后的方案,便是12864。自接触单片机以来,只研究过1206和OLED,还没有用过12864,这一个尝试,便只记录Arduino+Processing。
二、Arduino代码
什么新意也没有,从A0读电压,然后送给串口。注意只测了正电压。
#define ANALOG_IN 0
void setup() {
Serial.begin(9600);
//Serial.begin(115200);
}
void loop() {
int val = analogRead(ANALOG_IN);
Serial.write( 0xff );
Serial.write( (val >> 8) & 0xff );
Serial.write( val & 0xff );
}
三、processing代码
以下代码,在processing 3.54下调试通过。代码不是我写的。这个代码似乎很不processing,但人家是现成的代码。不必改了。
按键盘上的+号,图象实现Y增益,-号Y增益减小,按p键,图象保持,即hold。
import processing.serial.*;
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int[] values;
float zoom;
boolean paused;
void setup()
{
size(1280, 600);
// Open the port that the board is connected to and use the same speed (9600 bps)
port = new Serial(this, "COM9", 9600);//这里直接改串口号,运行速度极快
values = new int[width];
zoom = 1.0f;
paused = false;
smooth();
}
int getY(int val) {
return (int)(height - val / 1023.0f * (height - 1));
}
int getValue() {
int value = -1;
while (port.available() >= 3) {
if (port.read() == 0xff) {
value = (port.read() << 8) | (port.read());
}
}
return value;
}
void pushValue(int value) {
for (int i=0; i<width-1; i++)
values[i] = values[i+1];
values[width-1] = value;
}
void drawLines() {
stroke(255);
int displayWidth = (int) (width / zoom);
int k = values.length - displayWidth;
int x0 = 0;
int y0 = getY(values[k]);
for (int i=1; i<displayWidth; i++) {
k++;
int x1 = (int) (i * (width-1) / (displayWidth-1));
int y1 = getY(values[k]);
line(x0, y0, x1, y1);
x0 = x1;
y0 = y1;
}
}
void drawGrid() {
stroke(255, 0, 0);
line(0, height/2, width, height/2);
}
void keyReleased() {
switch (key) {
case '+':
zoom *= 2.0f;
println(zoom);
if ( (int) (width / zoom) <= 1 )
zoom /= 2.0f;
break;
case '-':
zoom /= 2.0f;
if (zoom < 1.0f)
zoom *= 2.0f;
break;
case 'p':
paused = !paused;
break;
}
}
void draw()
{
if(paused) {return;}
background(0);
drawGrid();
val = getValue();
if (val != -1) {
pushValue(val);
}
drawLines();
}