• Skip to main content
  • Skip to primary sidebar
  • Skip to footer
  • HOME
  • Arduino
    • Arduino初心者編
    • Arduino基礎編
    • Arduino応用編
    • Arduino実践編
  • Raspberry Pi
  • microbit
  • XBee
  • Scratch
  • Contact Us
  • Privacy Policy

STEMSHIP

ものづくりを通して、科学を学ぼう!

現在の場所:ホーム / Arduino / Arduino実践編 / ArduinoでSTEM教育​ 実践編:かけっこタイム計測器

ArduinoでSTEM教育​ 実践編:かけっこタイム計測器

2020年3月8日 by STEMSHIP コメントを書く

陸上競技のタイム計測機を模擬して作ります。「いちについて、よーい、どん」の音とともに、タイム計測を開始して、ゴールしたかどうかは赤外線センサーで検知します。Arduino機器はスタート地点とゴール地点にそれぞれ設置します。これまで紹介した、ZigBee通信、音再生、タイム計測などを組み合わせた作品です。

使用する部品

  • ELEGOO Arduino用UNO R3コントロールボード ATmega328P ATMEGA16U2  2個
  • XBee S2C / ワイヤアンテナ型  2個
  • XBeeシールド(Seeed Studio社製) 2個
  • Pirate Radio用アドオンスピーカーキット
  • シリアル接続7セグメント4桁LED(赤)
  • LED赤・緑・青 各2個
  • 220 ohm 抵抗  6個
  • タクトスイッチ 2個
  • 電池スナップDCプラグアダプタ 2個
  • 小型ボリューム 10KΩB
  • PAM8012使用2ワットD級アンプモジュール
  • ジャンパーワイヤ

かけっこタイム計測器の概要

 完成品のイメージは、陸上トラック競技のゴールに置かれている計測器です。スタートの音でタイム計測を開始し、経過時間がディジタル表示で進んでいきます。ゴールした瞬間にタイマーのカウントアップを止めます。
 器械は2台作成します。1台はスタート地点において、スタート音を鳴らします。もう1台はゴール地点でタイマーをカウントアップして、ゴールとともにタイマーを止めます。

ピンアサイン

 スタートボタン用に2番ピンを割り当てます。このピンはプルアップに設定し、スイッチを接続します。スイッチが押されていないときはHighが入力され、スイッチが押されたときはLowが入力されます。詳細は、「ArduinoでSTEM教育​ 基礎編:プッシュスイッチ」を参照して下さい。

 圧電スピーカに出力する端子は3番ピンを割り当てます。これはPWMを出力する必要があるため、Arduino Uno 以外でコードを書く場合は、端子の仕様を確認して下さい。こちらについても、以前の記事で詳細を紹介していますので、「ArduinoでSTEM教育​ 基礎編:パッシブブザー」を参照して下さい。

リセットボタン用に8番ピンを割り当てます。リセットボタンは、スタートでフライングしたときに使用します。このボタンを押すことで初期状態(スタートボタンを押すのを待つ状態)に戻ります。

 スタート機の動作状態を視覚的にわかるように、LEDを接続します。LEDは赤・緑・青を5・6・7番ピンに接続します。詳細は「ArduinoでSTEM教育​ 基礎編:RGB-LED」を参照して下さい。

const int startPin = 2;
const int speakerPin = 3; //PWM
const int resetPin = 8;
const int redLedPin = 5;
const int greenLedPin = 6;
const int blueLedPin = 7;

void setup() {
  pinMode(startPin, INPUT_PULLUP);
  pinMode(speakerPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  Serial.begin(9600);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS20);
}

ステートマシン

スタート機の状態を管理するため、ステートマシンを使用します。ライブラリを使用するため、冒頭でFiniteStateMachine.hを読み込みます。ステートは5個定義します。”READY”は、スタートボタンが押されるのを待っている状態。”Cal”は、ゴール機の準備が完了するまで待っている状態。”Audio”は、スタート音源を再生している状態。”Measure”は、走っている時間を測定している状態。”Goal”は、ゴールしてリセットボタンかスタートボタンが押されるまで待っている状態です。 ステートとLEDの関係は以下のとおりです。LEDの制御はステートが変化するときのみ行います。

