I had a heck of a time finding a usable basic oscilloscope so i combined a couple poor man's scopes I found
its simple, basic and quick. Feel free to improve it ... I wont have time to work on it for awhile ![]()
It uses an arduino and processing ...
/*
This particular release should be considered a Beta release. I'll call it Beta V0.9 The timing scale is likely not correct right now as it assumes
10k samples per second which is prolly kinda high! its prolly closer to 5k.
Copy and paste this top code into processing and the bottom code ino the arduino ide and load it.
Inspiration cam from the poor mans oscilliscope which i found here http://accrochages.drone.ws/en/node/90 and also
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233536778
This release had in mind simple and uses the computer to buffer the samples. There are directions at the bottom of the
processing window when you use it.
General idea is you hit the 'c' button to start a 6 second capture which is then displayed in the viewer window. You can zoom in
and scroll left and right ...
Feel free to hack and improve :-) I had a hard time finding a suitable software oscilliscope so I hope this helps someone
- Hotshotharry :-)
*/
import processing.serial.*;
Serial inPort;Â Â Â Â Â Â Â Â Â Â Â Â Â // the port to read from
int BAUD_RATE = 230400;Â Â Â Â Â Â Â Â Â // set baud rate here, needs to be the same value as in the arduino code
int BUFFER_SIZE=60000;Â // data buffer size (bytes - default use is 1 byte per smaple
int BUFFER_ZOOM;
int BUFFER_WINDOWLO;
int BUFFER_WINDOWHI;
int GRIDS=10;Â Â // number of grids to draw
int range = 10000;  // samples per second *** not currently working but all calculations are based on this
float value;
int inVal;Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // y-data read in from the arduino
//int lastVal;Â Â Â Â Â Â Â Â Â Â Â Â Â Â // old value of y-data
int[] yVals = new int[BUFFER_SIZE];Â Â Â // y-data buffer, scaled to the screen size
int[] xVals = new int[BUFFER_SIZE];Â // x-data buffer, scaled to the screen size
//int trigger;Â Â Â Â Â Â Â Â Â Â Â Â Â Â // trigger, when the incoming data passes this value a frame starts
//int timeOut;Â Â Â Â Â Â Â Â Â Â Â Â Â Â // if no trigger is detected by timeOut samples, plot what is at input port
int i;Â Â Â
int j;
boolean blinker;            // blinks a light on each frame update so you know when program is running Â
//boolean noTrigger;Â Â Â Â Â Â Â Â Â Â Â // true until trigger is detectedÂ
//boolean noTimeOut;Â
int width = 1400;Â Â // display window width
int displaywidth;
int height = 400;Â Â // display window height
int capture = 0;Â Â // capture flag dont touch
int zoom = 1;Â Â Â Â //zoome value dont touch
int windows;Â Â Â //value for some display calulations dont touch
int slidingwindow;Â //value for zoom window sizing dont touch
void setup()
{Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
 inPort = new Serial(this, Serial.list()[0], BAUD_RATE); Â
 size(width, height);                     Â
 background(0);
 stroke(255);
 inPort.clear();
 drawgrid();
 println("Press c to capture ");
 println("Press + to zoom in and - to zoom out ");
 println("Press < to scroll trace left and > to scroll trace right");
}
void draw()
{
 if (inPort.available()>=BUFFER_SIZE && capture == 0) {
  // dump any old data sent while program wasn't running or was busy
  inPort.clear();
 }
 if (inPort.available()>=BUFFER_SIZE && capture == 1) {Â
  getdata();
  drawgrid();
  drawtrace();
 }
}
void getdata() {
 capture = 0;Â
 for (i=0;i<BUFFER_SIZE-1;i++) {                      // read a buffer full of date        Â
  inVal=( inPort.read());
  yVals[i]=height-((height)*inVal)/254;          // scale data to screen height
  xVals[i]=(width*i)/BUFFER_SIZE;             // scale x-value to screen width
 }
}
void drawgrid() {
 background(0);
 stroke(0, 64, 0);
 for (i=1;i<GRIDS;i++) {
  line((width*i)/GRIDS, 0, (width*i)/GRIDS, height);
  line(0, (height*i)/GRIDS, width, (height*i)/GRIDS);
  // stroke(128,0,128);
  //line(0,height-(height*trigger)/254,width,height-(height*trigger)/254);
 }
}
void drawtrace() {
 for (i=1;i<BUFFER_SIZE-1;i++) {
  stroke(0, 245, 0);
  line(xVals[i-1], yVals[i-1], xVals[i], yVals[i]);
  stroke(255, 0, 0);
  point(xVals[i-1], yVals[i-1]);
 }
}
void drawgridzoom() {Â // ------------------------------Â ZOOM
 background(0);
 stroke(0, 64, 0);
 for (i=1;i<GRIDS;i++) {
  line((width*i)/GRIDS, 0, (width*i)/GRIDS, height);
  line(0, (height*i)/GRIDS, width, (height*i)/GRIDS);
  // stroke(128,0,128);
  //line(0,height-(height*trigger)/254,width,height-(height*trigger)/254);
 }
}
void drawtracezoom() {Â // -----------------------------Â ZOOM
 for (i=1;i<BUFFER_ZOOM;i++) {
  //for (i=1;i<(BUFFER_ZOOM);i++) {
  // stroke(0, 245, 0);
  //line(xVals[(i-1)*zoom], yVals[i-1], xVals[i*zoom], yVals[i]);
  //stroke(255, 0, 0);
  // point(xVals[(i-1)*zoom], yVals[i-1]);
  stroke(0, 245, 0);
  line((width*(i-1))/BUFFER_ZOOM, yVals[i-1], (width*i)/BUFFER_ZOOM, yVals[i]);
  stroke(255, 0, 0);
  point(width*(i-1)/BUFFER_ZOOM, yVals[i-1]);
 }
}
void drawtracescan() {Â // -----------------------------Â ZOOM
 for (i=BUFFER_WINDOWLO;i<BUFFER_WINDOWHI;i++) {
  //for (i=1;i<(BUFFER_ZOOM);i++) {
  // stroke(0, 245, 0);
  //line(xVals[(i-1)*zoom], yVals[i-1], xVals[i*zoom], yVals[i]);
  //stroke(255, 0, 0);
  // point(xVals[(i-1)*zoom], yVals[i-1]);
  stroke(0, 245, 0);
  line((width*(i-1-BUFFER_WINDOWLO))/BUFFER_ZOOM, yVals[i-1], (width*(i-BUFFER_WINDOWLO))/BUFFER_ZOOM, yVals[i]);
  stroke(255, 0, 0);
  point(width*(i-1-BUFFER_WINDOWLO)/BUFFER_ZOOM, yVals[i-1]);
 }
}
void keyReleased() {
 switch (key) {
 case 'c':
  capture = 1;
  inPort.clear();
  println("");
  print("Capturing sample ");
  print(BUFFER_SIZE/10000);
  println(" seconds long");
  println("");
  break;
 case '+':
  zoom *= 2.0f;
  //println(zoom);
  if ( (int) (width / zoom) <= 1 ) zoom /= 2.0f;
  displaywidth = width/zoom;
  BUFFER_ZOOM = BUFFER_SIZE/zoom;
  BUFFER_WINDOWLO = 1;
  BUFFER_WINDOWHI = BUFFER_ZOOM; Â
  drawgridzoom();
  drawtracezoom();
  println("Zoom In");
  print("Period ");
  print(BUFFER_SIZE/zoom/10);
  println(" ms");
  println("");
  break;
 case '-':
  if (zoom != 1) {
   zoom /= 2.0f;
  }
  println(zoom);
  if (zoom < 1.0f) zoom *=2.0f;
  displaywidth = width/zoom;
  BUFFER_ZOOM = BUFFER_SIZE/zoom;
  BUFFER_WINDOWLO = 1;
  BUFFER_WINDOWHI = BUFFER_ZOOM;
  drawgridzoom();
  drawtracezoom();
  println("Zoom Out");
  print("Period ");
  print(BUFFER_SIZE/zoom/10);
  println(" ms");
  println("");
  break;
 case '<':
  println("Move trace to the left.");
  windows++;
  if (windows > zoom) windows = zoom;
  slidingwindow = BUFFER_SIZE/zoom;
  BUFFER_WINDOWHI = slidingwindow * windows;
  BUFFER_WINDOWLO = (slidingwindow * windows) - slidingwindow;
  if (BUFFER_WINDOWLO == 0) BUFFER_WINDOWLO = 1;
  print("Window sample width ");
  print(BUFFER_SIZE/zoom/10);
  println(" ms");
  //println(slidingwindow);
  print("From ");
  print(BUFFER_WINDOWLO/10);
  print(" To ");
  print(BUFFER_WINDOWHI/10);
  print(" ms of ");
  print(BUFFER_SIZE/10);
  println(" ms");
  drawgridzoom();
  drawtracescan();
  break;
 case '>':
  println("Move trace to the right.");
  windows--;
  if (windows < 1) windows = 1;
  slidingwindow = BUFFER_SIZE/zoom;
  BUFFER_WINDOWHI = slidingwindow * windows;
  BUFFER_WINDOWLO = (slidingwindow * windows) - slidingwindow;
  if (BUFFER_WINDOWLO == 0) BUFFER_WINDOWLO = 1;
  print("Window sample width ");
  print(BUFFER_SIZE/zoom/10);
  println(" ms");
  //println(slidingwindow);
  print("From ");
  print(BUFFER_WINDOWLO/10);
  print(" To ");
  print(BUFFER_WINDOWHI/10);
  print(" ms of ");
  print(BUFFER_SIZE/10);
  println(" ms");
  drawgridzoom();
  drawtracescan();
  break;
 }
}
/* ----------- Start of arduino code -------------
#include <avr/io.h>
#define BAUD_RATE 230400Â Â // processing must be set to the same rate
#define INPUT_PIN 0
unsigned char data;
void setup()
{
 Serial.begin(BAUD_RATE);      Â
}
void loop() {
 data = (analogRead(INPUT_PIN)/4); // changes data to 8 bit value < 256 ie one byte to maximize transfer
 Serial.write(data);
}Â
*/ // ------------- end of arduino code -----------------