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

JX 웨이브 생성기

구성품 및 소모품

Arduino Nano R3
시도하지는 않았지만 아마 모든 Arduino 모델을 사용할 수 있을 것입니다.
× 1
디스플레이 SH1106 I2C Oled 128x64 픽셀(4핀)
× 1
AD9833 DDS 모듈
× 1
푸시 버튼이 있는 로터리 인코더
납땜 인두가 필요합니다.
× 1
로터리 인코더 모듈
브레드보드 장착의 경우 더 좋습니다.
× 1
5V 릴레이 모듈(옵션)
AC/DC 출력 커플링 모드를 변경할 필요가 없는 경우 선택 사항입니다. 브레드보드 장착의 경우 더 좋습니다
× 1
릴레이 리드 5V 500옴
이것은 작은 신호에 가장 적합하지만 납땜 인두가 필요합니다.500옴 코일을 사용하면 Arduino 디지털 핀(10mA)에 직접 연결해야 합니다.
× 1
커패시터 10μF
× 1
커패시터 10nF
폴리에스터 커패시터
× 1
AC-DC 100-220V ~ 5V 강압 전원 공급 장치 모듈
선택 사항, USB를 통해 연결되지 않은 경우 회로에 전원 공급
× 1

필요한 도구 및 기계

납땜 인두(일반)
브레드보드에서 프로젝트를 테스트하려는 경우 필수 사항은 아닙니다.

앱 및 온라인 서비스

image2cpp
사용자 정의 아이콘을 PROGMEM용 16진수 형식으로 변환하려면

이 프로젝트 정보

오랫동안 오실로스코프 구입을 미루었습니다. 이제 구입 후 오디오 회로 등을 진단하는 데 필수적인 취미용 저렴한 신호 발생기를 가질 때입니다. 전자 제품과 컴퓨팅에 대한 두 가지 열정을 결합한 가장 좋은 방법은 Arduino로 직접 해보는 것입니다.

기능

