標準入出力もどき

Netduino MiniはRS232Cで用いることのできるシリアル信号は1つしかなく、COM1のみだけが使用可能です。複数のシリアルを用いないので、staticのメソッドを用います。同様にConsoleクラスもstaticにします。また、簡易printfを用いてC言語のような表示ができるようにしてみます。「標準入出力もどき」となっていますが、今のところ出力のみです。

RS232Cクラスを作る

通信速度は115200bpsをデフォールトにしています。このクラス単独でもそれなりに使えます。

RS232C.cs
using System;
using System.Text;          // Encoding.UTF8.GetBytes(str);
using System.IO.Ports;      // Microsoft.SPOT.Hardware.SerialPort

/* Net Mini    PC
 * P6  Tx0   →
 * P7  Rx0  ←
 * COM1のみ
 */
namespace BoeBotLib
{
    public class RS232C
    {
        static SerialPort UART;

        public RS232C()
        {
            setBaud(115200);
        }
        public static void setBaud(int baud)
        {
            UART = new SerialPort("COM1", baud);
            UART.Open();
        }
        static byte[] buffer = new byte[100];
        public static void Write(String str)
        {
            buffer = Encoding.UTF8.GetBytes(str);
            UART.Write(buffer, 0, buffer.Length);
        }
        public static void WriteLine(String str)
        {
            Write(str);
            WriteLine();
        }
        public static void WriteLine(int n)
        {
            WriteLine(n.ToString());
        }
        public static void Write(int n)
        {
            Write(n.ToString());
        }
        public static void WriteLine(uint n)
        {
            WriteLine(n.ToString());
        }
        public static void Write(byte ch)
        {
            byte[] buffer = new byte[1];
            buffer[0] = ch;
            UART.Write(buffer, 0, 1);
        }
        public static void WriteLine()
        {
            Write("\r\n");
        }