<スタート機/ゴール機ともに共通>
READY  :緑
CAL    :青
AUDIO  :青
MEASURE :赤
GOAL   :緑

#include <FiniteStateMachine.h>

void enterReady();
void enterCal();
void enterAudio();
void enterMeasure();
void enterGoal();

State READY = State(enterReady, NULL, NULL);
State CAL = State(enterCal, NULL, NULL);
State AUDIO = State(enterAudio, NULL, NULL);
State MEASURE = State(enterMeasure, NULL, NULL);
State GOAL = State(enterGoal, NULL, NULL);

FSM stateMachine = FSM(READY);
void enterReady() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

void enterCal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}

void enterAudio() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}
void enterMeasure() {
  digitalWrite(redLedPin, HIGH);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, LOW);
}

void enterGoal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

スタート機とゴール機の間で通信する(READY, CAL)

スタート機のスタートボタンが押されると、スタート機は’S’を無線通信(ZigBee)で出力します。ゴール機はこの’S’を受信して、’CAL’ステートに移行します。’CAL’ステートでは、「よーい」と「どん」の間合いを何秒にするか、ランダム関数で生成し、また、ゴールを検知する赤外線センサーのキャリブレーションも行います。「randTime = random(0,999);」で0~1000msのランダム時間を生成します。「baseline = calSense(1000);」で赤外線センサーから得た電圧の 1000ms間平均値を取得します。そして、ゴール機は「Serial.print(randTime);」で生成した値を 無線通信(ZigBee)で出力します。 スタート機は、その値を「waitTime = Serial.read();」で受け取って、次のステート’AUDIO’に移行します。

<スタート機のプログラム>

  if(stateMachine.isInState(READY)) {
    if(digitalRead(startPin) == LOW) {
      Serial.print('S');
      stateMachine.transitionTo(CAL);
    }
  }
  if(stateMachine.isInState(CAL)) {
    while(Serial.available() == 0) {
    }
    waitTime = Serial.read();
    stateMachine.transitionTo(AUDIO);
  }
(以下省略)

<ゴール機のプログラム>

if(stateMachine.isInState(READY)) {
    timeCount = 0;
    while(Serial.available() == 0) {
      int sensorVal = analogRead(sensePin);
      float a = 0.6;
      filterSensorVal = filterSensorVal = a * filterSensorVal + (1-a) * sensorVal;
      Serial.print(sensorVal);
      Serial.print(",");
      Serial.println(filterSensorVal);
      delay(1);
    }
    if(Serial.read() == 'S') {
      stateMachine.transitionTo(CAL);
    }
  }
  if(stateMachine.isInState(CAL)) {
    dispS7S(timeCount);
    randTime = random(0,999);
    baseline = calSense(1000);
    threshold = baseline + 150;  
    Serial.print(randTime);
    //Serial.println(baseline);
    //Serial.println(threshold);
    stateMachine.transitionTo(AUDIO);
  }

(途中省略)

int calSense(int time) {
  int count = 0;
  int sensorVal = 0;
  long sumVal = 0;
  float average = 0;

  // <time>ms間のセンサ値を合計する
  for(int i=0; i<time; i++) {
    sensorVal = analogRead(sensePin);
    sumVal += sensorVal;
    count++;
    delay(1);
  }

  //平均値を計算
  average = sumVal / count;

  return average;
}

スタート音を再生する(AUDIO)

