Skip to content

Instantly share code, notes, and snippets.

@hadoopmarc
Last active January 7, 2024 14:08
Show Gist options
  • Save hadoopmarc/77ecd3d6ab098faa3cbdded3760660db to your computer and use it in GitHub Desktop.
Save hadoopmarc/77ecd3d6ab098faa3cbdded3760660db to your computer and use it in GitHub Desktop.
Improved time resolution for the "poor man's oscilloscope"
/*
* Oscilloscope
* Gives a visual rendering of analog pin 0 in realtime.
*
* This project is part of Accrochages
* See http://accrochages.drone.ws
*
* (c) 2008 Sofian Audry (info@sofianaudry.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Original blog: https://www.instructables.com/Arduino-Oscilloscope-poor-mans-Oscilloscope/
// Original source: https://gist.github.com/chrismeyersfsu/3270419#file-gistfile1-c
// Pause feature: https://gist.github.com/zsolt-szilagyi/2e4088f6ba0d30c04aa6bc589fb41739
// Current source: https://gist.github.com/hadoopmarc/77ecd3d6ab098faa3cbdded3760660db
import processing.serial.*;
Serial port; // Create object from Serial class
IntList vals; // 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 baudrate as the Arduino
port = new Serial(this, Serial.list()[0], 2000000);
values = new int[width];
zoom = 1.0f;
paused = false;
}
int getY(int val) {
return (int)(height - val / 1023.0f * (height - 1));
}
// Arduino UNO R3 takes about 8000 analog measurements per second.
// Processing IDE seems to have a minimum buffer size of 96 bytes for serial
// events to get processed, irrespective of the port.buffer(3) setting or the
// frameRate of the draw() loop. So, the implementation below reads all values
// from the buffer, once they are available.
IntList getValues() {
IntList vals = new IntList();
while (port.available() >= 3) {
if (port.read() == 0xff) {
int value = port.read() << 8 | port.read();
vals.append(value);
}
}
return vals;
}
void pushValues(IntList vals) {
for (int i = 0; i < width; i++)
if (i < width - vals.size()) {
values[i] = values[i + vals.size()];
} else {
values[i] = vals.get(i - width + vals.size());
}
}
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();
vals = getValues();
if (vals.size() > 0) {
pushValues(vals);
}
drawLines();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment