Arduinoシミュレータ「Wokwi」はどこまで実機の代わりになるか|実測で比較
Arduinoのボードや部品を買う前に、書いたスケッチが実際に動くのか試したいと思ったことはないでしょうか。ブラウザで動くArduinoシミュレータ「Wokwi」なら、実機がなくてもコードを動かして動作確認ができます。
実機のUNO R3で関数の実行時間を測ったスケッチを、そのままWokwiで動かして比べました。ずれたのはanalogRead()とSerial.printの連続送信の2つで、ほかの関数1回の実行時間は実機とほぼ同じ(差は最大0.048µs)です。UNO R4は選べず、電気のふるまいも再現されません。
Wokwiでどこまでできるか
実機と比べて分かったことを「できる」「条件つき」「できない」の3つに分けました。「条件つき」は、使い方によって実機と同じにならないものと、無料で使うときの制約です。気になる項目のリンクから、詳しい節へ進んでください。
- スケッチを書いて動かし、シリアルモニタで見る
- ライブラリを追加する(Library Managerから)
- digitalWrite・millisなど、測った関数1回の実行時間(
analogRead()とSerial.printを除く。実機との差は最大0.048µs)
実機と同じにならない
analogRead()の時間(実機より短く出る。差は最大8µs)Serial.printの連続送信(115200bpsで約5%遅い)- 部品(無い部品は近い部品で代わりにして進め、最後は実機で確かめる)
無料で使うときの制約
登録なしで最初のスケッチを動かす
UNOの新規プロジェクトを開く
ブラウザでWokwiのUNOの新規プロジェクトを開くと、UNOが1台置かれた新しいプロジェクトができます。新規プロジェクトの一覧ではこのボードを「Arduino Uno Rev3」と呼んでいて、これはUNO R3のことです。
画面の左がスケッチを書くコーディングエリア、右が回路を組む配線エリアです。幅の狭い画面では、「Code」と「Simulation」のタブに分かれて表示されます。
部品を置いて配線する
配線エリアの上にある青い「+」ボタンを押すと、Wokwiで使える部品のリストが表示されます。リストの一番上は入力欄で、そのすぐ下の「Basic」にLEDと抵抗(Resistor)があります。ほかの部品は、この入力欄に名前(LEDなら「led」)を入れて検索します。
追加した部品は決まった位置に置かれるので、ドラッグして好きな場所へ動かします。向きを変えるときは、部品をクリックして選んでから R キーを押します。
置いた直後の抵抗は1kΩです。この記事の回路では220Ωを使うので、抵抗をクリックして出る「Resistance」の欄を220に書き換えます。
配線は、つなぎたいピンをクリックし、次に相手のピンをクリックします。途中でクリックすると、線を曲げられます。
LEDのどちらの足がプラス側か分からないときは、足にマウスカーソルを合わせます。「led1:A」と出るのがアノード(プラス側)、「led1:C」と出るのがカソード(マイナス側)です。
この記事の例では、次の順につなぎます。
D8 → 220Ωの抵抗 → LEDのA → LEDのC → GND
GNDは、基板の上側で13番ピンの隣にあるものを使います。Wokwiの中では抵抗が無くてもLEDは光りますが、実機と同じ回路にしておくために入れておきます。

スケッチを書いて実行する
コーディングエリア(sketch.ino)には、あらかじめ空のsetup()とloop()が入っています。すべて削除してから、次のスケッチを貼り付けます。D8につないだLEDを1秒ごとに点滅させ、状態をシリアルモニタに出すものです。
// Wokwi で最初に動かすスケッチ
// D8 につないだ LED を1秒ごとに点滅させ、状態をシリアルモニタに出す
const int LED_PIN = 8;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
Serial.println("LED ON");
delay(1000);
digitalWrite(LED_PIN, LOW);
Serial.println("LED OFF");
delay(1000);
}
回路の左上にある緑色の▶ボタン(次の図の①)を押すと、ビルド(スケッチをマイコンで動く形に変換すること)が済んでからシミュレーションが始まります。Ctrl+Enterでも始められます。

