이 프로젝트 정보
이번 영상에서는 집에서 나만의 미니 오실로스코프를 만드는 방법을 알려드리겠습니다. 간단하고 만들기 쉽습니다. 제 코드가 아니라 여러분을 위해 튜토리얼을 만들 뿐입니다. 이 프로젝트를 만들기 위해 나는 아래 링크에 있는 타사 소스 코드에 의존했습니다. 질문이나 제안 사항이 있으면 언제든지 내 YouTube 동영상에 댓글을 달고 내 YouTube 채널을 좋아하고 구독하는 것을 잊지 마세요. .
전체 자습서 및 소스 코드를 보려면 여기를 클릭하십시오.
내 IG :https://www.instagram.com/pm.goharian/
필요한 구성 요소 <울> 아두이노 나노
<울> SSD1306 OLED 디스플레이
<울> 1N4148
<울> 마이크로스위치
<울> 104 커패시터
<울> 저항:100Ω, 12k, 120k, 510k
오실로스코프란 무엇입니까?
이전에는 '오실로그래프'라고 했으며 비공식적으로는 스코프라고 알려진 '오실로스코프' 또는 o-scope ,CRO (음극선 오실로스코프용) 또는 DSO (더 현대적인 디지털 스토리지 오실로스코프의 경우)는 일반적으로 시간의 함수로 하나 이상의 신호의 2차원 플롯으로 다양한 신호[전압]를 그래픽으로 표시하는 일종의 전자 테스트 장비입니다. 다른 신호(예:소리 또는 진동)는 전압으로 변환되어 표시될 수 있습니다.
오실로스코프는 교정된 스케일에서 전압과 시간을 각각 Y축과 X축으로 사용하여 시간에 따른 전기 신호의 변화를 표시합니다. 그런 다음 파형에서 진폭, 주파수, 상승 시간, 시간 간격, 왜곡 등과 같은 속성을 분석할 수 있습니다. 최신 디지털 기기는 이러한 속성을 직접 계산하고 표시할 수 있습니다. 원래 이러한 값을 계산하려면 계측기 화면에 내장된 스케일에 대해 파형을 수동으로 측정해야 했습니다.
프로젝트 도식
참고: 회로의 모든 연결이 회로도와 정확히 동일한지 확인하십시오.
참조:
http://radiopench.blog96.fc2.com/blog-entry-893.html
https://www.wikipedia.org/
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드"> 코드
<울> 코드
코드C/C++
/* (_20190212_OLEDoscilloscope.ino) 1285byte ram free 2019/02/12 */#include #include #include #include // PROGMEM#include #define SCREEN_WIDTH 128 // OLED 디스플레이 너비#define SCREEN_HEIGHT 64 // OLED 디스플레이 높이#define REC_LENGTH 200 // // I2C(SDA, SCL 핀)에 연결된 SSD1306 디스플레이 선언 #define OLED_RESET -1 // 핀 번호 재설정(또는 Arduino 재설정 핀을 공유하는 경우 -1)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]; // 문자열 hScale ="xxxAs";String vScale ="xxxx";float lsb5V =0.0055549; // 5V0.005371 V/1LSBfloat lsb50V =0.051513; // 50V 0.05371휘발성 int vRange; // 0:A50V, 1:A 5V, 2:50V, 3:20V, 4:10V, 5:5V, 6:2V, 7:1V, 8: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; // (최대:1023)int dataAve; // 10 최대:10230)int rangeMax; // int rangeMin; // int rangeMaxDisp; // max100int rangeMinDisp; // 최소 trigP; // 부울 trigSync; // int att10x; // 1void setup() { pinMode(2, INPUT_PULLUP); // (int0 pinMode(8, INPUT_PULLUP); // pinMode(9, INPUT_PULLUP) 선택; // Up pinMode(10, INPUT_PULLUP); // Down pinMode(11, INPUT_PULLUP); // pinMode(12, INPUT) 유지; // 1/10 pinMode(13, OUTPUT); // // Serial.begin(115200); // RAM if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 주소 0x3C for 128x64 // Serial. println(F("SSD1306 failed")); for (;;); // 계속 진행하지 않고 계속 반복 } loadEEPROM(); // EEPROM analogReference(INTERNAL); // ADC1.1Vvref) attachInterrupt(0, pin2IRQ , 떨어지는); // 시작 화면(); // }void 루프() { digitalWrite(13, HIGH); setConditions(); // RAM40 readWave(); // (1.6ms ) digitalWrite(13, LOW); // 데이터 분석(); // (0.4-0.7ms) writeCommonImage(); // (4.6ms) plotData(); // (5.4ms+) dispInf(); // (6.2ms) display.display(); // (37ms) saveEEPROM(); // EEPROM while (hold ==true) { // 홀드 dispHold(); 지연(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 스위치(vRange) { // 케이스 0:{ // Auto50V // rangeMax =1023; // 범위 최소 =0; at10x =1; // 부서지다; } 경우 1:{ // 자동 5V // rangeMax =1023; // 범위 최소 =0; at10x =0; // 부서지다; } 사례 2:{ // 50V 범위 최대 =50 / lsb50V; // rangeMaxDisp =5000; // 100 rangeMin =0; 범위MinDisp =0; at10x =1; // 부서지다; } 사례 3:{ // 20V 범위 최대 =20 / lsb50V; // rangeMaxDisp =2000; 범위 최소 =0; 범위MinDisp =0; at10x =1; // 부서지다; } 경우 4:{ // 10V 범위 최대 =10 / lsb50V; // rangeMaxDisp =1000; 범위 최소 =0; 범위MinDisp =0; at10x =1; // 부서지다; } 사례 5:{ // 5V 범위 최대 =5 / lsb5V; // rangeMaxDisp =500; 범위 최소 =0; 범위MinDisp =0; at10x =0; // 부서지다; } 사례 6:{ // 2V 범위 최대 =2 / lsb5V; // rangeMaxDisp =200; 범위 최소 =0; 범위MinDisp =0; at10x =0; // 부서지다; } 경우 7:{ // 1V 범위 최대 =1 / lsb5V; // rangeMaxDisp =100; 범위 최소 =0; 범위MinDisp =0; at10x =0; // 부서지다; } 사례 8:{ // 0.5V 범위 최대 =0.5 / lsb5V; // rangeMaxDisp =50; 범위 최소 =0; 범위MinDisp =0; at10x =0; // 부서지다; } 사례 9:{ // 0.5V 범위 최대 =0.2 / lsb5V; // rangeMaxDisp =20; 범위 최소 =0; 범위MinDisp =0; at10x =0; // 부서지다; } }} 무효 writeCommonImage() { // display.clearDisplay(); // (0.4ms) display.setTextColor(WHITE); // display.setCursor(86, 0); // 왼쪽 상단에서 시작 display.println(F("av V")); // 1 display.drawFastVLine(26, 9, 55, WHITE); // display.drawFastVLine(127, 9, 55, WHITE); // display.drawFastHLine(24, 9, 7, WHITE); // 최대 display.drawFastHLine(24, 36, 2, WHITE); // display.drawFastHLine(24, 63, 7, WHITE); // display.drawFastHLine(51, 9, 3, WHITE); // 최대 display.drawFastHLine(51, 63, 3, WHITE); // display.drawFastHLine(76, 9, 3, WHITE); // 최대 display.drawFastHLine(76, 63, 3, WHITE); // display.drawFastHLine(101, 9, 3, WHITE); // 최대 display.drawFastHLine(101, 63, 3, WHITE); // display.drawFastHLine(123, 9, 5, WHITE); // 최대 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, 흰색); // 3 } }}void readWave() { // if (att10x ==1) { // 1/10 pinMode(12, OUTPUT); // digitalWrite(12, 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 dataMax) { // dataMax =d; } } // dataAve =(합 + 10) / 20; // 10 // 최대, 최소 if (vRange <=1) { // Auto1 rangeMin =dataMin - 20; // -20 rangeMin =(rangeMin / 10) * 10; // 10 if (rangeMin <0) { rangeMin =0; // 0 } 범위 최대 =데이터 최대 + 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 =참; if (trigP>=((REC_LENGTH / 2) + 50)) { // trigP =(REC_LENGTH / 2); trigSync =거짓; // 비동기화 }}void startScreen() { // display.clearDisplay(); display.setTextSize(1); // 2 display.setTextColor(WHITE); // display.setCursor(10, 25); // display.println(F("PM.GOHARIAN")); // display.setCursor(10, 45); // display.println(F("펜 스코프")); 디스플레이.디스플레이(); // 지연(5000); display.clearDisplay(); display.setTextSize(1); // }void dispHold() { // display.fillRect(32, 12, 24, 8, BLACK)를 유지합니다. // 4 display.setCursor(32, 12); display.print(F("대기")); // display.display()를 유지합니다. //}void dispInf() { // 부동 전압; // 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, 흰색); } // display.setCursor(34, 0); // display.print(hScale); // (시간/div) if (scopeP ==1) { // display.drawFastHLine(32, 7, 33, WHITE); // display.drawFastVLine(32, 5, 2, WHITE); display.drawFastVLine(64, 5, 2, 흰색); } // 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, 흰색); } // if (att10x ==1) { // 10 전압 =dataAve * lsb50V / 10.0; // 50V } else { 전압 =dataAve * lsb5V / 10.0; // 5V } dtostrf(전압, 4, 2, chrBuff); // x.xx display.setCursor(98, 0); // display.print(chrBuff); // // display.print(saveTimer); // // 전압 =rangeMaxDisp / 100.0; // 최대 if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(voltage, 4, 2, chrBuff); // *.** } else { // dtostrf(전압, 4, 1, chrBuff); // **.* } display.setCursor(0, 9); display.print(chrBuff); // 최대 전압 =(rangeMaxDisp + rangeMinDisp) / 200.0; // if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(전압, 4, 2, chrBuff); // 2 } else { // dtostrf(전압, 4, 1, chrBuff); // 1 } display.setCursor(0, 33); display.print(chrBuff); // 전압 =rangeMinDisp / 100.0; // 최소 if (vRange ==1 || vRange> 4) { // 5VAuto5V dtostrf(전압, 4, 2, chrBuff); // 2 } else { dtostrf(전압, 4, 1, chrBuff); // 1 } display.setCursor(0, 57); display.print(chrBuff); // 최소 // if (trigSync ==false) { // display.setCursor(60, 55); // display.print(F("비동기화")); // 비동기화 }}void plotData() { // long y1, y2; for (int x =0; x <=98; x++) { y1 =map(waveBuff[x + trigP - 50], rangeMin, rangeMax, 63, 9); // y1 =제약(y1, 9, 63); // y2 =map(waveBuff[x + trigP - 49], rangeMin, rangeMax, 63, 9); // y2 =제약(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); } }}무효 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) { // 아래로 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) { // 홀드 홀드 =! 홀드; // }}
섹션> 회로도