スイッチサイエンスさんから素敵な暑中見舞いを頂きました(ぇ
ArduinoとHW互換で.NET Micro Frameworkを使ったMAKE:でもウワサのnetduinoの話題です。
ATMELのARM7コアのAT91SAM7X512(FLASH:512kB,RAM:128kB)を使用したボードです。(ユーザ開放FLASH:128kB,ユーザ開放RAM 60kB)今回スイッチサイエンスさんでも取り扱いが始まりましたが、ご厚意によりこの人気フィジカルコンピューティングボードをレビュワーとして1台お譲りくださいました。
かるーくレビュー。
◆きた!
小さいぞ。(メール便サイズなので高さは2cm以内)
◆全アイテム(SDはサイズ比較のため)
Micro-B USB ケーブルが同梱されています。このサイズのケーブルは手元に無かったり、入手が大変だったりするので助かります。
◆ご開帳
本丸に突入
本体、ビックリマンチョコシール、netduinoシール8月23日訂正:Microsoft Tagというもので、QRコードみたいにカメラで読み込むとnetduinoのサイトに誘導されます、ゴム足が入ってます
ゴム足あるとうっかり金属ボードの上で通電してしまって壊すことがないし便利。
◆Lチカ
http://jp.makezine.com/blog/2010/08/new_in_the_maker_shed_netduino_a_ne.html を参考にMicrosoft Visual C# 2010にて動作させ、確認できました。
◆OLEDドライブ
wiki.microframework.nlを参考にしてSPI通信プロトコルをC#で記述します。といってもMSが標準ライブラリを提供しているのでそれを使うだけです。
public static SPI SPI_Out = new SPI(new SPI.Configuration( Pins.GPIO_PIN_D9, // SS on GPIO_PIN_D9 false, // SS active-low 0, // No setup time 0, // No hold time true, // Clock high on idle <-こうしないとOLEDが初期化できない false, // Data valid on falling edge 1000, // 1Mbps clock rate SPI.SPI_module.SPI1 // SPI device 1 ) );
(注意!:clock rateに間違っても40000以上を代入しない事。暴走してnetnuinoファームウェアを再書き込みする事になります)
そして、以前にPSoCで制御したときのルーチンをC#向けに記述しなおし実装しました。
こんな感じ。次回は日本語表示にもチャレンジします。そのまえにSDカードに対応したいので、そちらが先かな。
※今回作ったコードを参考までに。ちょっと汚いのはお許しを。*.csファイルにコピペすればOK。
using System; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.Netduino; namespace NetduinoApplication1 { public class Program { public static SPI SPI_Out = new SPI(new SPI.Configuration( Pins.GPIO_PIN_D9, // SS on GPIO_PIN_D9 false, // SS active-low 0, // No setup time 0, // No hold time true, // Clock high on idle false, // Data valid on falling edge 1000, // 1Mbps clock rate SPI.SPI_module.SPI1 // SPI device 1 ) ); // Use 2 GPIO pin for "RESET","DC" pin public static OutputPort RES = new OutputPort(Pins.GPIO_PIN_D10, false); public static OutputPort DC = new OutputPort(Pins.GPIO_PIN_D8, false); public static ushort Char_Color; public static void Main() { OutputPort led = new OutputPort(Pins.ONBOARD_LED, true); OLED_Init(); Full_OLED_Screen(0); //erase OLED ChangeFontColor(0xff00); //font color ="Blue" PutChar((byte)14, (byte)6, (byte)'W'); PutChar((byte)20, (byte)6, (byte)'e'); PutChar((byte)26, (byte)6, (byte)'l'); PutChar((byte)32, (byte)6, (byte)'c'); PutChar((byte)38, (byte)6, (byte)'o'); PutChar((byte)44, (byte)6, (byte)'m'); PutChar((byte)50, (byte)6, (byte)'e'); PutChar((byte)14, (byte)20, (byte)'N'); PutChar((byte)20, (byte)20, (byte)'e'); PutChar((byte)26, (byte)20, (byte)'t'); PutChar((byte)32, (byte)20, (byte)'d'); PutChar((byte)38, (byte)20, (byte)'u'); PutChar((byte)44, (byte)20, (byte)'i'); PutChar((byte)50, (byte)20, (byte)'n'); PutChar((byte)56, (byte)20, (byte)'o'); PutChar((byte)62, (byte)20, (byte)'!'); ChangeFontColor(0xffff); //font color="White" PutChar((byte)8, (byte)40, (byte)'S'); PutChar((byte)14, (byte)40, (byte)'W'); PutChar((byte)20, (byte)40, (byte)'I'); PutChar((byte)26, (byte)40, (byte)'T'); PutChar((byte)32, (byte)40, (byte)'C'); PutChar((byte)38, (byte)40, (byte)'H'); PutChar((byte)44, (byte)40, (byte)' '); PutChar((byte)50, (byte)40, (byte)'S'); PutChar((byte)56, (byte)40, (byte)'C'); PutChar((byte)62, (byte)40, (byte)'I'); PutChar((byte)68, (byte)40, (byte)'E'); PutChar((byte)74, (byte)40, (byte)'N'); PutChar((byte)80, (byte)40, (byte)'C'); PutChar((byte)86, (byte)40, (byte)'E'); while (true) { } }//main end public static void OLED_Init() { RES.Write(false); // Reset active (Reset=0) Thread.Sleep(9); RES.Write(true); // Reset off(Reset=1) Thread.Sleep(9); OLED_RegWrite(new byte[1] {0xAE} ); //OLED display OFF //Row Address OLED_RegWrite(new byte[1]{0x75}); /* Set Row Address */ OLED_RegWrite(new byte[1]{0x00}); /* Start = 0 */ OLED_RegWrite(new byte[1]{0x3f}); /* End = 63 */ OLED_RegWrite(new byte[1]{0x15}); /* Set Column Address */ OLED_RegWrite(new byte[1]{0x00}); /* Start = 0 */ OLED_RegWrite(new byte[1]{0x5F}); /* End = 96 */ //Contrast OLED_RegWrite(new byte[1]{0xa0}); //Set remap & data format 0111 0000 OLED_RegWrite(new byte[1]{0x74}); OLED_RegWrite(new byte[1]{0xa1}); //set display star row RAM OLED_RegWrite(new byte[1]{0x00}); OLED_RegWrite(new byte[1]{0xa2}); //set dispaly offset OLED_RegWrite(new byte[1]{0x00}); OLED_RegWrite(new byte[1]{0xa4}); //Set Display Mode OLED_RegWrite(new byte[1]{0xa8}); //Set Multiplex Ratio OLED_RegWrite(new byte[1]{0x3f}); OLED_RegWrite(new byte[1]{0xad}); //Set Master Configuration OLED_RegWrite(new byte[1]{0x8f}); //(External VCC Supply Selected) OLED_RegWrite(new byte[1]{0xB0}); //Set Power Saving Mode OLED_RegWrite(new byte[1]{0x1a}); OLED_RegWrite(new byte[1]{0xB1}); //Set Phase 1 & 2 Period Adjustment OLED_RegWrite(new byte[1]{0x74}); OLED_RegWrite(new byte[1]{0xb3}); //Set Display Clock Divide Ratio / Oscillator Frequency OLED_RegWrite(new byte[1]{0xd0}); OLED_RegWrite(new byte[1]{0x8A}); //Set Second Pre-charge Speed of Color A OLED_RegWrite(new byte[1]{0x81}); OLED_RegWrite(new byte[1]{0x8B}); //Set Second Pre-charge Speed of Color B OLED_RegWrite(new byte[1]{0x82}); OLED_RegWrite(new byte[1]{0x8C}); //Set Second Pre-charge Speed of Color C OLED_RegWrite(new byte[1]{0x83}); OLED_RegWrite(new byte[1]{0xBB}); //Set Pre-charge Level OLED_RegWrite(new byte[1]{0x3e}); OLED_RegWrite(new byte[1]{0xBE}); //Set VCOMH OLED_RegWrite(new byte[1]{0x3e}); OLED_RegWrite(new byte[1]{0x87}); //Set Master Current Control OLED_RegWrite(new byte[1]{0x0f}); OLED_RegWrite(new byte[1]{0x81}); //Set Contrast Control for Color “A” OLED_RegWrite(new byte[1]{0x80}); OLED_RegWrite(new byte[1]{0x82}); //Set Contrast Control for Color “B” OLED_RegWrite(new byte[1]{0x80}); OLED_RegWrite(new byte[1]{0x83}); //Set Contrast Control for Color “C” OLED_RegWrite(new byte[1]{0x80}); OLED_RegWrite(new byte[1]{0xaf}); //display ON } public static void OLED_RegWrite(byte[] Command) { DC.Write(false); // DC=0 SPI_Out.Write(Command); } public static void OLED_DataWrite(byte[] Data) { DC.Write(true); SPI_Out.Write(Data); } public static void OLED_DataWrite_to(ushort Dat) { byte[] i = new byte[2]{(byte)((Dat >> 8) & 0xff),(byte)(Dat & 0xff)}; OLED_DataWrite(i); } //=============power function================================= // Illustration: Function // Function: Fill all oled screen,all of color,e.g.:Dot=0x0000h,black screen // Dot=0x0018h,red screen // Parameter: Dot // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port configer // More: Can refer e.g. //========================================================= public static void Full_OLED_Screen(ushort Dot) { for(byte i=0;i<64;i++) { for(byte j=0;j<96;j++) { Draw_Dot(j,i,Dot); //OLED_DataWrite_to(Dot); } } } //=============power function================================= // Illustration: Function // Function: Write a dot in screen // Parameter: x,y,Color // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= public static void Draw_Dot(byte x,byte y,ushort Color) { byte[] RegWrite = new byte[6]{0x15,x,x,0x75,y,y}; OLED_RegWrite(RegWrite); OLED_DataWrite_to(Color); OLED_DataWrite_to(Color); } public static void ChangeFontColor(ushort color) { Char_Color = color; } //=============power function================================= // Illustration: Function // Function: Input a normal character // Parameter: X:X coordinate,Y:Y coordinate,a:display a character from word stock's offset // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= public static void PutChar(byte x,byte y,byte a) { // unsigned char __f lash *p_data; byte Temp=0; //byte Index=0; byte X_Witch = 5; byte Y_Witch = 8; //Char_Color = 0xffff if(a < 32)a=32; for(byte i=0; i<X_Witch; i++) { Temp =(byte) FontLookup[a-32][i]; for(byte j=Y_Witch;j!=0;j--){ if((Temp & 0x80)==0x80){ Draw_Dot((byte) (x+i),(byte) (y+j),Char_Color); }else{ Draw_Dot((byte)(x+i),(byte)(y+j),(ushort)0); } Temp = (byte)(Temp << 1); } } } //-------------------------------------------------------------------------------------------------- // Character generator // This table defines the standard ASCII characters in a 5x7 dot format. //-------------------------------------------------------------------------------------------------- public static byte[][] FontLookup = new byte[][] { new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp new byte[]{ 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! new byte[]{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // " new byte[]{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # new byte[]{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ new byte[]{ 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // % new byte[]{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // & new byte[]{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' new byte[]{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( new byte[]{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) new byte[]{ 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * new byte[]{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + new byte[]{ 0x00, 0x00, 0x50, 0x30, 0x00 }, // , new byte[]{ 0x10, 0x10, 0x10, 0x10, 0x10 }, // - new byte[]{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // . new byte[]{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // / new byte[]{ 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 new byte[]{ 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 new byte[]{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 new byte[]{ 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 new byte[]{ 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 new byte[]{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 new byte[]{ 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 new byte[]{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 new byte[]{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 new byte[]{ 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 new byte[]{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // : new byte[]{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; new byte[]{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // < new byte[]{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // = new byte[]{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // > new byte[]{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? new byte[]{ 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ new byte[]{ 0x7E, 0x11, 0x11, 0x11, 0x7E }, // A new byte[]{ 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B new byte[]{ 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C new byte[]{ 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D new byte[]{ 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E new byte[]{ 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F new byte[]{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G new byte[]{ 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H new byte[]{ 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I new byte[]{ 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J new byte[]{ 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K new byte[]{ 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L new byte[]{ 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M new byte[]{ 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N new byte[]{ 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O new byte[]{ 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P new byte[]{ 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q new byte[]{ 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R new byte[]{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // S new byte[]{ 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T new byte[]{ 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U new byte[]{ 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V new byte[]{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W new byte[]{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // X new byte[]{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y new byte[]{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z new byte[]{ 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ new byte[]{ 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55 new byte[]{ 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] new byte[]{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ new byte[]{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ new byte[]{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' new byte[]{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // a new byte[]{ 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b new byte[]{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // c new byte[]{ 0x38, 0x44, 0x44, 0x48, 0x7F }, // d new byte[]{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // e new byte[]{ 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f new byte[]{ 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g new byte[]{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h new byte[]{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i new byte[]{ 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j new byte[]{ 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k new byte[]{ 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l new byte[]{ 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m new byte[]{ 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n new byte[]{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // o new byte[]{ 0x7C, 0x14, 0x14, 0x14, 0x08 }, // p new byte[]{ 0x08, 0x14, 0x14, 0x18, 0x7C }, // q new byte[]{ 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r new byte[]{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // s new byte[]{ 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t new byte[]{ 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u new byte[]{ 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v new byte[]{ 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w new byte[]{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // x new byte[]{ 0x0C, 0x50, 0x50, 0x50, 0x3C }, // y new byte[]{ 0x44, 0x64, 0x54, 0x4C, 0x44 } // z }; } }
次回に続く