Here's one way to write a Python function that returns a list of prime numbers up to a given maximum value:

Copy code
def get_primes(maximum):
    primes = []
    for num in range(2, maximum + 1):
        for prime in primes:
            if num % prime == 0:
                break
        else:
            primes.append(num)
    return primes

print(get_primes(20))
This function uses a for loop to iterate through the numbers from 2 to the given maximum value. For each number, it checks if it is divisible by any of the prime numbers that have been found so far. If it is not divisible by any of them, it is added to the list of primes. At the end, the list of primes is returned.

You can call the function with a maximum value to get a list of all prime numbers up to that value. In the example above, the output would be [2, 3, 5, 7, 11, 13, 17, 19].

Posted by 살레시오
,

Q) 아두이노의 5번핀에 LED가 연결되어 있을 경우 1초 간격으로 깜박이는 프로그램을 작성해줘.
A)

void setup() {
  pinMode(5, OUTPUT); // 5번 핀을 출력으로 설정
}

void loop() {
  digitalWrite(5, HIGH); // 5번 핀에 전압 인가
  delay(1000); // 1초 대기
  digitalWrite(5, LOW); // 5번 핀에 전압 끄기
  delay(1000); // 1초 대기
}
위 코드를 사용하면 1초 간격으로 LED가 깜박입니다.

 

 

Q) 아두이노의 I2C에 LCD가 연결된 경우 "Hello world"를 표시하는 프로그램을 작성해줘.
A)

#include <Wire.h> 
#include <LiquidCrystal_I2C.h> 

LiquidCrystal_I2C lcd(0x27,16,2); 

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.print("Hello world!");
}

void loop() {
}
위 코드를 사용하면 I2C를 이용하여 연결된 LCD에 "Hello world"가 표시됩니다.
LiquidCrystal_I2C.h 라이브러리를 추가해야 하며, 사용하는 LCD의 I2C 주소를 확인해야 할 수 있습니다.

 


Q) 아두이노로 DC모터를 제어하는 프로그램을 작성해줘.
A)

#include <Adafruit_MotorShield.h> 
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);

void setup() {
  AFMS.begin();
  myMotor->setSpeed(255); // set the speed to 255
  myMotor->run(FORWARD); // run the motor forward
  myMotor->run(RELEASE); // stop the motor
}

void loop() {
    myMotor->run(FORWARD); // run the motor forward
    delay(1000); // wait for 1 second
    myMotor->run(BACKWARD); // run the motor backward
    delay(1000); // wait for 1 second
    myMotor->run(RELEASE); // stop the motor
}
위 코드를 사용하면, Adafruit Motor Shield 라이브러리를 사용하여 1번 모터를 제어하며, 1초마다 방향을 바꾸어 DC모터를 제어 할 수 있습니다.

모터의 방향을 제어하기 위해서는 아래 구문 사용 가능
myMotor->run(FORWARD); // run the motor forward
myMotor->run(BACKWARD); // run the motor backward
myMotor->run(RELEASE); // stop the motor

모터 속도를 제어하기 위해서는 아래 구문 사용 가능
myMotor->setSpeed(255); // set the speed to 255

(모터 속도는 0~255 사이의 값을 사용 가능)

라이브러리는 아두이노 IDE에서 Adafruit Motor Shield V2 for Arduino library를 설치해야 합니다.

Posted by 살레시오
,

윤동주의 서시 "죽는 날까지 하늘을 우러러 한 점 부끄럼이 없기를, 잎새에 이는 바람에도 나는 괴로워했다. 별을 노래하는 마음으로 모든 죽어 가는 것을 사랑해야지 그리고 나한테 주어진 길을 걸어가야겠다. 오늘 밤에도 별이 바람에 스치운다."를 영어로 번역해줘.

"Until the day I die, I will gaze at the sky

Wishing for not a single speck of shame

Even when the wind blows through the leaves

I have felt pain.

With a heart that sings of stars

I must love all that dies

And the path that is given to me

I must walk it."

Please note that the above is my interpretation of the poem, and there might be variations in the translation of some phrases or expressions depending on the context and the translator's perspective.

 

