Created
June 22, 2026 19:57
-
-
Save Yuikawa-Akira/af00370917072a164b8cdf960f42bc0c to your computer and use it in GitHub Desktop.
NTSC test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <M5UnitRCA.h> | |
| #include <M5Unified.h> | |
| // M5UnitRCA | |
| const uint16_t canvas_width_pix = 240, canvas_height_pix = 180; | |
| const uint16_t panel_width_pix = 240, panel_height_pix = 180; | |
| M5UnitRCA display(canvas_width_pix, canvas_height_pix, panel_width_pix, panel_height_pix, M5UnitRCA::signal_type_t::NTSC, M5UnitRCA::use_psram_t::psram_no_use, 26, 128); | |
| M5Canvas canvas(&display); | |
| const int BUFFER_SIZE = (canvas_width_pix * canvas_height_pix) / 8; // 9600 bytes | |
| const uint8_t MAGIC[4] = { 0xAA, 0x55, 0x00, 0xFF }; | |
| void setup() { | |
| //auto cfg = M5.config(); | |
| //M5.begin(cfg); | |
| display.begin(); | |
| Serial1.begin(2000000, SERIAL_8N1, 22, 19); | |
| // 表示用キャンバス作成 (1ビットカラー) | |
| canvas.setColorDepth(1); | |
| canvas.createSprite(canvas_width_pix, canvas_height_pix); | |
| // 受信待機画面 | |
| canvas.clear(); | |
| canvas.setTextSize(2); | |
| canvas.setCursor(10, 10); | |
| canvas.print("Waiting for Signal..."); | |
| canvas.pushSprite(0, 0); | |
| } | |
| void loop() { | |
| // マジックナンバーを待機 | |
| if (Serial1.available() >= 4) { | |
| uint8_t header[4]; | |
| // 1バイトずつ確認してヘッダーを探す(簡易的な実装) | |
| if (Serial1.read() == MAGIC[0]) { | |
| header[0] = MAGIC[0]; | |
| Serial1.readBytes(&header[1], 3); | |
| if (header[1] == MAGIC[1] && header[2] == MAGIC[2] && header[3] == MAGIC[3]) { | |
| // マジックナンバーが一致したら映像データを受信 | |
| uint8_t* buffer = (uint8_t*)canvas.getBuffer(); | |
| size_t readLen = 0; | |
| // タイムアウトを考慮した受信ループ | |
| uint32_t startTime = millis(); | |
| while (readLen < BUFFER_SIZE && millis() - startTime < 100) { | |
| if (Serial1.available()) { | |
| size_t len = Serial1.readBytes(&buffer[readLen], BUFFER_SIZE - readLen); | |
| readLen += len; | |
| } | |
| } | |
| // 受信完了したら画面に描画 | |
| if (readLen == BUFFER_SIZE) { | |
| canvas.pushSprite(0, 0); | |
| } | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <M5Cardputer.h> | |
| #include <M5GFX.h> | |
| M5Canvas canvas(&M5Cardputer.Display); | |
| // 画面サイズとデータサイズ | |
| const int WIDTH = 240; | |
| const int HEIGHT = 180; | |
| const int BUFFER_SIZE = (WIDTH * HEIGHT) / 8; // 9600 bytes | |
| // 同期用マジックナンバー (4バイト) | |
| const uint8_t MAGIC[4] = { 0xAA, 0x55, 0x00, 0xFF }; | |
| int frameCount = 0; | |
| // スクロール量の累積用変数 | |
| int currentOffsetX = 0; | |
| int currentOffsetY = 0; | |
| // 8方向のベクトル定義 (上から時計回り) | |
| // 0:上, 1:右上, 2:右, 3:右下, 4:下, 5:左下, 6:左, 7:左上 | |
| const int dx[8] = { 0, 1, 1, 1, 0, -1, -1, -1 }; | |
| const int dy[8] = { -1, -1, 0, 1, 1, 1, 0, -1 }; | |
| int currentDirection = 0; // 現在の進行方向 (0〜7) | |
| unsigned long lastChangeTime = 0; // 方向切り替えタイマー用 | |
| void setup() { | |
| auto cfg = M5.config(); | |
| M5Cardputer.begin(cfg); | |
| // UART初期化: ボーレート2Mbps, RX=G1, TX=G2 (CardputerのGroveポート) | |
| Serial1.begin(2000000, SERIAL_8N1, 1, 2); | |
| // 1ビットカラー(白黒)のキャンバスを作成 | |
| canvas.setColorDepth(1); | |
| canvas.createSprite(WIDTH, HEIGHT); | |
| } | |
| void loop() { | |
| M5Cardputer.update(); | |
| // 2秒(2000ms)ごとに進行方向を切り替える | |
| if (millis() - lastChangeTime > 2000) { | |
| currentDirection = (currentDirection + 1) % 8; // 0〜7をループ | |
| lastChangeTime = millis(); | |
| } | |
| // スクロール速度 (1フレームあたりの移動ピクセル数) | |
| int scrollSpeed = 2; | |
| // オフセット座標を更新してスクロールさせる | |
| currentOffsetX += dx[currentDirection] * scrollSpeed; | |
| currentOffsetY += dy[currentDirection] * scrollSpeed; | |
| // 1マス30ピクセル、緑(TFT_DARKGREEN)と黒(TFT_BLACK)の市松模様を描画 | |
| drawCheckerboardScroll(&canvas, 16, TFT_WHITE, TFT_BLACK, currentOffsetX, currentOffsetY); | |
| canvas.setTextSize(2); | |
| canvas.setCursor(10, 10); | |
| canvas.printf("Frame: %d", frameCount); | |
| // カードピューター自身の画面にも描画(縮小表示など適宜) | |
| canvas.pushSprite(0, 0); | |
| // UARTでデータを送信 | |
| uint8_t* buffer = (uint8_t*)canvas.getBuffer(); | |
| // 1. マジックナンバーを送信 | |
| Serial1.write(MAGIC, 4); | |
| // 2. 映像バッファを送信 | |
| Serial1.write(buffer, BUFFER_SIZE); | |
| frameCount++; | |
| yield(); | |
| } | |
| void drawCheckerboardScroll(M5Canvas* canvas, int gridSize, uint32_t color1, uint32_t color2, int offsetX, int offsetY) { | |
| if (canvas == nullptr || gridSize <= 0) return; | |
| int width = canvas->width(); | |
| int height = canvas->height(); | |
| int period = gridSize * 2; | |
| int startX = offsetX % period; | |
| if (startX > 0) startX -= period; | |
| int startY = offsetY % period; | |
| if (startY > 0) startY -= period; | |
| for (int y = startY; y < height; y += gridSize) { | |
| for (int x = startX; x < width; x += gridSize) { | |
| int gridX = (x - startX) / gridSize; | |
| int gridY = (y - startY) / gridSize; | |
| bool isColor1 = (gridX + gridY) % 2 == 0; | |
| canvas->fillRect(x, y, gridSize, gridSize, isColor1 ? color1 : color2); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment