Lynx-EyEDの電音鍵盤 新館

制御とか数学とか駄文とか

スイッチサイエンスさんから素敵な暑中見舞いを頂きました(ぇ

ArduinoとHW互換で.NET Micro Frameworkを使ったMAKE:でもウワサのnetduinoの話題です。
ATMELのARM7コアのAT91SAM7X512(FLASH:512kB,RAM:128kB)を使用したボードです。(ユーザ開放FLASH:128kB,ユーザ開放RAM 60kB)今回スイッチサイエンスさんでも取り扱いが始まりましたが、ご厚意によりこの人気フィジカルコンピューティングボードをレビュワーとして1台お譲りくださいました。
かるーくレビュー。
◆きた!
f:id:Lynx-EyED:20100819165141j:image
小さいぞ。(メール便サイズなので高さは2cm以内)

◆全アイテム(SDはサイズ比較のため)
Micro-B USB ケーブルが同梱されています。このサイズのケーブルは手元に無かったり、入手が大変だったりするので助かります。
f:id:Lynx-EyED:20100819165224j:image



◆ご開帳
本丸に突入
f:id:Lynx-EyED:20100819165420j:image
本体、ビックリマンチョコシール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にて動作させ、確認できました。
f:id:Lynx-EyED:20100819171348j:image




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#向けに記述しなおし実装しました。
f:id:Lynx-EyED:20100821150415j:image


こんな感じ。次回は日本語表示にもチャレンジします。そのまえに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)&#39;W&#39;);
            PutChar((byte)20, (byte)6, (byte)&#39;e&#39;);
            PutChar((byte)26, (byte)6, (byte)&#39;l&#39;);
            PutChar((byte)32, (byte)6, (byte)&#39;c&#39;);
            PutChar((byte)38, (byte)6, (byte)&#39;o&#39;);
            PutChar((byte)44, (byte)6, (byte)&#39;m&#39;);
            PutChar((byte)50, (byte)6, (byte)&#39;e&#39;);
            
            PutChar((byte)14, (byte)20, (byte)&#39;N&#39;);
            PutChar((byte)20, (byte)20, (byte)&#39;e&#39;);
            PutChar((byte)26, (byte)20, (byte)&#39;t&#39;);
            PutChar((byte)32, (byte)20, (byte)&#39;d&#39;);
            PutChar((byte)38, (byte)20, (byte)&#39;u&#39;);
            PutChar((byte)44, (byte)20, (byte)&#39;i&#39;);
            PutChar((byte)50, (byte)20, (byte)&#39;n&#39;);
            PutChar((byte)56, (byte)20, (byte)&#39;o&#39;);
            PutChar((byte)62, (byte)20, (byte)&#39;!&#39;);

            ChangeFontColor(0xffff);                    //font color="White"
            PutChar((byte)8, (byte)40, (byte)&#39;S&#39;);
            PutChar((byte)14, (byte)40, (byte)&#39;W&#39;);
            PutChar((byte)20, (byte)40, (byte)&#39;I&#39;);
            PutChar((byte)26, (byte)40, (byte)&#39;T&#39;);
            PutChar((byte)32, (byte)40, (byte)&#39;C&#39;);
            PutChar((byte)38, (byte)40, (byte)&#39;H&#39;);
            PutChar((byte)44, (byte)40, (byte)&#39; &#39;);
            PutChar((byte)50, (byte)40, (byte)&#39;S&#39;);
            PutChar((byte)56, (byte)40, (byte)&#39;C&#39;);
            PutChar((byte)62, (byte)40, (byte)&#39;I&#39;);
            PutChar((byte)68, (byte)40, (byte)&#39;E&#39;);
            PutChar((byte)74, (byte)40, (byte)&#39;N&#39;);
            PutChar((byte)80, (byte)40, (byte)&#39;C&#39;);
            PutChar((byte)86, (byte)40, (byte)&#39;E&#39;);

            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&#39;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 }, // &#39;
            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 }, // &#39;
            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
        };
        


    }
}


次回に続く