        public static char Read()
        {
            int n = UART.BytesToRead;
            if (n == 0) return (char)0;
            byte[] buffer = new byte[1];
            UART.Read(buffer, 0, 1);
            return (char)buffer[0];
        }
        public static String ReadLine()
        {
            char[] ch = new char[100];
            byte[] buffer = new byte[1];
            int n = 0;
            do
            {
                UART.Read(buffer, 0, 1);
                UART.Write(buffer, 0, 1);       // エコー
                ch[n] = (char)buffer[0];
                if (buffer[0] == '\r') break;
            } while (n++ < ch.Length-1);
            buffer[0] = 10;             // 改行
            UART.Write(buffer, 0, 1);
            String str = new String(ch, 0, n);
            return str;
        }
        public static int ReadInt()
        {
            return int.Parse(ReadLine());
        }

    }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 


sprintfを作る



sprintf.cs
using System;
/*********************************************************************/
/*  C言語のprintf擬きを実現させるためのsprintf機能制限版            */
/*           引数は6個まで(拡張可能)                                 */
/*  %[n][d|D]   nカラム確保し、十進数で表示する                      */
/*  %[n][x|X]   nカラム確保し、十六進数で表示する                    */
/*  %[m.n][f|F] mカラム確保し、小数点以下n桁で実数を表示する         */
/*  %c|C        一文字表示                                           */
/*  %s|S        文字列表示                                           */
/*  &b|B        論理型表示(True, False)                              */
/*********************************************************************/

namespace BoeBotLib
{
    class Std
    {
        static object[] obInit(int n){
          object[] val = new object[n];
          for(int i=0; i<val.Length; i++) val[i]=null;
          return val;
        }
        public static String sprintf(String fmt, object val0)
        {
          object[] val = obInit(1);
          val[0]=val0;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, object v0, object v1)
        {
          object[] val = obInit(2);
          val[0]=v0; val[1]=v1;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2)
        {
          object[] val = obInit(3);
          val[0]=v0; val[1]=v1; val[2]=v2;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3)
        {
          object[] val = obInit(4);
          val[0]=v0; val[1]=v1; val[2]=v2; val[3]=v3;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3, object v4)
        {
          object[] val = obInit(5);
          val[0]=v0; val[1]=v1; val[2]=v2; val[3]=v3; val[4]=v4;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3, object v4, object v5)
        {
          object[] val = obInit(6);
          val[0]=v0; val[1]=v1; val[2]=v2;val[3]=v3;val[4]=v4;val[5]=v5;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, object[] xval)
        {
            char ch;
            int j = 0;
            char[] str = new char[80];
            char[] types = {'s','c','f','d','x','b','S','C','F','D','X','B'};
            int fmtNumber=0;
            String Value;
            int column=0, space;
            for (int i = 0; i i< fmt.Length; i++)
            {
                ch = fmt[i];
                if (ch == '%')
                {
                    int last =(i+6>fmt.Length) ? fmt.Length-i : 6; 
                    int k=100, m=0, mm=0;
                    for(mm=0; mmi<types.Length; mm++) {
                      int kk = fmt.IndexOf(types[mm], i, last);
                      if(kk!=-1 && kki<k) {k=kk;m=mm;}
                    }
                    if(k==100) k=0;
                    if(k>0) {
                      switch(types[m])
                      {
                        case 'd':
                        case 'D':
                                  column = (k - 1 - i != 0) ? 
                                    int.Parse(fmt.Substring(i + 1, k - 1 - i)) : 0;
                                  int ival = (int)xval[fmtNumber];
                                  Value=ival.ToString();
                                  if(column>0)
                                  {
                                    space = column - Value.Length;
                                    for (int mn = 0; mn i< space; mn++) str[j++] = ' ';
                                  }
                                  
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'x':
                                  bool upper = false;
                                  goto X;                  
                        case 'X':
                                  upper = true;
                               X:
                                  column = (k - 1 - i != 0) ?
                                        int.Parse(fmt.Substring(i + 1, k - 1 - i)) : 0;
                                  int hval=(int)xval[fmtNumber];
                                  Value=hval.ToString(types[m].ToString());
                                  if (!upper) Value = Value.ToLower();
                                  if(column>0)
                                  {
                                    space = column - Value.Length;
                                    for (int mn = 0; mn i< space; mn++) 
                                      str[j++] = fmt[i+1]=='0'? '0':' ';
                                  }
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'f': 
                        case 'F': // 小数点を探す
                                  int point=fmt.IndexOf(".",i,k-i+1);
                                  int low=-1;        // 小数点以下
                                  if(point>=0)
                                  { // 桁数
                                    column=int.Parse(fmt.Substring(i + 1, point - 1 - i));
                                    low = int.Parse(fmt.Substring(point + 1, k-1-point));
                                  }
                                  double dval = (double)xval[fmtNumber];
                                  Value=(lowi>=0) ? dval.ToString("f"+ low) : dval.ToString("f") ;
                                  space = column - Value.Length;
                                  for (int mn = 0; mn i< space; mn++) str[j++] = ' ';
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'c':
                        case 'C':
                                  char cx = '*';
                                  try
                                  {
                                      cx = (char)xval[fmtNumber];
                                  }
                                  catch (Exception)
                                  {
                                  }
                                  str[j++] = cx;
                                  break;
                        case 'b':
                        case 'B':
                                  bool ft = (bool)xval[fmtNumber];
                                  String fts = ft ? "True" : "False";
                                  foreach (char c in fts)
                                      str[j++] = c;
                                  break;
                        case 's':
                        case 'S': 
                                   String sval = (String)xval[fmtNumber];
                                   foreach(char c in sval)
                                       str[j++] = c;
                                   break;
                      }
                      i = k;  //書式指定の次の文字へ
                      fmtNumber++;
                    }
                }
                else str[j++] = ch;
            }
            return new String(str,0,j);
        }
    }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101
102
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 


Consoleクラスを作る

Console.WriteやConsole.WriteLineで表示できるようにする。上記のsprintfを利用すると複数の値を表示できます。

Console.cs
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using BoeBotLib;

namespace BoeBotLib
{
  public class Console
  {
    static String buffer="";
    public delegate void ShowMessage(String s);

//    static ShowMessage show = new ShowMessage(pr);
    public static ShowMessage show = new ShowMessage(rs);
    static public void pr(string s)
    {
        Debug.Print(s);
    }
    static public void rs(string s)
    {
        RS232C.WriteLine(s);
    }

    public static void Write(int x)
    {
      buffer += x.ToString();
    }
    public static void Write(byte x)
    {
      buffer += x.ToString();
    }
    public static void Write(char x)
    {
        buffer += x.ToString();
    }
    public static void Write(bool x)
    {
        buffer += x.ToString();
    }
    public static void Write(double x)
    {
        buffer += x.ToString();
    }
    public static void Write(String x)
    {
      buffer += x;
    }
    public static void WriteLine()
    {
      show(buffer);
      buffer = "";
    }
    public static void WriteLine(int x)
    {
        Write(x);
        WriteLine();
    }
    public static void WriteLine(byte x)
    {
        Write(x);
      WriteLine();
    }
    public static void WriteLine(char x)
    {
        Write(x);
        WriteLine();
    }
    public static void WriteLine(bool x)
    {
        Write(x);
        WriteLine();
    }
    public static void WriteLine(double x)
    {
        Write(x);
        WriteLine();
    }
    public static void WriteLine(String x)
    {
        Write(x);
      WriteLine();
    }
  }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 


標準出力のテストプログラム



標準出力のテストプログラム
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using BoeBotLib;

namespace stdio
{
    public class Program
    {
        public static void Main()
        {
            new RS232C();
            new Program().main();
        }
        public void main()
        {
            int x = 1234;
            bool ft = true;
            double y = 12.345;
            // rs232cで出力
            Console.WriteLine(Std.sprintf("%x %d %b %7.3f", x,1234, ft, y));
            Console.show = new Console.ShowMessage(Console.pr);
            // Debug.Printで出力
            Console.WriteLine(Std.sprintf("%x %d %b %7.3f", x, 1234, ft, y));
        }
    }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 


出力は以下のようになります。



出力結果
4d2 1234 True  12.345