Arduino에서 난수 생성기 사용: Random 및 RandomSeed 함수. Arduino 과정 - 무작위 비트 시퀀스를 생성하는 시간 및 무작위 Arduino

아두이노를 프로그래밍하다 보면 스케치를 작성하는 프로그래머나 해당 프로그램과 함께 아두이노를 사용할 사용자 모두가 미리 알 수 없는 숫자를 얻어야 할 때가 있다. 이 경우 난수 생성기가 구출됩니다.



이 생성기를 활성화하려면 Random() 또는 RandomSeed() 함수를 사용하면 됩니다. 이 자료에서는 이러한 함수를 사용하는 방법과 숫자를 생성할 때 의사 무작위성을 제거하는 방법을 보여줍니다.


일반적으로 의사 난수 생성기는 숫자의 혼란스럽거나 무작위적인 모양을 시뮬레이션하지만 실제로 충분히 오랜 기간 동안 일련의 숫자를 분석하면 특정 패턴을 발견할 수 있습니다.


따라서 의사 난수 생성을 위한 Random 함수는 최대 2개의 매개변수를 가질 수 있으며, Random(max) 또는 Random(min, max)로 작성됩니다. 여기서 필수 매개변수인 max는 의사 난수 생성 범위의 상한을 설정합니다. 사용하여 추가 매개변수최소 범위의 하한을 설정할 수 있습니다. 결과적으로 이 함수는 min에서 max-1 범위의 일부 의사 난수를 반환합니다.


random() 함수를 사용할 때 매번 정확히 동일한 의사 난수 목록이 생성된다는 점을 이해하는 것이 중요합니다. 예를 들어, 슬롯머신을 만들고 처음 핸들을 누르면 당첨 조합이 표시되고, Arduino를 재설정하고 핸들을 다시 누르면 해당 슬롯머신이 동일한 당첨 조합이 표시됩니다. . 실제로 예를 들어 게임기 www.igrovye-apparati-vulcan.com/에서 구현된 것처럼 Arduino에서 완전한 난수 생성 기능을 갖춘 게임기를 구현하는 것은 쉽지 않지만, RandomSeed를 사용하여 문제를 부분적으로 해결할 수 있습니다. () 기능.


이 함수는 정수와 같은 값을 취하고, 그 숫자를 사용하여 random() 함수에 의해 생성된 무작위 목록을 수정합니다. setup 함수에 randomSeed()를 넣고, 무한대에서 random() 함수를 사용할 수 있습니다. 고리. 그러나 그럼에도 불구하고, RandomSeed() 함수를 사용할 때 난수 순서가 달라지더라도 스케치가 실행될 때마다 여전히 동일하다는 것이 문제입니다.


이 경우 유일한 해결 방법은 아날로그 주변 장치(ADC)와 해당 AnalogRead() 함수를 사용하는 것입니다. 아날로그 입력이 아무 것에도 연결되지 않은 경우, 즉 공중에 "매달려" 있는 경우 이 라인의 노이즈 덕분에 진정한 난수를 얻을 수 있습니다. 그런 다음 설정 설정에서 randomSeed(analogRead(A0))를 쓸 수 있습니다. 단, 아날로그 포트 A0은 어디에도 연결되어 있지 않습니다.

난수 생성기에 관해 많은 글이 작성되었지만 구현에 관해서는 거의 항상 다음과 같이 암시(또는 명시적으로 언급)됩니다. 우리 얘기 중이야 x86/x64 및 기타 "성인" 아키텍처에 대해 설명합니다. 동시에 마이크로 컨트롤러 장치 개발 전용 포럼에는 "%controllername%에서 어떻게 난수를 생성할 수 있습니까?"라는 질문이 가득합니다. 게다가 답변의 범위는 'Google/Wikipedia를 살펴보세요'에서 '표준 기능을 사용하세요'까지 확장됩니다. 이 "표준 기능"은 항상 존재하는 것은 아니며 모든 측면에서 개발자에게 적합합니다. 더 자주는 그 반대입니다. 때로는 숫자가 무작위와 거리가 멀고 때로는 작업 속도가 너무 느리거나 결과 코드가 그렇지 않은 경우도 있습니다. 여유 메모리에 전혀 맞습니다.
난수 생성 알고리즘이 무엇인지, 올바른 알고리즘을 선택하는 방법, 가장 중요한 것은 컨트롤러에서 이러한 알고리즘을 구현하는 기능이 무엇인지 알아 보겠습니다.

