查看: 10460|回复: 75

[教程技巧] [ 菜鸟也玩IoT ] 教你借助Win10手机制作Arduino蓝牙遥控小车

  [复制链接]

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

发表于 2016-12-3 20:55:26 | 显示全部楼层 |阅读模式

马上注册,享受积分奖励和更多功能,让您轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
先看下图:

QQ截图20161203142103.jpg

动图演示:



选择Arduino是因为这个上手比较简单,而且win10商店已经入驻了Arduino官方出品的IDE开发工具微软商店少有的Win32转制应用之一,您也可以选择用Arduino IDE for Visual Studio来编写)。已经是很入门的套件了。基本上只要你懂点C语言,再懂点初中生级别的电路基础知识就能搞定了。

虽然不是很难,但这里还是以我个人情况,来说一下本教程所涉及的知识难度:
电子元器件知识:都是中学时代自己研究积累的基础知识,很多都忘了,所以得在网易云课堂,搜索几个关于Arduino的基础视频,来顺带的回顾一下。(您也可以直接照搬我下面的电路连接图,唯一要注意的是,正负极千万别搞错!正负极千万别搞错!正负极千万别搞错!)
Arduino部分:C语言是大学时候学的(当时没兴趣全部学完,计算机等级二),基础的编程概念能懂,Arduino开发,也主要是用的C语言。
UWP客户端部分:C#只看过基础教程,没做过项目,UWP手机客户端开发相关的知识都是网上搜索得到的。


这里核心需要了解的是电子元器件知识和C语言知识,UWP开发部分你可以略过,直接用我的源代码。

电路连接图已经献上。。。。有什么问题可以在本贴回复。

IOT小车.jpg

因为是实验项目,所以下图接线看起来很糙,请莫怪。

侧视图.jpg

俯视图.jpg

底视图.jpg

地线和火线接法.jpg

四个引脚.jpg

以下是我用的mini版L298N电机驱动模块的引脚说明:(数字口和PWM模拟口可以共用一个)

逻辑真值表.jpg

相关代码已经放到了Githubhttps://github.com/wfuncom/iot-car

评分

参与人数 1 智慧币 +10 支持 +6 收起 理由
Dev.Testing.Acc + 10 + 6 必须支持

查看全部评分

WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

 楼主| 发表于 2016-12-3 20:56:17 | 显示全部楼层
本帖最后由 机机 于 2016-12-3 23:55 编辑

代码方面我已经帮你写好了,主要复制以下四段代码即可。