Posted by 살레시오
,

  ChatGPT는 OpenAI에서 개발한 언어 모델입니다. 이 모델은 크기가 매우 크고 매우 높은 정확도를 가지고 있어, 인공 지능 언어 처리 작업에 많이 사용됩니다. 이 모델은 자연어 생성, 문장 완성, 대화 생성 등 다양한 작업에 사용될 수 있습니다.

  ChatGPT는 트랜스포머 네트워크를 기반으로 하며, 이를 통해 입력된 텍스트를 기반으로 다음에 올바른 단어를 생성할 수 있습니다. 또한, 이 모델은 인공 지능 언어 처리 작업을 수행하는데 있어 훈련된 데이터의 양과 품질이 매우 중요하며, OpenAI는 이를 위해 많은 데이터를 사용하여 학습하였습니다.

  ChatGPT는 인공 지능 언어 처리 작업에서 매우 높은 성능을 보이고 있습니다. 이는 크기가 매우 크고 훈련된 데이터의 양과 품질이 뛰어나기 때문입니다. 이 모델은 트랜스포머 네트워크를 기반으로 하여 입력된 텍스트를 기반으로 다음에 올바른 단어를 생성할 수 있습니다.

  ChatGPT는 다양한 작업에서 성능이 우수합니다. 예를 들어, 자연어 생성, 문장 완성, 대화 생성 등에서 우수한 성능을 보이고 있습니다. 이는 이 모델이 많은 데이터를 통해 학습되어 있기 때문입니다. 또한, ChatGPT는 상황에 따라 알맞은 답변을 생성하는데도 우수한 성능을 보입니다. 단, 성능을 더욱 향상시키기 위해서는 fine-tuning을 통해 특정 분야에 대한 정보를 학습시켜야 합니다.

  ChatGPT는 상업적으로 다양한 분야에서 활용될 수 있습니다. 아래는 ChatGPT의 상업적 활용 예 중 몇 가지 입니다.

  1. 자연어 질의 응답 (Natural Language Processing, NLP): ChatGPT는 인공 지능 언어 처리 작업에서 뛰어난 성능을 보입니다. 이를 통해 사용자가 질문을 할 때 알맞은 답변을 생성하는 챗봇을 구축할 수 있습니다.
  2. 자동 번역: ChatGPT를 이용하면 자연어를 다른 언어로 자동으로 번역할 수 있습니다.
  3. 자동 기재: ChatGPT는 자연어를 기반으로 하여 자동으로 글을 작성할 수 있습니다. 이를 통해 이메일, 문서, 기사 등을 자동으로 작성할 수 있습니다.
  4. 음성 인식: ChatGPT는 음성을 텍스트로 변환하는 작업에도 사용될 수 있습니다.
  5. 인공 지능 음성 대화 생성: ChatGPT를 이용하면 인공 지능과 사용자가 상호작용하는 대화를 생성할 수 있습니다.

 

Posted by 살레시오
,

// Advanced Microcontroller-based Audio Workshop
//
// http://www.pjrc.com/store/audio_tutorial_kit.html
// https://hackaday.io/project/8292-microcontroller-audio-workshop-had-supercon-2015
// 
// Part 1-3: First "Hello World" program, play a music file
//
// WAV files for this and other Tutorials are here:
// http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlaySdWav           playSdWav7;     //xy=91,352.00000953674316
AudioPlaySdWav           playSdWav6;     //xy=102,307.00000953674316
AudioPlaySdWav           playSdWav5;     //xy=108,261.0000286102295
AudioPlaySdWav           playSdWav3;     //xy=111.00000381469727,148.00000381469727
AudioPlaySdWav           playSdWav4;     //xy=113.00000381469727,210.0000057220459
AudioPlaySdWav           playSdWav1;     //xy=114,43.000003814697266
AudioPlaySdWav           playSdWav2;     //xy=114,95.00000190734863
AudioMixer4              mixer1;         //xy=308.0000114440918,118.00000381469727
AudioMixer4              mixer2;         //xy=473.0000534057617,227.0000057220459
AudioOutputI2S           i2s1;           //xy=640.0000991821289,266.0000276565552
AudioConnection          patchCord1(playSdWav7, 0, mixer2, 3);
AudioConnection          patchCord2(playSdWav6, 0, mixer2, 2);
AudioConnection          patchCord3(playSdWav5, 0, mixer2, 1);
AudioConnection          patchCord4(playSdWav3, 0, mixer1, 2);
AudioConnection          patchCord5(playSdWav4, 0, mixer1, 3);
AudioConnection          patchCord6(playSdWav1, 0, mixer1, 0);
AudioConnection          patchCord7(playSdWav2, 0, mixer1, 1);
AudioConnection          patchCord8(mixer1, 0, mixer2, 0);
AudioConnection          patchCord9(mixer2, 0, i2s1, 0);
AudioConnection          patchCord10(mixer2, 0, i2s1, 1);
// GUItool: end automatically generated code

AudioControlSGTL5000     sgtl5000_1;


///* Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14
//*/

/*// Use these with the Teensy 4.1 onboard SD card
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used
//*/

