TFTシールドは中々面白いデバイスなのですが、UNOに装着すると、ほぼすべての端子がTFTシールドに取られてしまい他のセンサなどもつながらないし、ゲーム(ardious.ino)を作った時には音楽演奏用のサウンド出力回路を接続するのも一苦労でした。
もうちょっと何とかしてTFTシールドを使い倒してみたいと思ったのですが、兎に角、自由に使える端子が余っておらず、UNO+TFTシールドでは限界だと判断しました。
「TFTシールド」と言う形態は悪くなくて、UNO等の機体にぴったりはまって動作できるのはGoodだと思っていました。と、言う事は、ターゲットはArduino MEGAかな?と。
Arduino MEGAは、UNOと同じAVR系のMCUで、メモリやI/Oポート数が増設されたATmega2560というMCUを搭載したマイコンボードです。
UNOの長辺側を少し引き延ばしたサイズの機体ですが、短辺側の長さは変わらず、更に、UNOのピンソケットと同じフォームファクタでピンソケットを備えています。つまり、UNO用のシールドをそのまま挿すことが出来ます。I/Oポートの割り当てはUNOと異なるので、一部プログラムの修正は必要な場合がありますが、ピンソケットの電源などの端子位置はそろっています。
UNOよりも伸びた部分には、ATmega2560で増設された分のI/Oポートが追加のピンソケットに引き出されています。その数何と、50本。
Arduino | UNO | MEGA |
AVR | ATmega328 @16MHz | ATmega2560 @16MHz |
電源・I/O | 5V | |
Flashメモリ | 32Kバイト | 256Kバイト |
RAM | 2Kバイト | 8Kバイト |
EEPROM | 1Kバイト | 4Kバイト |
PKG | 28DIP | 100TQFP |
ATmega2560はATmega328の上位機種と言う事で、メモリや端子数が増設されていることが上表からもお解りになるでしょう。I/Oユニット数も増設されていて、16ビットタイマが+3本、UARTが+3本など。TWI(I2C)、SPI、AD変換器なども、備わっています。
MCUコアがAVRと言うだけではなくて、I/OユニットもUNOと同機能の物が増設されて搭載されているので、完全に「上位コンパチブル」としての役割を果たします。
ピンアウトの仕様が異なるため、I/Oユニットのレジスタを直接叩いているプログラム等は修正が必要となりますが、Arduinoのコアライブラリを使ったプログラムは、ほぼそのまま流用が可能です。
「UNOで開発してきたけど、あと少しの所でメモリが足りない/I/Oポートが足りない」と、なった時、Arduino MEGA(ATmega2560)を使って、問題を解決できるわけです。
悪くない。
Arduino MEGAは、Arduino HPによると$40となっています。単純に$/円レートをかけても、4,000円超の価格です。互換機で良いのだけど、もう少し安くならないものか?と、Amazonで探してみました。
AmazonでArduino MEGAを検索する(別ウインドウが開きます)
この時の互換機の相場は1,400〜1,700円くらいでした。中国発送のショップや、Amazon発送のショップ、口コミなどをチェック中、ふと、違和感を覚えた商品が目に付きました。MEGAと同じフォームファクタに見えるのに、MEGAに比べて、なんとなくチップが大きく見える。価格も、ちょっと高めで2,000〜2,400円程度。
「おや?これは何?」と、商品ページを詳細に読んでみると、それはArduino DUEという機体でした。
Arduino DUEには、AVR系ではなくARM Cortex-M3のSAM3X8E @84MHzと言うMCUチップが搭載されているようです。しかも84MHzですか、これは何でもありですね。多少ヘボいコードを書いても大概のアプリケーションは動いてしまう事でしょう。
ここでちょっと、これまでに購入したマイコンボードの性能と購入価格をまとめてみました。
マイコンボード | 価格 | 性能 | 備考 |
Arduino UNO | 1,200円 | ATmega328 @16MHz |
スタータキット(1,407円)に同梱されていた。 実勢価格では1,200円程度。 |
Arduino Leonardo Micro | 1,130円 | ATmega32U4 @16MHz | USBコネクタが壊れてしまった。 |
Arduino Pro Mini | 326円 | ATmega328 @16MHz | |
STM32 | 398円 |
STM32F103C8T6 ARM Cortex-M3 @72MHz |
ほとんどの端子が5Vトレラントなため、Logiscopeを使ったデバッグ用マシンとして大活躍している。 |
Raspberry Pi ZeroW | 1,296円 | ARM11 @1GHz | 今やMathematica専用マシン。 |
ATmega328P-PU | 309円 | ATmega328 @20MHz | 328duinoを作って、25MHzにクロックアップした。 |
以下、購入を検討中の機体 | |||
Arduino MEGA | 1,700円 | ATmega2560 @16MHz | |
Arduino DUE | 2,000円 |
SAM3X8E ARM Cortex-M3 @84MHz |
性能的には破格のPi ZeroWでさえ1,296円と言うことで、ほとんどお金がかかっていないのですが、今回購入を検討しているMEGA、DUEは、ちょっとお高いですね。MCUチップその物の価格と言うより、そこそこ大きな基板を持っているせいで、単純に材料費がかさんでいるのかもしれません。
結局、電子工作には使えなかったPi ZeroWを除くと、費用対効果が一番高かったのはSTM32だったみたいです。
※ちなみに、Pi ZeroWはクソ重いOS(Linux)が乗っているせいで、遅いと感じることは多々あれど速さを実感したことは一度もありません(1−p−)。
今回、新規マイコンボードを導入しようと思い立ったモチベーションは「TFTシールドを活用するため」、なのですが、これだけの金額で購入する機体であれば、それ以外にも意味を見出したいと考えました。即ち、UNOに比べてメモリとI/Oポート数が増設されただけの上位互換ボード(MEGA)ではなく、新しいMCU、新しいI/Oユニット、を搭載したDUEを使ってみたい、と。
イタリア発のArduinoは、イタリア語のUNO(数字の"1")で始まります。一の次は二、イタリア語で数字の"2"はDUE、と言うことで、我が家にArduino DUEがやってきました(下図)。
UNOと、DCコネクタ、USBコネクタ側のフォームファクタは同じです。少し長辺側が長くなっていて、そこに追加のピンソケットが引き出されています。DUEのフォームファクタは、MEGAと同一です。TFTシールドはUNOと同様にして、DUEの上図左側寄りのピンソケットにぴったりと収まります。
ICSPピンソケットも、基板上UNOと同じ位置に引き出されていますが、DUEには「シリアルプログラミングモード」が無い為、AVRプログラマなどを繋いでも書き込みはできません。
DUEに搭載されているSAM3X8EというMCUチップのデータシートを探して、ざっと目を通してみました。
SAM3X8Eのデータシートを検索する(別ウインドウが開きます)
メモリ容量などの概要を以下表にまとめておきます。
Arduino DUE | ||
項目 | 概要 | 備考 |
MCU | Atmel ATSAM3X8E-AU | これがMCUチップの型名です。 |
CPU |
ARM Cortex-M3 @84MHz |
あまり好みではない、Thumb ARMです。 |
Flash | 512Kバイト |
メモリは潤沢にあります。 UNOに搭載されていた、不揮発メモリEEPROMはありません。 |
RAM | 96Kバイト | |
PKG | 144LQFP |
I/Oポートも沢山あります。 DUEの有効ピンソケット数は75本なので、ピンソケットに引き出されていない端子も相当数あります。 |
電源・I/O | 3.3V |
3.3V I/Oです。 絶対最大定格でVin=−0.3〜4[V]なので、5Vトレラントではありません。 5Vのレギュレータも載っているので、TFTシールドの様に5V電源を要求するシールドもそのまま使えます。 |
I/Oユニット |
USB2.0 UART×4 I2C(TWI)×2 SPI×1 Timer×9 PWM×8 ADC×12 DAC×2 等 |
目新しい所では、12ビットDA変換器を搭載しています。 AD変換器も12ビットです。 タイマは全て32ビットカウンタです。 UARTは、ハードウェアフロウ制御(RTS,CTS)が使えるようです。 I2C(TWI)も2チャンネル搭載しています。 |
UNOより一回り大きいMEGAと同じフォームファクタで、3.3V定格の機体なのでTFTシールドにはうってつけです。
I/Oユニットとしては、他にEther MACやHSMCI(SDカードI/F)などを持っています。
Arduino HPの「RESOURCES ⇒ PRODUCTS ⇒ ARDUINO DUE ⇒ DOCUMENTATION ⇒ SCHEMATIC」から、DUEの回路図もダウンロードしておきました。データシートと回路図から起こしたピン配置表を示します。
Arduinoピン# | Arduino UNO | Arduino DUE |
D0 | PD0(PCINT16/RXD0) | PA8(URXD/PWMH0/WKUP4) |
D1 | PD1(PCINT17/TXD0) | PA9(UTXD/PWMH3) |
D2 | PD2(PCINT18/INT0) | PB25(RTS0/TIOA0) |
D3 | PD3(OC2B/INT1/PCINT19) | PC28(A7/TIOA7) |
D4 | PD4(XCK0/T0/PCINT20) | PC26(A5/TIOB6)/PA29(SPI0_NPCS1/NRD) |
D5 | PD5(OC0B/T1/PCINT21) | PC25(A4/TIOA6) |
D6 | PD6(OC0A/PCINT22/AIN0) | PC24(A3/PWML7) |
D7 | PD7(PCINT23/AIN1) | PC23(A2/PWML6) |
D8 | PB0(ICP1/CLKO/PCINT0) | PC22(A1/PWML5) |
D9 | PB1(OC1A/PCINT1) | PC21(A0/NBS0/PWML4) |
D10 | PB2(SS0/OC1B/PCINT2) | PC29(A8/TIOB7)/PA28(SPI0_NPCS0/PCK2/WKUP11) |
D11 | PB3(MOSI0/OC2A/PCINT3) | PD7(A17/BA1/TIOA8) |
D12 | PB4(MISO0/PCINT4) | PD8(A21/NANDALE/TIOB8) |
D13 | PB5(PCINT5/SCK0) | PB27(NCS3/TIOB0) |
D14 | PC0(ADC0/PCINT8) | PD4(A14/TXD3) |
D15 | PC1(ADC1/PCINT9) | PD5(A15/RXD3) |
D16 | PC2(ADC2/PCINT10) | PA13(TXD1/PWMH2) |
D17 | PC3(ADC3/PCINT11) | PA12(RXD1/PWML1/WKUP7) |
D18 | PC4(ADC4/PCINT12/SDA0) | PA11(TXD0/ADTRG/WKUP6) |
D19 | PC5(ADC5/PCINT13/SCL0) | PA10(RXD0/DATRG/WKUP5) |
D20 | − | PB12(TW1_SDA/PWMH0/ADC8) |
D21 | − | PB13(TW1_SCK/PWMH1/ADC9) |
D22 | − | PB26(CTS0/TCLK0/WKUP15) |
D23 | − | PA14(RTS1/TK) |
D24 | − | PA15(CTS1/TF/WKUP8) |
D25 | − | PD0(A10/MCDA4) |
D26 | − | PD1(A11/MCDA5) |
D27 | − | PD2(A12/MCDA6) |
D28 | − | PD3(A13/MCDA7) |
D29 | − | PD6(A16/BA0/PWMFI2) |
D30 | − | PD9(A22/NANDCLE/TCLK8) |
D31 | − | PA7(TCLK2/NCS1/WKUP3) |
D32 | − | PD10(NWR1/NBS1) |
D33 | − | PC1() |
D34 | − | PC2(D0/PWML0) |
D35 | − | PC3(D1/PWMH0) |
D36 | − | PC4(D2/PWML1) |
D37 | − | PC5(D3/PWMH1) |
D38 | − | PC6(D4/PWML2) |
D39 | − | PC7(D5/PWMH2) |
D40 | − | PC8(D6/PWML3) |
D41 | − | PC9(D7/PWMH3) |
D42 | − | PA19(MCCK/PWMH1) |
D43 | − | PA20(MCCDA/PWML2) |
D44 | − | PC19(NANDOE/PWMH5) |
D45 | − | PC18(NWR0/NWE/PWMH6) |
D46 | − | PC17(D15/ETXER) |
D47 | − | PC16(D14/ETX3) |
D48 | − | PC15(D13/ETX2) |
D49 | − | PC14(D12/ERXCK) |
D50 | − | PC13(D11/ECOL) |
D51 | − | PC12(D10/ERX3) |
D52 | − | PB21(RXD2/SPI0_NPCS2/ADC14/WKUP13) |
D53 | − | PB14(CANTX1/PWMH2) |
D54 | − | PA16(SCK1/TD/ADC7) |
D55 | − | PA24(MCDA3/PCK1/ADC6) |
D56 | − | PA23(MCDA2/TCLK4/ADC5) |
D57 | − | PA22(MCDA1/TCLK3/ADC4) |
D58 | − | PA6(TIOB2/NCS0/ADC3) |
D59 | − | PA4(TCLK1/NWAIT/ADC2) |
D60 | − | PA3(TIOB1/PWMFI1/ADC1/WKUP1) |
D61 | − | PA2(TIOA1/NANDRDY/ADC0) |
D62 | − | PB17(RF/PWML1/ADC10) |
D63 | − | PB18(RD/PWML2/ADC11) |
D64 | − | PB19(RK/PWML3/ADC12) |
D65 | − | PB20(TXD2/SPI0_NPCS1/ADC13) |
D66 | − | PB15(CANRX1/PWMH3/DAC0/WKUP12) |
D67 | − | PB16(TCLK5/PWML0/DAC1) |
D68 | − | PA1(CANRX0/PCK0/WKUP0) |
D69 | − | PA0(CANTX0/PWML3) |
A0 | PC0(ADC0/PCINT8) | PA16(SCK1/TD/ADC7) |
A1 | PC1(ADC1/PCINT9) | PA24(MCDA3/PCK1/ADC6) |
A2 | PC2(ADC2/PCINT10) | PA23(MCDA2/TCLK4/ADC5) |
A3 | PC3(ADC3/PCINT11) | PA22(MCDA1/TCLK3/ADC4) |
A4 | PC4(ADC4/PCINT12/SDA0) | PA6(TIOB2/NCS0/ADC3) |
A5 | PC5(ADC5/PCINT13/SCL0) | PA4(TCLK1/NWAIT/ADC2) |
A6 | − | PA3(TIOB1/PWMFI1/ADC1/WKUP1) |
A7 | − | PA2(TIOA1/NANDRDY/ADC0) |
A8 | − | PB17(RF/PWML1/ADC10) |
A9 | − | PB18(RD/PWML2/ADC11) |
A10 | − | PB19(RK/PWML3/ADC12) |
A11 | − | PB20(TXD2/SPI0_NPCS1/ADC13) |
A12 | − | PB15(CANRX1/PWMH3/DAC0/WKUP12) |
A13 | − | PB16(TCLK5/PWML0/DAC1) |
A14 | − | PA1(CANRX0/PCK0/WKUP0) |
A15 | − | PA0(CANTX0/PWML3) |
UNO D0〜D13と同じピンソケット | ||
UNO D0の並びに追加されたピンソケット | ||
追加の2列ピンソケット | ||
UNO A0〜A5と同じピンソケット | ||
UNO A5の並びに追加されたピンソケット | ||
アナログ端子Axと兼用のデジタル端子 | ||
存在しない端子 |
表には記載しませんでしたが、AREFピンソケットの隣にある2ピンにI2C(TW0_SCL、TW0_SDA)端子、ICSPピンヘッダにSPI端子(SPI0_SCK、SPI0_MOSI、SPI0_MISO)が引き出されています(下図)。
上表の様にMCUベースで見た時のピン配置は、UNOとDUEでは大きく異なっています。良く使ってしまうのだけど、直接I/Oレジスタを叩いてI/Oユニットを制御しているアプリケーションは、流用不可です。digitalRead()関数やdigitalWrite()関数など、コアライブラリを使って作られたプログラムなら、多くの場合流用が可能です。
I/Oユニットを直接制御するのは、コアライブラリに存在しない機能を実現するためや、UNO @16MHzで色々なアプリケーションを何とかギリギリ機能させるために止むを得ない対応だったと理解しています。
だって、コアライブラリだけじゃ不足だったんだもの。
本HP的には、特定の機体用に作ったプログラムを別な機体に移植したり、より上位の機体にアップグレイドしたりすることは想定も期待もしていないので、全く問題なしです。
はっきり言って、UNOでできることをDUEにやらせる意味は全くないから。DUEには、DUEにしかできないことをやらせたいと思います。その為なら、例えDUEであってもI/Oユニットを直接叩きます。
ただ、「UNOで開発していたのだけど、パフォーマンスや処理能力が不足して、MCUをアップグレイドする」みたいな事が頻繁に起こる皆様は、要注意ですね。
UNOやSTM32の開発に使用しているArduino IDEがそのまま使えます。下図はArduino IDEの「ツールメニュー ⇒ ボード」の設定です。
現在使用中のバージョンはArduino IDE v.1.8.11です。上図に見えている「328duino」と「STM32F1 Boards」は、筆者が後でインストールした物ですが、「Arduino Due」に関してはv.1.8.11のインストール時に含まれていた物なので、DUEを使うに当たって特に作業(ボードのインストール等)は必要ありませんでした。
DUEのボードに2つの選択肢があります。どちらでもプログラムの書き込みはできるみたいですが、上図で選択した「Programming Port」の方を使うのが良い様です。DUEのボードには、2つのUSBコネクタがあります(下図)。
電源DCコネクタに近い側のUSBコネクタは、UNOと同様ボード上のATmega16U2と接続されていて、IDEの「Programming Port」からの書き込みに使用します。リセットボタンに近い方のUSBコネクタは、ボード上のSAM3X8Eと接続されていて、USBのアプリケーションとして使う時に接続します。こちらのポートからプログラムを書き込む場合には「Native USB Port」を選択します。
おさらいしておくと、UNOのボード設定ファイル(boards.txt)やコアライブラリなどは、以下の場所にありました。
<Program Files>\Arduino\hardware\arduino\avr\
ディレクトリ構造的には、<Program Files>\Arduino\hardware\arduino\sam\みたいなディレクトリがあって良いはずなのだけど、ありません。DUEのファイル群は以下の場所にあります。
<User>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12\
どういう訳か、ユーザディレクトリ<User>の下です。<User>の部分は、各自のWindowsに設定したユーザ名で異なります。WindowsのDocumentsディレクトリ(昔のMy Documents)は、<User>\Documents\にあります。<User>\AppDataディレクトリはその並び(同じ階層)にあるのですが、不可視属性が付いており、通常Explorerからは見えないのでご注意ください。
この下のlibrariesディレクトリを見てみると、HID、SPI、Wireのライブラリが確認できました。
今更Lチカと言う事も無いので、円周率の計算プログラム(calc_pi.ino)を実行させてみたいと思います。I/Oポートも何も使わず、ただただ計算だけするプログラムですので、ほとんどそのままコンパイル可能だったのですが、メモリの設定など一部変更したDUE対応版を以下にリンクしておきます。
DUE対応版プログラム:calc_pi.ino
プログラム(calc_pi.ino)の使い方についてはこちらをご参照ください。コンパイルしてDUEに書き込むと、2,000桁の円周率を計算して期待値と比較し、一致している間はLED_BUILTINを点滅させています(約1s間隔)。識別子LED_BUILTINには数値13が設定されていて、これはUNOと同じです。
先ほどArduino HPからダウンロードしてきたDUEの回路図でも、D13端子からボード上のLEDに接続されていて、UNOと同じ、D13=HIGHで点灯、D13=LOWで消灯することが解ります。UNOではD13にSPI端子が配置されていて、SPIを使うとLED_BUILTINは使用不能だったのですが、DUEのD13はPWMと汎用I/Oポートですので干渉せずに使用可能です。
しかも、PWM出力可能な端子なので、analogWrite()関数を使うとLED_BUILTINの明るさを制御することもできます。
実験サンプル:【 】内はシリアルモニタからの送信データ
【pi,1020】
OK+ start calculation
OK+ PI=3.
1415926535 8979323846 2643383279 5028841971 6939937510
:
: (中略)
:
3809525720 1065485847
OK+ digits=1020 (size=256)
OK+ time=258278[us] →→→ 約0.26s
OK+ check=0x9c6bf0fa
OK: pi F_CPU=84000000
DUEには、96KバイトのRAMがあるので、5,000桁ちょっとまで計算できるようにしてあります(↓)。
【pi,5116】
OK+ start calculation
OK+ PI=3.
1415926535 8979323846 2643383279 5028841971 6939937510
:
: (中略)
:
4037014163 149665
OK+ digits=5116 (size=1280)
OK+ time=6473106[us] →→→ 約6.5s
OK+ check=0xb222d46e
OK: pi F_CPU=84000000
Arduinoでこれ以上の桁数を計算させる意味が無いので、ここで止めてありますが、まだまだメモリには余裕があるため、もっと桁数を増やすことは可能です(定数LFP_MAX)。
UNOでの実行結果はこちら(↓)。
【pi,1020】
OK+ start calculation
OK+ PI=3.
1415926535 8979323846 2643383279 5028841971 6939937510
:
: (中略)
:
3809525720 1065485847
OK+ digits=1020 (size=256)
OK+ time=25185788[us] →→→ 約25s
OK+ check=0x9c6bf0fa
OK: pi F_CPU=16000000
クロックアップした328duino @25MHzでの実行結果はこちら(↓)。
【pi,1020】
OK+ start calculation
OK+ PI=3.
1415926535 8979323846 2643383279 5028841971 6939937510
:
: (中略)
:
3809525720 1065485847
OK+ digits=1020 (size=256)
OK+ time=16119068[us] →→→ 約16s
OK+ check=0x9c6bf0fa
OK: pi F_CPU=25000000
速い!UNO=25sに対してDUE=0.26sと、2桁近く違います。さすがはCortex-M3 @84MHz。腐っても32ビットMCUですし、1サイクルのフラッシュ乗算器や2〜12[サイクル]の除算器も持っていて、演算は高速です。
ザクとは違うのだよ!ザクとは! | 🔴 |
初期動作も問題ないようです。
Arduino IDEからの書き込み速度ですが、もう少し大きなプログラムを書き込んで時間を計測したところ、以下の様になりました。
UNO | DUE | |
コードサイズ | 11,902バイト | 51,836バイト |
書き込み時間 | 約3s | 約25s |
コードサイズで正規化 | ×1 | ×1.9 |
同じプログラムを書き込んだのですが、そもそも、コードサイズが異なります。Cortex-M3のコード効率が低いのかもしれませんが、さすがにコード効率だけで上表の差にはならないので、恐らく、コアライブラリ等のコードサイズが大きいのだと思います。
コードサイズで正規化して見ても、DUEの方がUNOより×1.9倍の時間がかかっています。その上コードサイズが大きいので、ダブルパンチで書き込み速度の遅さが際立って感じられます。
デバッグ中、思ったように動作しなかった場合、コードを変えながら、シリアルモニタへのデバッグ出力を追加しながら、コンパイル&書き込みを繰り返すことになるので、書き込み速度はボディブロウのように効いてくると思われます……(地味に痛い)。
※後日、DUEの書き込みに於いて、ベリファイ(検証)ステップを省くことで書き込み時間を短縮する記事を掲載しました。詳しくはこちらを参照してください。
以下の様なコードをsetup()関数に記述しておいて、データサイズを確認しました。
Serial.println (sizeof (char));
Serial.println (sizeof (short));
:
データ型 | サイズ | 備考 |
char | 1 | |
short | 2 | |
int | 4 | int型は32ビットです。 |
long | 4 | long型もint型と同じサイズです。 |
long long | 8 | AVRでも使えました。64ビット型です。 |
float | 4 | IEEE単精度浮動小数です。 |
double | 8 |
倍精度も使えるみたいです。 AVRではfloat型と同じでした。 |
intのサイズがUNOとは異なるので、プログラム移植の際には注意が必要です。
※K&Rご両名には敬意を表するけど、唯一、intサイズを環境(プロセッサ)依存にしてしまった仕様だけは頂けない。
ARMはだいたいLEなので確認するまでも無いですが、一応エンディアンも確認しておきます。
// endian
int tst=0x12345678;
const char *str_c;
str_c=(char *)&tst;
Serial.println (str_c[0], HEX);
Serial.println (str_c[1], HEX);
Serial.println (str_c[2], HEX);
Serial.println (str_c[3], HEX);
実行結果:
78
56
34
12
リトルエンディアン(LE)でした。
本HPで作ってきたプログラムのいくつかをDUEターゲットでコンパイルさせて、エラーや警告の出力具合を確認していた時に気付いたのですが、キャラが違います。charが。
// char
char cc;
signed char sc;
unsigned char uc;
cc=0x80;
sprintf (lbuf,"%02x>>4=%02x",cc,cc>>4);
Serial.println (lbuf);
sc=0x80;
sprintf (lbuf,"%02x>>4=%02x",sc,sc>>4);
Serial.println (lbuf);
uc=0x80;
sprintf (lbuf,"%02x>>4=%02x",uc,uc>>4);
Serial.println (lbuf);
上のコードをUNOとDUEで実行すると、以下の様になります。
データ型 | UNO | DUE |
char signed char unsigned char |
ff80>>4=fff8 ff80>>4=fff8 80>>4=08 |
80>>4=08 ffffff80>>4=fffffff8 80>>4=08 |
intサイズの違い(16⇔32)を無視すると、UNOとDUEでcharの符号付/無が異なっています。
ちなみに、WindowsのVisual Studio Community 2017で同様なコードを実行してみると、charは符号付(UNOと同じ)でした。
昔から、charも処理系に依存して符号付/無が異なることは知っていたので、プログラムを組むときは気を付けていたつもりなのですが、また微妙に引っ掛かるケースが出てくるかもしれません(イヤらしい)……。
これも、C言語プログラムの移植を妨げる火種の1つです。
コンパイル時にプリデファインされている識別子の主だったところを上げておきます。
UNOとDUE両方で動作させるプログラムにおいて、処理を分ける必要が生じた場合、上の識別子を使用します。
今回のお買い物は、以下の通りです。
「Arduino DUE」で検索していますが、「Arduino MEGA」も表示されてしまうみたいなので、ご注意ください。
時に、先程お見せしたDUEの画像(以下再掲)ですが、Arduinoのロゴ(−∞+)が付いています。互換品を発注したつもりが、届いたDUEは純正品なのでしょうか?
実はこの機体、ちょっと訳ありみたいです。
純正Arduino DUEの画像を検索する(別ウインドウが開きます)
最新の純正DUEは緑色がかった基板となっています。ピンソケットも特注の一体型が付いています。手元の基板は青色で、初期の古い基板だそうです。
回路にも少し違いが有ります。純正DUEにはリアルタイムクロック(RTC)用の32.768kHz発振子が載っていて、SAM3X8Eに搭載されたリアルタイムクロック(RTC)が使用できるのですが、今回届いた機体にはその発振子が実装されていませんでした(下図)。
どうやら、極、初期の一部機体には32.768kHz発振子が搭載されていなかった様です。
つまり手元に届いた機体は、恐らく、DUE登場当時の極初期の純正品だと思われます。ただ、現時点となってしまっては、32.768kHz発振子が付いていないことから、「純正品」を謳ってしまうと「32.768kHz発振子が載っていない」というクレームにつながってしまうため、「互換品」扱いで安く販売していたものと推定できます。
いくつか見た互換品には、32.768kHz発振子が載っていない様でした(商品写真で確認)。RTC用の発振子が付いた機体が必要な方は、ちゃんとした正規品をご購入されたし。
バッテリバックアップの付いていないRTCは使わないし、その他の機能が正常に動くなら問題なしです。
※Amazonの「置き配」で、てっきり宅配ボックスに配達されるもの、と思っていたところ、普通に郵便受けに入っていました。∵化粧箱などには入っておらず、帯電防止ビニル袋とクッション封筒で配達可能なサイズだったため。
「装着してしまうと、ほとんどの端子が埋まってしまうTFTシールドの活用」を言い訳に、かなり強力なマイコンボードを入手してしまいました。こんだけのMCUパワーが有ったら力業で何でもできてしまうし、ちょっと反則ですか?ね……(1^−^;)っ。