如果你懂编程,你可以在我的基础上继续完善,代码都不难(难点也就在C#的蓝牙连接那几句),我这代码应该属于初学者级别。

先附上Arduino上需要写入的代码:

[C] 纯文本查看 复制代码
//以下数字都是Arduino上的引脚编号,你可以看到合计有四个引脚需要在代码里面用到了,而且每个引脚可以同时设置为数字/模拟端口。
const int kong_in1 = 5; //数字端口 只有开和关 (所谓数字,你可以理解为把物理上的低电平和高电平转换为编程上的0和1两个数值,再简单点理解就是开关,只不过这里的开关在关闭状态下仍然是有电流在流入的。)
const int kong_in2 = 6; //数字端口  只有开和关
const int kong_in3 = 9; //数字端口  只有开和关
const int kong_in4 = 10; //数字端口  只有开和关
const int pwm_in1 = 5; //模拟端口  数值范围0~255(所谓模拟,可以理解为把电子元件的物理值转换为范围为编程上的0~255的数值,比如电机的转速就需要这个来控制)
const int pwm_in2 = 6; //模拟端口 
const int pwm_in3 = 9;//模拟端口
const int pwm_in4 = 10;//模拟端口

int l_speed = 0;//定义速度变量,PWM输出范围为0~255
int l_pwm_in;
int r_speed = 0;//定义速度变量,PWM输出范围为0~255
int r_pwm_in;

int gs = 0;
//先初始化,可以理解为Arduino在启动之后需要执行的代码
void setup() {
	Serial.begin(115200);  // 115200是蓝牙通信过程蓝牙接收器元件需要用到的的端口号,有的蓝牙模块可能和我这个不一样。
	pinMode(kong_in1,OUTPUT); //模拟端口默认设置为输出,这个用来控制电机速度
	pinMode(kong_in2,OUTPUT);
	digitalWrite(kong_in1, LOW); //数字端口默认设置为低电平,也就是先关闭电机
	digitalWrite(kong_in2, LOW);
	pinMode(kong_in3, OUTPUT);
	pinMode(kong_in4, OUTPUT);
	digitalWrite(kong_in3, LOW);
	digitalWrite(kong_in4, LOW);
	
}

// Arduino在运行的时候会循环的执行这里面的代码
void loop() {	
	
	while (Serial.available())
	{
		char c = Serial.read();//读取蓝牙接收到的字符串
		Serial.println(c);
		if (c == 'q') {  // 如果给蓝牙串口传一个'q'字符表示左侧轮子前进
			l_speed = 150; 			//先设定一个可以控制转速的模拟数值为150,注意这里只是编程值,不是转速也不是电压值/电流值。
			l_pwm_in = pwm_in1; 		//把这个数值传给1号模拟口
			//以下一高一低,就让左侧电机正转
			digitalWrite(kong_in1, HIGH);	 //给1号端口一个高电平
			digitalWrite(kong_in2, LOW); 	 //给2号端口一个低电平
			
			
		}

		if (c == 'a') {  // 如果给蓝牙串口传一个'a'字符表示左侧轮子后退
			l_speed = 150;				//先设定一个可以控制转速的模拟数值为150,注意这里只是编程值,不是转速也不是电压值/电流值。
			l_pwm_in = pwm_in2; 		//把这个数值传给2号模拟口
			//以下一低一高,就让左侧电机反转
			digitalWrite(kong_in1, LOW);  //给1号端口一个低电平
			digitalWrite(kong_in2, HIGH);  //给2号端口一个高电平
			

		}
		if (c == 'z') {  // 如果给蓝牙串口传一个'z'字符表示左侧轮子停止

			//以下表示电机速度为0,而去两个相同电平,表示左侧电机停转
			l_speed = 0;			
			digitalWrite(kong_in1, LOW);
			digitalWrite(kong_in2, LOW);		
			
			
		}		
		//以下解释不多,因为与上面意思差不多
		if (c == 'w') {  // 如果给蓝牙串口传一个'w'字符表示右侧轮子前进
			r_speed = 150;
			r_pwm_in = pwm_in3;
			digitalWrite(kong_in3, HIGH);
			digitalWrite(kong_in4, LOW);
			
			
		}				
		if (c == 's') { // 如果给蓝牙串口传一个's'字符表示右侧轮子后退
			r_speed = 150;
			r_pwm_in = pwm_in4;
			digitalWrite(kong_in3, LOW);
			digitalWrite(kong_in4, HIGH);
		}
		if (c == 'x') { // 如果给蓝牙串口传一个'x'字符表示右侧轮子停止
			r_speed = 0;
			digitalWrite(kong_in3, LOW);
			digitalWrite(kong_in4, LOW);
		}
		
	}
	//左侧轮子开始转动
	if (l_speed > 0) { //速度为0时开始加速
		l_speed += 10;          //因为在循环里面,所以这里表示随时间加速	
	}
	if (l_speed > 250) {     //速度达到最大值250则不要再加了,防止电机发热。
		l_speed = 250;
	}
	//右侧轮子开始转动
	if (r_speed > 0) {
		r_speed += 10;
	}
	if (r_speed > 250) {     
		r_speed = 250;
	}
	delay(100); // 循环一次停100毫秒,因为循环太快的话,加速效果看不到了。
	if (l_pwm_in) { //结合上面代码,这里用来判断是前进还是后退
		analogWrite(l_pwm_in, l_speed); // 模拟端口向左边电机输出速度值
	}
	if (r_pwm_in) { //结合上面代码,这里用来判断是前进还是后退
		analogWrite(r_pwm_in, r_speed); // 模拟端口向右边电机输出速度值
	}
}


你可能有点疑惑,为啥要用 q,w,a,s,z,x 这6个字符,注意看下图,相信你能懂:

IOT小车遥控器.jpg
3 人支持
WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。
[你知道吗]:

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

 楼主| 发表于 2016-12-3 20:56:45 | 显示全部楼层
本帖最后由 机机 于 2016-12-4 10:12 编辑

继续UWP客户端代码:


MainPage.xaml 代码:

[XML] 纯文本查看 复制代码
<Page
    x:Class="Arduino_bluetooth.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Arduino_bluetooth"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">





    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="80" />
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>



        <Button x:Name="btn_button_Click" Grid.Row="0" Grid.Column="0" Content="搜索设备" HorizontalAlignment="Center"  VerticalAlignment="Center" Click="button_Click" Width="150" Height="32" Grid.ColumnSpan="2"  />
        <Button x:Name="btn_button_close" Grid.Row="0" Content="关闭" HorizontalAlignment="Center"  VerticalAlignment="Center" Click="button_close" Height="32" Width="50" Grid.Column="3"  />
        <Button x:Name="btn_click_info" Grid.Column="4" Content="状态" HorizontalAlignment="Center"  VerticalAlignment="Center" Click="click_info" Height="32" Width="50" Background="Red" Foreground="White"  />

        <ListView x:Name="resultsListView" Grid.Row="0" Grid.Column="2" SelectionChanged="resultsListView_SelectionChanged"     Margin="0,24">
        </ListView>
	<!-- 注意我这里绑定的是Holding事件,只能触摸操作,不支持鼠标,要用鼠标,就得绑定到Click事件。-->
        <Button x:Name="btn_clickLeftTOP" Grid.Row="1" Content="左前进" HorizontalAlignment="Center"  VerticalAlignment="Center" Height="75" Width="150"  Grid.ColumnSpan="2" Holding="LeftTOP_Holding"   />
        <Button x:Name="btn_clickLeftBOTTOM" Grid.Row="2" Content="左后退" HorizontalAlignment="Center"  VerticalAlignment="Center" Height="75" Width="150"  Grid.ColumnSpan="2" Holding="LeftBOTTOM_Holding"    />
        <Button x:Name="btn_clickRightTOP" Grid.Row="1" Content="右前进" HorizontalAlignment="Center"  VerticalAlignment="Center" Height="75" Width="150"  Grid.ColumnSpan="2" Holding="RightTOP_Holding"  Grid.Column="3"    />
        <Button x:Name="btn_clickRightBOTTOM" Grid.Row="2" Content="右后退" HorizontalAlignment="Center"  VerticalAlignment="Center" Height="75" Width="150"  Grid.ColumnSpan="2" Holding="RightBOTTOM_Holding"    Grid.Column="3"   />


    </Grid>
</Page>


MainPage.cs 代码:

[C#] 纯文本查看 复制代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Rfcomm;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.System;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

//“空白页”项模板在 [url]http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409[/url] 上有介绍

namespace Arduino_bluetooth
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {

        private RfcommDeviceService service;       
        private DeviceInformationCollection services;
        private StreamSocket socket;
        private DataWriter writer;
        private DataReader reader;
        private string deviceName;

        public MainPage()
        {
            this.InitializeComponent();
            var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {           
                
            }));
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            
           bluetooth_list(); //进入APP立即搜索设备
           base.OnNavigatedTo(e);


        }
        private void button_Click(object sender, RoutedEventArgs e)
        {
            
            if (services == null || services.Count == 0)
            {
                bluetooth_list(); //先搜索设备
            }else if(service == null)
            {                
                bluetooth_connect(); //如果有搜索到设备,则连接选中的设备
            }

        }         
        /// <summary>
        /// 执行蓝牙设备搜索。
        /// </summary>
        public async void bluetooth_list()
        {
            services = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
            //获取周围所有的蓝牙串口设备
            foreach (DeviceInformation v in services)
            {
                resultsListView.Items.Add(v.Name);
                //把找到的设备名称添加到前端XAML界面的ListView里面去
            }           

            if (services == null || services.Count == 0)
            {
                bluetooth_check();
            }
            else
            {
                btn_button_Click.Content = "继续连接";
                OnConnectionEstablished(true, false); //让连接按钮可点击
                btn_click_info.Background = new SolidColorBrush(Windows.UI.Colors.Blue);
            }
            

        }

        private void resultsListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
           
            foreach(string Item in e.AddedItems)
            {
                deviceName = Item;
               
            }
        }

        /// <summary>
        /// 开始连接蓝牙串口设备
        /// </summary>
        private async void bluetooth_connect()
        {

            if (deviceName == null)
            {
                await new MessageDialog("请您先从搜索到的蓝牙设备列表选择一个设备").ShowAsync();
                return;
            }
            OnConnectionEstablished(false, false); //点击连接按钮后立即禁用连接按钮,防止误操作
            services = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort)); //这里再扫描一次设备,是确保设备没有掉线。
            if (services.Count > 0)
            {
                foreach (DeviceInformation info in services)
                {
                    if (deviceName==info.Name)
                    {                      

                        service = await RfcommDeviceService.FromIdAsync(info.Id);

                        //调试代码
                        //Debug.WriteLine(service.DeviceAccessInformation.CurrentStatus.ToString());
                        //确保设备有权访问再连接,否则会遭遇闪退!
                        if (service.DeviceAccessInformation.CurrentStatus.ToString() != null && service.DeviceAccessInformation.CurrentStatus.ToString() == "Allowed")
                        {
                            socket = new StreamSocket();
                            await socket.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName);
                            writer = new DataWriter(socket.OutputStream);
                            reader = new DataReader(socket.InputStream);

                            OnConnectionEstablished(false, true); //连接成功后继续禁用连接按钮,但开启控制按钮。
                            btn_button_Click.Content = "连接成功!";                            
                            btn_click_info.Background = new SolidColorBrush(Windows.UI.Colors.LawnGreen);
                        }
                        else
                        {
                            bluetooth_check();
                            return;
                        }
                        
                    }
                    
                }


            }
            else
            {
                bluetooth_check();
                return;
            }

        }
        /// <summary>
        /// 断开蓝牙连接
        /// </summary>
        public void bluetooth_close()
        {
            if (writer != null)
            {
                writer.DetachStream();
                writer.Dispose();
                writer = null;
            }
            if (socket != null)
            {
                socket.Dispose();
                socket = null;
            }
            if (service != null)
            {
                service.Dispose();
                service = null;
            }
            //断开后让连接按钮可点击
            OnConnectionEstablished(true, false);            
            btn_button_Click.Content = "继续连接";
            btn_click_info.Background = new SolidColorBrush(Windows.UI.Colors.Blue);
        }
        /// <summary>
        /// 连接按钮状态,因为在已经连接成功的情况下重复点击连接会出错闪退
        /// </summary>
        /// <param name="off">不可点击</param>
        /// <param name="on">可点击</param>
        private void OnConnectionEstablished(bool off, bool on)
        {
            var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {
                btn_button_Click.IsEnabled = off;
                btn_clickLeftTOP.IsEnabled = on;
                btn_clickLeftBOTTOM.IsEnabled = on;
                btn_clickRightTOP.IsEnabled = on;
                btn_clickRightBOTTOM.IsEnabled = on;
            }));
        }
        /// <summary>
        /// Win10里面的蓝牙串口长时间不交换数据会掉线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async  void click_info(object sender, RoutedEventArgs e)
        {
            await Launcher.LaunchUriAsync(new Uri("ms-settings:bluetooth"));
        }
        

        private async void bluetooth_check()
        {
            var message = new MessageDialog("搜索设备失败,请确保您的蓝牙串口设备已经开启连接");
            message.Commands.Add(new UICommand("确认"));
            message.Commands.Add(new UICommand("取消"));
            var result = await message.ShowAsync();
            if (result.Label == "确认")
            {
                await Launcher.LaunchUriAsync(new Uri("ms-settings:bluetooth"));
            }
        }


        private void button_close(object sender, RoutedEventArgs e)
        {
            bluetooth_close();
        }
        

        /// <summary>
        /// 左侧前进按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void LeftTOP_Holding(object sender, HoldingRoutedEventArgs e)        {
            
	    //注意我这里绑定的是Holding事件,只能触摸操作,不支持鼠标,要用鼠标,就得绑定到Click事件。
	    //以下代码可以实现手指长按前进,移开就停止的操作。
            //如果按钮按下,则给串口设备发送一个字符"q",左侧马达开始正转。
            if(e.HoldingState == Windows.UI.Input.HoldingState.Started){
                writer.WriteString("q");
                await writer.StoreAsync();
            }else{ //如果按钮没有按下,比如释放掉,则给串口设备发送一个字符"z",左侧马达停止转动。
                writer.WriteString("z");
                await writer.StoreAsync();
            }
            
        }
        /// <summary>
        /// 左侧后退按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void LeftBOTTOM_Holding(object sender, HoldingRoutedEventArgs e)
        {
            if (e.HoldingState == Windows.UI.Input.HoldingState.Started)
            {
                writer.WriteString("a");
                await writer.StoreAsync();
            }
            else
            {
                writer.WriteString("z");
                await writer.StoreAsync();
            }
        }
        /// <summary>
        /// 右侧前进按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void RightTOP_Holding(object sender, HoldingRoutedEventArgs e)
        {
            if (e.HoldingState == Windows.UI.Input.HoldingState.Started)
            {
                writer.WriteString("w");
                await writer.StoreAsync();
            }
            else
            {
                writer.WriteString("x");
                await writer.StoreAsync();
            }
        }
        /// <summary>
        /// 右侧后退按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void RightBOTTOM_Holding(object sender, HoldingRoutedEventArgs e)
        {
            if (e.HoldingState == Windows.UI.Input.HoldingState.Started)
            {
                writer.WriteString("s");
                await writer.StoreAsync();
            }
            else
            {
                writer.WriteString("x");
                await writer.StoreAsync();
            }
        }
        
    }
}