"무작위성" 평가

RNG의 애플리케이션은 장난감부터 심각한 암호화까지 매우 다를 수 있습니다. 따라서 발전기에 대한 요구 사항도 크게 다릅니다. 생성기의 품질("무작위성" 수준)을 평가하기 위한 특별한 테스트가 있습니다. 그 중 가장 기본적인 것은 다음과 같습니다.
  • 주파수 테스트. 일련의 비트에서 0과 1의 개수를 세는 것으로 구성됩니다. 1과 0의 개수는 대략 동일해야 합니다.
  • 동일한 비트 시퀀스를 테스트합니다. 000...0 또는 111...1과 같이 동일한 비트의 행이 검색됩니다. 길이에 따라 계열이 발생하는 주파수 분포는 진정한 무작위 신호에 대한 이 분포와 일치해야 합니다.
  • 스펙트럼 테스트. 이산 푸리에 변환이 원래 시퀀스에 적용됩니다. 결과 스펙트럼에는 시퀀스의 주기적인 특성이 있음을 나타내는 중요한 피크가 없어야 합니다.
  • 자기 상관 테스트. 서로에 대해 이동된 서열 사본 간의 상관값이 계산됩니다. 테스트를 통해 시퀀스에서 반복 영역을 찾을 수 있습니다.
수십 개의 유사한 테스트를 포함하는 특수 키트가 있습니다.
NIST - AES 대회에서 암호화 알고리즘을 평가하는 데 사용됩니다.
DIEHARD는 현존하는 가장 엄격한 세트 중 하나입니다.

PRNG 알고리즘

엄격하게 정의된 알고리즘에 따라 생성된 시퀀스는 실제로 무작위로 간주될 수 없으므로 알고리즘 생성기에 대해 말할 때 다음이라는 용어를 사용합니다. 의사 난수후속. 모든 의사 난수 생성기(PRNG)는 조만간 루프에 들어갈 것입니다. 또 다른 문제는 이 "늦은" 현상이 몇 밀리초 또는 몇 년 안에 발생할 수 있다는 것입니다. 사이클의 길이는 생성기 N의 내부 상태 크기(실제로 생성기에 필요한 메모리 양)에 따라 달라지며 범위는 2(N/2)에서 2N 비트입니다.
매우 다양한 PRNG 알고리즘이 발명되었지만 모든 알고리즘이 마이크로 컨트롤러에서 구현하기에 편리한 것은 아닙니다. 속도와 사용 가능한 메모리가 심각하게 제한되어 있으며 많은 컨트롤러가 실수 연산이나 곱셈 명령어를 지원하지 않습니다. 이러한 제한 사항을 염두에 두고 몇 가지 잘 알려진 알고리즘을 살펴보겠습니다.
선형합동법
시퀀스의 다음 멤버는 다음 공식을 사용하여 계산됩니다.
X i+1 = (aX i + c) mod m
숫자 시퀀스의 최대 기간, 정수를 정의합니다. 그리고 - "마법의" 계수. 숫자 2의 거듭제곱과 동일하게 선택하는 것이 합리적입니다. 이 경우 모듈로 변환 작업은 가장 중요한 비트를 삭제하는 것으로 축소됩니다. 최대 기간을 얻으려면 다음 조건을 충족해야 합니다.
- 그리고 m은 상대적으로 소수여야 합니다.
- a-1배수여야 합니다 모든 주요 요인에 대해 숫자 ,
- 만약에 는 4의 배수입니다(이 경우에는 배수가 됩니다). a-1 4의 배수여야 합니다.
한 가지 더 미묘한 점이 있습니다. 상태 변수 X의 가장 중요한 비트만 결과로 취해야 합니다. 왜냐하면 가장 낮은 비트의 경우 무작위성의 통계 매개변수가 훨씬 더 나쁘기 때문입니다. 선형 합동 알고리즘은 일반적으로 많은 라이브러리에서 표준 rand()로 구현됩니다.

