查看: 3339|回复: 4

Windows平板控制下的 MINI LFR

[复制链接]

该用户从未签到

发表于 2017-12-30 14:11 | 显示全部楼层 |阅读模式
本帖最后由 Zoologist 于 2017-12-30 14:24 编辑

继续上次的话题,我选择 C# 来实现,主要是因为语言简单,特别是在界面开发所见即所得。如果说20年前的Delphi VB Killer的话,眼下 C# 也能称得上Delphi Killer了。不由得发出风轮流转的感叹。
从界面入手,介绍功能:左右放置两个TrackBar用来控制左右轮子的速度,上方放置2个控制LEDButton(具体的做法是Button上显示图片,通过ImageList来进行切换),一个 Text输入框用来输入小车的IP,剩下的大按钮是用来控制车前灯。

image017.png
除了这些可见的控件之外,还有下面三个不可见的控件,2ImageList是给Button显示图标用的,一个 Timer是用来每隔100ms发送命令用到(发出的命令是左右轮子转动加持续100ms,这样就能做到连续运行)。同时Trackbar如果有一个数值低于30就直接停止。

image018.png
完整代码如下:

[kenrobot_code]
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Net.Sockets;

using System.IO;



namespace Tempshow

{

    public partial class Form1 : Form

    {

        // Telnet 对象

        TelnetConnection tc;

        // 前灯是否有改变的标记,如果有改变我们才发送命令给小车

        Boolean LedChanged = false;



        public Form1()

        {

            InitializeComponent();



        }



        //左车灯按钮

        private void button1_Click(object sender, EventArgs e)

        {

            // ImageIndex 为 0 表示关,1表示开

            if (this.button1.ImageIndex == 0) { this.button1.ImageIndex = 1; }

            else { this.button1.ImageIndex = 0; }

            LedChanged = true;

        }



        //右车灯按钮

        private void button2_Click(object sender, EventArgs e)

        {

            // ImageIndex 为 0 表示关,1表示开

            if (this.button2.ImageIndex == 0) { this.button2.ImageIndex = 1; }

            else { this.button2.ImageIndex = 0; }

            LedChanged = true;

        }



        //连接小车的按钮

        private void button3_Click(object sender, EventArgs e)

        {

            if (this.button3.ImageIndex == 0) {

                this.button3.ImageIndex = 1;

                this.textBox1.Enabled = true;

                timer1.Enabled = false;

                if (tc.IsConnected) {

                    tc.DisConnect();

                }

            }

            else {

                // 创建 Telnet 连接

                tc = new TelnetConnection(textBox1.Text, 23);

                string s = tc.Login(" ", " ", 100);



                // 正确连接之后

                if (tc.IsConnected) {

                    // 改变连接的图标

                    button3.ImageIndex = 0;

                    // 不可以输入 Ip

                    textBox1.Enabled = false;

                    //打开定时器

                    timer1.Enabled = true;

                }



            }

        }



        //每隔100ms发生一次的定时器

        private void timer1_Tick(object sender, EventArgs e)

        {

            string led="M6 ";

            if (LedChanged) {

                if (button1.ImageIndex==0) {

                    //发送开左灯

                    led += "0 ";

                } else

                {

                    //发送关左灯

                    led += "1 ";

                }



                if (button2.ImageIndex == 0)

                {

                    //发送开右灯

                    led += "0";

                }else

                {

                    //发送关右灯

                    led += "1";

                }

                tc.WriteLine(led);

                LedChanged = false;

            }



            if ((trackBar1.Value<30) || (trackBar2.Value <30)) {

                tc.WriteLine("M200 0 0 0");

            }

            else {

                string Motor = "M200 " + trackBar1.Value.ToString() + " "+trackBar2.Value.ToString() + " 100";

                tc.WriteLine(Motor);

            }

        }



    }



    enum Verbs

    {

        WILL = 251,

        WONT = 252,

        DO = 253,

        DONT = 254,

        IAC = 255

    }



    enum Options

    {

        SGA = 3

    }



    class TelnetConnection

    {

        TcpClient tcpSocket;



        int TimeOutMs = 1 * 1000;



        public TelnetConnection(String Hostname, int Port)

        {

            tcpSocket = new TcpClient(Hostname, Port);



        }



        public string Login(string Username, string Password, int LoginTimeOutMs)

        {

            int oldTimeOutMs = TimeOutMs;

            TimeOutMs = LoginTimeOutMs;

            // string s;

            // string s = Read();

            // if (!s.TrimEnd().EndsWith(":"))

            //     throw new Exception("Failed to connect : no login prompt");

            // WriteLine(Username);



            //s += Read();

            //if (!s.TrimEnd().EndsWith(":"))

            //    throw new Exception("Failed to connect : no password prompt");

            // WriteLine(Password);

            WriteLine("M0");

            string s = Read();

            TimeOutMs = oldTimeOutMs;



            return s;

        }



