GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
RL78/G13用ライブラリに対して、次版のV2.02にSoftwareSerialを入れようと考えています。FTDI USBシリアル変換モジュールを用いて4800, 9600, 57600, 115200bpsでの動作確認を行いました。ソースは以下の通りです。
GR-ADZUKIでは、USB通信用(pin0, pin1)、Wire(pin7, pin8)、モーター(pin9, pin10)でシリアルがつぶれてしまい、ESP8266やXBee等を使ったリモート制御がやりづらい状況でした。SoftwareSerialによって、これを解決したいという理由です。
なお、Arduino(AVR)ではピンチェンジ割り込みというほぼ全端子に外部割り込みが使える機能があるので、ArduinoではSoftwareSerialはほぼ全端子に使えますが、RL78/G13ではそんな機能がないため、シリアルの受信開始用に使用できるピンは外部割り込みがアサインされたpin2(INT0), pin3(INT1)だけとなります。送信はいずれのピンでも大丈夫です。
9月初旬にV-upを考えていますので、何かご意見、コメントありましたらよろしくお願いいたします。
pins_arduino.hも変更してます。
以下、サンプルです。
#include <Arduino.h>#include <SoftwareSerial.h>SoftwareSerial mySerial(2, 3); // RX, TXvoid setup() { // Open serial communications and wait for port to open: Serial.begin(115200); // set the data rate for the SoftwareSerial port mySerial.begin(115200);}void loop() { // run over and over#if 0 mySerial.println("Hello, world?"); delay(100);#else if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available()) { mySerial.write(Serial.read()); }#endif}
SoftwareSerial クラスの仕様ですが HardwareSerial クラスと同様の機能を提供すてべきと思います。較べてみると色々違いがあります。SoftwareSerial クラスを HardwareSerial の派生クラスにするのが良いかもしれません。
HardwareSerial クラスも見てみるとメンバ変数 _rx_buffer_head 等が public になってる等、わけわからんところがあるので見直すべきと思う箇所があります。
HardwareSerial::begin() で受信と送信のバッファのサイズが指定できるよういつの間にかなっており、begin() と end() の中で malloc() と free() を呼んでいますがヒープを使用しない様ならないでしょうか? GNURL78 の標準のライブラリではスタックとヒープの領域が厳密に分けられておらず、ヒープ取得のリクエストがあるとスタックとヒープの共用の領域から「ある程度の容量」をヒープとして確保し、その中から要求された容量を確保する動作となるのでメモリの容量的に無駄があります。また、頻繁にヒープの取得と解放を繰り返すとヒープ領域が増大しスタック領域とクラッシュすることゝなるので、「なんか動くけど動かんプログラム」というものができてしまう危険性もあります。RL78 等の RAM の少ないマイコンで、標準関数でヒープを使うことは避けるべきと思います。begin() や end() の中で malloc()/free() するのではなく、ユーザーが静的か動的かで確保したバッファを指定できるようにするのが無難と思います。
> SoftwareSerialですが、115200bpsでFTDIとの通信はできるものの、ESP8266はうまくいかないようです。
ビルドすると通信速度に拠ってビット当たりディレイ時間の計算をしている箇所で
In file included from gr_common/libraries/SoftwareSerial/SoftwareSerial.cpp:44:0: gr_common/libraries/SoftwareSerial/SoftwareSerial.cpp: In member function 'void SoftwareSerial::begin(long int)': ./gr_common/cores/Arduino.h:452:26: warning: integer overflow in expression [-Woverflow] #define F_CPU (32 * 1000 * 1000) ^ gr_common/libraries/SoftwareSerial/SoftwareSerial.cpp:330:25: note: in expansion of macro 'F_CPU' uint16_t bit_delay = (F_CPU / speed) / 9;
以上の警告が出ますが
#define F_CPU (32 * 1000 * 1000L)
等する必要がある気がします。
SoftwareSerial::recv() と SoftwareSerial::write(uint8) が GNURL78 のアレな部分も相まってどう見ても精度が出る訳ないコードとなっているので、インラインアセンブラでも使うべきと思います。
あと、SoftwareSerial::begin(long) の中の
// Note that this code is a _lot_ slower, mostly due to bad register // allocation choices of gcc. This works up to 57600 on 16Mhz and // 38400 on 8Mhz. _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4); _rx_delay_intrabit = subtract_cap(bit_delay - 2, 11 / 4); _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
は RL78/G13@32MHz 用に適当である気がしません。