<울>
  • 1Hz에서 999999Hz 사이의 출력 주파수
  • 주파수 변화의 두 가지 모드:대수 및 한 자리 수
  • 세 가지 유형의 파동, 사인, 삼각형 및 사각형
  • AC 또는 DC 출력 커플링
  • 2개의 사전 정의된 주파수 값 사이를 연속적으로 스위프하는 기능
  • 단일 노브로 독점적으로 제어
  • oled 디스플레이의 수명을 유지하기 위한 통합 화면 보호기
  • 참고

    빠른 참조

    프로토타입

    나는 10A 접점이 있는 미리 조립된 릴레이 모듈을 사용했습니다. 왜냐하면 현재로서는 마이크로 리드 릴레이가 없었기 때문에 전력 릴레이가 필요하지 않을 때 트랜지스터 다이오드와 저항을 피하기 위한 최선의 선택이었기 때문입니다. Arduino 디지털 PIN은 최대 40mA를 전달할 수 있으므로 120/150ohm 코일이 있는 전기 기계 릴레이를 직접 연결할 수 없습니다.

    항상 매우 조심하세요 주 전압을 사용할 때!

    감전 및/또는 피부와 눈 손상의 위험이 있습니다.
    하나뿐인 인생을 조심하십시오!

    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • JX_Wave_Generator_8.7.7.ino
  • JXWG_Defs.h
  • JXWG_Graphics.h
  • JX_Wave_Generator_8.7.7.inoC/C++
    버전 8.7.7. 2021년 1월 16일<미리 수정>/* Copyright (c) 2020 Janux 이 소프트웨어 및 관련 문서 파일("소프트웨어")의 사본을 얻는 모든 사람에게 무료로 다음을 수행할 수 있는 권한이 부여됩니다. 소프트웨어의 사본을 사용, 복사, 수정, 병합, 출판, 배포, 2차 라이선스 부여 및/또는 판매할 수 있는 권리와 소프트웨어가 제공되는 사람에게 그렇게 하도록 허용하는 권한을 포함하되 이에 국한되지 않는 제한 없이 소프트웨어에서 위의 저작권 표시 및 이 허가 표시는 소프트웨어의 모든 사본 또는 상당 부분에 포함되어야 합니다. 소프트웨어는 상품성, 특정 목적에의 적합성 및 비침해에 대한 보증을 포함하되 이에 국한되지 않는 어떠한 종류의 명시적 또는 묵시적 보증 없이 "있는 그대로" 제공됩니다. 어떤 경우에도 저자 또는 저작권자는 계약, 불법 행위 또는 기타의 행위로 인해 소프트웨어 또는 다른 거래와 관련하여 발생하는 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다. 소프트웨어. 구성 저장-로딩 코드는 Norwegian Creation 웹사이트의 Ragnar Ranyen Homb이 작성한 "How to Load and Save Configurations on Arduino" 기사의 독창적인 아이디어를 개발한 것입니다.*/#include "JXWG_Defs.h#include "JXWG_Graphics .h"void setup() { //단순 인코더와 3x10K 풀업 저항을 사용하는 경우 이 설정을 pinMode(PinA, INPUT) 아래에 적용합니다. 핀모드(핀B, 입력); 핀모드(핀, 입력); //단순 인코더를 사용하는 경우 3x10K 저항은 다음 트리 행을 사용합니다. //pinMode(PinA, INPUT_PULLUP); //핀모드(핀B, INPUT_PULLUP); //핀모드(핀S, INPUT_PULLUP); //대부분의 PCB 용접 인코더는 이미 핀 A와 B에 풀업 저항이 있지만 스위치 핀에는 없습니다 //그런 다음 아래 설정을 사용합니다. //pinMode(PinA, INPUT); //핀모드(핀B, 입력); //핀모드(핀S, INPUT_PULLUP); digitalWrite(PinA, HIGH); 디지털 쓰기(PinB, HIGH); 디지털 쓰기(핀, 높음); 핀모드(핀커플링, 출력); //커플링 모드 Encoder.setDebounceDelay(5); display.begin(SH1106_SWITCHCAPVCC, 0x3C); //I2C addr로 초기화 0x3C(128x64용) display.clearDisplay(); //디스플레이.setRotation(2); //디스플레이를 거꾸로 장착하려면 이 줄의 주석 처리를 제거합니다. Wire.begin(); // i2c 버스를 마스터로 조인 TWBR =5; // freq=615kHz period=1.625uS //Arduino의 1번 핀 3번 핀에 인코더 스위치 푸시 이벤트를 할당합니다. attachInterrupt(digitalPinToInterrupt(PinS), encoderSwitch, FALLING); DDS_Init(); //DDS 모듈을 초기화합니다. 설정 구성(); //구성 로드 및 시작 값 설정} //---> end setup()void loop() { JX_WaveGenerator_MAIN();}//------------------- -------------------------------------------------- -------------------------------------------------- ------------------// JX WaveGenerator MAIN 기능//------------------------- -------------------------------------------------- -------------------------------------------------- ------------- 무효 JX_WaveGenerator_MAIN() { 바이트 인코더 스핀 =Encoder.rotate(); //엔코더 회전 방향 1=CW, 2=CCW 바이트 인코더LongPush =Encoder.pushLong(1000); //인코더 롱 푸시 이벤트 long lStep =0; //현재 주파수 스텝 값 long wTime =600000; //10분 if (encoderPush) delay(250); if (encoderSpin) { cTime =millis(); } else { if (millis() - cTime> wTime) { ScreenSaver(); } } 스위치(모드) { 케이스 로그://0 //------------------------------------------------- -------------------------------------------------- ---------------------------------------------- // 로그 모드 :엔코더 회전 변경 주파수 대수 1,10,100,1000,10000,100000 Hz //------------------------------ -------------------------------------------------- -------------------------------------------------- - if (encoderSpin) { if (lFreq>=1) { lStep =AutoStep(lFreq, encoderSpin); //로그 단계 계산 } else if (_CouplingMode ==OFF) { //커플링 모드가 OFF로 설정된 경우 resetCouplingMode(); //주파수가 0이 아닐 때 기본 커플링 모드를 설정합니다. encoderSpin =0; //첫 번째 스핀 건너뛰기 } if (encoderSpin ==CW &&lFreq <=999999 - lStep) { //스핀 CW는 주파수 lFreq +=lStep을 증가시킵니다. } if (encoderSpin ==CCW &&lFreq>=lStep + 1) { // CCW를 스핀하여 주파수 lFreq -=lStep을 감소시킵니다. } DDS_FrequencySet(lFreq, Wave[_WaveType]); // 주파수 값을 DDS 모듈로 전송 displayFrequency(lFreq); //포맷된 주파수를 전송하여 lLastFreq =lFreq를 표시합니다. //현재 주파수 저장 } //------------------------------------------ -------------------------------------------------- --------------------------------------- // 작업 모드 LOGARITHMIC:인코더 푸시 스위치를 OPTIONS 모드로 전환 //------------------------------------------------ -------------------------------------------------- ---------------------------------- if (encoderPush) { encoderPush =false; //푸시 플래그 지우기 drawSymbol(1); //화살표 기호 그리기 selectIcon(0, WHITE); //첫 번째 아이콘 주위에 테두리를 그립니다. idx =0; 아이디 =0; //포인터 재설정 var mode =OPTIONS; // OPTIONS 모드로 이동 } break; // 종료 모드 LOGARITHMIC 케이스 SINGLEDIGIT://1 //---------------------------------------- -------------------------------------------------- ---------------------- // 하위 모드 SINGLEDIGIT:인코더 회전 커서를 왼쪽과 오른쪽으로 이동 //---------------- -------------------------------------------------- ------------------------------------------ if (encoderSpin) { if (encoderSpin ==CW &&idx 0) idx--; //시계 반대 방향 감소 포인터 //------------------------------------------- -------------------------------------------------- --------------- // idx가 0에서 5일 때 주파수 자릿수 선택 //---------------------- -------------------------------------------------- -------------------------------------- if (idx>=0 &&idx =MAXDIGIT &&idx <=MAXDIGIT + 2) { //현재 위치가 숫자를 넘어서면 hideCursor(MAXDIGIT - 1); //마지막 자리에 커서 숨기기 drawSymbol(1); //dn 화살표 그리기 selectIcon(idx - MAXDIGIT, WHITE); // 아이콘 선택 } } //------------------------------------------ -------------------------------------------------- --------------------------------------- // 하위 모드 SINGLEDIGIT:인코더 푸시 이벤트 //- -------------------------------------------------- -------------------------------------------------- ------------------------------ if (encoderPush) { encoderPush =false; //------------------------------------------------ -------------------------------------------------- ----------- // 0에서 5까지의 숫자가 선택되면 DIGITCHANGE 모드로 이동 //------------------------------------ -------------------------------------------------- -------------------------------------- if (idx <=MAXDIGIT - 1) { hideCursor(idx ); //플래시 커서 지연(250); // selectDigit(idx)의 경우; //시각적 확인 drawSymbol(2); // 턴 아이콘 그리기 모드 =DIGITCHANGE; //모드 변경 } //------------------------------------------- -------------------------------------------------- ---------------- // 그렇지 않으면 아이콘이 선택된 다음 OPTIONS로 이동합니다. //-------------------- -------------------------------------------------- --------------------------------------- else { if (idx>=MAXDIGIT &&idx <=MAXDIGIT + 2) { idy =idx - MAXDIGIT; 선택옵션(ID); 아이디 =옵션[아이디]; } } } 부서지다; //종료 모드 SINGLEDIGIT 케이스 SWEEP://2 //---------------------------------------------------- -------------------------------------------------- ------------------------- // 작업 모드 SWEEP:인코더 회전 커서를 왼쪽과 오른쪽으로 이동하여 옵션 선택 //-------- -------------------------------------------------- -------------------------------------------------- ---- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) idy++; if (encoderSpin ==CCW &&idy> 0) idy--; selectIcon(ID, WHITE); } if (encoderPush) { //-------------------------------------------- -------------------------------------------------- --------------------------------------- // 작업 모드 SWEEP:인코더 푸시가 옵션으로 이동합니다. 스위프 옵션 또는 시작/중지 스위프 //----------------------------------------- -------------------------------------------------- ---------------------------------------- 인코더푸시 =거짓; 스위치(idy) { 경우 0:lFreq =atol(Freq); 선택옵션(ID); 아이디 =옵션[아이디]; 지연(100); if (_WorkMode !=2) displayFrequency(lLastFreq); 스위프 리셋(); 부서지다; 경우 1:lFreq =atol(Freq); drawSymbol(9); 그리기 기호(1); 디스플레이 스위프 아이콘(); 선택 아이콘(0, 흰색); 아이디 =0; displayFrequency(_Sweep(idy)); 지연(100); 스위프 리셋(); 모드 =OPTSWEEP; 부서지다; 사례 2://** 스위프 상태:STILL 0(시작되지 않음), 1 BREAK, 2 PAUSE ** if (sweepStatus ==STILL || sweepStatus ==PAUSE) { drawSymbol(3); //일시정지 아이콘 그리기 selectIcon(2, WHITE); // 아이콘 선택 FrequencySweep(); // 스윕 실행 } else { //일시 중지된 경우 drawSymbol(4); //재생 아이콘 그리기 sweepStatus =PAUSE; } 부서지다; } } if (sweepStatus ==PAUSE) flashIcon(250); // 깜박임 일시 중지 텍스트 break; // 종료 모드 SWEEP 케이스 OPTIONS://3 if (encoderLongPush) reset(); //------------------------------------------------ -------------------------------------------------- ---------------------------------- // 모드 옵션:변경할 인코더 스핀 선택 옵션(작업 모드, 웨이브 유형, 커플링 모드 ) //----------------------------------------------- -------------------------------------------------- ---------------------------------- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) 아이디++; if (encoderSpin ==CCW &&idy> 0) idy--; selectIcon(ID, WHITE); } //------------------------------------------------- -------------------------------------------------- ---------------------------------- // 모드 옵션:인코더 푸시 스위치를 상대 모드로 전환 //--- -------------------------------------------------- -------------------------------------------------- ---------------------------- if (encoderPush) { encoderPush =false; //selectIcon(idy, BLACK); 선택옵션(ID); 숨기기 커서(0); 아이디 =옵션[아이디]; } 부서지다; // 종료 모드 OPTIONS 경우 OPTMODE://4 //---------------------------------------- -------------------------------------------------- -------------------------------------------- // 모드 OPTMODE:인코더 스핀 선택 모드 아이콘(로그, 한자리수, 스위프) //---------------------------------------- -------------------------------------------------- -------------------------------------------- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) idy++; if (encoderSpin ==CCW &&idy> 0) idy--; selectIcon(ID, WHITE); } //------------------------------------------------- -------------------------------------------------- ---------------------------------- // 모드 OPTMODE:설정할 인코더 푸시 선택 작업 모드(옵션[ 0]) //------------------------------------------------------------ -------------------------------------------------- ------------------------------------ if (encoderPush) { encoderPush =false; 바이트 pMode =_WorkMode; 스위치(idy) { 경우 0:hideCursor(0); 그리기 기호(0); lFreq =lLastFreq; displayFrequency(lFreq); _setWorkMode(로그); 부서지다; 사례 1:drawSymbol(0); 선택숫자(0); lFreq =lLastFreq; displayFrequency(lFreq); _setWorkMode(SINGLEDIGIT); 부서지다; 경우 2:lLastFreq =lFreq; displayFrequency(_SweepMin); //시작 준비 _setWorkMode(SWEEP); 부서지다; } 모드 =_WorkMode; if (pMode !=_WorkMode) saveConfig(); if (_CouplingMode ==OFF) resetCouplingMode(); 아이디 =0; drawAllIcons(); } 부서지다; //종료 모드 OPTMODE 케이스 OPTWAVE://5 //---------------------------------------- -------------------------------------------------- ------------------------- // 모드 OPTWAVE:파형 선택을 위해 인코더 회전 커서를 왼쪽 및 오른쪽으로 이동(sqr, sin, tri) //- -------------------------------------------------- -------------------------------------------------- ----------- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) idy++; if (encoderSpin ==CCW &&idy> 0) idy--; selectIcon(ID, WHITE); } //------------------------------------------------- -------------------------------------------------- ------------------- // 모드 OPTWAVE:인코더 푸시 설정 새로운 웨이브 유형 //------------------ -------------------------------------------------- ------------------------------------------------ 만약 ( 인코더푸시) { 인코더푸시 =거짓; if (_WaveType !=idy) { _setWaveType(idy); 저장 구성(); } 업데이트 빈도(); //파형 업데이트 drawAllIcons(); 아이디 =0; 모드 =_WorkMode; } 부서지다; //종료 모드 OPTWAVE 경우 OPTCOUP://6 //---------------------------------------- -------------------------------------------------- ---------------------- // 모드 OPTCOUP:커플링 모드 선택을 위해 엔코더 회전 커서를 좌우로 이동 //------- -------------------------------------------------- -------------------------------------------------- ----- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) idy++; if (encoderSpin ==CCW &&idy> 0) idy--; selectIcon(ID, WHITE); } //------------------------------------------------- -------------------------------------------------- ------------------- // 모드 OPTCOUP:인코더 푸시 선택 현재 커플링 모드 //------------------ -------------------------------------------------- ------------------------------------------------ 만약 ( 인코더푸시) { 인코더푸시 =거짓; setCouplingMode(ID); drawAllIcons(); 아이디 =0; 모드 =_WorkMode; } 부서지다; //종료 모드 OPTCOUP 케이스 OPTSWEEP://7 //---------------------------------------- -------------------------------------------------- -------------------------- // 모드 OPTSWEEP:인코더 회전 편집할 스윕 값 선택 //------- -------------------------------------------------- -------------------------------------------------- --------- if (encoderSpin) { if (encoderSpin ==CW &&idy <2) idy++; //시계 방향 증가 포인터 if (encoderSpin ==CCW &&idy> 0) idy--; // 시계 반대 방향 감소 포인터 selectIcon(idy, WHITE); //첫 번째 아이콘 선택 displayFrequency(_Sweep(idy)); //현재 스위프 값 표시 } if (encoderPush) { encoderPush =false; //------------------------------------------------ -------------------------------------------------- ------------------ // 모드 OPTSWEEP:인코더 푸시 확인 스위프 값 편집 //------------------ -------------------------------------------------- ------------------------------------------------ drawSymbol( 0); 선택숫자(0); selectIcon(ID, WHITE); 아이디 =0; displayFrequency(_Sweep(idy)); 모드 =SWEEPEDIT; } 부서지다; //종료 모드 OPTSWEEP 케이스 SWEEPEDIT://8 //---------------------------------------- -------------------------------------------------- ----------------------- // 모드 SWEEPEDIT:인코더 회전 변경할 숫자 선택 //---------------- -------------------------------------------------- ---------------------------------------------- if (encoderSpin) { if (encoderSpin ==CW &&idx 0) idx--; // 시계 반대 방향 감소 포인터 selectDigit(idx); } //------------------------------------------------- -------------------------------------------------- ------------- // 모드 SWEEPEDIT:인코더 longpush 편집에서 종료하고 SWEEP으로 돌아갑니다. //--------------------- -------------------------------------------------- --------------------------------------- if (encoderLongPush ==LONGPUSH) { encoderPush =false; drawAllIcons(); displayFrequency(_SweepMin); 숨기기 커서(idx); _setWorkMode(스윕); 스위프 리셋(); 모드 =_WorkMode; 지연(250); } if (encoderPush) { 인코더푸시 =거짓; //------------------------------------------------ -------------------------------------------------- ----------- // 모드 SWEEPEDIT:인코더 푸시 DIGITCHANGE 모드로 이동 //-------------------------- -------------------------------------------------- ---------------------------------- hideCursor(idx); //플래시 커서 지연(250); // selectDigit(idx)의 경우; //시각적 확인 drawSymbol(2); // 턴 아이콘 그리기 모드 =DIGITCHANGE; //모드 변경 } break;//모드 종료 SWEEPEDIT 케이스 DIGITCHANGE://9 //------------------------------ -------------------------------------------------- ------------------------- // 모드 DIGITCHANGE:인코더 longpush가 SWEEP 모드에 있을 때 DIGITCHANGE에서 종료 //--------- -------------------------------------------------- ---------------------------------------------- if (encoderLongPush ==LONGPUSH &&_WorkMode ==스위프) { 인코더푸시 =거짓; 숨기기 커서(idx); 그리기 기호(1); 모드 =OPTSWEEP; 지연(250); } //------------------------------------------------- -------------------------------------------------- -------- // 모드 DIGITCHANGE:인코더 회전 변경 자릿수 값(0 -> 9 ->0 등) //------------------ -------------------------------------------------- -------------------------------------- if (encoderSpin) { //인코더 회전 if (encoderSpin ==CW) { //시계 방향 Freq[idx]++; if (Freq[idx]> '9') Freq[idx] ='0'; } else { //시계 반대 방향 Freq[idx]--; if (주파수[idx] <'0') 주파수[idx] ='9'; } updateDigit(idx, 주파수[idx]); //디스플레이의 숫자 업데이트 } //----------------------------------------- -------------------------------------------------- -------------- // 모드 DIGITCHANGE:인코더 푸시 복귀 모드 SINGLEDIGIT 또는 SWEEPEDIT //--------------------- -------------------------------------------------- ---------------------------------- if (encoderPush) { //인터럽트에 의해 설정된 인코더 푸시 플래그 encoderPush =false; // 이벤트 플래그 재설정 hideCursor(idx); //플래시 커서 지연(250); // selectDigit(idx)의 경우; //시각적 확인 drawSymbol(0); if (_WorkMode ==SWEEP) { 긴 ltemp =_Sweep(idy); //값 저장 _setSweep(idy, atol(Freq)); //새 값을 배열에서 long으로 변환 if (_SweepMax> 0 &&_SweepMax> _SweepMin &&_SweepStep> 0) { //새 스윕 값의 일치 여부 확인 if (_Sweep(idy) !=ltemp) saveConfig(); //값이 변경된 경우 EEPROM에 새 값을 씁니다. displayFrequency(_Sweep(idy)); 모드 =SWEEPEDIT; //모드 변경 } else { _displayErrMsg; //플래시 메모리에 저장된 오류 메시지 표시 delay(1000); _setSweep(idy, ltemp); //저장된 값 복원 displayFrequency(_Sweep(idy)); //값 재표시 drawSymbol(2); // 회전 아이콘 다시 그리기 } } else { //스위프 모드가 아닌 경우 if (_CouplingMode ==OFF) { //커플링 모드가 OFF인 경우 lLastFreq =atol(Freq); //현재 주파수를 저장합니다. resetCouplingMode(); //기본 커플링 모드 설정 } UpdateFrequency(); // DDS 모듈 모드로 주파수 보내기 =SINGLEDIGIT; //모드 변경 } } break; // 종료 모드 DIGITCHANGE 기본값:break; }}//---------------------------------------------- -------------------------------------------------- -----------------------------------// 푸시 인코더 이벤트 - 인터럽트에 의해 호출됨//---- -------------------------------------------------- -------------------------------------------------- --------------------------- 무효 인코더스위치(무효) { 인코더푸시 =true;}//---------- -------------------------------------------------- -------------------------------------------------- ---------------------// Utility functions//----------------------- -------------------------------------------------- -------------------------------------------------- --------// Draw graphics interface//----------------------------------- -------------------------------------------------- ---------------------------void drawInterface() { display.clearDisplay(); display.display(); delay(1000); display.drawRoundRect(0, 0, 128, 64, 3, WHITE); //draw external frame display.fillRect(1, 1, 126, 14, WHITE); //draw caption frame displayText(12, 4, strFromFlash(0), BLACK, WHITE, SMALL); //print caption title delay(1000); if (cTime ==1) { //only on power on displayText(XPOS - 6, YPOS + 10, strFromFlash(1), WHITE, BLACK, BIG); //show Welcom message delay(1000); display.fillRect(2, 16, display.width() - 3, 35, BLACK); //clear Welcome message cTime =0; } display.display(); displayText(XPOS + 84, YPOS + 4, strFromFlash(2), WHITE, BLACK, SMALL); //print "Hz" sprintf(Freq, "%06li", lFreq); //put frequency value into char array with template "000000" for (int i =MAXDIGIT - 1; i>=0; i--) { display.drawChar(XPOS + 2 + i * DELTAX, YPOS, Freq[i] , WHITE, BLACK, BIG); //Display with animation effect from right to left display.display(); }}//end drawInterface()//----------------------------------------------------------------------------------------------------------------// Print string in x,y pos with specified colors and size//----------------------------------------------------------------------------------------------------------------void displayText(byte x, byte y, const char *str, byte foreColor, byte backColor, byte textSize) { display.setTextSize(textSize); //textsize:SMALL or BIG global const display.setTextColor(foreColor, backColor); //colors WHITE or BLACK global const of the library display.setCursor(x, y); //set the cursor position display.print(str); //str is the pointer to the string of chars display.display(); //update display}//----------------------------------------------------------------------------------------------------------------// Copies element [i] of the string_table array from flash memory to the ram buffer and returns the pointer to the buffer//----------------------------------------------------------------------------------------------------------------char* strFromFlash(byte i) { strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); return (char*)buffer;}//----------------------------------------------------------------------------------------------------------------// Draw or clear a border around selected icon after clearing border of the previous one//----------------------------------------------------------------------------------------------------------------void selectIcon(byte icon, byte color) { static byte prevIcon; display.drawRect(XPOS - 10 + prevIcon * 32, YPOS + 19, 29, 20, BLACK); display.drawRect(XPOS - 10 + icon * 32, YPOS + 19, 29, 20, color); display.display(); prevIcon =icon;}//----------------------------------------------------------------------------------------------------------------// Display all workmode icons//----------------------------------------------------------------------------------------------------------------void displayWorkModeIcons(void) { byte const *bitmap[3] ={imgLog, imgDigit, imgSweep}; _clearIconsArea; for (byte i =0; i <=2; i++) { display.drawBitmap(XPOS - 8 + i * 32, YPOS + 21, bitmap[i], 25, 16, WHITE); } display.display();}//----------------------------------------------------------------------------------------------------------------// Display all wavetype icons//----------------------------------------------------------------------------------------------------------------void displayWaveTypeIcons(void) { byte const *bitmap[3] ={imgSqr, imgSin, imgTri}; _clearIconsArea; for (byte i =0; i <=2; i++) { display.drawBitmap(XPOS - 8 + i * 32, YPOS + 21, bitmap[i], 25, 16, WHITE); } display.display();}//----------------------------------------------------------------------------------------------------------------// Display all coupling mode icons//----------------------------------------------------------------------------------------------------------------void displayCouplingModeIcons(void) { byte const *bitmap[3] ={imgCoAc, imgCoDc, imgCoOff}; _clearIconsArea; for (byte i =0; i <=2; i++) { display.drawBitmap(XPOS - 8 + i * 32, YPOS + 21, bitmap[i], 25, 16, WHITE); } display.display();}//----------------------------------------------------------------------------------------------------------------// Display all sweep icons//----------------------------------------------------------------------------------------------------------------void displaySweepIcons(void) { byte const *bitmap[3] ={imgSwMax, imgSwMin, imgSwStep}; _clearIconsArea; for (byte i =0; i <=2; i++) { display.drawBitmap(XPOS - 8 + i * 32, YPOS + 21, bitmap[i], 25, 16, WHITE); } display.display();}//----------------------------------------------------------------------------------------------------------------// Draw all icons//----------------------------------------------------------------------------------------------------------------void drawAllIcons(void) { _clearIconsArea; drawModeIcon(); if (_WorkMode ==SWEEP || _WorkMode ==SWEEPEDIT ) { display.drawBitmap(XPOS + 24, YPOS + 21, imgSwOpt, 25, 16, WHITE); display.drawBitmap(XPOS + 56, YPOS + 21, imgSwStart, 25, 16, WHITE); drawSymbol(1); idy =2; selectIcon(idy, WHITE); //ready to sweep drawSmallWaveIcon(); drawSmallCouplingIcon(); } else { drawWaveIcon(); drawCouplingIcon(); drawSymbol(0); if (_WorkMode ==SINGLEDIGIT) selectDigit(0); } display.display();}//----------------------------------------------------------------------------------------------------------------// Draws the icon based on the value of relative option//----------------------------------------------------------------------------------------------------------------void drawModeIcon(void) { byte x =XPOS - 8, y =YPOS + 21; byte const *bitmap[3] ={imgLog, imgDigit, imgSweep}; display.fillRect(x, y, 25, 16, BLACK); display.drawBitmap(x, y, bitmap[_WorkMode], 25, 16, WHITE); display.display();}void drawWaveIcon(void) { byte x =XPOS + 24, y =YPOS + 21; const byte *bitmap[3] ={imgSqr, imgSin, imgTri}; display.fillRect(x, y, 25, 16, BLACK); display.drawBitmap(x, y, bitmap[_WaveType], 25, 16, WHITE); display.display(); drawSmallWaveIcon();}void drawCouplingIcon(void) { byte x =XPOS + 56, y =YPOS + 21; const byte *bitmap[3] ={imgCoAc, imgCoDc, imgCoOff}; display.fillRect(x, y, 25, 16, BLACK); display.drawBitmap(x, y, bitmap[_CouplingMode], 25, 16, WHITE); display.display(); drawSmallCouplingIcon();}//----------------------------------------------------------------------------------------------------------------// Draws small wave icon based on the value of relative option//----------------------------------------------------------------------------------------------------------------void drawSmallWaveIcon(void) { byte x =114, y =41; const byte *bitmap[3] ={imgSqrSmall, imgSinSmall, imgTriSmall}; display.fillRect(x, y, 9, 8, BLACK); display.drawBitmap(x, y, bitmap[_WaveType], 9, 8, WHITE); display.display();}//----------------------------------------------------------------------------------------------------------------// Draws small coupling icon based on the value of relative option//----------------------------------------------------------------------------------------------------------------void drawSmallCouplingIcon(void) { byte x =114, y =50; const byte *bitmap[3] ={imgAcSmall, imgDcSmall, imgOffSmall}; display.fillRect(x, y, 9, 8, BLACK); display.drawBitmap(x, y, bitmap[_CouplingMode], 9, 8, WHITE); display.display();}//----------------------------------------------------------------------------------------------------------------// Show cursor at x position//----------------------------------------------------------------------------------------------------------------void showCursor(byte x) { display.drawChar(XPOS + 2 + x * DELTAX, YPOS + DELTAY, CURSOR, WHITE, WHITE, BIG); display.display();}//----------------------------------------------------------------------------------------------------------------// Hide cursor at x position//----------------------------------------------------------------------------------------------------------------void hideCursor(byte x) { display.drawChar(XPOS + 2 + x * DELTAX, YPOS + DELTAY, CURSOR, BLACK, BLACK, BIG); display.display();}//----------------------------------------------------------------------------------------------------------------// Show cursor at x position after hiding previous one//----------------------------------------------------------------------------------------------------------------void selectDigit(byte x) { static byte lastDigit; hideCursor(lastDigit); display.drawChar(XPOS + 2 + x * DELTAX, YPOS + DELTAY, CURSOR, WHITE, WHITE, BIG); display.display(); lastDigit =x;}//----------------------------------------------------------------------------------------------------------------// Update single digit frequency to chr value//----------------------------------------------------------------------------------------------------------------void updateDigit(byte digit, char chr) { display.drawChar(XPOS + 2 + digit * DELTAX, YPOS, chr , WHITE, BLACK, BIG); display.display();}//----------------------------------------------------------------------------------------------------------------// Drwaw or clear some symbols/icons//----------------------------------------------------------------------------------------------------------------void drawSymbol(byte symbol) { switch (symbol) { case 0://Top arrow display.fillRect(2, 20, 25, 16, BLACK); display.fillRect(2, 43, 14, 16, BLACK); display.drawChar(XPOS - 20 , YPOS + 4, ARROW, WHITE, BLACK, SMALL); //draw top arrow top break; case 1://Bottom arrow display.fillRect(2, 20, 25, 16, BLACK); display.fillRect(2, 43, 14, 16, BLACK); display.drawChar(XPOS - 20 , YPOS + 25, ARROW, WHITE, BLACK, SMALL); //draw bottom arrow break; case 2://Turn icon display.fillRect(2, 20, 25, 16, BLACK); display.drawBitmap(XPOS - 21, YPOS + 1, imgTurn, 13, 13, WHITE); //draw turn icon break; case 3://Play icons display.fillRect(4, 23, 23, 11, BLACK); //clear pause icon display.drawBitmap(4, 23, imgSwRun, 23, 11, WHITE); //draw sweep icon display.fillRect(XPOS + 56, YPOS + 21, 25, 16, BLACK); //clear icon area display.drawBitmap(XPOS + 56, YPOS + 21, imgSwPause, 25, 16, WHITE); //drwaw sweep play symbol icon break; case 4://Pause icons display.fillRect(4, 23, 23, 11, BLACK); //clear sweep icon display.drawBitmap(4, 23, imgSwPsd, 23, 11, WHITE); //draw pause icon display.fillRect(XPOS + 56, YPOS + 21, 25, 16, BLACK); //clear icon area display.drawBitmap(XPOS + 56, YPOS + 21, imgSwStart, 25, 16, WHITE); //draw sweep pause symbol icon break; case 9://Simply clear symbol area display.fillRect(2, 20, 25, 16, BLACK); //clear top symbol area display.fillRect(2, 43, 14, 16, BLACK); //clear bottom symbol area break; default:break; } display.display();}//---------------------------------------------------------------------------------------------------------------// Set current frequency in DDS module, if frequency is 0 it will be set to 1//---------------------------------------------------------------------------------------------------------------void UpdateFrequency(void) { lFreq =atol(Freq); //convert char array to long if (lFreq <1) { //the frequency at zero makes no sense ++Freq[MAXDIGIT - 1]; //increase the right most digit lFreq =1; //set frequency to 1 } displayFrequency(lFreq); //update the display DDS_FrequencySet(lFreq, Wave[_WaveType]); //send the frequency value to DDS module lLastFreq =lFreq; //save current freq}//---------------------------------------------------------------------------------------------------------------// Display the frequency with the six-zero template//---------------------------------------------------------------------------------------------------------------void displayFrequency(long f) { sprintf(Freq, "%06li", f); //convert long to char with template '000000' displayText(XPOS + 2, YPOS, Freq , WHITE, BLACK, BIG); //print frequency on display display.display(); //refresh display}//---------------------------------------------------------------------------------------------------------------// Reset coupling mode to default//---------------------------------------------------------------------------------------------------------------void resetCouplingMode(void) { if (lFreq ==0 &&_CouplingMode ==OFF) { setCouplingMode(AC); drawCouplingIcon(); }}//---------------------------------------------------------------------------------------------------------------// Set a specific coupling mode//---------------------------------------------------------------------------------------------------------------void setCouplingMode(byte cMode) { byte pMode =_CouplingMode; switch (cMode) { case 0:if (lLastFreq> 0) lFreq =lLastFreq; digitalWrite(PinCoupling, LOW); _setCouplingMode(AC); break; case 1:if (lLastFreq> 0) lFreq =lLastFreq; digitalWrite(PinCoupling, HIGH); _setCouplingMode(DC); break; case 2:lLastFreq =lFreq; lFreq =0; digitalWrite(PinCoupling, LOW); _setCouplingMode(OFF); break; } DDS_FrequencySet(lFreq, Wave[_WaveType]); displayFrequency(lFreq); if (cMode !=pMode) saveConfig();}//---------------------------------------------------------------------------------------------------------------// Select options//---------------------------------------------------------------------------------------------------------------void selectOption(byte opt) { selectIcon(opt, BLACK); switch (opt) { case 0://workMode; displayWorkModeIcons(); selectIcon(_WorkMode, WHITE); mode =OPTMODE; break; case 1://waveType; displayWaveTypeIcons(); selectIcon(_WaveType, WHITE); mode =OPTWAVE; break; case 2://couplingMode; displayCouplingModeIcons(); selectIcon(_CouplingMode, WHITE); mode =OPTCOUP; break; }}//----------------------------------------------------------------------------------------------------------------// Calculate logarithmic steps of the frequency//----------------------------------------------------------------------------------------------------------------long AutoStep(long value, byte spin) { if (spin ==CW) { if (value>=100000) return 100000; if (value>=10000) return 10000; if (value>=1000) return 1000; if (value>=100) return 100; if (value>=10) return 10; if (value>=1) return 1; 반환 0; // Invalid value } else { if (value <=10) return 1; if (value <=100) return 10; if (value <=1000) return 100; if (value <=10000) return 1000; if (value <=100000) return 10000; if (value <=1000000) return 100000; 반환 0; // Invalid value }}//-------------------------------------------------------------------------------------------// Start Sweep or restart it from where it came from before the pause//-------------------------------------------------------------------------------------------void FrequencySweep() { do { if (sweepDnPausedVal ==0) { //if sweepDown has not been stopped if (sweepUpPausedVal> 0) { //and sweepUp has been stopped sweepUpPausedVal =SweepUp(sweepUpPausedVal); //continues from current value } else { sweepUpPausedVal =SweepUp(_SweepMin); //else start from min } } if (sweepStatus !=BREAK) { //if sweep has been stopped if (sweepDnPausedVal> 0) { //and sweepDn has been stopped sweepDnPausedVal =SweepDn(sweepDnPausedVal); //continues from current value } else { sweepDnPausedVal =SweepDn(_SweepMax); //else start from max } } } while (sweepStatus !=BREAK); //continues sweep until stopped}//-----------------------------------------------------------------------------------------// Sweep Up from sweepmin push encoder to pause//-----------------------------------------------------------------------------------------long SweepUp(long sweepmin) { long f; for (f =sweepmin; f <_SweepMax; f +=_SweepStep) { DDS_FrequencySet(f, Wave[_WaveType]); displayFrequency(f); if (encoderPush) { sweepStatus =BREAK; break; } } if (sweepStatus ==BREAK) return f; return 0;}//-----------------------------------------------------------------------------------------// Sweep down from sweepmax push encoder to pause//-----------------------------------------------------------------------------------------long SweepDn(long sweepmax) { long f; for (f =sweepmax; f> _SweepMin; f -=_SweepStep) { DDS_FrequencySet(f, Wave[_WaveType]); displayFrequency(f); if (encoderPush) { sweepStatus =BREAK; break; } } if (sweepStatus ==BREAK)return f; return 0;}//-----------------------------------------------------------------------------------------// Clear global sweep vars and restore display//-----------------------------------------------------------------------------------------void SweepReset(void) { sweepStatus =STILL; sweepUpPausedVal =0; sweepDnPausedVal =0; display.fillRect(4, 23, 23, 11, BLACK); //clear sweep text display.display();}//-----------------------------------------------------------------------------------------// Flash sweep pause icon//-----------------------------------------------------------------------------------------void flashIcon(int interval) { static long previousMillis; static boolean picShow; if (millis() - previousMillis>=interval) { previousMillis =millis(); picShow =!picShow; if (picShow) { display.drawBitmap(4, 23, imgSwPsd, 23, 11, WHITE); //drwaw sweep pause icon display.display(); } else { display.fillRect(4, 23, 23, 11, BLACK); //clear sweep pause icon display.display(); } }}//-----------------------------------------------------------------------------------------// Arduino software reset//-----------------------------------------------------------------------------------------void reset(void) { display.fillRect(1, 16, 125, 46, BLACK); display.display(); displayText(30, 30, strFromFlash(4), WHITE, BLACK, BIG); char str[2]; for (byte i =3; i> 0; i--) { sprintf(str, "%d", i); displayText(95, 30, str, WHITE, BLACK, BIG);...This file has been truncated, please download it to see its full contents.
    JXWG_Defs.hC/C++
    Declarections section
    // This file is an integral part of the JX_WaveGenerator.ino and must be// distributed together with the main file to allow it to function correctly.// The same license of the main file applies to this file.// Janux 01/04/2021 on Turin, Italy.#ifndef JXWG_Defs#define JXWG_Defs#include #include //Encoder library, see https://www.arduino.cc/reference/en/libraries/simplerotary/#include  // //adaptation of the library for SSD1306 to the SH1106 display, see https://github.com/wonho-maker/Adafruit_SH1106#include #define DEBUG 0#define OLED_RESET -1Adafruit_SH1106 display(OLED_RESET);#define PinA 5 //Encoder pin A#define PinB 4 //Encoder pin B #define PinS 3 //Encoder pin SwitchSimpleRotary Encoder(PinA, PinB, PinS);//list of loop mode#define LOGARITHMIC 0 //+workmode#define SINGLEDIGIT 1 //+workmode#define SWEEP 2 //+workmode#define OPTIONS 3 //-submode of LOGARITHMIC and SINGLEDIGIT#define OPTMODE 4 //-submode of OPTIONS#define OPTWAVE 5 //-submode of OPTIONS#define OPTCOUP 6 //-submode of OPTIONS#define OPTSWEEP 7 //-submode of SWEEP#define SWEEPEDIT 8 //-submode of OPTSWEEP#define DIGITCHANGE 9 //-submode of SINGLEDIGIT and SWEEPEDIT#define PinCoupling 7 //Coupling mode pin (relay pin)//constants #define XPOS 28#define YPOS 21#define DELTAX 12#define DELTAY 4#define SMALL 1#define BIG 2#define CW 1#define CCW 2#define PUSH 1#define LONGPUSH 1//Num Freq digit#define MAXDIGIT 6//Wave type#define SQUARE 0#define SINE 1#define TRIANGLE 2//Coupling mode#define AC 0#define DC 1#define OFF 2//Sweep status#define STILL 0#define BREAK 1#define PAUSE 2//Symbols chars#define CURSOR 0x5F#define ARROW 0x10//AD9833 module Pin connection#define DDS_FSY 9#define DDS_CLK 10#define DDS_DAT 11//AD9833 Wave Type const#define wSquare 0x28#define wSine 0x00#define wTriangle 0x02//-----------------------------------------------------------------------------// Variables declarections //-----------------------------------------------------------------------------//Strings constants placed in flash memory save ram spaceconst char str1[] PROGMEM ="JX WAVE GENERATOR"; // 18 byteconst char str2[] PROGMEM ="WELCOME"; // 8 byteconst char str3[] PROGMEM ="Hz"; // 3 byteconst char str4[] PROGMEM ="ERROR!"; // 7 byteconst char str5[] PROGMEM ="RESET"; // 6 byte //42 byte totalconst char* const string_table[] PROGMEM ={str1, str2, str3, str4, str5};char buffer[18]; //local buffer for string, make sure this is large enough for the largest string it must holdlong lFreq =1000; //main frequency variablelong lLastFreq =1000; //used to save the current freq value in some situationslong sweepUpPausedVal =0; //value of sweep when pusedlong sweepDnPausedVal =0; //value of sweep when pusedlong lSweep[3] ={20000, 0, 100}; //Sweep Hz default value MAX, MIN, STEP;byte sweepStatus =STILL; //current status of the sweep processconst byte Wave[] ={wSquare, wSine, wTriangle}; //array for WaveTypevolatile boolean encoderPush =false; //var used in the routine called by interruptchar Freq[MAXDIGIT + 1]; //array for display frequency in 6 digit template "000000"byte mode =0; //current loop modebyte idx =0; //pointer to digit index (0 to 5)byte idy =0; //same of idx in submodelong cTime =1; //screensaver counter//default startup preferencesbyte options[3] ={LOGARITHMIC, SINE, DC}; //mode, wavetype, couplingmode//define others macros#define _WorkMode options[0]#define _setWorkMode(x) options[0]=x#define _WaveType options[1]#define _setWaveType(x) options[1]=x#define _CouplingMode options[2]#define _setCouplingMode(x) options[2]=x#define _reservedbyte 0xFF#define _SweepMax lSweep[0]#define _SweepMin lSweep[1]#define _SweepStep lSweep[2]#define _Sweep(x) lSweep[x]#define _setSweep(x,f) lSweep[x]=f#define _setSweepMax(x) lSweep[0]=x#define _setSweepMin(x) lSweep[1]=x#define _setSweepStep(x) lSweep[2]=x//define short functions macros#define _clearIconsArea display.fillRect(XPOS - 11, YPOS + 18, 94, 24, BLACK)#define _displayErrMsg displayText(XPOS + 2, YPOS, strFromFlash(3), WHITE, BLACK, BIG);//define CONFIG consts &vars #define CONFIG_START 32 //EEPROM Memory start location#define CONFIG_VERSION "JXWG1" //Config version ID//define custom type structtypedef struct { char version[6]; byte workmode; byte wavetype; byte couplingmode; byte reservedbyte; long sweepmax; long sweepmin; long sweepstep;} config_type;//create new struct and load it with default valueconfig_type CONFIG ={ CONFIG_VERSION, _WorkMode, _WaveType, _CouplingMode, _reservedbyte, _SweepMax, _SweepMin, _SweepStep,};//define processor reset functionvoid(*ATmegaReset)(void) =0;#endif
    JXWG_Graphics.hC/C++
    Icon resource data file
    // This file is an integral part of the JX_WaveGenerator.ino and must be// distributed together with the main file to allow it to function correctly.// The same license of the main file applies to this file.// Janux 01/04/2021 on Turin, Italy.#ifndef JXWG_Graphics#define JXWG_Graphics//----------------------------------------------------------------------------------------------// Plain b&w bitmaps PROGMEM icons data//----------------------------------------------------------------------------------------------const byte imgLog[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x88, 0x00, 0x40, 0x80, 0x9c, 0x00, 0x40, 0x80, 0x88, 0x00, 0x80, 0x80, 0x88, 0x00, 0x80, 0x80, 0x88, 0x01, 0x00, 0x80, 0x88, 0x02, 0x00, 0x80, 0x88, 0x0c, 0x00, 0x80, 0x88, 0x30, 0x00, 0x80, 0x89, 0xc0, 0x00, 0x80, 0x8e, 0x00, 0x10, 0x80, 0x9f, 0xff, 0xf8, 0x80, 0x88, 0x00, 0x10, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgDigit[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x9c, 0x47, 0x3e, 0x80, 0xa2, 0xc8, 0x82, 0x80, 0xa6, 0x40, 0x84, 0x80, 0xaa, 0x47, 0x0c, 0x80, 0xb2, 0x48, 0x02, 0x80, 0xa2, 0x48, 0x22, 0x80, 0x9c, 0xef, 0x9c, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x3e, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSweep[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x8f, 0xcf, 0x38, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0x88, 0x49, 0x28, 0x80, 0xb8, 0x79, 0xee, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSqr[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x82, 0x08, 0x20, 0x80, 0x80, 0xff, 0x80, 0x80, 0x82, 0x88, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x88, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xaa, 0xaa, 0xaa, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x88, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x88, 0xa0, 0x80, 0xff, 0x80, 0xff, 0x80, 0x82, 0x08, 0x20, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSin[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x82, 0x08, 0x20, 0x80, 0x80, 0x1c, 0x00, 0x80, 0x82, 0x2a, 0x20, 0x80, 0x80, 0x41, 0x00, 0x80, 0x82, 0x49, 0x20, 0x80, 0x80, 0x80, 0x80, 0x80, 0xaa, 0xaa, 0xaa, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc3, 0x08, 0x61, 0x80, 0xc1, 0x00, 0x41, 0x80, 0xa2, 0x08, 0x22, 0x80, 0x9c, 0x00, 0x1c, 0x80, 0x82, 0x08, 0x20, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgTri[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x82, 0x08, 0x20, 0x80, 0x82, 0x00, 0x20, 0x80, 0x87, 0x08, 0x70, 0x80, 0x85, 0x00, 0x50, 0x80, 0x8a, 0x88, 0xa8, 0x80, 0x88, 0x80, 0x88, 0x80, 0xba, 0xeb, 0xae, 0x80, 0x90, 0x41, 0x04, 0x80, 0xa2, 0x2a, 0x22, 0x80, 0xa0, 0x22, 0x02, 0x80, 0xc2, 0x1c, 0x21, 0x80, 0xc0, 0x14, 0x01, 0x80, 0x82, 0x08, 0x20, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgCoAc[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x9c, 0x70, 0x00, 0x80, 0xa2, 0x88, 0x00, 0x80, 0xa2, 0x80, 0xc0, 0x80, 0xa2, 0x81, 0x24, 0x80, 0xbe, 0x81, 0x24, 0x80, 0xa2, 0x88, 0x18, 0x80, 0xa2, 0x70, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgCoDc[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xbc, 0x70, 0x00, 0x80, 0xa2, 0x88, 0x00, 0x80, 0xa2, 0x81, 0x54, 0x80, 0xa2, 0x80, 0x00, 0x80, 0xa2, 0x81, 0xfc, 0x80, 0xa2, 0x88, 0x00, 0x80, 0xbc, 0x70, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgCoOff[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x9c, 0xf7, 0x80, 0x80, 0xa2, 0x84, 0x22, 0x80, 0xa2, 0x84, 0x14, 0x80, 0xa2, 0xe7, 0x08, 0x80, 0xa2, 0x84, 0x14, 0x80, 0xa2, 0x84, 0x22, 0x80, 0x9c, 0x84, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwMax[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x81, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x80, 0x87, 0x01, 0x00, 0x80, 0x82, 0x03, 0x80, 0x80, 0x82, 0x07, 0xc0, 0x80, 0x82, 0x0f, 0xe0, 0x80, 0x82, 0x1f, 0xf0, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwMin[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x81, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x80, 0x87, 0x1f, 0xf0, 0x80, 0x82, 0x0f, 0xe0, 0x80, 0x82, 0x07, 0xc0, 0x80, 0x82, 0x03, 0x80, 0x80, 0x82, 0x01, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwOpt[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x84, 0x08, 0x10, 0x80, 0x88, 0x1c, 0x38, 0x80, 0x9c, 0x3e, 0x10, 0x80, 0x88, 0x00, 0x00, 0x80, 0x88, 0x00, 0x00, 0x80, 0x88, 0x3e, 0x00, 0x80, 0x88, 0x1c, 0x38, 0x80, 0x88, 0x08, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwStep[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x84, 0x08, 0x04, 0x80, 0x88, 0x0c, 0x08, 0x80, 0x9c, 0x7e, 0x1c, 0x80, 0x88, 0x7f, 0x08, 0x80, 0x88, 0x7e, 0x08, 0x80, 0x88, 0x0c, 0x08, 0x80, 0x88, 0x08, 0x08, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwStart[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x00, 0x80, 0x80, 0xf0, 0x00, 0x80, 0x80, 0xfc, 0x00, 0x80, 0x80, 0xff, 0x00, 0x80, 0x80, 0xff, 0xc0, 0x80, 0x80, 0xff, 0xc0, 0x80, 0x80, 0xff, 0x00, 0x80, 0x80, 0xfc, 0x00, 0x80, 0x80, 0xf0, 0x00, 0x80, 0x80, 0xc0, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgSwPause[] PROGMEM ={ 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x81, 0xe3, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x80};const byte imgTurn[] PROGMEM ={ 0x0f, 0x80, 0x30, 0x60, 0x47, 0x10, 0x58, 0xd0, 0x90, 0x48, 0x80, 0xe8, 0x90, 0x48, 0xb8, 0x08, 0x90, 0x48, 0x58, 0xd0, 0x47, 0x10, 0x30, 0x60, 0x0f, 0x80};const byte imgSwRun[] PROGMEM ={ 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x9b, 0xa2, 0x22, 0x6b, 0xae, 0xec, 0x7b, 0xae, 0xec, 0x9a, 0xa6, 0x62, 0xea, 0xae, 0xee, 0x6a, 0xae, 0xee, 0x9c, 0x62, 0x2e, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00};const byte imgSwPsd[] PROGMEM ={ 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x1c, 0xdb, 0x30, 0x6b, 0x5a, 0xd6, 0x6b, 0x5a, 0xf6, 0x18, 0x5b, 0x32, 0x7b, 0x5b, 0xd6, 0x7b, 0x5a, 0xd6, 0x7b, 0x67, 0x30, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00};//Small icons ---------------------------------------------------------------------------------const byte imgSqrSmall[] PROGMEM ={ 0x00, 0x00, 0x3e, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0xe3, 0x80, 0x00, 0x00};const byte imgSinSmall[] PROGMEM ={ 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x84, 0x80, 0x84, 0x80, 0x03, 0x00, 0x00, 0x00};const byte imgTriSmall[] PROGMEM ={ 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x88, 0x80, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};const byte imgAcSmall[] PROGMEM ={ 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x84, 0x80, 0x84, 0x80, 0x03, 0x00, 0x00, 0x00};const byte imgDcSmall[] PROGMEM ={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x80, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00};const byte imgOffSmall[] PROGMEM ={ 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x22, 0x00, 0x00, 0x00};//Total program memory space used by icons data:1148 byte#endif

    회로도

    Display type updated

    제조공정

    1. Arduino로 물방울 캡처
    2. Arduino 스파이봇
    3. FlickMote
    4. 수제 TV B-Gone
    5. 마스터 시계
    6. 나를 찾기
    7. Arduino Power
    8. DIY 가상 현실 스케이트보드
    9. Arduino Mega를 NEO-6M GPS 모듈과 인터페이스하는 방법
    10. Tech-TicTacToe