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

아두이노 나노 DIY 오실로스코프 (10Hz~50kHz, 128x64 LCD)

부품 및 준비물

부품수량
아두이노 나노 R31
커패시터 100µF1
ST7920 LCD 128x641
로터리 포텐셔미터2
모멘터리 푸시버튼3

필요 도구

사용 소프트웨어

프로젝트 개요

외부 DAC 칩 없이 아두이노 나노만으로 10Hz~50kHz 대역의 간이 오실로스코프를 제작합니다. 128x64 해상도의 ST7920 LCD에 파형을 표시하며, 측정 영역 96x64, 정보 표시 영역 32x64로 구성됩니다.

주요 기능

아두이노 나노 DIY 오실로스코프 (10Hz~50kHz, 128x64 LCD)

구성이 매우 단순하고 저렴하여 교육용이나 저주파 신호 테스트용으로 적합합니다. 원본 코드는 Wu Hanqing의 블로그에 공개되어 있으며, 하드웨어에 맞게 최소한만 수정했습니다.

소스 코드

U8glib 라이브러리 필요 (U8GLIB_ST7920_128X64_4X 사용)

#include <U8glib.h>
U8GLIB_ST7920_128X64_4X u8g(6, 5, 4);  // SCK, MOSI, CS

int Input = A0;
int Key_add = 8;
int Key_sub = 9;
int Key_hold = 10;

int x, y, i, i1, i2, V_min, V_max, V_mid, t, t0, t1, sta, Key = 1, hold = 0;
long Freq;
float Vpp;
int Y[96];
int Buffer[192];

// 폰트 비트맵 데이터 (생략 - 원본 참조)
const uint8_t L[] PROGMEM = { ... };

void setup() {
  pinMode(Key_add, INPUT); digitalWrite(Key_add, HIGH);
  pinMode(Key_sub, INPUT); digitalWrite(Key_sub, HIGH);
  pinMode(Key_hold, INPUT); digitalWrite(Key_hold, HIGH);
  
  ADMUX = 0x60;   // ADC 설정
  ADCSRA = 0xe2;  // 프리스케일러 등
  
  u8g.setFont(u8g_font_5x7);
  u8g.firstPage();
  do { u8g.drawBitmapP(0, 0, 16, 64, L); } while (u8g.nextPage());
  delay(2000);
}

void loop() {
  sample();
  Measure();
  Transform();
  Key_scan();
  if (hold == 0) {
    u8g.firstPage();
    do { draw(); } while (u8g.nextPage());
  }
}

void sample() {
  for (i = 0; i < 192; i++) {
    Buffer[i] = ADCH;
    switch (Key) {
      case 1: break;
      case 2: delayMicroseconds(4); break;
      case 3: delayMicroseconds(10); break;
      case 4: delayMicroseconds(23); break;
      case 5: delayMicroseconds(60); break;
      case 6: delayMicroseconds(123); break;
      case 7: delayMicroseconds(248); break;
      case 8: delayMicroseconds(623); break;
      case 9: delayMicroseconds(1247); break;
    }
  }
}

void Measure() {
  V_max = Buffer[0]; V_min = Buffer[0];
  for (i = 0; i < 192; i++) {
    if (Buffer[i] > V_max) V_max = Buffer[i];
    if (Buffer[i] < V_min) V_min = Buffer[i];
  }
  V_mid = (V_max + V_min) / 2;
  Vpp = (V_max - V_min) * 5.0 / 255.0;
  
  // 주파수 측정 (제로 크로싱)
  for (i = 0; i < 97; i++) {
    if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i1 = i; break; }
  }
  for (i = i1 + 1; i < 98 + i1; i++) {
    if (Buffer[i] < V_mid && Buffer[i+1] >= V_mid) { i2 = i; break; }
  }
  t = i2 - i1;
  Freq = (t > 0) ? 8000 / t : 0;
}

void Transform() {
  for (sta = 0; sta < 96; sta++) {
    if (Buffer[sta] < 128 && Buffer[sta+2] > 128) break;
  }
  for (i = 0; i < 96; i++) Y[i] = 63 - (Buffer[i+sta] >> 2);
}