3 人支持
WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。
[你知道吗]:

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

 楼主| 发表于 2016-12-3 20:56:52 | 显示全部楼层
对了,别忘了给你的UWP配置好权限,否则你是不能调用手机的蓝牙接口的:

配置文件就是Package.appxmanifest
关键在下面这一段,写到</Applications>的后面

Package.appxmanifest:
[XML] 纯文本查看 复制代码
<Capabilities>
    <Capability Name="internetClient" />
    <Capability Name="internetClientServer" />
    <DeviceCapability Name="bluetooth" />
    <DeviceCapability Name="bluetooth.rfcomm">
      <Device Id="any">
        <Function Type="name:serialPort" />
      </Device>
    </DeviceCapability>
</Capabilities>
WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

 楼主| 发表于 2016-12-3 20:57:01 | 显示全部楼层
最后附上,我这整个项目用到的一些软件工具,大部分都在微软官方商店有下载:

[ IDE ]

Arduino IDE 官方UWP版(Win32转制,叼的不要不要的):
https://www.microsoft.com/zh-cn/ ... 35166)(2858066)()()

Arduino IDE For Visual Studio 插件版:
http://www.visualmicro.com/page/ ... udio-Downloads.aspx

以上二选一,我推荐后者,有代码提示。

[ C#编写 ]

然后是C#编程,这就不说了 Visual Studio 必须的:

https://www.visualstudio.com/zh-hans/

[ 蓝牙串口调试工具 ]

商店里面搜索"蓝牙串口",有很多。

比如,蓝牙串口调试助手(UWP免费试用版足够调试了):https://www.microsoft.com/zh-cn/ ... 35166)(2858066)()()
调试工具的作用,就是确保你的蓝牙模块和手机之间可以正常通信,比如用调试工具给你的蓝牙串口设备发送字符串,看看蓝牙串口设备能不能响应。

WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。
[你知道吗]:

签到天数: 99 天

连续签到: 1 天

[LV.6]常住居民II

4

主题

244

积分

0

支持

发表于 2016-12-3 21:03:02 来自手机 | 显示全部楼层
不错,我在做着用wifi控制四轴的uwp,干巴爹
来自:Surface 3 WIN10 PC版客户端

签到天数: 364 天

连续签到: 7 天

[LV.8]以坛为家I

24

主题

876

积分

6

支持

发表于 2016-12-3 21:11:17 来自手机 | 显示全部楼层
希望直接来个github链接,更易阅读

来自:Lumia 950 Win10新机-智机社区客户端
[你知道吗]:

签到天数: 373 天

连续签到: 266 天

[LV.9]以坛为家II

12

主题

771

积分

4

支持

发表于 2016-12-3 21:14:40 来自手机 | 显示全部楼层

签到天数: 18 天

连续签到: 1 天

[LV.4]偶尔看看III

267

主题

4183

积分

3395

支持

微软核心粉丝

 楼主| 发表于 2016-12-3 21:19:57 | 显示全部楼层
PHone5y 发表于 2016-12-3 21:11
希望直接来个github链接,更易阅读


代码就三个部分,github牛刀了。
https://github.com/wfuncom/iot-car
WP虽然有缺陷,但有些特性是安卓没有的,这就是差异化。
有人觉得WP够用,用起来安逸;有人觉得不够用,功能相对少。
就这么简单,够用档和贪心档 之间的战争,可能永远不会结束。
[你知道吗]:

签到天数: 585 天

连续签到: 376 天

[LV.9]以坛为家II

37

主题

855

积分

3

支持

彩虹勋章

发表于 2016-12-3 21:24:13 来自手机 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • WP10论坛

    智机社区
  • WP10软件

    应用推荐
  • APK云端转制

    APK云端转制
  • 智机网微博
    [email protected]
  • 智机网微信

    微信公众号
         

网站地图| 小黑屋|京ICP证150706号|京B2-20160045| 京公网安备11010802018258号

Powered by Discuz! X3.2 / Copyright 2010-2017 © 智机网 WFUN.COM Inc. All rights reserved.

快速回复 返回顶部 返回列表