LEDが1秒ごとに点滅し、下のシリアルモニタに「LED ON」と「LED OFF」が交互に出れば成功です。
シリアルモニタは、プログラムが何か出力すると自動で表示されます。通信速度も自動で合わせるので、Arduino IDEのように速度を選ぶ操作は要りません。
Build Servers Busy が出たら
無料で使っていると、▶を押したあと「Compiling project…」のまま待たされることがあります。混んでいるときは、2〜4分待ったあとに次のダイアログが出て止まりました。

「コンパイルが予想より長引いている。ビルドサーバーが混んでいるのかもしれない」という意味です。ダイアログは、手元のパソコンでコンパイルして Wokwi for VS Code で動かすか、有料プランでビルドの待ち行列を飛ばすかを案内しています。
VS Codeで動かす方法は、サインインと手元でのコンパイルが必要で、無料で使えるのはオープンソースのプロジェクトに限られます。登録なしで進めるなら、CLOSEで閉じ、時間を置いてからもう一度▶を押します。9月24日の夜に2回続けて止まったスケッチが、翌朝8時台には約3秒でビルドできました。
一度ビルドが通ったあと、↻でシミュレーションをやり直したときは、ビルドをやり直さずにすぐ始まりました。
保存する・ライブラリを追加する
保存は Save ボタン(または Ctrl+S)で行います。サインインしていない状態で Save ボタンを押しても、サインインは求められず、保存のダイアログが出ました。ただし、無料で保存したプロジェクトは誰でも見られる公開プロジェクトになります。スケッチにWi-Fiのパスワードや自分の名前を書いたまま保存しないでください。
保存したプロジェクトは、どこから開けばいいのか。Wokwi公式FAQによると、サインインせずに保存した場合は、保存したのと同じ端末・同じブラウザで wokwi.com/dashboard/projects を開きます。サインインしてから保存すれば、別の端末からも同じページで開けます。何も保存していないブラウザでこのページを開くと、サインインの画面が出ます。
ライブラリは、コーディングエリアの「Library Manager」タブを開き、「+」から名前で検索して追加します。サインインしていない状態で「DHT sensor library」を追加し、一覧に入ることを確かめました。Arduino IDEのライブラリマネージャにあるものなら、無料で使えます。
数字はどこまで実機と同じか
analogRead()とSerial.printの連続送信の2つで、ほかの関数1回の実行時間は実機との差が最大0.048µsでした。LEDを点滅させたりセンサーの値を表示したりするだけなら、どちらの差も結果に出ません。比べる相手は、Arduino日本語リファレンス(実機で測った関数の実行時間)に載せたUNO R3の値です。その記事の測定スケッチを、サインインしていない無料のWokwiにそのまま貼り、2026年9月24日に実行しました。
Wokwiのシリアルモニタに出た値は次のとおりです(関数の時間と、シリアル送信の時間の行を抜き出しています)。
==== Arduino日本語リファレンス 実測 ====
board: UNO R3 (ATmega328P)
F_CPU: 16 MHz
繰り返し回数: 1000
空ループのコスト: 0.340 us/回(各項目から差し引き済み)
### 1. 関数1回あたりの実行時間
| 関数 | 1回あたり | 備考 |
| --- | --- | --- |
| digitalWrite() | 4.964 us | ピン番号から毎回レジスタを引く |
| PORTB |= _BV(PB0) | 0.076 us | 直接ポート操作(同じ動作) |
| digitalRead() | 3.320 us | |
| analogRead() | 106.432 us | ADCの変換待ちを含む |
| analogWrite() | 8.280 us | PWMのデューティを書くだけ |
| millis() | 2.008 us | |
| micros() | 3.936 us | |
| map() | 39.508 us | 整数の割り算を含む |
### 2. millis() が1つ進む実際の時間
平均 1024.2 us(1.000 ms からどれだけずれるか)
### 10. Serial.print のコスト(115200bps・10文字)
1回あたり 891.0 us ※ 送信バッファが空くまで待つと、この値は跳ね上がる
実機の値と並べると、次のようになります。
| 測ったもの | 差(µs) | Wokwi(µs) | 実機 UNO R3(µs) |
|---|---|---|---|
digitalWrite() |
−0.016 | 4.964 | 4.980 |
レジスタを直接書く(PORTB |= _BV(PB0)) |
+0.020 | 0.076 | 0.056 |
digitalRead() |
−0.004 | 3.320 | 3.324 |
analogWrite() |
+0.012 | 8.280 | 8.268 |
millis() |
0 | 2.008 | 2.008 |
micros() |
+0.008 | 3.936 | 3.928 |
map() |
+0.048 | 39.508 | 39.460 |
analogRead() |
−5.360 | 106.432 | 111.792 |
Serial.print(10文字・115200bps) |
+41.0(+4.8%) | 891.0 | 850.0 |
太字の2行を除くと、差がいちばん大きいmap()でも0.048µsです。UNOのクロック1周期(0.0625µs)より小さい差です。
millis()が1つ進む時間も、Wokwiは1024.2µs、実機は1024.0µsでした。1msちょうどでないのは、時間を数えているタイマが一周するのが1024µsだからです(端数を貯めて約42回に1回だけ2つ進めるので、長く数えてもずれません)。1024µsになるところまで、Wokwiも同じです。
Wokwiは、スケッチをマイコンで動く形(ファームウェア)にコンパイルし、実際のマイコンと同じように1命令ずつ実行しています。Wokwi公式FAQの原文は“executes the binary firmware one instruction at a time, as a real microcontroller would”です。ここまで揃うのは、この仕組みのためと考えられます。実機用のプログラムをそのまま動かすこの方式は、エミュレータとも呼ばれます。
analogRead()がWokwiで短く出る理由
アナログの値を読むADCは、CPUより遅い専用のクロック(1周期8µs)で動きます。変換そのものは13クロック×8µs=104µsです。
実機は、変換を「次のADCクロックの立ち上がり」から始めます。続けて読むと、この待ちと関数の処理が加わって約112µsになります。Wokwiのエンジンはこの待ちを再現しておらず、開始を指示した瞬間から数えるので、そのぶん短く出ます。
待つ時間は開始を指示したタイミング次第で0〜8µsの間で変わるため、差の大きさもコードによって変わります(最大8µs)。
analogRead()の根拠(原文と出典)を見る
「When initiating a single ended conversion by setting the ADSC bit in ADCSRA, the conversion starts at the following rising edge of the ADC clock cycle.」
「A normal conversion takes 13 ADC clock cycles.」
和訳:ADCSRAのA/D変換開始(ADSC)ビットの設定(1)によってシングルエンド入力の変換を起動すると、その変換は直後の変換クロックの上昇端で始まります。通常の変換は13変換クロック周期で行われます。(AVR.jpの有志による和訳 160頁)
連続で読むと、実機は1回あたりADCクロック14周期(112.0µs)になると考えられます。これはデータシート p.250 の図24-5と実測からの推論です。
Wokwiのエンジン側
Wokwiが公開しているエンジンはAVR8jsです。そのadc.ts 154行目(v0.21.1)は、変換の完了を「開始の指示から13×分周比クロック後」に予約しています。次のクロックの立ち上がりを待つ処理を足して動かすと、analogRead()は111.764µsになり、実機の値に近づきました。
Wokwiで実際に動いている版は公開されていません。ただ、手元のAVR8jsで測り直しても、Wokwiと同じ106µs台になります。
実機側の値は、ほかの人が16MHzのUNOで測った結果(R3互換機で約111µs、112µs、112µs辺り)とも合っています。
Serial.printがWokwiで遅く出る理由
実機のシリアルは、1文字を送っている最中に次の1文字を積んでおけるので、文字と文字の間に隙間ができません。Wokwiのエンジンは1文字を送り終えるまで次を積めないため、1文字ごとに次の文字を書き込む処理の時間(約4µs)が足されると考えられます(推定)。
この推定どおりなら、1文字あたりの遅れは通信速度によらずほぼ一定なので、9600bpsでは差は約0.4%まで小さくなる計算です。
Serial.printの根拠(原文と出典)を見る
「The buffered data in the transmit buffer will be moved to the Shift Register when the Shift Register is ready to send a new frame.」
和訳:送信緩衝部内のデータは移動レジスタが新規フレームを送る準備が整った時に移動レジスタへ移されます。(AVR.jp有志訳 118頁)
「This bit is set when the transmit buffer is empty, and cleared when the transmit buffer contains data to be transmitted that has not yet been moved into the Shift Register.」
和訳:このビットは送信緩衝部が空の時に設定(1)され、送信緩衝部が移動レジスタに未だ移動されてしまっていない送信されるべきデータを含む時に解除(0)されます。(同 119頁)
「このビット」は、送信データレジスタが空いたことを示すフラグ(UDRE)です。
Wokwiのエンジン側
AVR8jsのusart.ts 158〜176行目(v0.21.1)は、送信データを書き込むとUDREを下ろします。1文字ぶんの時間が過ぎてから、UDREと送信完了フラグを同時に立てます。
1文字あたりの遅れ(約4µs)は、次の文字を書き込むまでの命令のクロック数から見積もった推定です。エンジンを実機と同じ作りに直して850µsに戻ることまでは確かめていません。
analogRead()を何百回も回してかかる時間を数えるときや、115200bpsで大量に送るときは、実機で測り直してください。
Wokwiの出力の全文を見る
WokwiではLEDやジャンパ線を配線していないので、§4〜§9と§13の値は比較に使っていません(配線していないピンを読んだ値です)。
==== Arduino日本語リファレンス 実測 ====
board: UNO R3 (ATmega328P)
F_CPU: 16 MHz
繰り返し回数: 1000
空ループのコスト: 0.340 us/回(各項目から差し引き済み)
### 1. 関数1回あたりの実行時間
| 関数 | 1回あたり | 備考 |
| --- | --- | --- |
| digitalWrite() | 4.964 us | ピン番号から毎回レジスタを引く |
| PORTB |= _BV(PB0) | 0.076 us | 直接ポート操作(同じ動作) |
| digitalRead() | 3.320 us | |
| analogRead() | 106.432 us | ADCの変換待ちを含む |
| analogWrite() | 8.280 us | PWMのデューティを書くだけ |
| millis() | 2.008 us | |
| micros() | 3.936 us | |
| map() | 39.508 us | 整数の割り算を含む |
### 2. millis() が1つ進む実際の時間
平均 1024.2 us(1.000 ms からどれだけずれるか)
### 3. delayMicroseconds() の指定値と実際
| 指定 | 実測 | 差 |
| --- | --- | --- |
| 1 us | 0.24 us | -76.0% |
| 10 us | 9.84 us | -1.6% |
| 100 us | 109.04 us | 9.0% |
| 1000 us | 1007.84 us | 0.8% |
### 4. analogWrite のPWM周波数
| ピン | 周波数 | デューティ | 備考 |
| --- | --- | --- | --- |
| D3 (D3->D2) | ---- | ---- | ジャンパ未接続 |
| D5 (D5->D4) | ---- | ---- | ジャンパ未接続 |
### 5. 割り込みの応答遅延(D3をHIGHにしてからISRに入るまで)
測れず(D3--D2 のジャンパを確認)
### 6. ADCのばらつき(10k+10kの分圧=約2.5Vを200回読む)
| 分解能 | 平均 | 最小 | 最大 | 振れ幅 | 電圧換算 |
| --- | --- | --- | --- | --- | --- |
| 10bit | 515.2 | 369 | 673 | 304 LSB | 2.517 V |
#### 6-1. 同じピンを続けて2回読む(ソース抵抗の影響)
| ピン | ソース抵抗 | 1回目 | 2回目 | 差 |
| --- | --- | --- | --- | --- |
| A0 | 約5kΩ | 443 | 483 | 40 |
| A1 | 約1kΩ | 476 | 441 | -35 |
※ 2回目が明らかに上がるなら、1回目は充電しきる前の値を読んでいる
※ R3のanalogReadは10bit固定(analogReadResolutionは無い)
### 7. analogWrite の値と、平滑した平均電圧(D6→1k→10uF→A1)
測れず(D6→1kΩ→A1、A1→10uF→GND のRCを組んでいない)
### 8. tone() の指定周波数と実測
測れず(D8--D7 のジャンパを確認)
#### 8-1. tone() を鳴らしている間、PWMはどうなるか
測れず(D3--D2 と D5--D4 のジャンパを確認)
### 9. INPUT_PULLUP の内蔵抵抗を実測(D12--A2--10k--GND)
プルアップOFF: 3.162 V / ON: 2.610 V
→ 内蔵プルアップ抵抗 = 約 9.2 kΩ(データシートの範囲と比べる)
### 11. 型の大きさ(sizeof)
| 型 | 大きさ |
| --- | --- |
| char | 1 バイト |
| int | 2 バイト |
| long | 4 バイト |
| float | 4 バイト |
| double | 4 バイト |
| void* | 2 バイト |
### 12. digitalPinToInterrupt() が有効なピン
使えるピン: D2, D3
→ 合計 2 本(R3は2本、R4は全ピンと言われているものの実測)
### 13. ISRが長いと割り込みを取りこぼすか
2kHz(周期500us)を200ms=期待400回。ISRの中に入れる処理の長さを変えて測る
測れず(D3--D2 のジャンパを確認)
### 10. Serial.print のコスト(115200bps・10文字)
次の行は計測のために送っている文字列です(読み飛ばしてください)
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
1回あたり 891.0 us ※ 送信バッファが空くまで待つと、この値は跳ね上がる
==== ここまでをそのまま貼ってください ====
Wokwiで再現されないもの
UNO R4は選べない
Wokwiの新規プロジェクト画面のArduino欄に並ぶのは、Arduino Uno Rev3・Mega・Nano・ATtiny85などで、UNO R4はありません。