        public void DisConnect()

        {

            if (tcpSocket != null)

            {

                if (tcpSocket.Connected)

                {

                    tcpSocket.Client.Disconnect(true);

                }

            }

        }



        public void WriteLine(string cmd)

        {

            Write(cmd + "\r\n");

        }



        public void Write(string cmd)

        {

            if (!tcpSocket.Connected) return;

            byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));

            tcpSocket.GetStream().Write(buf, 0, buf.Length);

        }



        public string Read()

        {

            if (!tcpSocket.Connected) return null;

            StringBuilder sb = new StringBuilder();

            do

            {

                ParseTelnet(sb);

                System.Threading.Thread.Sleep(TimeOutMs);

            } while (tcpSocket.Available > 0);



            return ConvertToGB2312(sb.ToString());

        }



        public bool IsConnected

        {

            get { return tcpSocket.Connected; }

        }



        void ParseTelnet(StringBuilder sb)

        {

            while (tcpSocket.Available > 0)

            {

                int input = tcpSocket.GetStream().ReadByte();

                switch (input)

                {

                    case -1:

                        break;

                    case (int)Verbs.IAC:

                        // interpret as command

                        int inputverb = tcpSocket.GetStream().ReadByte();

                        if (inputverb == -1) break;

                        switch (inputverb)

                        {

                            case (int)Verbs.IAC:

                                //literal IAC = 255 escaped, so append char 255 to string

                                sb.Append(inputverb);

                                break;

                            case (int)Verbs.DO:

                            case (int)Verbs.DONT:

                            case (int)Verbs.WILL:

                            case (int)Verbs.WONT:

                                // reply to all commands with "WONT", unless it is SGA (suppres go ahead)

                                int inputoption = tcpSocket.GetStream().ReadByte();

                                if (inputoption == -1) break;

                                tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);

                                if (inputoption == (int)Options.SGA)

                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);

                                else

                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);

                                tcpSocket.GetStream().WriteByte((byte)inputoption);

                                break;

                            default:

                                break;

                        }

                        break;

                    default:

                        sb.Append((char)input);

                        break;

                }

            }

        }



        private string ConvertToGB2312(string str_origin)

        {

            char[] chars = str_origin.ToCharArray();

            byte[] bytes = new byte[chars.Length];

            for (int i = 0; i < chars.Length; i++)

            {

                int c = (int)chars;

                bytes
= (byte)c;

            }

            Encoding Encoding_GB2312 = Encoding.GetEncoding("GB2312");

            string str_converted = Encoding_GB2312.GetString(bytes);

            return str_converted;

        }

    }



}[/kenrobot_code]
Windows平板和普通的PC 笔记本没有差别,只是更轻薄

IMG_20171230_135523.jpg


工作的视频

该用户从未签到

 楼主| 发表于 2017-12-30 14:25 | 显示全部楼层

工作的测试视频

本帖最后由 Zoologist 于 2017-12-30 14:26 编辑

工作的测试视频
[]
  • TA的每日心情
    开心
    2018-6-6 20:38
  • 签到天数: 104 天

    [LV.6]常住居民II

    发表于 2017-12-30 14:44 | 显示全部楼层
    视频没看到啊
    C# 也能称得上Delphi Killer了。此话怎讲?

    该用户从未签到

     楼主| 发表于 2017-12-30 15:39 | 显示全部楼层
    sanhuasr 发表于 2017-12-30 14:44
    视频没看到啊
    C# 也能称得上Delphi Killer了。此话怎讲?

    支持平台多,免费,IDE功能强大

    视频的话,我发在知乎了

    https://zhuanlan.zhihu.com/p/32486714?group_id=930444603190968320

    虽然我已经在中文社区发过很多帖子,但是目前还是没搞明白如何发视频
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    [限时福利]5分钟带你快速了解新一代开发板:M5STACK
    [限时福利]5分钟带你快速
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    天猫精灵接入语音提示找不到该设备?
    天猫精灵接入语音提示找不
    今天又刷了一遍代码,天猫精灵提示 没有找到你要操作的设备! 怎么回事啊??? 折腾
    引入库的问题,不知道怎么叙述 看图吧
    引入库的问题,不知道怎么
    最左边的是主文件 也就是启动的文件 后边三个是引入的 在后边这个文件再引入库就报错
    blinker电源插座
    blinker电源插座
    这台blinker电源插座有blinker控制和手动控制两种工作方式. 1.blinker控制:滑条用于设
    blinker灯、环境传感器套件意见收集
    blinker灯、环境传感器套
    计划春节后推出blinker氛围灯和环境检测套件。 本帖收集相关建议,如若采纳,发红包(
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表