/*
//file names of guitar strings(gs):
const char* gs6[] ={"g600E.wav","g601F.wav","g602F#.wav","g603G.wav","g604G#.wav","g605A.wav","g606A#.wav","g607B.wav","g608C.wav","g609C#.wav","g610D.wav","g611D#.wav"};
const char* gs5[] ={"g500A.wav","g501A#.wav","g502B.wav","g503C.wav","g504C#.wav","g505D.wav","g506D#.wav","g507E.wav","g508F.wav","g509F#.wav"};
const char* gs4[] ={"g400D.wav","g401D#.wav","g402E.wav","g403F.wav","g404F#.wav","g405G.wav","g406G#.wav","g407A.wav","g408A#.wav","g409B.wav"};
const char* gs3[] ={"g300G.wav","g301G#.wav","g302A.wav","g303A#.wav","g304B.wav","g305C.wav","g306C#.wav","g307D.wav","g308D#.wav","g309E.wav"};
const char* gs2[] ={"g200B.wav","g201C.wav","g202C#.wav","g203D.wav","g204D#.wav","g205E.wav","g206F.wav","g207F#.wav","g208G.wav","g209G#.wav"};
const char* gs1[] ={"g100E.wav","g101F.wav","g102F#.wav","g103G.wav","g104G#.wav","g105A.wav","g106A#.wav","g107B.wav","g108C.wav","g109C#.wav"};
//C:C,E,G:{8,7,5,5,5,3}
//F:F,A,C:{1,0,3,2,1,1}
//*/

const char* gstr[] ={
 "g600E.wav"/*0*/,"g601F.wav"/*1*/,"g602F#.wav"/*2*/,"g603G.wav"/*3*/,"g604G#.wav"/*4*/
,"g500A.wav"/*5*/,"g501A#.wav"/*6*/,"g502B.wav"/*7*/,"g503C.wav"/*8*/,"g504C#.wav"/*9*/
,"g400D.wav"/*10*/,"g401D#.wav"/*11*/,"g402E.wav"/*12*/,"g403F.wav"/*13*/,"g404F#.wav"/*14*/
,"g300G.wav"/*15*/,"g301G#.wav"/*16*/,"g302A.wav"/*17*/,"g303A#.wav"/*18*/                
,"g200B.wav"/*19*/,"g201C.wav"/*20*/,"g202C#.wav"/*21*/,"g203D.wav"/*22*/,"g204D#.wav"/*23*/
,"g100E.wav"/*24*/,"g101F.wav"/*25*/,"g102F#.wav"/*26*/,"g103G.wav"/*27*/,"g104G#.wav"/*28*/
//아래는 1번 줄의 고음을 sampling한 것들
,"g105A.wav"/*29*/,"g106A#.wav"/*30*/,"g107B.wav"/*31*/,"g108C.wav"/*32*/,"g109C#.wav"/*33*/
,"g110D.wav"/*34*/,"g111D#.wav"/*35*/,"g112E.wav"/*36*/,"g113F.wav"/*37*/,"g114F#.wav"/*38*/,"g115G.wav"/*39*/
,"g116G#.wav"/*40*/,"g117A.wav"/*41*/,"g118A#.wav"/*42*/,"g119B.wav"/*43*/
};

//C:C,E,G:{8(C),0(E),3(G),12(E),15(G),20(C)}
//F:F,A,C:{1(F),5(A),8(C),13(F),17(A),20(C)}

//주의: 13번핀(LED)는 다른 용도(SCK)로 예약되어 있으므로 사용하면 안됨!
void setup() {
  
  Serial.begin(9600);
  
  // AudioMemoryUsageMax() 함수로 조사한 것보다 커야 한다
  // 이 예제의 경우에 7값이 찍혔다
  // https://www.pjrc.com/teensy/td_libs_AudioConnection.html
  AudioMemory(50);
  
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.7);
  
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      while(1);
    }
  }

  
  delay(1000);

/*
  mixer1.gain(0, 0.5);
  mixer1.gain(1, 0.5);
  mixer1.gain(2, 0.5);
  mixer1.gain(3, 0.5);
  mixer2.gain(0, 0.5);
  mixer2.gain(1, 0.5);
  mixer2.gain(2, 0.5);
  */
}

