산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino Nano를 사용하여 집에서 미니 오실로스코프를 만드는 방법

구성품 및 소모품

Arduino Nano R3
× 1
ElectroPeak 0.96" OLED 64x128 디스플레이 모듈
× 1
촉각 스위치, 상단 작동
× 9
1N4148 – 범용 고속 전환
× 4

앱 및 온라인 서비스

Arduino IDE

이 프로젝트 정보

이번 영상에서는 집에서 나만의 미니 오실로스코프를 만드는 방법을 알려드리겠습니다. 간단하고 만들기 쉽습니다. 제 코드가 아니라 여러분을 위해 튜토리얼을 만들 뿐입니다. 이 프로젝트를 만들기 위해 나는 아래 링크에 있는 타사 소스 코드에 의존했습니다. 질문이나 제안 사항이 있으면 언제든지 내 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) { // 홀드 홀드 =! 홀드; // }}

    회로도


    제조공정

    1. 집에서 DIY 숙제 작성 기계 만들기
    2. Arduino Nano RP 2040을 사용하는 DIY Photoshop 편집 콘솔
    3. 집에서 탄소 섬유를 만드는 방법
    4. Arduino를 사용하여 모니터 Ambilight 만들기
    5. 사용자 정의 가능한 펀치 키보드 버튼을 만드는 방법
    6. Arduino를 사용하여 지구의 질량을 측정하는 방법
    7. PHP를 사용하여 Arduino와 통신하는 웹사이트를 만드는 방법
    8. Arduino로 음악을 만드는 방법
    9. Arduino 기반 자동 문 열림을 만드는 방법
    10. Arduino 및 Processing IDE를 사용하여 나침반을 만드는 방법