Di video ini, saya akan menunjukkan cara membuat osiloskop mini sendiri di rumah. Ini sederhana dan mudah dibuat.ini bukan kode saya sendiri, saya hanya membuat tutorial untuk kalian. Untuk tujuan membuat proyek ini, saya bergantung pada kode sumber pihak ketiga, yang tautannya diberikan di bawah ini. Jika Anda memiliki pertanyaan atau saran, jangan ragu untuk berkomentar di video youtube saya dan jangan lupa untuk menyukai dan berlangganan saluran YouTube saya .
Klik di sini untuk tutorial lengkap dan kode sumber.
Sebuah 'osiloskop', sebelumnya disebut 'oscillograph', dan secara informal dikenal sebagai lingkup atau o-scope ,CRO (untuk osiloskop sinar katoda), atau DSO (untuk osiloskop penyimpanan digital yang lebih modern), adalah jenis instrumen uji elektronik yang secara grafis menampilkan berbagai sinyal [tegangan], biasanya sebagai plot dua dimensi dari satu atau lebih sinyal sebagai fungsi waktu. Sinyal lain (seperti suara atau getaran) dapat diubah menjadi voltase dan ditampilkan.
Osiloskop menampilkan perubahan sinyal listrik dari waktu ke waktu, dengan tegangan dan waktu sebagai sumbu Y dan X, masing-masing, pada skala yang dikalibrasi. Bentuk gelombang tersebut kemudian dapat dianalisis sifat-sifatnya seperti amplitudo, frekuensi, waktu naik, interval waktu, distorsi, dan lain-lain. Instrumen digital modern dapat menghitung dan menampilkan properti ini secara langsung. Awalnya, perhitungan nilai-nilai ini membutuhkan pengukuran bentuk gelombang secara manual terhadap skala yang terpasang di layar instrumen.
Kode
kodeC/C++
/* (_20190212_OLEDoscilloscope.ino) 1285byte ram gratis 2019/02/12 */#include #include #include #include // PROGMEM#include #define SCREEN_WIDTH 128 // OLED display width#define SCREEN_HEIGHT 64 // OLED display height#define REC_LENGTH 200 // // Deklarasi untuk display SSD1306 yang terhubung ke I2C (SDA, pin SCL) #define OLED_RESET -1 // Reset pin # (atau -1 jika berbagi pin reset Arduino)Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);//const char vRangeName[10][5] PROGMEM ={"A50V", "A 5V", "50V", "20V", "10V", "5V", "2V", "1V", "0,5V", "0.2V"}; // \0const char * const vstring_table[] PROGMEM ={vRangeName[0], vRangeName[1], vRangeName[2], vRangeName[3], vRangeName[4], vRangeName[5], vRangeName[6], vRangeName[ 7], vRangeName[8], vRangeName[9]};const char hRangeName[8][6] PROGMEM ={" 50ms", " 20ms", " 10ms", " 5ms", " 2ms", " 1ms", "500us", "200us"}; // (48const 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/1LSBfloat lsb50V =0,051513; // 50V 0,05371volatil int vRange; // 0:A50V, 1:A 5V, 2:50V, 3:20V, 4:10V, 5:5V, 6:2V, 7:1V, 8:0.5 Vvolatile int hRange; // 0:50m, 1:20m, 2:10m, 3:5m, 4;2m, 5:1m, 6:500u, 7;200uvolatile int trigD; // 0:1:volatile int scopeP; // 0:, 1:, 2:volatile boolean hold =false; // volatile boolean paraChanged =false; // truevolatile int saveTimer; // EEPROMint timeExec; // (ms)int dataMin; // (min:0) int dataMax; // (max:1023)int dataAve; // 10 max:10230)int rangeMax; // int rentangMin; // int rangeMaxDisp; // max100int rangeMinDisp; // menit trigP; // boolean trigSync; // int att10x; // 1batalkan setup() { pinMode(2, INPUT_PULLUP); // (int0 pinMode(8, INPUT_PULLUP); // Pilih pinMode(9, INPUT_PULLUP); // Up pinMode(10, INPUT_PULLUP); // Bawah pinMode(11, INPUT_PULLUP); // Tahan pinMode(12, INPUT); // 1/10 pinMode(13, OUTPUT); // // Serial.begin(115200); // RAM if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Alamat 0x3C untuk 128x64 // Serial. println(F("SSD1306 gagal")); for (;;); // Jangan lanjutkan, loop selamanya } loadEEPROM(); // EEPROM analogReference(INTERNAL); // ADC1.1Vvref) attachInterrupt(0, pin2IRQ , JATUH); // layar mulai(); // }void loop() { digitalWrite(13, TINGGI); setKondisi(); // RAM40 readWave(); // (1.6ms ) digitalWrite(13, LOW); // analisis data(); // (0.4-0.7ms) writeCommonImage(); // (4.6ms) plotData(); // (5.4ms+) dispInf(); // (6.2ms) display.display(); // (37ms) simpanEEPROM(); // EEPROM while (tahan ==true) { // Tahan dispHold(); penundaan (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; // sakelar vScale (vRange) { // case 0:{ // Auto50V // rangeMax =1023; // rentangMin =0; att10x =1; // merusak; } kasus 1:{ // Otomatis 5V // rangeMax =1023; // rentangMin =0; att10x =0; // merusak; } kasus 2:{ // 50V rangeMax =50 / lsb50V; // rangeMaxDisp =5000; // 100 rentangMin =0; rangeMinDisp =0; att10x =1; // merusak; } kasus 3:{ // 20V rangeMax =20 / lsb50V; // rangeMaxDisp =2000; rentangMin =0; rangeMinDisp =0; att10x =1; // merusak; } kasus 4:{ // 10V rangeMax =10 / lsb50V; // rangeMaxDisp =1000; rentangMin =0; rangeMinDisp =0; att10x =1; // merusak; } kasus 5:{ // 5V rangeMax =5 / lsb5V; // rangeMaxDisp =500; rentangMin =0; rangeMinDisp =0; att10x =0; // merusak; } kasus 6:{ // 2V rangeMax =2 / lsb5V; // rangeMaxDisp =200; rentangMin =0; rangeMinDisp =0; att10x =0; // merusak; } kasus 7:{ // 1V rangeMax =1 / lsb5V; // rangeMaxDisp =100; rentangMin =0; rangeMinDisp =0; att10x =0; // merusak; } kasus 8:{ // 0.5V rangeMax =0.5 / lsb5V; // rangeMaxDisp =50; rentangMin =0; rangeMinDisp =0; att10x =0; // merusak; } kasus 9:{ // 0.5V rangeMax =0.2 / lsb5V; // rangeMaxDisp =20; rentangMin =0; rangeMinDisp =0; att10x =0; // merusak; } }}void writeCommonImage() { // display.clearDisplay(); // (0.4ms) display.setTextColor(PUTIH); // display.setCursor(86, 0); // Mulai dari pojok kiri atas display.println(F("av V")); // 1 tampilan.drawFastVLine(26, 9, 55, WHITE); // display.drawFastVLine(127, 9, 55, WHITE); // display.drawFastHLine(24, 9, 7, PUTIH); // Tampilan maksimal.drawFastHLine(24, 36, 2, WHITE); // display.drawFastHLine(24, 63, 7, WHITE); // tampilan.drawFastHLine(51, 9, 3, PUTIH); // Tampilan maksimal.drawFastHLine(51, 63, 3, WHITE); // display.drawFastHLine(76, 9, 3, PUTIH); // Tampilan maksimal.drawFastHLine(76, 63, 3, WHITE); // display.drawFastHLine(101, 9, 3, PUTIH); // Tampilan maksimal.drawFastHLine(101, 63, 3, WHITE); // display.drawFastHLine(123, 9, 5, PUTIH); // Tampilan maksimal.drawFastHLine(123, 63, 5, WHITE); // untuk (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, PUTIH); // 3 } }}void readWave() { // if (att10x ==1) { // 1/10 pinMode(12, OUTPUT); // digitalWrite(12, RENDAH); // RENDAH } 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 dataMax) { // dataMax =d; } } // dataAve =(jumlah + 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 =benar; if (trigP>=((REC_LENGTH / 2) + 50)) { // trigP =(REC_LENGTH / 2); trigSync =salah; // Unsync }}void startScreen() { // display.clearDisplay(); tampilan.setTextSize(1); // 2 tampilan.setTeksWarna(PUTIH); // display.setCursor(10, 25); // display.println(F("PM.GOHARIAN")); // display.setCursor(10, 45); // display.println(F("Pen oskop")); tampilan.display(); // tunda(5000); tampilan.clearDisplay(); tampilan.setTextSize(1); // }void dispHold() { // Tahan display.fillRect(32, 12, 24, 8, HITAM); // 4 display.setCursor(32, 12); display.print(F("Tahan")); // Tahan tampilan.display(); //}void dispInf() { // tegangan mengambang; // display.setCursor(2, 0); // tampilan.print(vScale); // if (scopeP ==0) { // display.drawFastHLine(0, 7, 27, WHITE); // display.drawFastVLine(0, 5, 2, PUTIH); display.drawFastVLine(26, 5, 2, PUTIH); } // display.setCursor(34, 0); // tampilan.print(hScale); // (waktu/div) if (scopeP ==1) { // display.drawFastHLine(32, 7, 33, WHITE); // display.drawFastVLine(32, 5, 2, WHITE); display.drawFastVLine(64, 5, 2, PUTIH); } // tampilan.setCursor(75, 0); // if (trigD ==0) { display.print(char(0x18)); // } else { tampilan.print(char(0x19)); // } if (scopeP ==2) { // display.drawFastHLine(71, 7, 13, WHITE); // display.drawFastVLine(71, 5, 2, PUTIH); display.drawFastVLine(83, 5, 2, PUTIH); } // if (att10x ==1) { // 10 voltase =dataAve * lsb50V / 10.0; // 50V } else { tegangan =dataAve * lsb5V / 10.0; // 5V } dtostrf(tegangan, 4, 2, chrBuff); // x.xx display.setCursor(98, 0); // tampilan.print(chrBuff); // // tampilan.print(saveTimer); // // tegangan =rangeMaxDisp / 100.0; // Max if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(voltage, 4, 2, chrBuff); // *.** } else { // dtostrf(tegangan, 4, 1, chrBuff); // **.* } display.setCursor(0, 9); display.print(chrBuff); // Tegangan maks =(rangeMaxDisp + rangeMinDisp) / 200.0; // if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(voltage, 4, 2, chrBuff); // 2 } else { // dtostrf(tegangan, 4, 1, chrBuff); // 1 } display.setCursor(0, 33); display.print(chrBuff); // tegangan =rangeMinDisp / 100.0; // Min if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(voltage, 4, 2, chrBuff); // 2 } else { dtostrf(tegangan, 4, 1, chrBuff); // 1 } display.setCursor(0, 57); display.print(chrBuff); // Min // if (trigSync ==false) { // display.setCursor(60, 55); // display.print(F("Tidak sinkron")); // Unsync }}void plotData() { // panjang y1, y2; for (int x =0; x <=98; x++) { y1 =map(waveBuff[x + trigP - 50], rangeMin, rangeMax, 63, 9); // y1 =kendala(y1, 9, 63); // y2 =peta(waveBuff[x + trigP - 49], rangeMin, rangeMax, 63, 9); // y2 =kendala(y2, 9, 63); // tampilan.drawLine(x + 27, y1, x + 28, y2, PUTIH); // }}void saveEEPROM() { // EEPROM if (paraChanged ==true) { // saveTimer =saveTimer - timeExec; // if (saveTimer <0) { // paraChanged =false; // EEPROM.write(0, vRange); // EEPROM.write(1, hRange); EEPROM.tulis(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.baca(1); // hRange if ((x <0) || (x> 7)) { // 0-9 x =3; // } hRange =x; x =EEPROM.baca(2); // trigD if ((x <0) || (x> 1)) { // 0-9 x =1; // } trigD =x; x =EEPROM.baca(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) { // 3Tinggi saveTimer =5000; // EEPROM(ms paraChanged =true; // ON } if ((x &0x01) ==0) { scopeP++; if (scopeP> 2) { scopeP =0; } } if ((x &0x02) ==0 ) { // NAIK 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) { // TAHAN tahan =! tahan; // }}
Skema