KeyeStudio 328 WiFi Plus
2025.04.08
YouTube でも紹介しています。画像をクリックすると再生できます。

今回は、KeyeStudio 328 WiFi Plus マイコンボードを使ってみました。
このUNO互換ボードは ATmega328 を搭載し、通信機能を補完するために ESP8266 を実装しています。
Keyestudio 328 WIFI PLUS
KS5013 Keyestudio 328 WIFI PLUS
1. Introduction — keyestudio WiKi documentation
Arduino UNO R4

Arduino UNO に通信機能を持たせたボードに R4 がありますが、ESP32S3のファームウェアの書き換えには詳しい知識が必要になります。
このボードには8つのDIPスイッチがあり、手動で物理的に配線を切り替えることができます。
これによりUSBシリアルの接続先を変更させて、ATmega328 と ESP8266 各々を単独でビルドすることができます。
また、スイッチ切替により、UNO側とESP8266側のシリアルポートを接続させることもできます。

Logo of the board as the positive direction, pin attributes from left to right.
CH-P0 → CH-PD ?

Taking Keyestudio LOGO as a reference, toggle the switch to the left(ON) and right(OFF).

| Working Voltage |
USB/5V DC/6-9V (Esp8266/3.3V;ATmega328P/5V) |
| Current |
Maximum output 3.3V/800mA、5V/800mA |
| Maximum Power |
4W |
| ATmega328P |
Digital I/O Pin |
14pin (6 for PWM output)
Serial: D0(RX), D1(TX)
PWM: D3 D5 D6 D9 D10 D11
External:D2(Interrupt0) and D3(Interrupt1)
SPI:D10(SS), D11(MOSI), D12(MISO), D13(SCK)
IIC:A4(SDA), A5(SCL)
|
| Analog Input Pin |
8pin (A4,A5 as regular I2C) |
| DC of each I/O Pin |
20mA |
| flash |
32KB, 0.5KB used for bootloader) |
| SRAM |
2KB(ATmega328P) |
| EEPROM |
1KB(ATmega328P) |
| Clock Speed |
16MHZ |
Esp8266 |
| Digital I/O Pin |
9 on-board pins
|
PWM Digital I/O |
PWM: IO4, IO12, IO14, IO15
|
| DC of each I/O Pin |
20mA |
| flash |
2Mb |
| SRAM |
50kb |
| Clock Speed |
26MHZ |
| Radio Frequency |
2.4GHZ Receiver and Transmitter |
| Wifi |
ESP8266EX supports TCP/IP protocol and 802.11 b/g/n WLAN MAC protocol.
Supports Basic Service Set (BSS) STA and SoftAP operation under Distributed Control Function (DCF).
Enables optimization of active hours by minimizing host interaction for power management.
|
●ソースコード
それでは、提供されているサンプルコードを試してみましょう。

KS5013 Keyestudio 328 WIFI PLUS Main Control Board
●Arduino UNO Burn Test Program:
まずは、UNO側ATmega328プログラムのビルドおよびアップロードです。