「位置について、よ~い、どん!」や「On your mark, get set, go!」というように、音を鳴らします。Arduinoで音を鳴らす方法については、以前の記事「ArduinoでSTEM教育​ 応用編:WAV音源をデータ変換して圧電スピーカから出力する」で説明しています。簡単に説明すると、今回使用する音の再生時間は短く、音質は悪くても問題ありません。走り出すタイミングが分かりさえすれば良いのです。したがって、SDカードを使うこと無く、音源をArduinoのメモリに置いて、圧電スピーカから再生することが出来ます。

音源は3種類用意します。「On your mark(いちについて)」、「Get set(よ~い)」、「Go(どん)」の3種類です。それぞれファイルを用意してプログラム冒頭で読み込みます。私は英語の音声が欲しかったので、 AudioJungle で音源を購入しましたが、まずは自分の声で試してみるのが良いと思います。音源は以下のように、データ変換してヘッダーファイルとして保存しておきます。

const uint8_t soundGetSet[] PROGMEM = {
  0x80,0x80,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80,0x80,0x80,
  0x80,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80,0x80,0x80,
  0x80,0x80,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80,0x80,
(以下省略)

タイマーで時間を計測する(MEASURE)

時間の計測については、「ArduinoでSTEM教育​ 応用編:割り込みタイマーで時間を計測する」で説明した方法でやります。スタート機は、「よーい、ドン」の音声再生後、「Serial.print(‘G’);」で’G’を無線通信(ZigBee)で出力します。ゴール機は、 タイマーを ‘Audio’ステートで「MsTimer2::start();」で開始します。そして、無線通信で ‘G’ を受けると、timeCountを0にして、’Audio’ステートから’Measure’ステートに移動します。ゴールすると、タイマーのカウントアップを止めます。

ゴールしたことを認識する(GOAL)

ゴール機は’Measure’ステートに移動すると、「if(analogRead(sensePin) > threshold)」で赤外線センサがゴールする人を検知するまで、経過時間をLEDセグメントモジュールに表示させながら待ちます。検知すると、タイマーのカウントアップを止めます。検知するしきい値は、’CAL’ステートで決めています。先述したとおり、「baseline = calSense(1000);」で赤外線センサーから得た電圧の 1000ms間平均値を取得します。そして、人を検知するしきい値は、この値に150を加算します。150という値は、実際にセンサーの前を通り過ぎるときに、どれくらいになるかを試して、調整した値です。コードでは、「 threshold = baseline + 150;」と記述しています。

プログラム

スタート機のプログラム

//www.stemship.com
//2020.01.03

#include <FiniteStateMachine.h>
#include "On-Your-Marks.h"
#include "Get-Set.h"
#include "Go.h"

const int startPin = 2;
const int speakerPin = 3; //PWM
const int resetPin = 8;
const int redLedPin = 5;
const int greenLedPin = 6;
const int blueLedPin = 7;

void enterReady();
void enterCal();
void enterAudio();
void enterMeasure();
void enterGoal();

State READY = State(enterReady, NULL, NULL);
State CAL = State(enterCal, NULL, NULL);
State AUDIO = State(enterAudio, NULL, NULL);
State MEASURE = State(enterMeasure, NULL, NULL);
State GOAL = State(enterGoal, NULL, NULL);

FSM stateMachine = FSM(READY);

void setup() {
  pinMode(startPin, INPUT_PULLUP);
  pinMode(speakerPin, OUTPUT);
  pinMode(resetPin, INPUT_PULLUP);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  Serial.begin(9600);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS20);
}