#define DELAY 2
void loop() {
  //if (playSdWav1.isPlaying() == false) {
  
    Serial.println(AudioMemoryUsageMax());
/*
    playChord(8,0,3,12,15,20);// playChord(8,0,15,24,32,39);
    delay(random(5,10)*40); // wait for library to parse WAV info
    playChord(8,0,3,12,15,20);// playChord(8,0,15,24,32,39);
    delay(random(5,10)*40); // wait for library to parse WAV info
    playChord(8,24,27,32,36,39);//playChord(8,3,12,20,27,36);
    delay(random(5,10)*40); // wait for library to parse WAV info
    playChord(8,24,27,32,36,39);//playChord(8,3,12,20,27,36);
    delay(random(5,10)*40); // wait for library to parse WAV info
*/
    playChord(8,0,15,24,32,39);
    delay(random(5,10)*10); // wait for library to parse WAV info
    playChord(8,0,15,24,32,39);
    delay(random(5,10)*10); // wait for library to parse WAV info
    playChord(8,3,12,20,27,36);
    delay(random(5,10)*10); // wait for library to parse WAV info
    playChord(8,3,12,20,27,36);
    delay(random(5,10)*10); // wait for library to parse WAV info
  
  // do nothing while playing...
}

void playChord(byte s1, byte s2, byte s3, byte s4, byte s5, byte s6){
  
    playSdWav1.stop();//must be stopped first
    do {
      playSdWav1.play(gstr[s1]);
      delay(DELAY);
    } while (!playSdWav1.isPlaying());
    
    playSdWav2.stop();//must be stopped first
    do{
      playSdWav2.play(gstr[s2]);
      delay(DELAY);
    } while (!playSdWav2.isPlaying());
    
    playSdWav3.stop();//must be stopped first
    do {
      playSdWav3.play(gstr[s3]);
      delay(DELAY);
    } while (!playSdWav3.isPlaying());
    
    playSdWav4.stop();//must be stopped first
    do {playSdWav4.play(gstr[s4]);
    delay(DELAY);} while (!playSdWav4.isPlaying());
    
    playSdWav5.stop();//must be stopped first
    do {playSdWav5.play(gstr[s5]);
    delay(DELAY);} while (!playSdWav5.isPlaying());
    
    playSdWav6.stop();//must be stopped first
    do {playSdWav6.play(gstr[s6]);
    delay(DELAY);} while (!playSdWav6.isPlaying());
}

Posted by 살레시오
,

teensy audio design GUI

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlaySdWav           playSdWav3;     //xy=74,367
AudioPlaySdWav           playSdWav1;     //xy=77,241
AudioPlaySdWav           playSdWav7;     //xy=78,597
AudioPlaySdWav           playSdWav4;     //xy=80,425
AudioPlaySdWav           playSdWav2;     //xy=81,303
AudioPlaySdWav           playSdWav6;     //xy=82,535
AudioPlaySdWav           playSdWav5;     //xy=86,476
AudioMixer4              mixer1;         //xy=291,316
AudioMixer4              mixer2;         //xy=449,424
AudioOutputI2S           i2s1;           //xy=626,430
AudioConnection          patchCord1(playSdWav3, 0, mixer1, 2);
AudioConnection          patchCord2(playSdWav1, 0, mixer1, 0);
AudioConnection          patchCord3(playSdWav7, 0, mixer2, 3);
AudioConnection          patchCord4(playSdWav4, 0, mixer1, 3);
AudioConnection          patchCord5(playSdWav2, 0, mixer1, 1);
AudioConnection          patchCord6(playSdWav6, 0, mixer2, 2);
AudioConnection          patchCord7(playSdWav5, 0, mixer2, 1);
AudioConnection          patchCord8(mixer1, 0, mixer2, 0);
AudioConnection          patchCord9(mixer2, 0, i2s1, 0);
AudioConnection          patchCord10(mixer2, 0, i2s1, 1);
// GUItool: end automatically generated code

AudioControlSGTL5000     sgtl5000_1;

// 오디오보드의 sd카드 슬롯을 이용
//#define SDCARD_CS_PIN    10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14

// Teensy4.1보드의 sd카드 슬롯을 이용
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used


//기타와 관련된 상수들
#define TOUCHED 1
#define UNTOUCHED 0

#define STRING1 24
#define STRING2 25
#define STRING3 26
#define STRING4 27
#define STRING5 28
#define STRING6 29


void setup() {
  Serial.begin(115200);
  delay(1000);

  // put your setup code here, to run once:
  AudioMemory(8);
  sgtl5000_1.enable();
  sgtl5000_1.volume(1.0);
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);

 
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  
  
  Serial.println("Ready.");
  
  pinMode(STRING1,INPUT);
  pinMode(STRING2,INPUT);
  pinMode(STRING3,INPUT);
  pinMode(STRING4,INPUT);
  pinMode(STRING5,INPUT);
  pinMode(STRING6,INPUT);
  
}


bool prevString1 = UNTOUCHED;
bool prevString2 = UNTOUCHED;
bool prevString3 = UNTOUCHED;
bool prevString4 = UNTOUCHED;
bool prevString5 = UNTOUCHED;
bool prevString6 = UNTOUCHED;