장점:

  • 주어진 상태 변수의 크기에 대해 가능한 최대 기간;
  • 충분히 빠르다;
  • 종종 이미 컴파일러 라이브러리에 구현되어 있습니다.
단점:
  • 곱셈 연산이 필요합니다.
  • 모든 비트가 똑같이 무작위인 것은 아닙니다.
요약:그다지 까다롭지 않은 애플리케이션을 위한 빠르고 간단한 알고리즘입니다.
시차가 있는 피보나치 방법
이 알고리즘은 다음 관계를 사용합니다.
X i = X i-a - X i-b ,
상태 변수는 어디에 있습니까? 엑스- 부호 없는 정수. 지연 값 그리고 일부가 아니라 엄격하게 정의된 항목이 사용되며 최대 품질을 얻으려면 쌍 (17.5), (55.24) 또는 (97.33)이 권장됩니다. 지연이 클수록 주기가 길어지고 시퀀스의 스펙트럼 특성이 좋아집니다. 반면에 생성기가 작동하려면 이전 숫자의 max(a,b)를 저장해야 하는데 이는 항상 허용되는 것은 아닙니다. 또한 생성기를 실행하려면 일반적으로 더 간단한 PRNG를 사용하여 얻는 max(a,b) 숫자가 필요합니다.

장점:

  • 곱셈 연산이 필요하지 않습니다.
  • 난수의 모든 비트는 통계적 속성에서 동일합니다.
단점:
  • 많은 양의 메모리가 필요합니다.
  • 실행하려면 많은 숫자 배열이 필요합니다.
요약:품질은 매우 높지만 리소스 집약적인 알고리즘입니다.
선형 피드백 시프트 레지스터


상태 변수는 길이 N의 레지스터에 저장됩니다. 다음 상태를 생성하는 데는 두 단계가 포함됩니다.
  1. 비트 값은 C = X i1 xor X i2 xor… X ik로 계산됩니다. 여기서 i1, i2…ik- 호출되는 비트 번호를 등록합니다. 굴곡.
  2. 레지스터가 오른쪽으로 1비트 이동하고 가장 왼쪽 비트가 값을 갖습니다. 와 함께.
생성기의 출력은 레지스터의 가장 오른쪽(또는 가장 왼쪽 등) 비트입니다. 즉, 의사 난수 시퀀스는 반복당 1비트가 생성됩니다. 올바르게 선택된 탭 번호를 사용하면 생성기의 주기는 2 N - 1이 됩니다. 레지스터에 금지된 0 상태가 있으므로 "마이너스 1"입니다. 지점 번호 N이 문서에서는 3부터 168까지의 내용을 찾을 수 있습니다.
그런데 위에서 설명한 구성(동일한 이름의 PRNG 방법과 혼동하지 말 것)을 피보나치 구성이라고 하는 구성 외에도 소위 말하는 구성이 있습니다. 갈루아 구성.


새로운 가장 왼쪽 비트를 생성하기 위해 탭 시퀀스의 비트 합계를 사용하는 대신 탭 시퀀스의 각 비트를 가장 오른쪽 비트와 XOR한 다음 전체 레지스터를 오른쪽으로 회전합니다. 이 방식은 모든 XOR 연산이 동시에 수행될 수 있으므로 이해하기는 더 어렵지만 구현하기는 더 쉽습니다. 의사 난수의 기간 길이와 품질 측면에서 피보나치 방식과 갈루아 방식은 동일합니다.

장점:

  • 구현이 매우 간단하고 산술 연산도 필요하지 않으며 비트 연산과 시프트만 필요합니다.
  • 매우 빠른 알고리즘(특히 Galois 방식)
  • 좋은 통계적 특성.
단점:
  • 부등식의 초기값이 0인지 확인해야 합니다.