void loop() {
  int waitTime;
  int resultTime;
  
  if(stateMachine.isInState(READY)) {
    if(digitalRead(startPin) == LOW) {
      Serial.print('S');
      stateMachine.transitionTo(CAL);
    }
  }
  if(stateMachine.isInState(CAL)) {
    while(Serial.available() == 0) {
    }
    waitTime = Serial.read();
    stateMachine.transitionTo(AUDIO);
  }
  if(stateMachine.isInState(AUDIO)) {
    playAudio(soundOnYourMarks, sizeof soundOnYourMarks / sizeof soundOnYourMarks[0]);
    delay(5000);
    playAudio(soundGetSet, sizeof soundGetSet / sizeof soundGetSet[0]);
    delay(2000+waitTime);
    playAudio(soundGo, sizeof soundGo / sizeof soundGo[0]);
    Serial.print('G');
    stateMachine.transitionTo(MEASURE);
  }
  if(stateMachine.isInState(MEASURE)) {
    while(Serial.available() == 0) {
      if(digitalRead(resetPin) == LOW) {
        Serial.print('R');
        stateMachine.transitionTo(READY);
        break;
      }
    }
    if(Serial.read() == 'F') {
      resultTime = Serial.read();
      stateMachine.transitionTo(GOAL);
    }  
  }
  if(stateMachine.isInState(GOAL)) {
    if( (digitalRead(resetPin) == LOW) or (digitalRead(startPin) == LOW) ) {
      Serial.print('R');
      stateMachine.transitionTo(READY);
    }
  }
  
  //それぞれの状態に応じてアップデータ
  stateMachine.update();

}

void enterReady() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

void enterCal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}

void enterAudio() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}
void enterMeasure() {
  digitalWrite(redLedPin, HIGH);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, LOW);
}

void enterGoal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

void playAudio(const uint8_t* soundArray, unsigned int soundArrayLength) {
  for (int i = 0; i < soundArrayLength; i++) {
    OCR2B = pgm_read_byte_near(&soundArray[i]);
    delayMicroseconds(125);
  }
}

ゴール機のプログラム

//www.stemship.com
//2019.12.28
#include <FiniteStateMachine.h>
#include <MsTimer2.h>
#include "sound.h"
#include <Wire.h> // Include the Arduino SPI library

// Here we'll define the I2C address of our S7S. By default it
//  should be 0x71. This can be changed, though.
const byte s7sAddress = 0x71;
char tempString[10];  // Will be used with sprintf to create strings

//const int startPin = 2;
//const int resetPin = 4;
const int redLedPin = 5;
const int greenLedPin = 6;
const int blueLedPin = 7;
const int sensePin = 0;
unsigned int timeCount = 0;
int filterSensorVal = 0;

int calSense();
void enterReady();
void enterCal();
void enterAudio();
void enterMeasure();
void enterGoal();
void timerFire();

State READY = State(enterReady, NULL, NULL);
State CAL = State(enterCal, NULL, NULL);
State AUDIO = State(enterAudio, NULL, NULL);
State MEASURE = State(enterMeasure, NULL, NULL);
State GOAL = State(enterGoal, NULL, NULL);

FSM stateMachine = FSM(READY);

void setup() {
//  pinMode(startPin, INPUT_PULLUP);
//  pinMode(resetPin, INPUT_PULLUP);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  pinMode(sensePin, INPUT);
  Serial.begin(9600);
  MsTimer2::set(1, timerFire);

  Wire.begin();  // Initialize hardware I2C pins

  // Clear the display, and then turn on all segments and decimals
  clearDisplayI2C();  // Clears display, resets cursor

  // Custom function to send four bytes via I2C
  //  The I2C.write function only allows sending of a single
  //  byte at a time.
  s7sSendStringI2C("-HI-");
  setDecimalsI2C(0b111111);  // Turn on all decimals, colon, apos

  // Flash brightness values at the beginning
  setBrightnessI2C(0);  // Lowest brightness
  delay(1500);
  setBrightnessI2C(255);  // High brightness
  delay(1500);

  // Clear the display before jumping into loop
  clearDisplayI2C();

  stateMachine.update();
}