///*
#define TIME_WAIT_TO_PLAY 2
void forcePlay(AudioPlaySdWav *ptrPlaySdWav, const char *wav){
  ptrPlaySdWav->stop();
  do{
    ptrPlaySdWav->play(wav);
    delay(TIME_WAIT_TO_PLAY);
  } while(!ptrPlaySdWav->isPlaying());
}
//*/

void loop() {

  int tm=millis();
///*
  bool str1 = digitalRead(STRING1);
  if (prevString1==UNTOUCHED and str1==TOUCHED){
    forcePlay(&playSdWav1, "g100E.wav");
  }

  bool str2 = digitalRead(STRING2);
  if (prevString2==UNTOUCHED and str2==TOUCHED){
    forcePlay(&playSdWav2, "g200B.wav");
  }

  bool str3 = digitalRead(STRING3);
  if (prevString3==UNTOUCHED and str3==TOUCHED){
    forcePlay(&playSdWav3, "g300G.wav");
  }

  bool str4 = digitalRead(STRING4);
  if (prevString4==UNTOUCHED and str4==TOUCHED){
    forcePlay(&playSdWav4, "g400D.wav");
  }


  bool str5 = digitalRead(STRING5);
  if (prevString5==UNTOUCHED and str5==TOUCHED){
    forcePlay(&playSdWav5, "g500A.wav");
  }

  bool str6 = digitalRead(STRING6);
  if (prevString6==UNTOUCHED and str6==TOUCHED){
    forcePlay(&playSdWav6, "g600E.wav");
  }

  
  prevString1=str1;
  prevString2=str2;
  prevString3=str3;
  prevString4=str4;
  prevString5=str5;
  prevString6=str6;
//*/
  

/*
  playSdWav1.stop();
  do{
    playSdWav1.play("g600E.wav");
    delay(TIME_WAIT_TO_PLAY);
  } while(!playSdWav1.isPlaying());
*/
  
  Serial.print(millis()-tm);
  Serial.print(", S1:");Serial.print(str1);
  Serial.print(", S2:");Serial.print(str2);
  Serial.print(", S3:");Serial.print(str3);
  Serial.print(", S4:");Serial.print(str4);
  Serial.print(", S5:");Serial.print(str5);
  Serial.print(", S6:");Serial.print(str6);
  Serial.println();
  delay(10);
}

Posted by 살레시오
,

// 2021/11/8: Lolin32+OLED final

//#define DEBUG_SERIAL

#include <WiFi.h>
#include <driver/adc.h> // for adc_power_off()


#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 oled(128, 64, &Wire, -1);

// 한 번만 샘플링하면 1~2%의 확률로 0에 가까운 값이 읽힌다고 한다(잡음)
// 따라서 여러번 샘플링하여 평균값으로 판단하는 것이 안정적이다.
// SAMPLES가 20이면 loop()함수 한 번 실행 시간이 76ms 정도이다.
// 30이면 113ms 정도이다.
#define SAMPLES 20


// touchRead() 평균값이 아래 문턱값 이하이면 터치된 걸로 판단
#define THRESHOLD 20


#define PAD1    36 //(1) C#
#define PAD2    39 //(2) C
#define PAD3    34 //(3) D#
#define PAD4    35 //(4) D
#define PAD5    25 //(5) E
#define PAD6    26 //(6) F#
#define PAD7    19 //(7) F
#define PAD8    23 //(8) G#
#define PAD9    18 //(9) G
#define TPAD10  T9 //(10)A#
#define TPAD11  T8 //(11)A
#define TPAD12  T7 //(12)B
#define TPAD13  T6 //(13)
#define TPAD14  T5 //(14)
#define TPAD15  T4 //(15)

#define OUT_1  5
#define OUT_2  17
#define OUT_3  16
#define OUT_4  4
#define OUT_A  0
#define OUT_B  2
#define OUT_C  15

void setup() {

  // 소모전력을 줄이기 위해서 WiFi와 bt는 끈다.
  // ADC도 사용하지 않으므로 꺼야 한다.
  adc_power_off();
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  btStop();

  // put your setup code here, to run once:
  
  ///*
  pinMode(PAD1, INPUT);
  pinMode(PAD2, INPUT);
  pinMode(PAD3, INPUT);
  pinMode(PAD4, INPUT);
  pinMode(PAD5, INPUT);
  pinMode(PAD6, INPUT);
  pinMode(PAD7, INPUT);
  pinMode(PAD8, INPUT);
  pinMode(PAD9, INPUT);
  
  pinMode(OUT_1, OUTPUT); //LED_BUILTIN
  pinMode(OUT_2, OUTPUT);
  pinMode(OUT_3, OUTPUT);
  pinMode(OUT_4, OUTPUT);
  pinMode(OUT_A, OUTPUT);
  pinMode(OUT_B, OUTPUT);
  pinMode(OUT_C, OUTPUT);

  // Address 0x3D for 128x64
  boolean isDisplayReady = oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);