요약:매우 빠르고 상당히 높은 품질의 알고리즘입니다.
암호화 방지 알고리즘
암호화에 사용하기 위해 PRNG에는 또 다른 필수 요구 사항이 있습니다. 되돌릴 수 없음. 위에 나열된 모든 알고리즘에는 이 속성이 없습니다. PRNG의 여러 출력 값을 알면 간단한 방정식 시스템을 풀어 알고리즘의 매개변수(동일한 "마법의" 상수)를 찾을 수 있습니다. 에이, 비, 씨등). 그리고 매개변수를 알면 전체 의사 무작위 시퀀스를 재현할 수 있습니다.
충분히 강력한 블록 암호는 강력한 암호화 PRNG 알고리즘으로 사용될 수 있습니다. 비밀 키를 선택하면 순차적 자연수에 알고리즘을 적용하여 의사 난수 블록을 얻을 수 있습니다. N비트 블록 암호의 경우 주기는 2N을 넘지 않습니다. 이러한 체계의 보안은 전적으로 키의 비밀성에 달려 있습니다.
모든 최신 암호화 알고리즘은 PRNG로 사용하기 위해 테스트되었습니다. 즉, 인증된 알고리즘을 사용하면 출력 스트림의 통계적 및 스펙트럼 속성에 특별히 신경 쓸 필요가 없습니다. 암호화 알고리즘의 계산 "폭식"에 대해서만 걱정하면 됩니다. 많은 수의 암호화 작업을 수행해야 하는 경우 하드웨어 암호화 블록이 있는 컨트롤러를 선택하는 것이 좋습니다. 종종 이러한 컨트롤러에는 매우 우수한 암호화 방지 하드웨어 PRNG도 있습니다.

엔트로피의 근원

이미 언급했듯이 결정론적 알고리즘만 사용하면 진정한 난수를 생성하는 것은 불가능합니다. 따라서 일반적으로 PRNG + 외부 조합이 사용됩니다. 엔트로피의 근원. 엔트로피 소스는 PRNG의 초기 값을 설정하는 데 사용되며 후자의 작업은 시퀀스의 스펙트럼 및 통계적 순도를 보장하는 것입니다. 엔트로피의 원천으로 사용할 수 있는 것은 무엇입니까? 예, 거의 모든 것입니다.
사용자 활동
장치가 어떤 방식으로든 사용자와 상호 작용하는 경우 사용자 자체를 엔트로피 소스로 사용하는 것이 매우 좋은 솔루션입니다. 예를 들어, 마이크로초(또는 최하위 자릿수)의 정확도로 측정된 버튼을 누르는 시간은 완전히 예측할 수 없습니다. 그러나 종종 장치는 자율적으로 작동해야 하며, 이는 우리가 이 놀라운 정보 채널을 박탈당한다는 것을 의미합니다.
아날로그-디지털 변환기
많은 컨트롤러에는 ADC가 내장되어 있습니다. 그리고 많은 컨트롤러의 품질은 매우 평범하여 단지 "있을 것"으로 만들어졌습니다. ADC 결과의 하위 비트에는 DC 전압을 측정하는 경우에도 거의 항상 상당한 노이즈가 포함됩니다. 이것은 사용할 수 있습니다: 분배기를 통해 ADC 입력을 공급 전압에 연결하고, 수십 번 측정하고, 최하위 비트를 가져옵니다. 여기에는 큰 난수가 있습니다. ADC에 내장 프리앰프가 포함되어 있으면 이를 켜면 잡음도 발생합니다.
비동기식 생성기
두 개의 비동기 클럭 생성기의 주기 차이를 사용할 수 있습니다. 예를 들어 대부분의 컨트롤러에는 감시 타이머가 포함되어 있습니다. 신뢰성을 높이기 위해 메인 클록 신호와 전혀 연결되지 않는 별도의 생성기에서 클록됩니다. 워치독 타이머의 한 주기 동안 메인 클록 신호의 사이클 수를 계산하는 것으로 충분합니다. 측정 중에 카운터가 여러 번 오버플로되도록 기간을 선택하면 꽤 난수를 얻을 수 있습니다. 이 방법의 단점은 최대 몇 초까지 많은 시간이 걸린다는 것입니다.
실시간 시계
다이어그램에 실시간 시계, 현재 판독값을 사용하여 PRNG를 초기화할 수 있습니다. 예를 들어, 현재 날짜/시간을 Unix 시간 형식으로 변환하면 즉시 32비트를 얻습니다. 절대초당 한 번 이상 판독하지 않으면 다시는 발생하지 않습니다. 실시간을 사용하면 값의 고유성이 부여되지만 예측 불가능성이 제공되지 않으므로 결합하는 것이 좋습니다. 이 방법다른 사람들과.
RC 회로
컨트롤러가 없는 경우 주변기기, I/O 포트 외에도 다음을 수행할 수 있습니다. 다리 중 하나는 커패시터를 통해 접지에 연결되고 저항을 통해 공급 전압에 연결됩니다. 컨트롤러 입력에 내부 풀업 저항이 있는 경우 외부 저항이 필요하지 않습니다.