void loop() {
  long randTime;
  int baseline;
  int threshold;
  unsigned long resultTime;
  unsigned int sample_raw_len = sizeof sample_raw / sizeof sample_raw[0];
  unsigned int timeC = sample_raw_len * 125 * 0.001; //[ms]
  unsigned int time1, time2;
  
  if(stateMachine.isInState(READY)) {
    timeCount = 0;
    while(Serial.available() == 0) {
      int sensorVal = analogRead(sensePin);
      float a = 0.6;
      filterSensorVal = filterSensorVal = a * filterSensorVal + (1-a) * sensorVal;
      Serial.print(sensorVal);
      Serial.print(",");
      Serial.println(filterSensorVal);
      delay(1);
    }
    if(Serial.read() == 'S') {
      stateMachine.transitionTo(CAL);
    }
  }
  if(stateMachine.isInState(CAL)) {
    dispS7S(timeCount);
    randTime = random(0,999);
    baseline = calSense(1000);
    threshold = baseline + 150;  
    Serial.print(randTime);
    //Serial.println(baseline);
    //Serial.println(threshold);
    stateMachine.transitionTo(AUDIO);
  }
  if(stateMachine.isInState(AUDIO)) {
    timeCount = 0;
    MsTimer2::start();
    while(Serial.available() == 0) {
    }
    if(Serial.read() == 'G') {
      time1 = timeCount;
      timeCount = 0;
      //MsTimer2::start();
      stateMachine.transitionTo(MEASURE);
    }
  }
  if(stateMachine.isInState(MEASURE)) {
    while(1) {
      if(analogRead(sensePin) > threshold){
        time2 = timeCount;
        MsTimer2::stop();
        Serial.print('F');
        resultTime = time2; //time2 - timeC - time1/2;
        Serial.print(resultTime);
        stateMachine.transitionTo(GOAL);
        break;
      }
      else{
        //Serial.println(analogRead(sensePin));
        if(timeCount % 10 == 0){
          dispS7S(timeCount);
          //Serial.println(timeCount - timeC - time1/2);
        }
        if(Serial.read() == 'R') {
          MsTimer2::stop();
          timeCount = 0;
          dispS7S(timeCount);
          stateMachine.transitionTo(READY);
          break;
        }
      }
    }
  }
  if(stateMachine.isInState(GOAL)) {
    dispS7S(resultTime);
    while(Serial.available() == 0) {
    }
    if(Serial.read() == 'R') {
      stateMachine.transitionTo(READY);
    }
  }
  
  //それぞれの状態に応じてアップデータ
  stateMachine.update();

}


void enterReady() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

void enterCal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}

void enterAudio() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, HIGH);
}
void enterMeasure() {
  digitalWrite(redLedPin, HIGH);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, LOW);
}

void enterGoal() {
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, HIGH);
  digitalWrite(blueLedPin, LOW);
}

int calSense(int time) {
  int count = 0;
  int sensorVal = 0;
  long sumVal = 0;
  float average = 0;

  // <time>ms間のセンサ値を合計する
  for(int i=0; i<time; i++) {
    sensorVal = analogRead(sensePin);
    sumVal += sensorVal;
    count++;
    delay(1);
  }

  //平均値を計算
  average = sumVal / count;

  return average;
}

void timerFire() {
  if(timeCount == 65535){
    timeCount = timeCount;
  }
  else {
    timeCount++;    
  }
}

// This custom function works somewhat like a serial.print.
//  You can send it an array of chars (string) and it'll print
//  the first 4 characters in the array.
void s7sSendStringI2C(String toSend)
{
  Wire.beginTransmission(s7sAddress);
  for (int i=0; i<4; i++)
  {
    Wire.write(toSend[i]);
  }
  Wire.endTransmission();
}

// Send the clear display command (0x76)
//  This will clear the display and reset the cursor
void clearDisplayI2C()
{
  Wire.beginTransmission(s7sAddress);
  Wire.write(0x76);  // Clear display command
  Wire.endTransmission();
}

// Set the displays brightness. Should receive byte with the value
//  to set the brightness to
//  dimmest------------->brightest
//     0--------127--------255
void setBrightnessI2C(byte value)
{
  Wire.beginTransmission(s7sAddress);
  Wire.write(0x7A);  // Set brightness command byte
  Wire.write(value);  // brightness data byte
  Wire.endTransmission();
}

