Mini Oscilloscope Using Arduino & OLED Display.
Project Fee:Negotiable
Project Discount:0
Project Duration:7 Days
How to Make a Mini Oscilloscope Using Arduino & OLED Display.
Introduction:
Measuring instruments like the
multi-meter, the oscilloscope and others are essential in the field of
electronics engineering. It is important to say here that the need for
measuring instruments improves accuracy and also gives the engineer the
understanding needed to create an efficient system. Without measurements we
will not be able to live in this modern world. The system discussed in this
report will help engineers to make vital measurements as circuits are being
designed.
This is an Arduino Based
Oscilloscope System. The main brain of our system is the Arduino Nano. In this
system there are four controlling buttons/switches. These buttons are mainly
used for controlling this system output on display. One button is variable
voltage controller, second is hold button, last two buttons are cycle select
and increase/decries.
Firstly input the power to run this system. Then supply 5V current for measuring various outputs. After connecting the extra current source then the system is controlled the proper voltage by the button variable voltage control. It helps to input the proper voltage in this system. If we find the proper wave shape of a signal then we will hold it in our screen by clicking the hold button. After the process if we need to change our cycle of wave we will change our cycle by using the cycle select button. And the last button will work to increase and decrease the current limit of this system. In this system it’s able to display Pure AC sign, Pulsating DC , Pure DC , Square Wave , Saw-tooth wave .
Circuit Diagram:
Figure: Circuit Diagram of an oscilloscope Using Arduino & OLED Display
Block Diagram:
Figure: Block Diagram of an oscilloscope Using Arduino & OLED Display
Required Instrument:
-
Arduino Nano-1nos.
-
OLED Display-1nos.
-
Push Switch.-4nos.
-
Battery.-2nos.
-
Variable Resistor.-1nos.
-
Transformer.-1nos.
-
Diode.-4nos.
-
Capacitor-1nos.
-
Resistor 100k-1nos.
- Resistor 300k-1nos.
Software:
- Arduino
IDE
Download:https://www.arduino.cc/en/software
Summary:
This project is truly interesting and
workable. By following the rules given to us, it will work for 100%. You can
make it for your own use as it has very high accuracy.
[N.B: If you have any problems working, please contact us and we will assist you In-Sha-Allah. ]
Any modification of this project can be done as per your requirement. We will make the project according to your needs. Contact us with your any innovative engineering projects idea. We will help you to implement your project.
Office: Road#04, Plot#03, Sec#6/Ka, Mirpur-2, Dhaka-1216 (Opposite of the Mirpur Cricket Stadium 4 No. Gate.) | e-Mail : projects.zeronebd@gmail.com ☎️Contact: 01676 99 80 99 , 01714 80 84 02 |
#include
#include // PROGMEM
#include
#include
#include
#define SCREEN_HEIGHT 64 // OLED display height
#define REC_LENGTH 200 //
#define SCREEN_WIDTH 128 // OLED display width
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//
const char voltageRangeName[10][5] PROGMEM = {"A50V", "A 5V", " 50V", " 20V", " 10V", " 5V", " 2V", " 1V", "0.5V", "0.2V"}; // \0
const char * const vstring_table[] PROGMEM = {voltageRangeName[0], {voltageRangeName[1], voltageRangeName[2], voltageRangeName[3], voltageRangeName[4], voltageRangeName[5], voltageRangeName[6], voltageRangeName[7], voltageRangeName[8], voltageRangeName[9]};
const char hRangeName[8][6] PROGMEM = {" 50ms", " 20ms", " 10ms", " 5ms", " 2ms", " 1ms", "500us", "200us"}; // (48
const char * const hstring_table[] PROGMEM = {hRangeName[0], hRangeName[1], hRangeName[2], hRangeName[3], hRangeName[4], hRangeName[5], hRangeName[6], hRangeName[7]};
int waveBuff[REC_LENGTH]; // (RAM)
char chrBuff[10]; //
String hScale = "xxxAs";
String vScale = "xxxx";
float lsb5V = 0.0055549; // 5V0.005371 V/1LSB
float lsb50V = 0.051513; // 50V 0.05371
volatile int vRange; // 0:A50V, 1:A 5V, 2:50V, 3:20V, 4:10V, 5:5V, 6:2V, 7:1V, 8:0.5V
volatile int hRange; // 0:50m, 1:20m, 2:10m, 3:5m, 4;2m, 5:1m, 6:500u, 7;200u
volatile int trigD; // 0:1:
volatile int scopeP; // 0:, 1:, 2:
volatile boolean hold = false; //
volatile boolean paraChanged = false; // true
volatile int saveTimer; // EEPROM
int timeExec; // (ms)
int dataMin; // (min:0)
int dataMax; // (max:1023)
int dataAve; // 10 max:10230)
int rangeMax; //
int rangeMin; //
int rangeMaxDisp; // max100
int rangeMinDisp; // min
int trigP; //
boolean trigSync; //
int att10x; // 1
void setup() {
pinMode(2, INPUT_PULLUP); // (int0
pinMode(8, INPUT_PULLUP); // Select
pinMode(9, INPUT_PULLUP); // Up
pinMode(10, INPUT_PULLUP); // Down
pinMode(11, INPUT_PULLUP); // Hold
pinMode(12, INPUT); // 1/10
pinMode(13, OUTPUT); //
// Serial.begin(115200); // RAM
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
// Serial.println(F("SSD1306 failed"));
for (;;); // Don't proceed, loop forever
}
loadEEPROM(); // EEPROM
analogReference(INTERNAL); // ADC1.1Vvref)
attachInterrupt(0, pin2IRQ, FALLING); //
startScreen(); //
}
void loop() {
digitalWrite(13, HIGH);
setConditions(); // RAM40
readWave(); // (1.6ms )
digitalWrite(13, LOW); //
dataAnalize(); // (0.4-0.7ms)
writeCommonImage(); // (4.6ms)
plotData(); // (5.4ms+)
dispInf(); // (6.2ms)
display.display(); // (37ms)
saveEEPROM(); // EEPROM
while (hold == true) { // Hold
dispHold();
delay(10);
}
}
void setConditions() { //
// PROGMEM
strcpy_P(chrBuff, (char*)pgm_read_word(&(hstring_table[hRange]))); //
hScale = chrBuff; // hScale
//
strcpy_P(chrBuff, (char*)pgm_read_word(&(vstring_table[vRange]))); //
vScale = chrBuff; // vScale
switch (vRange) { //
case 0: { // Auto50V
// rangeMax = 1023;
// rangeMin = 0;
att10x = 1; //
break;
}
case 1: { // Auto 5V
// rangeMax = 1023;
// rangeMin = 0;
att10x = 0; //
break;
}
case 2: { // 50V
rangeMax = 50 / lsb50V; //
rangeMaxDisp = 5000; // 100
rangeMin = 0;
rangeMinDisp = 0;
att10x = 1; //
break;
}
case 3: { // 20V
rangeMax = 20 / lsb50V; //
rangeMaxDisp = 2000;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 1; //
break;
}
case 4: { // 10V
rangeMax = 10 / lsb50V; //
rangeMaxDisp = 1000;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 1; //
break;
}
case 5: { // 5V
rangeMax = 5 / lsb5V; //
rangeMaxDisp = 500;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 0; //
break;
}
case 6: { // 2V
rangeMax = 2 / lsb5V; //
rangeMaxDisp = 200;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 0; //
break;
}
case 7: { // 1V
rangeMax = 1 / lsb5V; //
rangeMaxDisp = 100;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 0; //
break;
}
case 8: { // 0.5V
rangeMax = 0.5 / lsb5V; //
rangeMaxDisp = 50;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 0; //
break;
}
case 9: { // 0.5V
rangeMax = 0.2 / lsb5V; //
rangeMaxDisp = 20;
rangeMin = 0;
rangeMinDisp = 0;
att10x = 0; //
break;
}
}
}
void writeCommonImage() { //
display.clearDisplay(); // (0.4ms)
display.setTextColor(WHITE); //
display.setCursor(86, 0); // Start at top-left corner
display.println(F("av V")); // 1
display.drawFastVLine(26, 9, 55, WHITE); //
display.drawFastVLine(127, 9, 55, WHITE); //
display.drawFastHLine(24, 9, 7, WHITE); // Max
display.drawFastHLine(24, 36, 2, WHITE); //
display.drawFastHLine(24, 63, 7, WHITE); //
display.drawFastHLine(51, 9, 3, WHITE); // Max
display.drawFastHLine(51, 63, 3, WHITE); //
display.drawFastHLine(76, 9, 3, WHITE); // Max
display.drawFastHLine(76, 63, 3, WHITE); //
display.drawFastHLine(101, 9, 3, WHITE); // Max
display.drawFastHLine(101, 63, 3, WHITE); //
display.drawFastHLine(123, 9, 5, WHITE); // Max
display.drawFastHLine(123, 63, 5, WHITE); //
for (int x = 26; x <= 128; x += 5) {
display.drawFastHLine(x, 36, 2, WHITE); // ()
}
for (int x = (127 - 25); x > 30; x -= 25) {
for (int y = 10; y < 63; y += 5) {
display.drawFastVLine(x, y, 2, WHITE); // 3
}
}
}
void readWave() { //
if (att10x == 1) { // 1/10
pinMode(12, OUTPUT); //
digitalWrite(12, LOW); // LOW
} else { //
pinMode(12, INPUT); // Hi-z
}
switch (hRange) { //
case 0: { // 50ms
timeExec = 400 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x07; // 128 (arduino
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 112s
delayMicroseconds(1888); //
}
break;
}
case 1: { // 20ms
timeExec = 160 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x07; // 128 (arduino
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 112s
delayMicroseconds(688); //
}
break;
}
case 2: { // 10 ms
timeExec = 80 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x07; // 128 (arduino
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 112s
delayMicroseconds(288); //
}
break;
}
case 3: { // 5 ms
timeExec = 40 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x07; // 128 (arduino
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 112s
delayMicroseconds(88); //
}
break;
}
case 4: { // 2 ms
timeExec = 16 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x06; // 64 (0x1=2, 0x2=4, 0x3=8, 0x4=16, 0x5=32, 0x6=64, 0x7=128)
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 56s
delayMicroseconds(24); //
}
break;
}
case 5: { // 1 ms
timeExec = 8 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x05; // 16 (0x1=2, 0x2=4, 0x3=8, 0x4=16, 0x5=32, 0x6=64, 0x7=128)
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 28s
delayMicroseconds(12); //
}
break;
}
case 6: { // 500us
timeExec = 4 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x04; // 16(0x1=2, 0x2=4, 0x3=8, 0x4=16, 0x5=32, 0x6=64, 0x7=128)
for (int i = 0; i < REC_LENGTH; i++) { // 200
waveBuff[i] = analogRead(0); // 16s
delayMicroseconds(4); //
// 1.875snop 110.0625s @16MHz)
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop");
}
break;
}
case 7: { // 200us
timeExec = 2 + 50; // (ms) EEPROM
ADCSRA = ADCSRA & 0xf8; // 3
ADCSRA = ADCSRA | 0x02; // :4(0x1=2, 0x2=4, 0x3=8, 0x4=16, 0x5=32, 0x6=64, 0x7=128)
for (int i = 0; i < REC_LENGTH; i++) {
waveBuff[i] = analogRead(0); // 6s
// 1.875snop 110.0625s @16MHz)
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
}
break;
}
}
}
void dataAnalize() { //
int d;
long sum = 0;
//
dataMin = 1023; //
dataMax = 0; //
for (int i = 0; i < REC_LENGTH; i++) { //
d = waveBuff[i];
sum = sum + d;
if (d < dataMin) { //
dataMin = d;
}
if (d > dataMax) { //
dataMax = d;
}
}
//
dataAve = (sum + 10) / 20; // 10
// max,min
if (vRange <= 1) { // Auto1
rangeMin = dataMin - 20; // -20
rangeMin = (rangeMin / 10) * 10; // 10
if (rangeMin < 0) {
rangeMin = 0; // 0
}
rangeMax = dataMax + 20; // +20
rangeMax = ((rangeMax / 10) + 1) * 10; // 10
if (rangeMax > 1020) {
rangeMax = 1023; // 10201023
}
if (att10x == 1) { //
rangeMaxDisp = 100 * (rangeMax * lsb50V); // ADC
rangeMinDisp = 100 * (rangeMin * lsb50V); //
} else { //
rangeMaxDisp = 100 * (rangeMax * lsb5V);
rangeMinDisp = 100 * (rangeMin * lsb5V);
}
} else { //
//
}
//
for (trigP = ((REC_LENGTH / 2) - 51); trigP < ((REC_LENGTH / 2) + 50); trigP++) { //
if (trigD == 0) { // 0
if ((waveBuff[trigP - 1] < (dataMax + dataMin) / 2) && (waveBuff[trigP] >= (dataMax + dataMin) / 2)) {
break; //
}
} else { // 0
if ((waveBuff[trigP - 1] > (dataMax + dataMin) / 2) && (waveBuff[trigP] <= (dataMax + dataMin) / 2)) {
break;
} //
}
}
trigSync = true;
if (trigP >= ((REC_LENGTH / 2) + 50)) { //
trigP = (REC_LENGTH / 2);
trigSync = false; // Unsync
}
}
void startScreen() { //
display.clearDisplay();
display.setTextSize(1); // 2
display.setTextColor(WHITE); //
display.setCursor(10, 26); //
display.println(F("CITY University")); //
display.setCursor(10, 45); //
display.println(F(" Mini Oscilloscope"));
display.display(); //
delay(4000);
display.clearDisplay();
display.setTextSize(1); //
}
void dispHold() { // Hold
display.fillRect(32, 12, 24, 8, BLACK); // 4
display.setCursor(32, 12);
display.print(F(" Hold")); // Hold
display.display(); //
}
void dispInf() { //
float voltage;
//
display.setCursor(2, 0); //
display.print(vScale); //
if (scopeP == 0) { //
display.drawFastHLine(0, 7, 27, WHITE); //
display.drawFastVLine(0, 5, 2, WHITE);
display.drawFastVLine(26, 5, 2, WHITE);
}
//
display.setCursor(34, 0); //
display.print(hScale); // (time/div)
if (scopeP == 1) { //
display.drawFastHLine(32, 7, 33, WHITE); //
display.drawFastVLine(32, 5, 2, WHITE);
display.drawFastVLine(64, 5, 2, WHITE);
}
//
display.setCursor(75, 0); //
if (trigD == 0) {
display.print(char(0x18)); //
} else {
display.print(char(0x19)); //
}
if (scopeP == 2) { //
display.drawFastHLine(71, 7, 13, WHITE); //
display.drawFastVLine(71, 5, 2, WHITE);
display.drawFastVLine(83, 5, 2, WHITE);
}
//
if (att10x == 1) { // 10
voltage = dataAve * lsb50V / 10.0; // 50V
} else {
voltage = dataAve * lsb5V / 10.0; // 5V
}
dtostrf(voltage, 4, 2, chrBuff); // x.xx
display.setCursor(98, 0); //
display.print(chrBuff); //
// display.print(saveTimer); //
//
voltage = rangeMaxDisp / 100.0; // Max
if (vRange == 1 || vRange > 4) { // 5VAuto5V
dtostrf(voltage, 4, 2, chrBuff); // *.**
} else { //
dtostrf(voltage, 4, 1, chrBuff); // **.*
}
display.setCursor(0, 9);
display.print(chrBuff); // Max
voltage = (rangeMaxDisp + rangeMinDisp) / 200.0; //
if (vRange == 1 || vRange > 4) { // 5VAuto5V
dtostrf(voltage, 4, 2, chrBuff); // 2
} else { //
dtostrf(voltage, 4, 1, chrBuff); // 1
}
display.setCursor(0, 33);
display.print(chrBuff); //
voltage = rangeMinDisp / 100.0; // Min
if (vRange == 1 || vRange > 4) { // 5VAuto5V
dtostrf(voltage, 4, 2, chrBuff); // 2
} else {
dtostrf(voltage, 4, 1, chrBuff); // 1
}
display.setCursor(0, 57);
display.print(chrBuff); // Min
//
if (trigSync == false) { //
display.setCursor(60, 55); //
display.print(F("")); // Unsync
}
}
void plotData() { //
long y1, y2;
for (int x = 0; x <= 98; x++) {
y1 = map(waveBuff[x + trigP - 50], rangeMin, rangeMax, 63, 9); //
y1 = constrain(y1, 9, 63); //
y2 = map(waveBuff[x + trigP - 49], rangeMin, rangeMax, 63, 9); //
y2 = constrain(y2, 9, 63); //
display.drawLine(x + 27, y1, x + 28, y2, WHITE); //
}
}
void saveEEPROM() { // EEPROM
if (paraChanged == true) { //
saveTimer = saveTimer - timeExec; //
if (saveTimer < 0) { //
paraChanged = false; //
EEPROM.write(0, vRange); //
EEPROM.write(1, hRange);
EEPROM.write(2, trigD);
EEPROM.write(3, scopeP);
}
}
}
void loadEEPROM() { // EEPROM
int x;
x = EEPROM.read(0); // vRange
if ((x < 0) || (x > 9)) { // 0-9
x = 3; //
}
vRange = x;
x = EEPROM.read(1); // hRange
if ((x < 0) || (x > 7)) { // 0-9
x = 3; //
}
hRange = x;
x = EEPROM.read(2); // trigD
if ((x < 0) || (x > 1)) { // 0-9
x = 1; //
}
trigD = x;
x = EEPROM.read(3); // scopeP
if ((x < 0) || (x > 2)) { // 0-9
x = 1; //
}
scopeP = x;
}
void pin2IRQ() { // Pin2(int0)
//pin8,9,10,11Pin2
//
int x; //
x = PINB; // B
if ( (x & 0x07) != 0x07) { // 3High
saveTimer = 5000; // EEPROM(ms
paraChanged = true; // ON
}
if ((x & 0x01) == 0) {
scopeP++;
if (scopeP > 2) {
scopeP = 0;
}
}
if ((x & 0x02) == 0) { // UP
if (scopeP == 0) { //
vRange++;
if (vRange > 9) {
vRange = 9;
}
}
if (scopeP == 1) { //
hRange++;
if (hRange > 7) {
hRange = 7;
}
}
if (scopeP == 2) { //
trigD = 0; //
}
}
if ((x & 0x04) == 0) { // DOWN
if (scopeP == 0) { //
vRange--;
if (vRange < 0) {
vRange = 0;
}
}
if (scopeP == 1) { //
hRange--;
if (hRange < 0) {
hRange = 0;
}
}
if (scopeP == 2) { //
trigD = 1; //
}
}
if ((x & 0x08) == 0) { // HOLD
hold = ! hold; //
}
}