이 포트에 "0" 신호를 출력합니다. 즉, 커패시터가 방전됩니다. 포트를 입력 모드로 전환하면 커패시터가 충전되기 시작합니다. 전압이 임계값에 도달하면 입력이 "0" 상태에서 "1"로 전환됩니다. 충전 시간은 공급 전압, RC 회로 매개변수의 드리프트, 임계값 불안정성, 온도, 누출, 간섭 등 여러 요인에 따라 크게 달라집니다. 충분한 정확도로 측정하고 최하위 비트를 취하면 좋은 무작위성을 얻을 수 있습니다.
하드웨어 소음 발생기
많은 심각한 응용 프로그램(특히 암호화)의 경우 위에 나열된 것보다 더 안정적인 엔트로피 소스가 필요합니다. 이러한 경우 열, 샷 또는 양자 효과를 기반으로 하는 잡음 발생기의 신호를 디지털화합니다. 잡음 요소는 일반적으로 특수 다이오드 또는 제너 다이오드이며, 이로부터 신호가 증폭되어 이진 비트 스트림을 생성하는 비교기에 공급됩니다.

비교기 응답 임계값이 수신 신호의 통계적 특성에 영향을 미치지 않도록 하기 위해 하나의 비교기에서 작동하는 두 개의 잡음 생성기가 사용됩니다.

결론

마지막으로 내 인생의 한 가지 이야기를 들려 드리겠습니다. 포럼에서 "컨트롤러에서 난수를 어떻게 생성할 수 있나요?"라는 또 다른 질문으로 시작되었습니다. 질문 작성자는 코스 프로젝트로서 주사위 던지기를 흉내내는 장치를 만들고 있다고 설명했습니다. 알고리즘을 이해하려는 시도가 여러 번 실패한 후 주제 스타터는 자신의 솔루션을 공유했습니다. 그는 단순히 실제 주사위를 1000번 굴리고 컨트롤러의 모든 여유 메모리를 결과 숫자로 채웠습니다. 발전기는 시연 중에 "예비"의 1/3 미만을 사용했다는 점을 고려하면 모든 "무작위성" 테스트를 훌륭하게 통과했습니다.
따라서 이러한 솔루션에는 생명권도 있습니다. 특히 숫자의 무작위성에 대해 매우 엄격한 요구 사항이 부과되지만 너무 자주 요구되지 않는 경우에는 더욱 그렇습니다. 메모리 가격이 급락하면서 장치의 전체 수명 동안 지속되는 "카오스 예비"를 장치에 장착하는 것이 현명할 수 있습니다.
관심을 가져주셔서 감사합니다!

UPD1:의견에서 올바르게 언급했듯이 RNG에 대한 공격이 예상되고 공격자가 장치에 대한 하드웨어 액세스 권한을 갖고 있는 경우 외부 엔트로피 소스를 매우 주의해서 사용해야 합니다. 외부 소스. 외부 소스 외에 내부 소스도 사용해야 합니다.
엔트로피를 모두 축적하는 것도 좋은 생각이다 자유 시간, 또 다른 난수를 생성해야 할 때 사용하세요. 일반적으로 이러한 경우 소위 엔트로피 풀- PRNG 기능 중 하나가 주기적으로 수행되고 엔트로피 소스의 데이터가 지속적으로 혼합되는 배열입니다.