// Turn on any, none, or all of the decimals.
//  The six lowest bits in the decimals parameter sets a decimal 
//  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
//  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimalsI2C(byte decimals)
{
  Wire.beginTransmission(s7sAddress);
  Wire.write(0x77);
  Wire.write(decimals);
  Wire.endTransmission();
}

void dispS7S(unsigned int counter) {
  // Magical sprintf creates a string for us to send to the s7s.
  //  The %4d option creates a 4-digit integer.
  if(counter/10 > 5999) {
    sprintf(tempString, "%4d", 5999);
  }
  else {
    sprintf(tempString, "%4d", counter/10);
  }

  // This will output the tempString to the S7S
  s7sSendStringI2C(tempString);

  // Print the decimal at the proper spot
  setDecimalsI2C(0b00000010);  // Sets digit 3 decimal on
}

完成写真

スタート機

ゴール機

完成動画

Filed Under: Arduino実践編 関連タグ:XBee, スピーカ, タイマー, 無線通信

Reader Interactions

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。

最初のサイドバー

CONTACT US

  • Facebook
  • Twitter
  • Youtube

More to See

Arduinoベースのセンサノード:XBeeデータ収集ノードの製作

2021年9月27日 By STEMSHIP

Arduinoベースのセンサノード:Arduinoを使った温度センサの作製

2021年9月21日 By STEMSHIP

XBeeモジュールとBMP280センサを使用してデータ収集する

2021年5月31日 By STEMSHIP

XBeeモジュールでMicroPythonを使ってセンサを読み取る

2021年5月24日 By STEMSHIP

XBeeモジュールでセンサを読み取る:センサノードの設定と測定

2021年5月17日 By STEMSHIP

カテゴリー

  • Arduino (44)
    • Arduino初心者編 (15)
    • Arduino基礎編 (11)
    • Arduino実践編 (4)
    • Arduino応用編 (11)
    • Arduino番外編 (3)
  • MakeyMakey (1)
  • microbit (11)
  • Raspberry Pi (13)
  • Scratch (6)
  • STEM教育 (5)
  • XBee (15)
  • ものづくり教育 (2)
  • 子供の教育 (2)
  • 科学 (6)
  • 算数 (5)

Tags

BLE DCモータ EEPROM ELEGOO ESP32 ESP8266 IoT LCD LED makeymakey MQTT Node-RED scratch STEM教育 WiFi XBee アニメーション オンラインゲーム カメラ クローン ゲーム コスチュームの変更 サーボモータ ステッピングモータ ステートマシン スピーカ タイマー ピンポン ブロック定義 ペン ライントレース ラジコン リスト 分数 割り込み 実験 工作 幼児 当たり判定 温度センサ 無線通信 物理 角度制御 重力 音楽

Footer

最近の投稿

  • Arduinoベースのセンサノード:スケッチ(プログラム)の作製
  • Arduinoベースのセンサノード:XBeeデータ収集ノードの製作
  • Arduinoベースのセンサノード:Arduinoを使った温度センサの作製
  • XBeeモジュールとBMP280センサを使用してデータ収集する
  • XBeeモジュールでMicroPythonを使ってセンサを読み取る

タグ

BLE DCモータ EEPROM ELEGOO ESP32 ESP8266 IoT LCD LED makeymakey MQTT Node-RED scratch STEM教育 WiFi XBee アニメーション オンラインゲーム カメラ クローン ゲーム コスチュームの変更 サーボモータ ステッピングモータ ステートマシン スピーカ タイマー ピンポン ブロック定義 ペン ライントレース ラジコン リスト 分数 割り込み 実験 工作 幼児 当たり判定 温度センサ 無線通信 物理 角度制御 重力 音楽

Search

2023年3月
月 火 水 木 金 土 日
 12345
6789101112
13141516171819
20212223242526
2728293031  
« 10月    

Copyright © 2023 · STEMSHIP.COM