Today I’ll talk about a really good project you can do with your Arduino! This is the best way you can have a cheap oscilloscope around, I didn’t write this code, I’ve found it on the internet a while back ago and I’ve decided to share this awesome project. Let’s start…
First, download Processing. It’s free Click here to download. You don’t need to install anything, It runs like the Arduino IDE.
Upload this code to your Arduino
/*
Complete project details: https://randomnerdtutorials.com/arduino-poor-mans-oscilloscope/
*/
#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 );
}
Then Run this code in Processing IDE
/*
* 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 ([email protected])
*
* 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/>.
*/
import processing.serial.*;
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int[] values;
float zoom;
void setup()
{
size(1280, 480);
// Open the port that the board is connected to and use the same speed (9600 bps)
port = new Serial(this, Serial.list()[0], 9600);
values = new int[width];
zoom = 1.0f;
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;
}
}
void draw()
{
background(0);
drawGrid();
val = getValue();
if (val != -1) {
pushValue(val);
}
drawLines();
}
And then you just need to connect the Arduino analog pin 0 to the signal you want to read.
And It’s done!
Parts required
- Arduino UNO – read Best Arduino Starter Kits
- 1x Breadboard
- 1x LED
- 1x 10k resistor
- 1×4.7k resistor
- 1x 1k resistor
- 1x 100nF electrolytic capacitor
- Jumper wires
Schematics
This is the circuit I’ll be measuring , it’s a simple 555 timer circuit… that flashes an LED.
Watch the video demonstration
Thanks for reading, you can contact me by leaving a comment. If you like this post probably you might like my next ones, so please support me by subscribing my blog and my Facebook Page.
I like it.
Thanks 🙂
What is the Scope time base setting?
actually there’s no windows where you can change the time base, you can do that by changing the code a bit probably
Hi Rui,
Just got today the Teensey and used your intro toturial.
I would like to see how many sample points I can get via the Teensey Serial port (from Analog Pin 0). I sued your Code but the second one that should draw the trace caused several errors.
especially on the line “import processing.serial.*;”
Are there any preconditions?
btw: I am quite new to the Arduino stuff and C-Programming, I just modify some example codes.
Thanks
Hi Yariv,
Sorry for taking so long to answer I’ve been really busy and thanks for trying my projects.
Are you trying to upload the Processing code into your Arduino?
Don’t do that… The processing code should be only running you your computer.
The code that you need to upload to the Teensy board is this code only:
https://gist.github.com/chrismeyersfsu/3270358#file-gistfile1-c
I followed the instructions but no signal output on the processing screen, any help is most appreciated.
Thanks
Very informative post, i’m regular reader of your blog.
I noticed that your site is outranked by many other blogs in google’s search results.
You deserve to be in top10. I know what can help you,
search in google for:
Omond’s tips outsource the work
In every port, you will be amused by the different
activities such as partying in the different dockside establishments.
You will spend less time building your boat if the
plans are clear and easy to follow, you will spend less money trying to fix
problems due to inadequate or poorly designed plan elements.
But what good is sailing without food that appeals to the palate.
Dear Sir,
Can possible multi program upload 1 arduino broad ? and multi output?
You can only upload one program to an Arduino
Hi Rui,
Can you explain what the code is doing?
Can the o’scope traces be displayed in the serial plotter? How would you do that?
Thanks!
More information on the serial plotter: https://randomnerdtutorials.com/arduino-serial-plotter-new-tool/
Yes, but the serial plotter is very limited and it doesn’t offer most of the features that processing does
OK – room for the serial plotter to improve, I guess.
You still didn’t answer my first question 🙂
What is this code doing:
int val = analogRead(ANALOG_IN);
Serial.write( 0xff );
Serial.write( (val >> 8) & 0xff );
Serial.write( val & 0xff );
Thanks!
I know this was asked a long time ago, but in case someone is reading this and wondering, the code reads read the value (voltage) from pin ANALOG_IN (defined earlier as pin 0) into variable “val” of type integer (which is 16-bit). This value is from 0 to 1023 (corresponding to the range of 0 V to VCC V – 5V or 3.3V depending on which Arduino board is it). It then sends this value to the serial port (-> USB port of the computer), with a “magic” prefix of 0xFF.
(val >> 8) & 0xff
is the upper 8 bits of the 16-bit int, andval & 0xff
is the lower 8 bits – >> and & are just binary operations (right shift and binary AND).sorry but 16 bit is around 65k resolution. So 1024 is 10 bit resolution and 8 bit is only 256 but dont understant why the corect way is not “Serial.write( val & 0x00 );”?? i get that left shift 8 positions and then write “val” witch is 10 positions but after that 0xff is 256 or 8 bit .. and last 2 bits are they not somehow colide with your 10 bit val… i know i missing something 🙂
An int in this context is 16 bit (two bytes). Arduino’s ADC is 10-bit, indeed. So, any result of analogRead will obviously have the upper 6 bits as zeros. The code above wants to write the data to serial output. Serial.write can write bytes, strings or arrays (must specify the length). The author of the above code decide to write it as bytes. A 16-bit int consists of two bytes (in our case the upper byte has only 2 relevant digits, the rest are zeros, but it doesn’t really matter). To extract the upper and lower bytes from an int, we can use respectively
(val >> 8) & 0xff
andval & 0xff
. This is basic binary arithmetic. Just write 16 random binary digits on a piece of paper and do these operations by hand: “shift right by 8 positions, with the overflowing digits just disappearing, then bitwise AND 111111111”, or just “bitwise AND 11111111” and you will see how it works.You mentioned
val & 0x00
(might as well have writtenval & 0
), this doesn’t make sense, this will be always zero (anything & 0 is 0). If something’s still not clear, just read up on bitwise binary arithmetic operatorsWhat is the maximum frequency it could currently display, and what could be modified to support higher frequency signals.
Is there a possibility that they update the project and make it for an ESP32 or maybe a Raspberry Pico?