World’s Crappiest Oscilloscope… v1

When Ms Geek gave me an Arduino Leonardo to play with, one of the first things I did was go through the examples. After almost two decades of experience with PICs, I was amazed at how easy it was to get things like serial communication and ADC working. Don’t get me wrong – I’m still a PIC guy… but I think I’m an Arduino guy now, too.

The ReadAnalogVoltage example caught my attention because it was so simple. Here’s the setup. It’s just a potentiometer with one end terminal connected to +5v and one to GND, and the wiper connected to A0:

Not much to it, eh? That bent yellow wire in the middle just holds the Leonardo in place.

I played around with it for a while and watched the output on the Serial Plotter, but then I had a thought. You need to run the Arduino software to use the Serial Plotter, and besides, the Serial Plotter looks too nice. Half-remembered days of coaxing dusty old VT100 and TN3270 terminals back to life and running a BBS made me think – I could do the same thing, but not as good!

I dug through some of my old PIC programs and found a serial terminal that I wrote back in 2002. Between that and the ANSI sequences at http://ascii-table.com/ansi-escape-sequences.php, I stapled together a really bad looking display that I like to call the World’s Crappiest Oscilloscope, v1. Here’s the program:

// World's crappiest oscilloscope v1
// Borrows heavily from ReadAnalogVoltage example in the Arduino Examples menu
// Uses Arduino Leonardo, reads voltage on analog pin A0, then uses good old ANSI
// codes to
// draw a really bad oscilloscope in a serial terminal.
// A little amusing but very useless.
// Info about ANSI codes is at http://ascii-table.com/ansi-escape-sequences.php
// **THIS PROGRAM IS FREE TO USE AND MODIFY AS YOU SEE FIT**

void setup() {

  pinMode(A0, INPUT); // Set pin A0 to input.

  Serial.begin(9600); // initialize serial communication at 9600 bits per second.

  delay(3000);  // Should be enough time to start up a serial terminal.

  // Warm up the tubes...
  Serial.write(27); // Clear terminal screen with ESC [2J and ESC is ASCII 27
  Serial.print("[2J");
  Serial.println("Warming up the tubes, please wait...");
  delay(2000);  // This just here for dramatic effect.
  Serial.println("Starting...");
  delay(2000);  // This also just here for dramatic effect.
}


void loop() {

  // Now set up the fancy oscilloscope screen. Ah, the good old ANSI days...

  // Set Oscilloscope screen to white markers on black background.
  Serial.write(27);
  Serial.print("[0;37;40m");
  
  Serial.write(27);  // Clear Terminal screen with (esc)[2J, (esc) is ASCII 27
                    // Serial.write sends binary data to the serial port
  Serial.print("[2J");
  Serial.write(27); // ESC again.
  Serial.print("[H"); // cursor to home.

  // The following lines draw the scale up the left side of the terminal screen and
  // the bottom border.
  Serial.print("5.00V|\r\n");
  Serial.print("4.75V|\r\n");
  Serial.print("4.50V|\r\n");
  Serial.print("4.25V|\r\n");
  Serial.print("4.00V|\r\n");
  Serial.print("3.75V|\r\n");
  Serial.print("3.50V|\r\n");
  Serial.print("3.25V|\r\n");
  Serial.print("3.00V|\r\n");
  Serial.print("2.75V|\r\n");
  Serial.print("2.50V|\r\n");
  Serial.print("2.25V|\r\n");
  Serial.print("2.0V0|\r\n");
  Serial.print("1.75V|\r\n");
  Serial.print("1.50V|\r\n");
  Serial.print("1.25V|\r\n");
  Serial.print("1.00V|\r\n");
  Serial.print("0.75V|\r\n");
  Serial.print("0.50V|\r\n");
  Serial.print("0.25V|\r\n");
  Serial.print("0.00V|________________________________________________________________________________\r\n"); // 80x _
  Serial.print("                         WORLD'S CRAPPIEST OSCILLOSCOPE v1\r\n");

  byte ColumnCount = 7; // Okay, there are 50 columns to put data into, starting at column 7 and ending at 57.

  while (ColumnCount <= 87){
    int sensorValue = analogRead(A0); // read the input on analog pin 0. Need to use an int because it's a 10-bit number.
    
    float voltage = sensorValue * (5.0 / 1023.0); // Convert the reading (which goes from 0 - 1023) to a voltage (0 - 5V).

    int OscOut = (voltage * 4);  // so far so good but need to make it go the other way
 
    OscOut = 21 - OscOut;

    // now, staple everything together into one string to control the cursor
    // Control cursor position: ESC then [line;columnH
    
    String OscStr;
    OscStr = '[';
    OscStr = OscStr + OscOut;
    OscStr = OscStr + ';';
    OscStr = OscStr + ColumnCount;
    OscStr = OscStr + 'H';

    Serial.write(27);

    // Just for kicks, let's try to change the trace colour to green.
    Serial.print("[0;32;40m");

    Serial.write(27);

    Serial.print(OscStr);
    Serial.print("*");

    ColumnCount = ColumnCount +1;
  
    delay(50); // wait a bit before going back so the screen doesn't fly by too quickly.
  }

}

I really need to figure out how to widen the blocks in this theme… it kind of mangles the formatting. If you copy and paste it directly, it still works though. This is what it does (don’t start the video unless you have a strong heart – it’s THAT amazing):

I wonder if there actually were any of those old terminals set up with something like this back in the day…

Leave a Reply

Your email address will not be published. Required fields are marked *