Step09 シリアル通信(デバッグ)、スクリーンショット


#1

PCとの通信に役に立つテクニックです。printfデバッグに使えます。

正直、近代から石器時代に遡るような話でもあり、今更どうなのん?
という意見は出てくると思います。至極まっとうな話です。

ただArduino IDEにはブレークポイントを掛ける機能もなく、そうすると
Visual C++とArduboy Library(SDLラッパ)環境がいいのかもしれません。

ガチで作る場合は構築することを考えてみてください。

#include <Arduboy.h>

Arduboy ab;

uint8_t cnt;


void SerialInit()
{
    Serial.begin(9600);
    cnt = 0;
}

void SerialExec()
{
    if(Serial.available() <= 0)
    {
        return;
    }

    // clear buffer. no use char
    char c = Serial.read();

    Serial.println(++cnt, DEC);
}

void setup()
{
    ab.beginNoLogo();
    ab.setFrameRate(30);

    SerialInit();
}

void loop()
{
    if(!(ab.nextFrame()))
    {
        return;
    }

    SerialExec();

    ab.setCursor(1, 1);
    ab.print(cnt);

    ab.display();
    ab.clear();
}

ターミナルソフトにはTera Termを使いました。
発展として、ゲームパッド代わりにすることもできます。


#2

簡単にスクリーンショットを取るためのコードです。
python2.7 + Pillowを使用しました。

screenshot.py

from PIL import Image
import serial

print "Arduboy screenshot"
fnum = 0

while True:
    ser = serial.Serial(port="COM6")
    data = ser.read(128*64 / 8)
    ser.close()

    img = Image.new("RGB", (128, 64))
    i = 0

    for y in range(0, 64/8):
        for x in range(0, 128):
            if ord(data[i]) & 0x01: img.putpixel((x, y*8 + 0), (255, 255, 255))
            if ord(data[i]) & 0x02: img.putpixel((x, y*8 + 1), (255, 255, 255))
            if ord(data[i]) & 0x04: img.putpixel((x, y*8 + 2), (255, 255, 255))
            if ord(data[i]) & 0x08: img.putpixel((x, y*8 + 3), (255, 255, 255))
            if ord(data[i]) & 0x10: img.putpixel((x, y*8 + 4), (255, 255, 255))
            if ord(data[i]) & 0x20: img.putpixel((x, y*8 + 5), (255, 255, 255))
            if ord(data[i]) & 0x40: img.putpixel((x, y*8 + 6), (255, 255, 255))
            if ord(data[i]) & 0x80: img.putpixel((x, y*8 + 7), (255, 255, 255))
            i = i + 1

    fname = "%03.d" % (fnum) + ".png"
    fnum = fnum + 1

    print "saving... "  + fname
    img.save(fname)

・screenshot.ino

#include <Arduboy2.h>
Arduboy2 ab;

int y = 0;

void setup()
{
  Serial.begin(9600);

  ab.begin();
  ab.setTextSize(3);
  ab.setFrameRate(30);
}

void loop()
{
  if(!(ab.nextFrame()))
  {
      return;
  }

  ab.pollButtons();
  ab.clear();

  ab.setCursor(10, y);
  ab.print("ABC :D");

  if(y >= 64)
  {
    y = -20;
  }
  else
  {
      y++;
  }

  ab.drawRect(0, 0, 128, 64, WHITE);
  ab.drawCircle(48, 32, 20, WHITE);
  
  ab.display();
  
  if(ab.justPressed(A_BUTTON))
  {
      Serial.write(ab.getBuffer(), 128*64 / 8);
  }
}

何枚でも取れます。良さげなタイミングでAボタンを押してください。