Phone : +8801894-801150 Email : projects.zeronebd@gmail.com
support 24/7

#EHD073 Mini Oscilloscope Using Arduino & OLED Display.

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.

      Buy All Electronics Components:

  www.zeronetechbd.com


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.)


fb/projects.zeronebd

e-Mail :

projects.zeronebd@gmail.com

☎️Contact:

01676 99 80 99 , 01714 80 84 02


CODE

#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;                 // 
  }
}