DIPスイッチの上から5番目と6番目をオンにします。
ここのMCU表記がATmega328を指しています。
これでUSBシリアルにUNO側が接続されます。
ソースコードのビルドには、PlatformIOを使用しています。
Arduino開発環境構築 PlatformIO
328.ino
#include "MemoryFree.h"
#include <EEPROM.h>
/* Schematic of toggle switch
▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
▏ GND-GPIO0 |8| ○ ● ▏
▏ GND-GPIO0 |7| ○ ● ▏
▏ USB-ESP |6| ○ ● ▏
▏ USB-ESP |5| ○ ● ▏
▏ USB-MCU |4| ● ○ ▏
▏ USB-MCU |3| ● ○ ▏
▏ MCU-WIFI |2| ○ ● ▏
▏ MCU-WIFI |1| ○ ● ▏
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Test program: open the serial port and input a, b, and c in turn
*/
#define FIRST_PIN 0 // First pin
#define LAST_PIN 19 // Last pin
#define PIN_LED 13 // LED output
void PinTest1(byte pin)
{
if(pin < 10) Serial.print("PIN: ");
else Serial.print("PIN: ");
Serial.print(pin);
pinMode(pin, OUTPUT);
digitalWrite(pin, 0);
Serial.print(" LOW: ");
if(!digitalRead(pin)) Serial.print("OK ");
else Serial.print("FAIL");
digitalWrite(pin, 1);
Serial.print(" HIGH: ");
if(digitalRead(pin)) Serial.print("OK ");
else Serial.print("FAIL");
pinMode(pin, INPUT);
Serial.print(" PULL UP: ");
if(digitalRead(pin)) Serial.print("OK ");
else Serial.print("FAIL");
digitalWrite(pin, 0);
}
void PinTest2(byte pin)
{
Serial.print(" ");
pinMode(pin, OUTPUT);
digitalWrite(pin, 1);
delay(5);
if(!digitalRead(pin))Serial.println("SHORT");
else Serial.println("OK");
pinMode(pin, INPUT);
digitalWrite(pin, 0);
}
void EEPROMTest() {
}
void displayHelp() {
Serial.println(F("\nArduino hardware test"));
Serial.println(F("\ta = Blink test"));
Serial.println(F("\tb = EEPROM test"));
Serial.println(F("\tc = Pins test"));
Serial.println(F("\t? = Help page"));
Serial.println();
}
void setup() {
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
displayHelp();
}
void loop() {
if (Serial.available() > 0) {
switch (Serial.read()) {
case 'a': // LED测试
Serial.print(F("\nBlink test:"));
Serial.print(F("\n\tStart blinking - please check the board led\n\t"));
for(byte i = 1; i <= 5; i++) {
digitalWrite(PIN_LED, HIGH);
delay(500);
Serial.print(".");
digitalWrite(PIN_LED, LOW);
delay(500);
Serial.print(F("."));
}
Serial.print("\n\tStop blinking\n");
Serial.println();
displayHelp();
break;
case 'b':
Serial.print(F("\nEEPROM test:\n"));
Serial.print("\tSRAM free size: ");
Serial.print(freeMemory());
Serial.print(F(" bytes\n"));
Serial.print("\tEEPROM size: ");
Serial.print(EEPROM.length());
Serial.print(F(" bytes\n"));
Serial.println();
displayHelp();
break;
case 'c': // 引脚短路测试
Serial.print(F("\nTest of short circuit on GND or VCC and between pins:\n"));
for(byte i = FIRST_PIN; i <= LAST_PIN; i++) {
for(byte j = FIRST_PIN; j <= LAST_PIN; j++) {
pinMode(j, INPUT);
digitalWrite(j, 0);
}
Serial.print(F("\t"));
PinTest1(i);
for(byte j = FIRST_PIN; j <= LAST_PIN; j++) {
pinMode(j, OUTPUT);
digitalWrite(j, 0);
}
PinTest2(i);
}
for(byte j = FIRST_PIN; j <= LAST_PIN; j++) {
pinMode(j, INPUT);
digitalWrite(j, 0);
}
displayHelp();
break;
case '?':
displayHelp();
break;
default:
Serial.println();
break;
}
}
}
ビルドしてアップロードします
$ pio init -b uno
$ pio run -t upload
続いてシリアルモニターを起動します
$ pio device list
/dev/ttyUSB0
------------
Hardware ID: USB VID:PID=1A86:7523 LOCATION=1-1.2
Description: USB Serial
/dev/ttyAMA0
------------
Hardware ID: 3f201000.serial
Description: ttyAMA0
$ pio device monitor -p /dev/ttyUSB0 -b 115200
Arduino hardware test
a = Blink test
b = EEPROM test
c = Pins test
? = Help page
キーボードから'a'と打ち込むと13番ピンに接続されている赤色LEDが点滅します。