void draw() {
  for (x = 0; x < 95; x++) u8g.drawLine(x, Y[x], x, Y[x+1]);
  u8g.drawFrame(0, 0, 97, 64);
  u8g.drawLine(48, 0, 48, 63);  // 중앙 세로선
  u8g.drawLine(0, 32, 96, 32);  // 중앙 가로선
  for (x = 0; x < 96; x += 8) u8g.drawLine(x, 31, x, 33);  // 눈금
  for (y = 0; y < 64; y += 8) u8g.drawLine(47, y, 49, y);
  for (x = 8; x < 96; x += 8) for (y = 8; y < 64; y += 8) u8g.drawPixel(x, y);
  
  u8g.drawStr(98, 7, "MS/div");
  u8g.drawStr(98, 23, "V/div");
  u8g.drawStr(98, 30, "0.324");
  u8g.drawStr(98, 40, "Vpp");
  u8g.setPrintPos(98, 47); u8g.print(Vpp); u8g.drawStr(118, 47, "V");
  u8g.drawStr(98, 55, "F(HZ)");
  
  switch (Key) {
    case 1: u8g.drawStr(98, 14, "0.02"); u8g.setPrintPos(98, 62); u8g.print(Freq * 50); break;
    case 2: u8g.drawStr(98, 14, "0.05"); u8g.setPrintPos(98, 62); u8g.print(Freq * 20); break;
    case 3: u8g.drawStr(98, 14, " 0.1"); u8g.setPrintPos(98, 62); u8g.print(Freq * 10); break;
    case 4: u8g.drawStr(98, 14, " 0.2"); u8g.setPrintPos(98, 62); u8g.print(Freq * 5); break;
    case 5: u8g.drawStr(98, 14, " 0.5"); u8g.setPrintPos(98, 62); u8g.print(Freq * 2); break;
    case 6: u8g.drawStr(98, 14, " 1");   u8g.setPrintPos(98, 62); u8g.print(Freq); break;
    case 7: u8g.drawStr(98, 14, " 2");   u8g.setPrintPos(98, 62); u8g.print(Freq / 2); break;
    case 8: u8g.drawStr(98, 14, " 5");   u8g.setPrintPos(98, 62); u8g.print(Freq / 5); break;
    case 9: u8g.drawStr(98, 14, " 10");  u8g.setPrintPos(98, 62); u8g.print(Freq / 10); break;
  }
}

void Key_scan() {
  if (digitalRead(Key_add) == LOW) { while (digitalRead(Key_add) == LOW); Key++; if (Key == 10) Key = 9; delay(10); }
  if (digitalRead(Key_sub) == LOW) { while (digitalRead(Key_sub) == LOW); Key--; if (Key == 0) Key = 1; delay(10); }
  if (digitalRead(Key_hold) == LOW) { while (digitalRead(Key_hold) == LOW); hold = ~hold; delay(10); }
}

회로도

아두이노 나노 DIY 오실로스코프 (10Hz~50kHz, 128x64 LCD)

참고 사항

제조공정

  1. 나만의 LUMAZOID 만들기: DIY 아두이노 음악 비주얼라이저
  2. 아두이노 나노와 노키아 5110 LCD로 20kHz 오실로스코프 만들기: 쉬운 DIY 가이드
  3. 아두이노 아이언맨 제작: 부품, 센서, 단계별 가이드
  4. 아두이노와 블루투스로 만드는 스마트 물건 찾기 'Find Me'
  5. PIR 모션 센서 연동 인터랙티브 LED 매트릭스 도어 디스플레이 - 아두이노 홀리데이 인사
  6. 아두이노 릴레이 제어 가습기 자동화 – 고전압 안전 설계
  7. 아두이노와 노키아 5110 LCD로 만드는 DIY 전압계 - 단계별 가이드
  8. 아두이노 소나 & 프로세싱으로 실시간 거리 측정 및 시각화
  9. MobBob: 아두이노 로봇 직접 만들기, 안드로이드 스마트폰으로 매끄럽게 제어
  10. 아두이노 나노 DIY 오실로스코프 (10Hz~50kHz, 128x64 LCD)