公式の対応ハードウェアの一覧にも、UNO R4が使っているルネサスのマイコンRA4M1は載っていません。R4用の新規プロジェクトのURL(arduino-uno-r4)も開けませんでした。
「wokwi uno r4」で検索すると、タイトルにR4と付いたWokwiのプロジェクトが出てきます。中を4件開くと、4件とも置かれているのはUNO(R3)でした。UNO R4を買うつもりなら、Wokwiで練習するのはR3用のスケッチになる点を知っておいてください。R3とR4のどちらを選ぶかは、Arduinoは結局どれを買う?初心者へのおすすめと主要ボード比較の記事で扱っています。
電気のふるまいは再現されない
UNOに、220Ω・10kΩ・抵抗なしの3通りでLEDをつないで光らせると、3つとも同じ明るさで光りました。

実機では、抵抗の値でLEDに流れる電流が変わり、明るさも変わります。抵抗を省いてLEDへ直接電流を流すと危ないので、実機では必ず抵抗を入れてください。
Wokwiの抵抗の説明でも、アナログ回路のシミュレーションは「ごく基本的なもの」で、抵抗はプルアップ・プルダウンには使えると書かれています。Wokwiで明るさが変わるのは、抵抗ではなくanalogWrite()の値を変えたときです(LEDの説明)。
同じ理由で、配線のミスが結果に出ないことがあります。可変抵抗(ポテンショメータ)は、GNDとVCCをつながなくても同じ値になると公式に書かれています。仮想の部品は壊れないので、Wokwiの中で間違えても困りませんが、Wokwiで動いた配線を実機で組むときは、電源とGNDのつなぎ方と抵抗の値を回路図で見直してください。
UNOの3.3V・IOREF・AREF・RESETの各ピンも、シミュレーションでは使えません(Wokwi公式のUNOの説明)。
無い部品は近い部品で代わりにする
Wokwiで使える部品は、実物の部品ほど多くはありません。たとえば温湿度センサーのDHT11は公式の対応一覧に無く、DHT22はあります(2026年9月25日時点)。DHT11と題したWokwiのプロジェクトを3件開くと、3件とも置かれているのはDHT22でした。
DHT11とDHT22はデータの形式が違うので、置き換えるときはスケッチ側もDHT22に合わせます。ライブラリを使うなら、センサーの種類の指定をDHT22に変えます。最後は実機で確かめ、そのときDHT11を使うなら指定をDHT11に戻します。
Arduino総合演習|自動温湿度調整システムを作るの記事でも、Wokwiで試すときはDHT11をDHT22で代用する前提です。ただし、赤外線での実エアコン操作は実機でしか確かめられません。
無料でどこまでやれるか
Wokwiの公式ドキュメントには「Wokwi is free for personal use.(個人の利用は無料)」と書かれています。利用規約では、ブラウザ版を無料で使えるのは個人かつ非商用の目的とされているので、仕事で使うなら有料プランの対象です。
無料サービスゆえの注意点もあります。いちばん影響が大きいのはビルド待ちです。サインインなし・無料で、9月21日から25日までに待ち時間を記録したビルドは10回です。
| 開始 | 結果(待ち時間) |
|---|---|
| 9/21 23:34〜23:52(3回) | 3回とも Busy(各3〜4分) |
| 9/24 22:04 | 成功(約2分) |
| 9/24 22:09 | 成功(約2分40秒) |
| 9/24 22:23 | Busy(約2分) |
| 9/24 22:25 | 成功(約2分15秒) |
| 9/24 22:33 | Busy(約2分30秒) |
| 9/24 22:36 | Busy(約2分10秒) |
| 9/25 8:18 | 成功(約3秒) |
成功4回、Build Servers Busy 6回です。成功した回でも、待ち時間は約3秒から2分40秒まで開きがありました。測ったのは5日間のうちの限られた時間帯だけなので、何時なら空いているとまでは言えません。
有料プランでは、混む時間帯でも、ビルドの待ち行列を飛ばして専用のサーバーでビルドされます。ただし速いビルドを使えるのは、プランごとに決まった月あたりの分数の範囲です。非公開(Unlisted)での保存と、自作ライブラリのアップロードも、有料プランの機能です。
Wokwi for VS Code(VS Codeの中でシミュレーションする拡張機能)を無料のライセンスで使えるのは、オープンソースのプロジェクトだけです。利用規約では、GitHubでオープンソースのライセンスを付けて公開し、商用にしていないものを指します。GitHubで公開していない自分のスケッチで使うなら、有料プランのうち Hobby+ 以上が要ります(個人向けの Hobby には入っていません)。商用で使うなら、ライセンスの購入が必要です。
ボードを持っていない段階で、スケッチの書き方を覚えたり、配線とコードの組み合わせを試したりするだけなら、無料の範囲で足ります。
実機へ移る線引き
analogRead()の時間と、Serial.printで115200bpsの連続送信にかかる時間を数えるときは実機で測ります。Wokwiに無い部品は近い部品で代わりにして進め、最後は実機で確かめます。「条件つき」の項目を、Wokwiのまま進めるか実機へ移るかで分けると、次のようになります。
| 条件つきの項目 | どうするか |
|---|---|
analogRead()の時間を数える |
実機で測る |
Serial.printで115200bpsの連続送信にかかる時間を数える |
実機で測る |
| Wokwiに無い部品を使う | 近い部品で代わりにしてWokwiで進め、最後は実機で確かめる |
| ビルド待ち | 時間を置いて、Wokwiで進める |
| 保存 | 公開されて困るものを書かずに、Wokwiで進める |
「できない」に入れたUNO R4と電気のふるまい(抵抗で電流や明るさが変わること)を確かめたいときも、実機です。
車載の開発でも、シミュレーションは設計工程の検証に使います。実機で動かすよりも低コストで、実機やセンサーが手元に届く前から動作を確かめられるのが強みです。ボードを買う前にWokwiで試すのも、同じ使い方です。
実機へ移るときに注意が要るのは、UNO R4を選ぶ場合です。Arduino公式によると、UNO R3用のスケッチは、Arduinoの関数だけで書いてあればUNO R4でも動きます。レジスタを直接書くなど、R3のマイコン(AVR)専用の書き方をしている部分は書き換えが必要です。
Wokwiで書いたスケッチは、そのままArduino IDEに貼り付けて書き込めます。Library Managerで追加したライブラリは、Arduino IDEでも同じ名前で入れておきます。