Wio Terminal
発掘したのでさわってみる。
https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/ でgetting start
https://qiita.com/jksoft/items/c544d73b54323064ed06#プログラム書き込み のチカチカまではとりあえずできた。
https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/#wio-terminal-classroom でなんか最初のほうのやることあるっぽいけど、動画じゃなくて文字にしてほしい……。
uploadができない時
大抵ぬるぽで死んで固まっている。
2回resetすればいける(bootloader modeになるから?)。
RawImage.h
RawImage.h #pragma once#include<stdint.h>#include<SD/Seeed_SD.h>
/*USAGE:
// when use 8bit color. Raw8 * img8 = newImage<uint8_t>("path to sd card image.");
// when use 16bit color. Raw16 * img16 = newImage<uint16_t>("path to sd card image.");
// do some drawing. // img8->draw();
// remember release it img8->release(); img16->release(); */
extern TFT_eSPI tft;
template<class type>struct RawImage{ type * ptr(){ return (type *)(this + 1); } type get(int16_t x, int16_t y){ return this->ptr()[y * width() + x]; } void draw(size_t x = 0, size_t y = 0){ tft.pushImage(x, y, width(), height(), ptr()); } void release(){ delete [] this; } int16_t width(){ return _width; } int16_t height(){ return _height; }private: int16_t _width; int16_t _height;};
typedef RawImage<uint8_t> Raw8;typedef RawImage<uint16_t> Raw16;
template<class type>RawImage<type> * newImage(const char * path){ typedef RawImage<type> raw; File f = SD.open(path, FILE_READ); if (!f){ return nullptr; } int32_t size = f.size(); raw * mem = (raw *)new uint8_t[size]; if (mem == nullptr){ return nullptr; } f.read(mem, size); f.close(); return mem;}
template<class type>void drawImage(const char * path, size_t x = 0, size_t y = 0){ auto img = newImage<type>(path); img->draw(x, y); img->release();}このソースコードバグってない?
newImage の中で、 raw * mem = (raw *)new uint8_t[size] とファイルサイズ分確保してそれを RawImage 型にcastしているが、 draw から呼ばれている ptr では (type *)(this + 1) を返している。 が、
f.read で mem の先頭から(ここの実装知らないけど多分)memに書いている。 new する際に sizeof(raw) + size 分確保して、 mem + 1 にreadしないといけないのでは? なんか上記のようにしたら1行は出たけどばぐっとるな。
draw の中で width と height を呼んでるけどこれが初期化されるタイミングないのか。なんか適当に以下のように修正した。
interface変わったけど……。
sizeof(raw) + size 取ってきてplacement newしてもいいか? と思ったけど、どうせ tft.pushImage にはptrの形で渡ってるなら連続領域で取ってもそんなにメリット無い気がするし、大人しく2段階に割り付ける。 どうせ他の割り込みがなければ連続領域になるのではないか?(未確認)(順序は違うだろうけど)
myRawImage.h#pragma once#include<stdint.h>#include<SD/Seeed_SD.h>
/*USAGE: // when use 8bit color. Raw8 * img8 = newImage<uint8_t>("path to sd card image.");
// when use 16bit color. Raw16 * img16 = newImage<uint16_t>("path to sd card image.");
// do some drawing. // img8->draw();
// remember release it img8->release(); img16->release(); */
extern TFT_eSPI tft;
template<class type>struct RawImage { type * ptr() { return (type *)val_; } type get(int16_t x, int16_t y) { return this->ptr()[y * width() + x]; } void draw(size_t x = 0, size_t y = 0) { tft.pushImage(x, y, width(), height(), ptr()); } void release() { delete[] val_; } int16_t width(){ return width_; } int16_t height(){ return height_; }
RawImage(uint8_t* val, int16_t width, int16_t height) : val_{val}, width_{width}, height_{height} {}private: uint8_t* val_; int16_t width_; int16_t height_;};
typedef RawImage<uint8_t> Raw8;typedef RawImage<uint16_t> Raw16;
template<class type>RawImage<type> * newImage(const char * path, int16_t width, int16_t height){ typedef RawImage<type> raw; File f = SD.open(path, FILE_READ); if (!f){ return nullptr; } int32_t size = f.size(); uint8_t* buf = new uint8_t[size]; if (!buf){ return nullptr; } f.read(buf, size); f.close();
return new raw(buf, width, height);}
template<class type>void drawImage(const char * path, size_t x = 0, size_t y = 0){ // auto img = mynewImage<type>(path, 0, 0); // FIXME //img->draw(x, y); //img->release();} bmp_converter を使うのがダルいからimagemagickでなんとかできないか? とか思って適当に変換してみてるけどバグっているが、今まではぬるぽで死んでたのと比べてそんなことはない……。 チュートリアルにあるライブラリがこんな盛大にバグってるなんてことある?
↓ で変換して出したらうまいこといっていた。
いい感じ。
bmp_converter
ms paintで保存しろ とか言っててめんどくさい……。
ようするにピクセルの色単位でつっこんでけばいいっぽいのでgoで適当に書いた。
ある程度書いたらCopilotくんがどんどん補完してくれて便利。
color.Color の RGBA() は16bitで値を返すとこだけ若干ハマった。comment RGBA returns the alpha-premultiplied red, green, blue and alpha values for the color. Each value ranges within [0, 0xffff], but is represented by a uint32 so that multiplying by a blend factor up to 0xffff will not overflow. uint32 なら32bitなのかと思うじゃん……。