'b' を押すと
EEPROM test:
SRAM free size: 1730 bytes
EEPROM size: 1024 bytes
'c' を押すと
Test of short circuit on GND or VCC and between pins:
PIN: 0 LOW: FAIL HIGH: OK PULL UP: OK OK
PIN: 1 LOW: OK HIGH: OK PULL UP: FAIL OK
PIN: 2 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 3 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 4 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 5 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 6 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 7 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 8 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 9 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 10 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 11 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 12 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 13 LOW: OK HIGH: OK PULL UP: FAIL OK
PIN: 14 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 15 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 16 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 17 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 18 LOW: OK HIGH: OK PULL UP: OK OK
PIN: 19 LOW: OK HIGH: OK PULL UP: OK OK
●ESP8266 Burn Test Program:
つぎにESP8266側プログラムのビルドおよびアップロードです

上4つのDIPピンをオンにします。
注意: esp8266 をプログラミングする前に、スイッチを GND-GPIO0 で切り替える必要があります。
プログラミング後にスイッチをオフにすると、通常の IO ポートとして使用することもできます。
esp8266.ino
このプログラムはWEBサーバとして起動し、WEBページからの入力情報をATmega328側のプログラムに渡しています。
サンプルコードを変更して、固定IP{192,168,11,64}、STAモードにしています。
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
/* Schematic of toggle switch
▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
▏ GND-GPIO0 |8| ● ○ ▏
▏ GND-GPIO0 |7| ● ○ ▏
▏ USB-ESP |6| ● ○ ▏
▏ USB-ESP |5| ● ○ ▏
▏ USB-MCU |4| ○ ● ▏
▏ USB-MCU |3| ○ ● ▏
▏ MCU-WIFI |2| ○ ● ▏
▏ MCU-WIFI |1| ○ ● ▏
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Test description:
After the wifi connection is successful, open the IP address of 8266 in any browser,
Click the [ON] [OFF] switch of LED state to control the LED lights on the board.
*/
#define SECRET_SSID "xxxxxxxxxxxx"
#define SECRET_PASS "xxxxxxxxxxxxx"
const uint8_t PRIMARY_DNS[4] = {192,168,11,1};
const uint8_t GATEWAY[4] = {192,168,11,1};
const uint8_t SUBNETMASK[4] = {255,255,255,0};
const uint8_t LOCAL_IP[4] = {192,168,11,64};
ESP8266WebServer server(80);
MDNSResponder mdns;
String webPage = "";
int led_pin = 14;
void setup(void){
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
// WEBPAGE DESCRIPTION
webPage += "<h1>ESP8266 Web Server</h1>";
webPage += "<p>Chip ID: ";
webPage += ESP.getFlashChipId();
webPage += "</p>";
webPage += "<p>Core Version: ";
webPage += ESP.getCoreVersion();
webPage += "</p>";
webPage += "<p>Chip Real Size: ";
webPage += ESP.getFlashChipRealSize()/1024;
webPage += " Kbit</p>";
webPage += "<p>Chip Size: ";
webPage += ESP.getFlashChipSize()/1024;
webPage += " Kbit</p>";
webPage += "<p>Chip Flash Speed: ";
webPage += ESP.getFlashChipSpeed()/1000000;
webPage += " MHz</p>";
webPage += "<p>Chip Work Speed: ";
webPage += ESP.getCpuFreqMHz();
webPage += " MHz</p>";
webPage += "<p>Chip Mode: ";
webPage += ESP.getFlashChipMode();
webPage += "</p>";
webPage += "<p>LED state <a href=\"LedON\"><button>ON</button></a> <a href=\"LedOFF\"><button>OFF</button></a></p>";
if (!WiFi.config(LOCAL_IP, GATEWAY, SUBNETMASK, PRIMARY_DNS)) while(1);
// WiFi CONFIGURATION
WiFi.mode(WIFI_STA);
WiFi.begin(SECRET_SSID, SECRET_PASS); // Connect to WPA/WPA2 network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("WIFI TEST");
// MCU INFORMATION
Serial.println("");
Serial.println("ESP8266 board info:");
Serial.print("\tChip ID: ");
Serial.println(ESP.getFlashChipId());
Serial.print("\tCore Version: ");
Serial.println(ESP.getCoreVersion());
Serial.print("\tChip Real Size: ");
Serial.println(ESP.getFlashChipRealSize());
Serial.print("\tChip Flash Size: ");
Serial.println(ESP.getFlashChipSize());
Serial.print("\tChip Flash Speed: ");
Serial.println(ESP.getFlashChipSpeed());
Serial.print("\tChip Speed: ");
Serial.println(ESP.getCpuFreqMHz());
Serial.print("\tChip Mode: ");
Serial.println(ESP.getFlashChipMode());
Serial.print("\tSketch Size: ");
Serial.println(ESP.getSketchSize());
Serial.print("\tSketch Free Space: ");
Serial.println(ESP.getFreeSketchSpace());
Serial.println("");
Serial.print("Connected to ");
Serial.println(SECRET_SSID);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}
server.on("/", [](){
server.send(200, "text/html", webPage);
});
server.on("/LedON", [](){
server.send(200, "text/html", webPage);
digitalWrite(led_pin, HIGH);
Serial.println("[ON]");
delay(1000);
});
server.on("/LedOFF", [](){
server.send(200, "text/html", webPage);
digitalWrite(led_pin, LOW);
Serial.println("[OFF]");
delay(1000);
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}
$ pio init -b esp_wroom_02
$ pio run -t upload
テスト
プログラムを実行するには、Raspberry Pi から USBケーブルを外して、DIPスイッチを変更します。

再度、USBケーブルを Raspberry Pi に接続します。
WEBブラウザを起動して、ソースコード内で指定したローカルIPアドレスを打ち込みます。

WEBページのLED state欄の [ON]ボタンを押すとESP8266の14番ピンに割り振られているオンボードLEDが点灯します。

しかし、この状態ではソースコードに記述されているSerial出力は未接続状態になっています。
●TEST_UNO-ESP Remote Control
ESP8266側からのシリアル出力を受取れるようにUNO側プログラムを書き換えます。
TEST_UNO-ESP.ino
#include "MemoryFree.h"
#include <EEPROM.h>
#define PIN_LED 13
String inString;
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
}
void loop() {
serialEvent3();
}
void serialEvent3() {
while (Serial.available()) {
char inChar = Serial.read();
Serial.write(inChar);
inString += inChar;
if (inChar == ']') {
if (inString.indexOf("[ON]")>0) {
digitalWrite(PIN_LED, HIGH);
}
else if (inString.indexOf("[OFF]")>0) {
digitalWrite(PIN_LED, LOW);
}
else
{
Serial.println("Wrong command");
}
inString = "";
}
}
}
DIPスイッチを変更して、ソースコードをビルド、アップロードします。