UPD2:많은 경우 엔트로피 풀의 내용(죄송합니다. 일반적인 러시아어 번역은 모르겠습니다)을 EEPROM에 저장하면 장치를 껐다가 켠 후에 다시 누적되지 않도록 하는 것이 유용합니다. 이는 무엇보다도 비동기식 발전기의 방법을 사용하여 엔트로피를 얻는 것과 관련이 있습니다. 충분히 안정적인 조건에서 각 스위치를 켠 후에 동일한 시퀀스가 ​​생성될 수 있습니다.
공격이 예상되는 경우 EEPROM 변조에 대해 예방 조치를 취하십시오. 컨트롤러가 허용하는 경우 잠금 비트를 사용하여 읽기/삭제/쓰기를 차단하고, 전원을 켤 때 최소한 간단한 체크섬을 사용하여 EEPROM의 무결성을 모니터링하십시오.

태그:

  • 무작위
  • GPSCH
  • 마이크로컨트롤러
  • 알고리즘
태그 추가

무작위 시드(시드)

Random() 함수의 시작점으로 값 또는 시드를 설정합니다.

무작위 시드(값); // 'value'를 초기 무작위 값으로 설정합니다.

Arduino는 진정한 난수를 생성할 수 없기 때문에 RandomSeed를 사용하면 변수, 상수 또는 기타 함수를 난수 함수에 넣을 수 있어 더 많은 난수를 생성하는 데 도움이 됩니다.

"임의의" 숫자. 아날로그 핀을 통해 전기적 노이즈를 읽는 데는 millis()나 심지어 AnalogRead()를 포함하여 이 함수에 사용할 수 있는 다양한 시드 또는 함수가 있습니다.

무작위(최대)

무작위(최소,최대)

무작위 함수를 사용하면 최소값과 최대값으로 지정된 범위 내에서 의사 난수를 반환할 수 있습니다.

값 = 무작위(100, 200); // '값'을 무작위로 설정합니다.

// 100에서 200 사이의 숫자

메모: RandomSeed() 함수를 사용한 후 사용하세요. 다음 예에서는 0에서 255 사이의 난수를 생성하고 PWM을 출력합니다.

임의의 값과 동일한 PWM 출력 신호:

int randNumber; // 임의의 값을 저장하는 변수

int 주도 = 10; // 핀 10에 저항이 있는 LED

void setup() () // 설정이 필요하지 않습니다.

RandomSeed(밀리스()); // millis()를 초기 숫자로 설정합니다.

randNumber = 무작위(255); // 0~255 사이의 임의의 숫자 AnalogWrite (led, randNumber); // PWM 신호 출력

지연(500); // 0.5초 동안 멈춤

출처: Gololobov V. – 로봇은 어디에서 시작됩니까? 학생을 위한 Arduino 프로젝트 정보(뿐만 아니라) - 2011

관련 게시물