#ifdef DEBUG_SERIAL //#######################
  Serial.begin(115200);
  delay(100);
  if(!isDisplayReady) { 
    Serial.println(F("OLED(SSD1306) diaplay detection failed"));
  }
#endif //####################################

  oled.clearDisplay();
  oled.display();
}


byte getTouchAverage(byte tN){
  int totalRead = 0;
  for(byte n=0; n<SAMPLES; n++){
    totalRead += touchRead(tN);
  }
  return totalRead/SAMPLES;
}

char notes[] = {' ', 'C', 'D', 'E', 'F', 'G', 'A', 'B'};
char *chords[] = {
    "",  //CBA:000
    "7", //CBA:001
    "m", //CBA:010
    "m7",//CBA:011
    "M", //CBA:100
    "M7",//CBA:101
    "sus4", //CBA:110
    "dim7", //CBA:111
};
byte idNote=0;
boolean isHalfHigh=false;
byte idChord=0;
byte prevChordByte=0;



void loop() {

  
#ifdef DEBUG_SERIAL //#######################
  int tm = millis();//(2)
#endif //####################################

  byte chordByte;

  boolean p1=digitalRead(PAD1);
  boolean p2=digitalRead(PAD2);
  boolean p3=digitalRead(PAD3);
  boolean p4=digitalRead(PAD4);
  boolean p5=digitalRead(PAD5);
  boolean p6=digitalRead(PAD6);
  boolean p7=digitalRead(PAD7);
  boolean p8=digitalRead(PAD8);
  boolean p9=digitalRead(PAD9);

  byte tp10=getTouchAverage(TPAD10);
  byte tp11=getTouchAverage(TPAD11);
  byte tp12=getTouchAverage(TPAD12);
  byte tp13=getTouchAverage(TPAD13);
  byte tp14=getTouchAverage(TPAD14);
  byte tp15=getTouchAverage(TPAD15);
  
  boolean p10 = tp10 < THRESHOLD;
  boolean p11 = tp11 < THRESHOLD;
  boolean p12 = tp12 < THRESHOLD;
  boolean p13 = tp13 < THRESHOLD;
  boolean p14 = tp14 < THRESHOLD;
  boolean p15 = tp15 < THRESHOLD;


  if(p1==HIGH){ //C#
    
    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p4); //gpio0
    digitalWrite(OUT_B, p5);
    digitalWrite(OUT_C, p7);   

    idNote=1;
    isHalfHigh = true; 
    idChord = p4+p5*2+p7*4;

    chordByte = 1+idChord*16;
    
  } else if (p2==HIGH){ //C
    
    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p4); //gpio0
    digitalWrite(OUT_B, p5);
    digitalWrite(OUT_C, p7);  

    idNote=1;
    isHalfHigh = false; 
    idChord = p4+p5*2+p7*4;

    chordByte = 2+idChord*16;

  } else if (p3==HIGH){ //D#

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p5); //gpio0
    digitalWrite(OUT_B, p7);
    digitalWrite(OUT_C, p9);  

    idNote=2;
    isHalfHigh = true; 
    idChord = p5+p7*2+p9*4;

    chordByte = 3+idChord*16;

  } else if (p4==HIGH){ //D

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p5); //gpio0
    digitalWrite(OUT_B, p7);
    digitalWrite(OUT_C, p9);  

    idNote=2;
    isHalfHigh = false; 
    idChord = p5+p7*2+p9*4;

    chordByte = 4+idChord*16;

  } else if (p5==HIGH){ //E

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p7); //gpio0
    digitalWrite(OUT_B, p9);
    digitalWrite(OUT_C, p11);  

    idNote=3;
    isHalfHigh = false; 
    idChord = p7+p9*2+p11*4;

    chordByte = 5+idChord*16;
    
  } else if (p6==HIGH){ //F#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p9); //gpio0
    digitalWrite(OUT_B, p11);
    digitalWrite(OUT_C, p12);

    idNote=4;
    isHalfHigh = true; 
    idChord = p9 + p11*2 + p12*4;

    chordByte = 6+idChord*16;

  } else if (p7==HIGH){ //F

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p9); //gpio0
    digitalWrite(OUT_B, p11);
    digitalWrite(OUT_C, p12);  

    idNote=4;
    isHalfHigh = false; 
    idChord = p9+p11*2+p12*4;

    chordByte = 7+idChord*16;


  } else if (p8==HIGH){ //G#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p11); //gpio0
    digitalWrite(OUT_B, p12);
    digitalWrite(OUT_C, p13);  

    idNote=5;
    isHalfHigh = true; 
    idChord = p11 + p12*2 + p13*4;

    chordByte = 8+idChord*16;

  } else if (p9==HIGH){ //G

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p11); //gpio0
    digitalWrite(OUT_B, p12);
    digitalWrite(OUT_C, p13);  

    idNote=5;
    isHalfHigh = false; 
    idChord = p11 + p12*2 + p13*4;

    chordByte = 9+idChord*16;

  } else if (p10==HIGH){ //A#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p12); //gpio0
    digitalWrite(OUT_B, p13);
    digitalWrite(OUT_C, p14);  

    idNote=6;
    isHalfHigh = true; 
    idChord = p12 + p13*2 + p14*4;

    chordByte = 10+idChord*16;

  } else if (p11==HIGH){ //A

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p12); //gpio0
    digitalWrite(OUT_B, p13);
    digitalWrite(OUT_C, p14);  

    idNote=6;
    isHalfHigh = false; 
    idChord = p12 + p13*2 + p14*4;

    chordByte = 11+idChord*16;

  } else if (p12==HIGH){ //B

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p13); //gpio0
    digitalWrite(OUT_B, p14);
    digitalWrite(OUT_C, p15);  

    idNote=7;
    isHalfHigh = false; 
    idChord = p13 + p14*2 + p15*4;

    chordByte = 12+idChord*16;

  } else { //아무 코드도 짚지 않았을 때
  
    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, 0);
    digitalWrite(OUT_B, 0);
    digitalWrite(OUT_C, 0);      

    idNote=0;
    isHalfHigh = false; 
    idChord = 0;

    chordByte = 0;
  }


  // 만약 oled가 갱신된다면 87ms 가 소요되고
  // 갱신되지 않는다면 58ms가 소요된다.
  // (OLED에 코드를 새로 표시하는데 30ms정도가 소요됨)
  
  if (chordByte != prevChordByte) {

    oled.clearDisplay();
    oled.setTextColor(WHITE);
    if (idNote>0) {
      oled.setCursor(0, 5);
      oled.setTextSize(8);
      oled.print( notes[idNote] );
    }
    if (isHalfHigh){
      oled.setCursor(48, 0);
      oled.setTextSize(4);
      oled.print("#");
    }
    if (idChord>0){
      oled.setCursor(48, 32);
      oled.setTextSize(4);
      oled.print( chords[idChord] );
    }
    oled.display(); //display the text on the screen


    prevChordByte = chordByte;
  }


