物联网:使用MRAA抽象平台I/O功能
本白皮书解释了 MRAA API 的通用用法,它可以大大简化与各种设备一起工作。
获取新的Intel®物联网开发者套件,这是一个完整的硬件和软件解决方案,使开发人员能够使用Intel® Galileo和Intel® Edison开发板创建令人兴奋的新解决方案。请访问Intel® 物联网开发者专区。
目录
- 1. 摘要
- 2. MRAA概述
- 2.1. 获取MRAA API和API文档
- 2.2. GPIO引脚名称
- 2.3. MRAA通用用法
- 2.4. MRAA包含文件
- 3. 将MRAA与模拟设备一起使用
- 3.1. 电压基准
- 3.2. 模数转换器 (ADC) 分辨率
- 3.3. 数据解读
- 3.4. 模拟示例
- 4. 将MRAA与数字设备一起使用
- 5. 将MRAA与脉冲宽度调制 (PWM) 和数字设备一起使用
- 6. 将MRAA与集成电路间通信 (I2C) 一起使用
- 6.1. I2C示例
- 7. 将MRAA与通用异步收发器 (UART) 一起使用
- 7.1. UART示例
- 8. 结束语
1. 摘要
本白皮书解释了MRAA API的通用用法,它可以极大地简化与各种类型设备的交互,例如
- 模拟输入
- 数字输入和输出
- 脉冲宽度调制 (PWM)
- 集成电路间 (I2C) 设备
- 使用通用异步收发器 (UART) 硬件的设备
本文档包含C代码片段,演示了MRAA API的核心原理,而不是完整的程序示例。为了充分利用本文档中的信息,您应该了解或掌握以下内容
- 熟悉Linux操作系统和C编程语言。
- 对数字电子和GPIO的使用有基本了解。
- 拥有要使用的设备规格表。
注意:本文档不解释代码的编译或链接,也不解释在给定平台上安装软件。
2. MRAA概述
MRAA(发音为 em-rah)是一个用C语言编写的底层库。MRAA的目的是将访问和操作平台(如Intel® Galileo或Intel® Edison开发板)的基本I/O功能所涉及的细节抽象成一个单一、简洁的API。详情请参阅下文。
- MRAA充当Linux通用输入/输出 (GPIO) 设施之上的翻译层。虽然Linux为GPIO的操作提供了一个相当丰富的框架,并且其通用的GPIO处理指令相当标准,但使用起来可能很困难。
- 根据定义,所有平台都各不相同。它们各自具有不同的功能、引脚数量和GPIO类型。例如,一个GPIO引脚在一个平台上的功能可能与在另一个平台上的不同。一个引脚甚至可能在某个特定平台上不存在。此外,GPIO在平台上的配置方式取决于各种因素。例如,在一个模式下使用GPIO引脚可能会妨碍在另一种模式下使用另一个引脚,或者完全阻止使用另一个引脚。因此,MRAA使得开发程序更加简单,因为它可与其它软件一起使用,以创建平台无关的代码。
- 注意:虽然MRAA可用于编写平台无关的代码,但开发人员仍有责任确保代码足够健壮,能够适应其可能运行的各种平台的局限性。
2.1. 获取MRAA API和API文档
MRAA包已预装在Intel Galileo和Edison硬件上,可以按照下面的说明链接到您的代码中。您也可以从Intel源代码仓库获取最新版本。
API文档可在以下网址获得:http://iotdk.intel.com/docs/master/mraa/
2.2. GPIO引脚名称
本白皮书引用了各种“引脚”。这些硬件引脚通常用数字表示。引脚编号前面也可以加上一个字符,例如“D”代表数字,“A”代表模拟。例如,“D0”表示数字引脚0,“A3”表示模拟输入引脚3。引脚也可以用类似GPIO6的名称引用,表示GPIO引脚6,而不带“D”或“A”来指代模拟或数字。
2.3. MRAA通用用法
在开始编码之前,应遵循某些准则
- MRAA库必须链接到您的软件中。通常,您必须首先用如下语句初始化MRAA:
mraa_result_t rv; rv = mraa_init(); if (rv != MRAA_SUCCESS) <report the error, insert your own code below> . . .
- 许多MRAA函数返回一个
mraa_result_t
值。确认特定函数成功执行非常重要。 - 本文档中的示例不提供错误检查。强烈建议您对所有内容进行错误检查。
- 初始化后,您应该指示MRAA您将使用特定引脚用于给定目的。本文档后续的代码示例将演示此操作。
- 完成后(即在程序退出之前),您应该指示MRAA释放引脚,以便它清理任何内部状态。本文档后续的代码示例将演示此操作。
2.4. MRAA包含文件
MRAA使用的主要包含文件是mraa.h,以及任何设备相关的包含文件,例如:
- 模拟设备将包含
#include <mraa.h>
#include <mraa/aio.h>
- 数字设备将添加
#include <mraa/gpio.h>
3. 将MRAA与模拟设备一起使用
模拟设备是指提供0到支持的最高电压范围内的数据的设备。这些数据通常被称为模拟参考电压 (AREF)。例如,一个模拟压力传感器可以提供以0(表示无压力)开始然后随压力增加而增加的电压形式的数据。然后,这些电压由称为模数转换器 (ADC) 的设备进行解释和转换成数字。控制传感器的软件然后读取ADC生成的此数字。
以下信息在解读模拟传感器数据时非常重要。这些项目将在以下子节中单独讨论。
- 电压基准 (AREF) 值
- ADC的分辨率
- 如何解读数据(取决于传感器类型)
3.1. 电压基准
电压基准通常是3.3伏或5.0伏直流。然而,参考电压可能会有所不同,因为一些平台,如Intel® Edison开发板,允许您为平台生成自定义AREF,而不是使用其自带的AREF。因此,在从这些设备获得有意义的数据之前,您需要了解此AREF。
3.2. 模数转换器 (ADC) 分辨率
ADC分辨率非常重要,因为它决定了测量的精度。Intel平台上使用的所有ADC都支持1024(10位)分辨率,至少在Intel® Edison开发板的情况下,还支持4096(12位)分辨率。
通过将AREF值除以ADC分辨率,可以确定表示的近似电压“步长”。这个数字然后由您的应用程序使用。要确定电压步长,请将5.0伏的AREF除以1024的ADC分辨率。结果是ADC返回的每个步长代表大约4毫伏。
5.0 / 1024.0 = 0.00488 伏特
3.3. 数据解读
有了以上信息,您就可以确定设备模拟输入引脚上的近似电压水平。ADC分辨率越高,电压测量就越精确。
3.4. 模拟示例
Grove湿度传感器(http://www.seeedstudio.com/depot/Grove-Moisture-Sensor-p-955.html)就是一个简单的模拟设备的例子。它本质上是一个电阻,根据检测到的湿度改变模拟输入引脚上的电压水平。下面的示例通过将其连接到A0引脚来演示传感器的工作原理。以下代码示例演示了如何初始化MRAA和A0引脚,读取并打印其值,然后释放引脚。
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA analog context */
mraa_aio_context m_aio;
/* initialize A0 for use as an analog input */
m_aio = mraa_aio_init(0);
/* read the value, an integer */
int value;
value = mraa_aio_read(m_aio);
/* print the value */
printf("The value returned was: %d\n", value);
/* now release (close) the pin and exit */
mraa_aio_close(m_aio);
return(0) ;
}
对于1024(10位)的ADC分辨率,返回值将在0-1023之间。如何解读此值取决于传感器的设计。在Grove湿度传感器示例中,假设采用10位ADC分辨率,数据手册为干燥、湿润和潮湿的属性值提供了以下范围:
- 0-300 = 干燥
- 300-700 = 湿润
- 700+ = 潮湿
重要提示:每个传感器都不同,并非所有传感器都易于解码。请注意以下事项:
- 有些传感器会“抖动”(其输出电压会波动)。如果是这种情况,可能需要进行多次采样,然后计算其平均值。
- 如果您正在为不同平台编写MRAA驱动程序,那么在代码中指定正确的AREF电压以及可能的ADC分辨率以用于任何计算非常重要。否则,返回的数据可能无法使用。在上面的示例中,我们不需要知道AREF电压,但对于其他更复杂的模拟设备则不是这样。在某些设备上,精确的AREF电压值和ADC分辨率对于确定传感器的输出是必需的。
4. 将MRAA与数字设备一起使用
数字设备是指处理低电平 (LOW) 和高电平 (HIGH) 值。LOW表示低电压电平,HIGH表示高电压电平。只能表示两种状态。例如,在5.0v系统中,LOW可能表示0伏,HIGH可能表示5.0伏。然而,通常情况下,HIGH用1表示,LOW用0表示。
数字设备可以设置为输入或输出。作为输入设备,您将使用MRAA读取数字引脚并返回一个指示电压是低电平还是高电平的值。反之,写入数字设备会导致数字引脚被驱动为低电平或高电平。
MRAA提供了一个用于读取和写入数字引脚状态的API。此外,还可以将用户提供的中断处理程序附加到数字输入。中断处理程序将在第9页讨论。要使用MRAA的数字输入和输出功能,您需要此头文件:
#include <mraa/gpio.h>
4.1. 数字输入示例
例如,以一个简单的数字输入设备为例,如按钮开关。按下开关时,引脚上会产生高电压电平,否则会产生低电压电平。
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA digital context */
mraa_ai o_context m_aio;
/* initialize D2 for use as a digital pin */
m_gpio = mraa_gpio_init(2);
/* configure the digital pin as an input */
mraa_gpio_dir(m_gpio, MRAA_GPIO_IN);
/* read the value into an integer */
int value = mraa_gpio_read(m_gpio);
/* print the value */
if (value != 0)
printf("The button is being pushed\n");
else
printf("The button is not being pushed\n");
/* now release (close) the pin and exit */
mraa_gpio_close(m_gpio);
return(0);
}
如您所见,这相当直接。同时请注意,我们是如何使用mraa_gpio_dir()
告诉MRAA将引脚配置为输入的。数字引脚可以用于输入或输出,而模拟引脚只能作为输入。
4.2. 中断处理程序
在某些情况下,您不想反复读取数字引脚来确定其状态。例如,一个连接到电机的传感器,用于计算每分钟转数 (RPM)。在这种情况下,不断重新读取引脚(设备)以持续检测变化会相当痛苦且容易出错。
MRAA提供了创建中断处理程序并将其附加到引脚的功能。在这种情况下,MRAA将确保在发生指定的引脚状态/转换(从低到高或从高到低)时调用您的中断处理程序。
有了这个功能,很容易编写一个简单的计数函数,并指示MRAA在发生指定转换时调用此函数。下面是一个简单的示例,用于计算高到低转换并将它们保存在计数器中。
/* first, create our counting variable */
volatile int counter = 0;
/* Now our simple counting function. */
/* This will be our interrupt handler. */
void intrHandler(void *arg)
{
counter++;
}
/* now in our main() function */
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA digital context */
mraa_aio_context m_aio;
/* initialize D2 for use as digital pin */
m_gpio = mraa_gpio_init(2);
/* configure the digital pin as an input */
mraa_gpio_dir(m_gpio, MRAA_GPIO_IN);
/* now, setup an interrupt handler. */
/* Our function (intrHandler()) above will */
/* be called whenever the pin goes from */
/* HIGH to LOW */
*/
mraa_gpio_isr(m_gpio, MRAA_GPIO_EDGE_FALLING, intrHandler, NULL);
/* sleep for 5 seconds, and then print out the current */
/* value of counter */
sleep(5);
printf("Counter = %d\n", counter);
/* now, stop the interrupt handler and cleanup */
mraa_gpio_isr_exit(m_gpio);
/* now release (close) the pin and exit */
mraa_gpio_close(m_gpio);
return(0);
请观察上面示例中的以下内容:
- 计数变量已声明为
volatile
关键字。这非常重要。volatile
关键字告诉C编译器该变量可能在编译器不知情的情况下被修改,因此它阻止编译器在处理该变量时进行任何优化。如果没有volatile
关键字,编译器可能会得出结论,该变量实际上无法更改,因此由于优化,最终始终会打印出'0'。在中断处理程序中操作的任何对中断处理程序外部可见的变量都应标记为volatile
。 - 除了
MRAA_GPIO_EDGE_FALLING
之外,mraa_gpio_isr()
还支持MRAA_GPIO_EDGE_RISING
(检测低到高转换)和MRAA_GPIO_EDGE_BOTH
(检测任一转换)。
注意:并非所有平台都支持上述所有转换。确定支持哪些转换的最常见方法是检查mraa_gpio_isr()
的返回值。 - 传递给
mraa_gpio_isr()
的最后一个参数是一个可选的用户提供的指针值。此参数将作为其唯一参数传递给中断处理程序intrHandler()
。我们在上面的示例中不需要此功能,因此我们只传递NULL。 - 调用
mraa_gpio_isr_exit()
将禁用中断处理程序,强烈建议这样做以进行清理并避免意外情况。 - 每个引脚最多只能有一个中断处理程序生效。同时可以通过中断处理程序驱动的总引脚数量也是平台特定的,中断的类型(
MRAA_GPIO_EDGE_RISING
或MRAA_GPIO_EDGE_FALLING
或MRAA_GPIO_EDGE_BOTH
)也是如此。这也是为什么总是要对MRAA函数的返回值进行错误检查的另一个原因。
4.3. 数字输出示例
正如您可以想象的,数字输出非常直接。下面的示例将数字引脚驱动为高电平 (1) 和低电平 (0),中间间隔1秒钟。这样的代码可以用来闪烁连接到该引脚的LED。
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA digital context */
mraa_aio_context m_aio;
/* initialize D13 for use as a digital pin */
m_gpio = mraa_gpio_init(13);
/* configure the digital pin as an output */
mraa_gpio_dir(m_gpio, MRAA_GPIO_OUT);
/* now run in a loop 10 times, blinking the output each second */
int i;
for (i=0; i<10; i++)
{
/* turn output on (HIGH) */
mraa_gpio_write(m_gpio, 1);
sleep(1);
/* turn output off (LOW) */
mraa_gpio_write(m_gpio, 0);
sleep(1);
}
/* now release (close) the pin and exit */
mraa_gpio_close(m_gpio);
return(0);
}
如您所见,使用MRAA进行数字I/O非常容易。中断处理稍微复杂一些,但只要您小心使用volatile
关键字来处理中断处理程序外部共享的变量,它就可以为许多应用程序提供简单便捷的使用。
5. 将MRAA与脉冲宽度调制 (PWM) 和数字设备一起使用
脉冲宽度调制 (PWM) 是一种数字输出。PWM引脚的输出由两个要素组成:周期和占空比。
- 周期表示应生成脉冲的频率。
- 占空比表示该周期中有多少时间处于高电平状态。
例如,如果您设置的周期为2毫秒,占空比为50%,那么您将得到一个重复的模式:1毫秒高电平,1毫秒低电平,然后周期重复。此功能可用于各种功能,例如通过增加或减小占空比来调暗LED或控制电机速度。
5.1. 通用使用规则
- MRAA提供了将数字输出配置为PWM输出的功能。检查您的平台以找出哪些GPIO可以用作PWM输出非常重要。这因平台而异。
- 平台允许的周期长度不同,因此,检查MRAA调用中的错误非常重要。
- 有些设备对可使用的周期长度有要求。例如,伺服电机通常需要20毫秒的周期。
- 使用MRAA的PWM功能所需的头文件是:
#include <mraa/pwm.h>
5.2. PWM示例
在下面的示例中,我们将脉冲化LED的亮度。我们将通过设置10毫秒的周期,每100毫秒将占空比上下改变来实现。
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA PWM context */
mraa_pwm_context m_pwm;
/* initialize D3 for use as a digital pin */
m_pwm = mraa_gpio_init(3);
/* set the period to 10ms */
mraa_pwm_period_ms(m_pwm, 10);
/* set the initial duty cycle to 0 */
mraa_pwm_write(m_pwm, 0.0);
/* enable PWM output */
mraa_pwm_enable(m_pwm, 1);
/* now run in a loop 10 times, dimming or brightening /*
/* the LED every 100ms */
int i;
float duty = 0.0;
for (i=0; i<10; i++)
{
/* first, start at 0% duty cycle and increase to 100% */
for (duty= 0.0; duty < 1.0; duty+=0.1)
{
mraa_pwm_write(m_pwm, duty);
usleep(100000);
}
sleep(1);
/* now decrease it to 0% */
for (duty= 1.0; duty > 0.0; duty-=0.1)
{
mraa_pwm_write(m_pwm, duty);
usleep(100000);
}
sleep(1);
}
/* disable PWM output and clean up */
mraa_pwm_enable(m_pwm, 0);
mraa_pwm_close(m_pwm);
return(0);
}
请观察上面示例中的以下内容:
- 我们使用了
mraa_pwm_write()
,它接受一个介于0.0(关闭,或0%占空比)和1.0(开启,或100%占空比)之间的浮点值。 - MRAA还提供了一组函数,允许您直接指定脉冲宽度,而不是按时间百分比(占空比)。这在某些传感器对周期和该周期内输出必须为高电平的时间量有特定要求时非常有用。
- MRAA提供了各种函数来设置秒、毫秒(如示例中所用)和微秒的周期。MRAA还有允许您通过一次函数调用设置周期和占空比的函数。
- 您可能会遇到的一个常见问题是您的平台是否支持设备所需的周期。如果您设置了一个底层硬件不支持的周期,MRAA将返回相应的错误代码。
6. 将MRAA与集成电路间通信 (I2C) 一起使用
使用I2C时,请牢记以下几点:
- I2C是一个2线、双向总线。它可以工作在100Khz、400Khz和3.4Mhz。
- I2C由2条信号线组成:SCL(时钟)和SDA(数据)。
- I2C设备有一个地址,该地址在给定的I2C总线上必须是唯一的。多个设备可以连接到给定的总线,但每个设备必须有自己的唯一地址,并且一次只能有一个设备进行通信。
- 除了地址之外,I2C设备通常有一组寄存器(有时称为命令),可以读写。通过对给定设备的寄存器进行读写,可以实现通信和控制。
- 使用MRAA的I2C功能所需的头文件是:
#include <mraa/i2c.h>
6.1. I2C示例
在下面的示例中,我们查询一个实时时钟I2C设备模块(DS1307)并读取秒寄存器(0x00)。我们在I2C总线0上设置了一个MRAA I2C上下文,使用I2C地址0x68,然后每秒读取并打印秒寄存器,持续10秒。
重要提示:许多I2C设备在如何读写数据到设备方面有不同的要求。请参考设备规格以获取此信息。
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA I2C context */
mraa_i2c_context m_i2c;
/* initialize I2C on bus 0 */
m_i2c = mraa_i2c_init(0);
/* now run in a loop 10 times, reading the seconds */
/* register and printing it.*/
int i;
for (i=0; i<10; i++)
{
char buf;
/* always specify the address */
mraa_i2c_address(m_i2c, 0x68);
/* read in 1 byte. mraa_i2c_read() always reads */
/* starting at register 0x00 */
mraa_i2c_read(m_i2c, &buf, 1);
printf("The seconds returned was: %d\n", buf);
sleep(1);
}
mraa_i2c_stop(m_pwm);
return(0);
}
请观察上面示例中的以下内容:
- 我们使用了
mraa_i2c_read()
,它已经从寄存器0x00开始读取。对于更高级的用法,MRAA提供了更多函数,用于在特定寄存器处读取和写入,或读取/写入字(16位)数据。使用哪种方法取决于您的设备和软件的要求。 - 读取字数据时,您可能需要根据您的设备交换返回的字节。
- 某些访问方法与某些设备配合得更好。例如,我们尝试的一个设备在使用
mraa_i2c_read()
时工作不正常,而是需要mraa_i2c_read_byte_data()
。可能需要进行一些试验。
7. 将MRAA与通用异步收发器 (UART) 一起使用
请参阅以下内容:
- 基于UART的设备基本上是标准的串行端口设备,例如过去我们用来连接电脑的COM端口设备。通常,此连接是全双工的,并且以指定的速率(波特率)运行。许多传感器的常见波特率为9600(或每秒9600位)。
- 基本上,您有两条线:TX(传输)和RX(接收)。然而,对于大多数传感器,您将使用与传统的符合RS232标准的COM端口不同的电压电平。通常这些电压是5.0v或3.3v,而RS232 COM端口通常使用-15v到+15v。除非传感器制造商明确支持,否则不要将这种低电压传感器直接连接到COM端口。您可能会损坏您的设备。
- MRAA提供了一种机制,可以将Intel® Galileo或Intel® Edison开发板上的两个数字引脚D0和D1路由到硬件辅助UART,从而使软件能够轻松地读写UART可访问设备的数据。一旦MRAA设置好了引脚的正确路由,您就可以通过/dev/ttyX端口使用标准的Linux
read()
和write()
与设备通信。
注意:MRAA仅负责设置引脚的正确路由以连接到硬件UART;您的软件需要打开并设置正确的TTY设备并开始与之通信。
- 使用MRAA的UART功能所需的头文件是:
#include <mraa/uart.h>
7.1. UART示例
在下面的示例中,我们使用了一个连接到引脚D0和D1的神话般的基于UART的传感器。MRAA中的UART是编号的,所以这将对应于UART 0。
重要的是,在打开设备后,您需要正确启用和禁用Linux内核自动应用于串行设备的各种行规。我们在打开TTY设备本身之后,包含了一个名为setupTTY()
的函数来执行此操作。
int setupTTY(int fd, speed_t baud)
{
if (fd < 0)
return 0;
struct termios termio;
/* get current modes */
tcgetattr(fd, &termio);
/* setup for a 'raw' mode. 8bit, 1 stop bit, no parity, */
/* no echo or special character handling, */
/* no flow control or line editing semantics. */
cfmakeraw(&termio);
// set our baud rates
cfsetispeed(&termio, baud);
cfsetospeed(&termio, baud);
// make it so
if (tcsetattr(fd, TCSAFLUSH, &termio) < 0)
{
fprintf(stderr, "%s\n", "tcsetattr failed");
return 0;
}
return 1;
}
/* now our main function */
¬
int main()
{
/* initialize MRAA */
mraa_init();
/* create an MRAA UART context */
mraa_uart_context m_uart;
/* initialize UART 0 (pins D0 and D1 used for TX and RX) */
m_uart = mraa_uart_init(0);
/* now that we have our context, query MRAA */
/* to get the file name of the TTY device we need to open. */
char *devPath = mraa_uart_get_dev_path(m_uart);
/* if this fails, we can go no further */
if (!devPath)
{
fprintf(stderr, "%s\n", "Could not get device path");
return 0;
}
/* now that we have a device path, open it and set it up */
int fd;
if ((fd = open(devPath, O_RDWR)) == -1)
{
fprintf(stderr, "%s\n", "Could not open device path");
return 0;
}
/* now we are almost ready, call setupTTY() and from then on */
/* we can read/write to the device normally. */
/* We assume a baud rate of 9600/ */
if (!setupTTY(fd, B9600))
{
fprintf(stderr, "%s\n", "Could not setup TTY port");
return 0;
}
/* now we can use standard read and write calls */
/* read(fd, ...) or write(fd, …) */
/* when we are done, close the device and exit */
close(fd);
return(0);
}
请观察上面示例中的以下内容:
- 使用基于UART的设备就是让MRAA正确设置引脚,请求MRAA提供设备路径,打开并初始化设备路径,然后使用标准的Unix*
read()
和write()
调用。 - 直接使用
read()
和write()
在没有可读数据时会阻塞。为了避免这种阻塞行为,在大多数情况下,您会希望创建一个函数,在尝试读取之前检查是否有数据可用。这可以使用select()
系统调用来实现。请参阅UPM wt5001驱动程序以获取示例。此功能实现为一个名为dataAvailable()
的方法。 - 在示例中,我们假设波特率为9600,这是最常见的。‘B9600’常量定义在Linux系统头文件中,当然,还有其他波特率可用。您需要根据您使用的设备选择正确的波特率。
- 示例中使用的
setupTTY()
函数假定最常见的情况。您不太可能遇到有此方面其他要求的设备,但这是需要考虑的一点。
8. 结束语
MRAA简化了访问和操作平台(如Intel® Galileo或Intel® Edison开发板)的基本I/O功能的过程。作为一个强大的库,MRAA为在这些以及类似的平台上使用模拟、数字、PWM、I2C和UART设备提供了一种一致的方法。它是任何物联网工具箱中的一项重要补充。
关于ICS
Integrated Computer Solutions (ICS) 将广泛的领域知识和工程专业知识与对驱动程序、操作系统和物联网传感器的深入理解相结合,开发定制的嵌入式系统,这些系统具有消费者期望的创新、易于使用的用户界面。ICS降低了复杂性、成本、冗余和开发时间,同时解决了棘手的工程挑战。
立即开始创新!Intel® 物联网开发者计划提供知识、工具、套件以及专家社区,助您快速轻松地将您的创新想法转化为物联网解决方案。
通过Intel® Edison和Intel® Galileo平台的Intel® 物联网开发者套件,梦想和创造。这些套件功能多样,性能优化,并且是完全集成的端到端物联网解决方案,支持各种编程环境、工具、安全、云连接和硬件。
如需更多资源并了解新的 Intel® 物联网开发者套件 v1.0 如何帮助您简化物联网项目
- 下载 Intel® 物联网开发者套件
- 访问 Intel® 物联网开发者中心
- 参加我们的 Roadshows,获取创建您自己的物联网项目的实践培训