Serial.begin(rate) 직렬 포트를 열고 직렬 데이터 전송 속도를 설정합니다. 컴퓨터 통신의 일반적인 전송 속도는 9600이지만 다른 속도도 지원됩니다. 무효 설정() (Serial.begin…….

모든 변수는 사용하기 전에 선언되어야 합니다. 변수를 선언한다는 것은 해당 값의 유형(int, long, float 등)을 정의하고 변수에 고유한 이름을 할당하는 것을 의미합니다.

좋습니다. 이 프로그램을 설치했습니다. 우리는 모듈 작업의 "메커니즘"을 디버깅했습니다. 그리고 우리는 몇 가지 예를 살펴보았습니다. 하지만 나 자신도 유용한 것을 만들고 싶습니다. 해보자. 먼저 이전 프로젝트를 닫겠습니다. 이를 위해…

주목! 다른 개발 환경에서 Arduino 모듈을 사용할 때는 마이크로컨트롤러 구성(퓨즈)에 주의해야 합니다. 변화가 어떤 결과로 이어질지 정확히 알기 전까지는…

시간과 무작위성. 반응

이번에는 "Random" 값이 무엇인지 알아보고 시간을 다루는 방법도 배워보겠습니다.

우리는 다음이 필요합니다:

  • 택트 버튼
  • 신승
  • 연결 와이어 "MALE-MALE"

반응

오늘 우리의 임무는 반응 속도를 알아낼 수 있는 다이어그램을 만드는 것입니다.

왼쪽 버튼을 누르면 "임의의" 시간 후에 신호음이 울립니다. 그리고 오른쪽 버튼을 누르면 삐걱거리는 소리가 나고 오른쪽 버튼을 누르는 데까지 얼마나 많은 시간이 지났는지 알 수 있습니다.

숙련된 분들이 직접 시도해 보시고, 우리는 도표를 살펴보겠습니다.

#define BUZ 8 #define START 9 #define STOP 7 int time; //동기화를 위한 변수 void setup() ( Serial.begin(9600); pinMode(START, INPUT_PULLUP); pinMode(STOP, INPUT_PULLUP); pinMode(BUZ, OUTPUT); ) void loop() ( if(digitalRead(START) == 0) // START 버튼을 눌렀을 때.. ( int start_time = millis(); // 누른 시간을 기억한다 time = start_time; // 전역 변수에 쓴다. int Rand = random(0, 4000 ); // "무작위" 지연 시간을 생성합니다 = time + Rand; //지연 시간을 추가합니다. Delay(Rand); //톤을 기다립니다(BUZ, 3000, 500); //삐! ) if(digitalRead( STOP) == 0 && digitalRead( START) == 1) // STOP 버튼을 누르면... ( int stop_time = millis(); // 정지 시간을 기억합니다. time = stop_time - time; // 계산합니다. time Difference.Serial.println("Time: "); // 시간을 Serial로 출력합니다. Serial.println(time); Delay(1000); ) ) // 두 번째 시도 전에 다시 START 버튼을 누르세요.

설명

정수 시간; 변수(모두는 아님)를 표시할 때 값을 지정할 필요는 없습니다. 이 변수를 사용하여 두 개의 if 문을 연결했습니다.

C++에서 루프 내부에 선언된 변수는 해당 루프 내에서만 영향을 미치기 때문에 다른 루프에서 액세스할 수 없습니다. 이는 프로그래밍 오류를 방지하기 위해 수행됩니다. 프로그램 코드가 커지면 내가 말하는 내용을 이해하게 될 것입니다.

여러 문에서 변수를 사용할 수 있도록 하려면 변수를 전역으로 만들어야 합니다. 저것들. 함수 외부에서 변수를 선언합니다.

밀리초();프로그램이 시작된 이후 경과한 밀리초 수를 반환합니다.

신호가 전달된 후 버튼을 누르는 데 걸린 시간을 측정하려면 이 정보가 필요합니다.

무작위의(분,최대);이것은 난수 생성기입니다. 두 가지 값을 사용합니다. 최소에서 최대까지의 범위의 숫자를 생성합니다.

"임의" 숫자는 값의 특정 순서이기 때문입니다. 매우 길지만 동일합니다. 다른 시퀀스를 얻으려면 다음을 사용해야 합니다. 무작위의씨앗();

이 함수는 생성기를 초기화합니다. 매개변수를 무작위로 설정하면 필요한 시퀀스를 얻을 수 있습니다. 매개변수가 고정되어 있으면 순서는 동일합니다.

결론

이제 직접 만든 장치를 사용하여 반응을 훈련할 수 있습니다. 아니면 계속해서 더 공부할 수도 있습니다.

방사성 원소 목록

지정 유형 명칭 수량 메모가게내 메모장
아두이노 보드

아두이노 우노

1 메모장으로
빵판브레드보드-반1 메모장으로
피에조 이미터수동적인1 메모장으로
택트 버튼자물쇠 없음2 메모장으로
전선 연결"파파파파"1



맨 위