#ifdef DEBUG_SERIAL
  Serial.print(millis()-tm);//(3)소요 시간 표시
  Serial.print("ms per 1 loop :");Serial.print(p1);
  Serial.print(':');Serial.print(p2);
  Serial.print(':');Serial.print(p3);
  Serial.print(':');Serial.print(p4);
  Serial.print(':');Serial.print(p5);
  Serial.print(':');Serial.print(p6);
  Serial.print(':');Serial.print(p7);
  Serial.print(':');Serial.print(p8);
  Serial.print(':');Serial.print(p9);
  Serial.print(':');Serial.print(tp10);
  Serial.print(':');Serial.print(tp11);
  Serial.print(':');Serial.print(tp12);
  Serial.print(':');Serial.print(tp13);
  Serial.print(':');Serial.print(tp14);
  Serial.print(':');Serial.print(tp15);
  Serial.println();
#endif


}

Posted by 살레시오
,

//2021년10월29일:Wemos LOLIN32 Lite 보드 실험

#include <WiFi.h>
#include <driver/adc.h> // for adc_power_off()

// 터치입력핀(8개)과 출력핀번호(8개)를 저장한 배열들
// gpio22핀은 내부적으로 LED에 연결되어 LOW 값에 켜진다.(역동작)
// gpio22핀을 출력핀으로 사용하는 데에는 문제가 없다.
byte inTouch[8] ={T0, T2, T3, T4, T5, T6, T7, T8};
byte outPin[8] = {22, 19, 23, 18, 17, 16, 26, 25};


// 한 번만 샘플링하면 1~2%의 확률로 0에 가까운 값이 읽히는 것 같다.
// 따라서 여러번 샘플링하여 평균값으로 판단하는 것이 안정적이다.
// SAMPLES가 20이면 loop()함수 한 번 실행 시간이 76ms 정도이다.
// 30이면 113ms 정도이다.
#define SAMPLES 20