$ pio run -t upload
DIPスイッチを変更して、UNOとESPをシリアル接続します。

ESP8266は3.3V、UNO側は5V系なので、シリアル接続の回路上でレベル変換が行われているはずです。

先程のWEBページのLED state [ON]ボタンを押すと、ESP側とUNO側両方のLEDがともに点灯します。

$ pio device monitor -p /dev/ttyUSB0 -b 115200

また、シリアルモニターにはUNOを介してESP8266側からシリアル出力された情報が表示されます。

サンプルプログラムではESP8266をWEBサーバーとして利用していましたが、TELNETやUDP通信用プログラムを書き込んで遠隔操作するのも面白いかもしれません。
【その他】
ESP WROOM02(ESP8266)のアナログ入力(TOUT)の使い方
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」
「一念発起して何かを始めても、いつも三日坊主で終わってしまう」
「色んなことを先延ばしにしたまま、時間だけが過ぎていく」
そこで本書では、そんな著者が独自に開発した、
まったく新しい目標達成メソッド「100日デザイン」について、
その知識と技術を、余すところなくご紹介します。
まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。
ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。
今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。
ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。
29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!
【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。
基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。
Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説!
500以上のサンプルを掲載。実行結果も確認。
全24章の包括的なチュートリアル。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。
Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード
電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)
|