// touchRead() 평균값이 아래 문턱값 이하이면 터치된 걸로 판단
#define THRESHOLD 20


void setup() {
  
  // 소모전력을 줄이기 위해서 WiFi와 bt는 끈다.
  // ADC도 사용하지 않으므로 꺼야 한다.
  adc_power_off();
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  btStop();
    
  // 출력핀들을 OUTPUT으로 설정한다.
  for(byte k=0;k<8;k++){
    pinMode(outPin[k], OUTPUT);
  }

  //아래의 (1),(2),(3)은 소요시간을 확인하기 위한 코드
  //Serial.begin(115200); delay(100);//(1)
}


void loop() {
  //int tm = millis();//(2)

  for(byte k=0;k<8;k++) {
    int totalRead = 0;
    for(byte n=0; n<SAMPLES; n++) {
      totalRead += touchRead(inTouch[k]);
    }
    int averageRead = totalRead/SAMPLES;
    digitalWrite(outPin[k], averageRead<THRESHOLD);
  }

  //Serial.println(millis()-tm);//(3)소요 시간 표시
}

Posted by 살레시오
,

FreeCAD에서 스케치에 있는 치수(dimension)에 이름을 붙여서 다른 곳에서 재사용할 수 있다. 치수를 입력하는 창에 숫자값을 입력하는 칸 바로 맡에 이름을 기입하는 곳이 있는데 이곳에 이름을 기입하면 그 숫자값을 다른곳에서도 참조할 수 있다.

 

 

예를 들어 Sketch001 이라는 스케치 내에서 어떤 치수에 length 라는 이름을 주었다면 그 치수는 다음과 같은 이른으로 참조할 수 있다.

 

Sketch001.Constraints.length

 

중간에 Constraints 라는 이름을 거쳐야 사용할 수 있다는 점에 유의해야 한다. 치수를 입력하는 창에서 숫자 대신 '='키를 누르면 수식편집기 창이 뜨고 거기에 수식을 입력할 수 있다.

 

 

아예 spreadsheet를 하나 생성하고 거기에서 부품에 관련된 치수들에 이름을 붙여서 관리할 수도 있다. workbench에서 spreadsheet를 선택하면 부품에 Spreadsheet를 하나 생성할 수 있다.

 

 

Spreadsheet의 이름을 편의상 Var라고 변경했다. 이후에 한 셀에 11이라는 숫자를 기입하고 그 셀에서 마우스 우클릭을 하면 뜨는 셀 속성 창의 맨 오른쪽 탭인 별칭(A)을 선택하면 아래 그림과 같이 셀의 별칭을 입력할 수 있다.

 

 

이렇게 해 놓으면 이 셀의 수치는 다음과 같이 참조할 수 있고

 

Var.length

 

이 참조는 부품의 치수를 기입하는 어떤 창에서든 사용할 수 있다.

 

이렇게 추후에 변경될 가능성이 높은 치수들을 Spreadsheet로 관리하면 나중에 부품의 변경을 훨씬 용이하게 할 수 있다.

 

[gdoc]

 

Posted by 살레시오
,

FreeCAD의 스케치는 선분이나 사각형의 중심점을 자동으로 생성해 주지 않는다. (0.18버전 기준) 하지만 대칭구속기능을 이용하면 선분/사각형의 중심점을 쉽게 생성할 수 있다.  먼저 선분 주위 아무데나 점을 찍는다. 그리고 아래 그림과 같은 순서대로 점들을 선택한다.

 

(1)(2) 선분의 두 끝점을 차례로 선택

(2) (방금 생성한) 선분 밖의 점을 선택

(3) 대칭 구속조건 버튼 클릭

 

 

그러면 다음과 같이 중심점으로 설정된다.

 

 

사각형의 중심점도 비슷하게 생성할 수 있다. 먼저 사각형 내부에 점을 아무데나 찍는다. 이후에 다음과 같은 순서로 점을 선택한 후 구속조건 버튼을 누른다.

 

(1)(2) 사각형의 두 마주보는 꼭지점을 차례로 선택

(3) 방금 찍은 (사각형 내부의) 점을 선택

(4) 대칭구속버튼 클릭

 

 

그러면 아래와 같이 생성한 점이 사각형의 중심점이 된다.

 

 

이후에는 이 중심점을 끌어서 사각형의 위치를 조절할 수도 있다.

 

[gdoc]

 

'3D프린팅 > FreeCAD' 카테고리의 다른 글

FreeCAD에서 숫자값에 변수명 붙여서 참조하기  (0) 2021.03.11
FreeCAD의 마커크기 수정  (0) 2021.03.11
Posted by 살레시오
,