【小MU视觉传感器评测】之履带小车跟随FT显示0317更新视频-Arduino中文社区 - Powered by Discuz!
查看: 6651|回复: 14

【小MU视觉传感器评测】之履带小车跟随FT显示0317更新视频

[复制链接]

该用户从未签到

发表于 2017-3-13 00:59 | 显示全部楼层 |阅读模式
本帖最后由 沧海笑1122 于 2017-3-18 00:09 编辑

项目名称:小MU视觉传感器之履带小车跟随网球
时间:2017-02-04~03-12

【硬件】:
1、小MU For Maker视觉传感器 (杭州摩图科技)
2、履带式小车平台(金属齿轮减速电机、航模电池)
3、主控:Genuino UNO (蓝宙电子
4、双路电机驱动板:L9110S(蓝宙电子)
5、传感器扩展板(蓝宙电子)
61.8 TFT 全彩显示屏(美科)

【软件】:
1、小MU视觉传感器解析库forarduino(杭州摩图科技)
2、小车跟随算法:参考迹APP的小车端算法(目标XY轴偏差计算双轮差速算法

【关于小MU视觉传感器】
    小MU被称为视觉传感器的arduino,这次提供评测的是小MU家族的新成员,小MU for maker。通俗地理解,就是屏蔽了视觉识别的各种底层算法和枯燥的理论,通过摄像头采集与专用MCU的集成,解析视觉识别并且利用UART\SPI\USB串口输出识别结果,将目标的X,Y坐标,W\H尺寸以及识别评分传送出来。提供给用户进行创客应用(如arduino、树莓派等)。
    摩图科技开放了报文规约,同时专为arduino编制了解析库。供开发者深度利用。该传感器还可以直接驱动4PWM舵机。但本次测试没有对舵机功能进行评测。个人认为,对于舵机这样的电磁干扰源,应当采取有效的隔离措施,而且与单片机(如arduino)提供了丰富的舵机开发库以及驱动板,因此是否将其集成至一块PCB,值得进一步商榷。
    小MU可以识别线(line)、球体(ball)以及身体(body)和人脸(face)等四种模式,在基础测试中,我将四种模式均作了基本测试,识别情况类似,这一点其他玩家作了完整的测试,本文不再赘述。

【关于本次评测】
    感谢摩图科技以及arduino.cn社区提供本次评测,作为最后一名评测者提供报告。向组织方表示歉意。有些拖延症复萌的迹象。
    本文希望尝试两个评测点:一是用TFT彩色屏显示目标识别结果,相当于给MU加上了一个屏幕,让使用者直观地观察到目标的识别以及追踪、评分情况。二是利用在迹APP-小车端算法的学习,将目标XY轴偏差计算双轮差速算法运用到小MU的小车跟随中,提供了一种新的玩法。在评测中,参考了MU4Maker师兄发布的评测报告(http://www.arduino.cn/forum.php?mod=viewthread&tid=31761&highlight=MU)。

第一步:设置小MU,刷新固件
硬件接线:小MU一共三根线:VCC(3V3)、GND以及TX(数据发送,接到genuinoRX
TYPE_BALL.png NEW_SETUP.png
设置识别目标为球体(ball)模式。

在串口监视器中观察小MU发来的数据
数据1.png
红圈标识部分就是报文头(FF FE),说明小MU数据传输正常。
在二月初我们拿到额摩图科技提供的新固件,对照说明书进行了更新,主要是在稳定性方面以及解决已知冲突方面做了优化。
球体识别.png
第二步:安装履带小车平台。
本次评测的小车使用了履带式小车平台,本身是一个擦窗机器人的拆旧配件,经某宝商家改造,增加了一块亚克力面板,便于在上面安装主控、电机驱动以及电源。
履带小车整装图02122.jpg


安装完毕后,正常就是这样的形象。
整车3.jpg

第三步:测试TFT屏的目标显示功能加小车跟随
1)加卡尔曼滤波,(2TFT显示:
    TFT显示:十字线坐标、黄色矩形框表达目标的X,Y座标以及宽度和高度。在TFT底部一条蓝色的显示棒,显示目标的识别评分结果。
本代码原型来自MU4Maker师兄发布的评测报告(http://www.arduino.cn/forum.php?mod=viewthread&tid=31761&highlight=MU)。
在此致谢!
[kenrobot_code]
/*******************************************
Adapt to visionsensor command 1.1
morpx .inc
*******************************************/

/*
* ---------------------------
* |                         |
* |    -----------          |
* |    |         |          |  
* |    |    *    |          |   
* |    |  center |          |  
* |    -----------          |
* |      object             |
* |                         |
* ---------------------------
*        Field of view
* 2017-2-12:kalman滤波,小车跟随以及TFT屏显示测试成功   
* 履带小车底盘,蓝宙电机驱动板、蓝宙传感器HUB、arduino UNO
*
L9110 motor driver controlling 2 small DC motors
原型源代码来自:http://www.electrodragon.com/w/L ... two_small_DC_motors
根据蓝宙altar电机驱动模块对应pin进行定义
关于转向:因为是差速转向,所以不再编写左右转向程序,而是用差速表达。  
卡尔曼滤波;https://raw.github.com/nut-code-monkey/KalmanFilter-for-Arduino
*/



#include "KalmanFilter.h"
//----------卡尔曼滤波部分定义
KalmanFilter kalmanFilterx;//实例化kalmanFilterx--x坐标
KalmanFilter kalmanFiltery;//实例化kalmanFiltery--y坐标
KalmanFilter kalmanFilterw;//实例化kalmanFilterw--宽度
KalmanFilter kalmanFilterh;//实例化kalmanFilterh--高度

//视觉识别模块MU部分定义
#include "VisionSensor.h"
VisionSensor MU(Serial, 115200);

//TFT 1.8寸彩屏,美科(microduino),采用Adafruit ST7735驱动库
#define sclk 13
#define mosi 12
#define cs   7
#define dc   8
#define rst  -1  // you can also connect this to the Arduino reset
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>


//----------履带小车部分,采用蓝宙电子L9110S电机驱动板
const int  AIA =   3 ; // (pwm) pin 3 connected to pin A-IA  
const int  AIB =   5 ; // (pwm) pin 5 connected to pin A-IB  
const int  BIA =   6 ;  // (pwm) pin 6 connected to pin B-IA   
const int  BIB =   9 ; // (pwm) pin 9 connected to pin B-IB  
byte  speed =   200 ; // change this (0-255) to control the speed of the motors  


#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

int objx,objy,objw,objh,objscore,objdist; //定义全局变量

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

void setup() {
   //串口监视
   Serial.begin(115200);
   //打开MU传感器,uart上送端口
   MU.begin();
   MU.search();  //开始视觉识别目标搜索

   //小车部分
   pinMode(AIA ,OUTPUT) ;  // set pins to output
   pinMode(AIB ,OUTPUT) ;
   pinMode(BIA ,OUTPUT) ;
   pinMode(BIB , OUTPUT) ;

   //卡尔曼部分定义setState
   kalmanFilterx.setState( MU.getX());
   kalmanFiltery.setState( MU.getY());
   kalmanFilterw.setState( MU.getWidth());
   kalmanFilterh.setState( MU.getHeight());

  //TFT屏绘制背景
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);//清屏
  //画十字线
  tft.drawFastHLine(0, 80, 128, ST7735_RED);
  tft.drawFastVLine(64, 0, 160, ST7735_RED);
  //画距离的标题:Dist(cm):
  tft.setCursor(5, 5);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Dist(cm):");
  
  
}

void loop() {  
   MU.search();   //搜索目标并识别
//卡尔曼滤波处理部分   
double valueX = MU.getX();
double valueY = MU.getY();
double valueW = MU.getWidth();
double valueH = MU.getHeight();

kalmanFilterx.correct(valueX);
kalmanFiltery.correct(valueY);
kalmanFilterw.correct(valueW);
kalmanFilterh.correct(valueH);

double correctedValuex = kalmanFilterx.getState();
double correctedValuey = kalmanFiltery.getState();
double correctedValuew = kalmanFilterw.getState();
double correctedValueh = kalmanFilterh.getState();
     objx=correctedValuex;
    objy=correctedValuey;
    objw=correctedValuew;
    objh=correctedValueh;
   
//Serial.print(value); Serial.print(" | "); Serial.println(correctedValue);

  if (MU.valid()>0)  
  {
    if(MU.detected() == true) //如果目标搜索正确
    {
      /*
    Serial.print("detected score is:");
    Serial.println(MU.detectScore());
    Serial.print("Object detected at:");
    Serial.print(MU.getX());     // getX() means X (horizontal) coordinate of the center of the detection rectangle //
    Serial.print(",");
    Serial.print(MU.getY());     // getY() means Y (vertical) coordinate of the center of the detection rectangle //
    Serial.print(" with wdith of:");
    Serial.print(MU.getWidth());
    Serial.print(" and height of:");
    Serial.println(MU.getHeight());
    */

    objdist=600/(objw+objh);
//这部分为测试观察,实际运行可以去除
Serial.print(MU.getX());
Serial.print(",");
Serial.println(objdist);

//Serial.print(MU.getY());
//Serial.print(",");
//Serial.println(objy);
   
    objscore=MU.detectScore();
    ////画出目标识别框、显示距离以及识别评分棒
    drawobject();
   
    //小车跟随部分控制
       //if (objw>32){
        if (objdist<6){
          goBackward(230,230); //正后
          // delay(50);   
      }
      //else if (objw<28){
        else if (objdist>8){
          goForward(230,230);  //正前
           //delay(50);   
      }

      if (objx<40){
          goForward(0,230);  //前左
          // delay(50);   
        }
      else if (objx>60){
          goForward(230,0);  //前 右
           //delay(50);   
        }

      delay(50);      
      car_stop();  
     

    }
    else
    {
    //Serial.println("No object detected");
    delay(10);
    }
  }
  else
  {
    //Serial.println("No data or too many detected");
    delay(10);
  }
  

  }

void drawobject(){
     //画十字线
  tft.drawFastHLine(0, 80, 128, ST7735_RED);
  tft.drawFastVLine(64, 0, 160, ST7735_RED);
  
   tft.drawRect(objx,objy,objw,objh, ST7735_YELLOW); //画一个黄色框
   tft.fillRect(5, 153,int(5+objscore*0.04) , 154, ST7735_BLUE);
     //计算距离,常数为30*10=300
  //int length=600/(objw+objh);
  tft.setTextSize(0);
  tft.setCursor(64, 5);
  tft.setTextColor(ST7735_WHITE);
  tft.println(objdist);//打印距离,先占位
  
   delay(10);
   tft.drawRect(objx,objy,objw,objh, ST7735_BLACK); //画一个黑框,遮盖黄框
   tft.fillRect(5, 153, int(5+objscore*0.04), 154, ST7735_BLACK);
// delay(100);
  tft.setCursor(64, 5);
  tft.setTextColor(ST7735_BLACK);
  tft.println(objdist);  
  
  
}

void  goForward(int speedA_value,int speedB_value){ //小车向前(包含正前,前左及前右)
   analogWrite(AIA , 0 ); //A电机(左)反转
   analogWrite(AIB ,  speedA_value);
   analogWrite(BIA ,  speedB_value) ; //B电机(右)正转
   analogWrite(BIB ,   0) ;
}

void goBackward(int speedA_value,int speedB_value){ //小车向后,包括正后,后左及后右
   analogWrite(AIA ,   speedA_value); //A电机(左)正转
   analogWrite(AIB ,  0 )  ;
   analogWrite(BIA ,   0)   ;  //B电机(右)反转
   analogWrite(BIB ,  speedB_value)  ;
}

void car_stop(){   //全停
   analogWrite(AIA ,   0);
   analogWrite( AIB ,  0);
   analogWrite(BIA ,  0) ;
   analogWrite(BIB ,   0) ;
}
[/kenrobot_code]

【TFT目标识别】

【小车跟随】

第四步:采用迹APP的小车端算法,实现小车跟随
(明天补充,先占位)

【评测心得】:
1、小MU作为玩具级视觉识别传感器,屏蔽枯燥的技术细节,提供给用户(maker)识别结果,供用户二次开发,使得用户将精力关注在应用上,降低了用户开发视觉识别玩具或者创客作品的门槛,是一款极具创意的传感器,在此点赞!而且通过评测,检验了其设置简单、接口便捷,使用方便的特点。
2、摩图科技的产品服务及时,固件更新响应快,本次评测是专门为arduino.cn社区开放的内测,时间紧迫,但是仍很快更新了固件,响应了测试者提出的优化需求。这一点也值得称赞。尤其是MU4Maker师兄以及@平生须臾等群里的评测技术支持各位。
3、存在的问题和初步建议:
    一是识别距离短,我的体会和诸多玩家一样,10~15厘米左右,在20厘米左右识别率就大大下降。偶尔可以识别到,但很不稳定。这样的识别距离会限制在玩具上的应用。
    建议:对镜头以及其他硬件进行改进(和技术支持讨论,镜头采用90度广角,建议优化)。我想到了去年年底热销的cozmo小机器人,它的识别距离也不是很远,但是用户体验还不错,这一点我想小MU一定可以很快改进的。
    二是关于小MU formaker版的核心硬件。提请关注国外众筹的同类的产品(for maker--Openmv目前到了第三版,核心采用了stm32f765vit62M flash。这样高的配置,再加上micropython开发环境,使得运算解析能力大幅提升。
    建议:作为一个完整的产品系列,摩图科技对于玩具级和创客级的产品是否可以细分,在for maker版上硬件配置上可以提升,与玩具消费版加以区别。目前的硬件都能做到这么棒,如果核心提升后可以将原先迁就硬件做出的妥协补回来,获取的用户体验一定不俗。
    三是关于集成舵机接口的问题,建议对for maker版本可以调查一下需求,推敲是否需要集成到PCB上。集成舵机接口是双刃剑,电磁干扰隔离和电源供电问题都要考虑,可是换取对舵机的驱动能力有限。
    建议:不如这一工作放手交给树莓派或者arduino的库以及舵机扩展板去做更专业的事。小MU关注做好一颗黑匣子般的视觉传感器就好。

【感谢】:
    感谢摩图科技这样的国产创新企业,和乐鑫的8266一样,相似的创业背景,在不同领域让我们感受到长三角迸发出的创新活力,眼前真的一亮!

    感谢arduino.cn社区提供的评测机会,感谢各位玩家给我的指点,使我在MU配置阶段少走了很多弯路,本来我想笨鸟先飞,可是笨鸟还是飞到了后面,非常汗颜!感谢孝肃兄的组织和耐心。沧海抱拳!


该用户从未签到

发表于 2017-3-13 01:05 | 显示全部楼层
这个牛!太拼了啊

该用户从未签到

 楼主| 发表于 2017-3-13 01:56 | 显示全部楼层
本帖最后由 沧海笑1122 于 2017-3-18 00:08 编辑

【03-17更新------根据迹APP小车差速原理做的MU跟随---补充视频】
因为代码注释比较详细了。各位看官可以自行观察判断。
算法的分析详见http://www.arduino.cn/thread-42542-1-1.html
由于MU的视角和识别距离限制,效果有折扣。参数部分,根据各自的MU以及小车(尤其是电机、电机之间的距离不同)进行参数调整,在此例中,我使用的
参数也并非精确调整,仅供参考。




[kenrobot_code]/*******************************************
* date:2017-03-13
* 基于MU传感器输出,采用迹APP的小车差速算法的小车跟随。

小车算法:严格按照pz_cloud师兄的建议:
      左轮速度v_left=v_run+v_turn;
      右轮速度v_right=v_run-v_turn;
把v_left,v_right乘以一个系数之后当作pwm赋值给两个电机

判断条件:
v_left<-20  正转             v_left>20 反转      除此之外(-20<v_left<20) 停止
v_right<-20 反转             v_right>20 正转     除此之外(-20<v_right<20) 停止
构造 car_go()函数

关于系数的获取,如果系数过大,造成在追踪过程中,小车发生左右摇摆,如果系数过小,则动力不足。
因此设置了一只可变电阻,获取一个可以在运行中调整的系数,经过比对,选择kc作为我这部小车(对应mu)的调速系数。
一旦手机、小车固定,就可以在运行中,去除可变电阻。将系数写入程序即可


*******************************************/

//视觉识别模块MU部分定义
#include "VisionSensor.h"
VisionSensor MU(Serial, 115200);

float sensorValue = 0;    //存储调整系数
float kc=3.8;//系数定3.8,在调试后确定
int v_left,v_right,v_run,v_turn; //左右电机以及前进、转向等四个参数
int x,y;//目标的座标

//TFT 1.8寸彩屏,美科(microduino),采用Adafruit ST7735驱动库
#define sclk 13
#define mosi 12
#define cs   7
#define dc   8
#define rst  -1  // you can also connect this to the Arduino reset
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>


//小车部分设置L9110S单机驱动板
const int  AIA =   3 ; // (pwm) pin 3 connected to pin A-IA  
const int  AIB =   5 ; // (pwm) pin 5 connected to pin A-IB  
const int  BIA =   6 ;  // (pwm) pin 6 connected to pin B-IA   
const int  BIB =   9 ; // (pwm) pin 9 connected to pin B-IB  


int objx,objy,objw,objh,objscore,objdist; //定义全局变量

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, mosi, sclk, rst);

void setup()
{
   //串口监视
   Serial.begin(115200);
   //打开MU传感器,uart上送端口
   MU.begin();
   MU.search();  //开始视觉识别目标搜索
      //小车部分
   pinMode(AIA ,OUTPUT) ;  // set pins to output
   pinMode(AIB ,OUTPUT) ;
   pinMode(BIA ,OUTPUT) ;
   pinMode(BIB , OUTPUT) ;

  //TFT屏绘制背景
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);//清屏
  //画十字线
  tft.drawFastHLine(0, 80, 128, ST7735_RED);
  tft.drawFastVLine(64, 0, 160, ST7735_RED);
  //画距离的标题:Dist(cm):
  tft.setCursor(5, 5);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Dist(cm):");
  
}

void loop()
{
   MU.search();   //搜索目标并识别
    objx=MU.getX();
    objy=MU.getY();
    objw=MU.getWidth();
    objh=MU.getHeight();
   
  follow();//调用跟随子程序
   
}


void follow(){  //跟随子程序

  if (MU.valid()>0)  
  {
     if(MU.detected() == true) //如果目标搜索正确
    {
    objx=MU.getX();
    objy=MU.getY();
    objw=MU.getWidth();
    objh=MU.getHeight();
   
     x=MU.getX();//x坐标
     y=MU.getY();//y坐标

   objscore=MU.detectScore();
    ////画出目标识别框、显示距离以及识别评分棒
    drawobject();
   
   
    v_run=y-80;//根据我的MU情况,计算y偏移差值,也就是前进后退量,此参数需要根据各自MU情况标定,下同
          v_turn=x-64;//根据我的MU情况,计算x偏移差值,也就是转向量
    v_left=  v_run+  v_turn;//合成左电机参数
          v_right= v_run-  v_turn;//合成右电机参数
   // Serial.println(v_right,v_left);//右、左,为了匹配履带电机的右A,左B
    car_go(v_right,v_left);//调用小车控制函数
              
   }
}
}
/*
float getc(){
//读取可变电阻值,作为差速系数,在确定后,此段可以注释掉
   sensorValue = analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   sensorValue += analogRead(analogInPin);
   //show on the Serial Monitor
   Serial.print("kc = ");
   Serial.println(1023/(sensorValue/8));
   return 1023/(sensorValue/8);//返回1023/平均值,则在1023~1之间

}
*/

  

//小车控制函数
void  car_go(int speedA_value,int speedB_value){ //小车的双轮控制程序
//  以俯视小车,HUB为正向,A为右电机,B为左电机
//判断B(左)电机行为
   if (speedB_value<-10)
   {
     speedB_value=constrain(int(abs(speedB_value)*kc),0,255);
     analogWrite(BIA ,   speedB_value); //B电机(左)正转
     analogWrite(BIB ,  0 )  ;
     Serial.print("speedB_value:+");
     Serial.println(speedB_value);
   }
   else
   {
     if (speedB_value>10)
         {
     analogWrite(BIA , 0 ); //B电机(左)反转
     speedB_value=constrain(int(speedB_value*kc),0,255);
     analogWrite(BIB ,  speedB_value);
     Serial.print("speedB_value:-");
     Serial.println(speedB_value);
     

         }
         else
         {//停转
           analogWrite(BIA ,  0);
     analogWrite(BIB ,  0);
         }
   }
//判断A(右)电机行为
   if (speedA_value<-10)
   {
     analogWrite(AIA , 0 ); //A电机(右)反转
     speedA_value=constrain(int(abs(speedA_value)*kc),0,255);
     analogWrite(AIB , speedA_value);
     Serial.print("speedA_value:+");
     Serial.println(speedA_value);

   }
   else
   {
     if (speedA_value>10)
         {
     speedA_value=constrain(int(speedA_value*kc),0,255);
     analogWrite(AIA ,   speedA_value); //A电机(右)正转
     analogWrite(AIB ,  0 )  ;
     Serial.print("speedA_value:-");
     Serial.println(speedA_value);


         }
         else
         {//停转
           analogWrite(AIA ,  0);
     analogWrite(AIB ,  0);            
         }
   }
}

void drawobject(){
     //画十字线
  tft.drawFastHLine(0, 80, 128, ST7735_RED);
  tft.drawFastVLine(64, 0, 160, ST7735_RED);
  
   tft.drawRect(objx,objy,objw,objh, ST7735_YELLOW); //画一个黄色框
   tft.fillRect(5, 153,int(5+objscore*0.04) , 154, ST7735_BLUE);
     //计算距离,常数为30*10=300
  //int length=600/(objw+objh);
  tft.setTextSize(0);
  tft.setCursor(64, 5);
  tft.setTextColor(ST7735_WHITE);
  tft.println(objdist);//打印距离,根据10CM距离标定,系数可根据实际情况调整
  
   delay(10);
   tft.drawRect(objx,objy,objw,objh, ST7735_BLACK); //画一个黑框,遮盖黄框
   tft.fillRect(5, 153, int(5+objscore*0.04), 154, ST7735_BLACK);
// delay(100);
  tft.setCursor(64, 5);
  tft.setTextColor(ST7735_BLACK);
  tft.println(objdist);  
  
  
}
[/kenrobot_code]




该用户从未签到

发表于 2017-3-13 08:24 | 显示全部楼层
真不错 好厉害

该用户从未签到

发表于 2017-3-13 09:26 | 显示全部楼层
好仔细啊,赞一个!

该用户从未签到

 楼主| 发表于 2017-3-13 14:41 | 显示全部楼层

感谢师兄指导!

该用户从未签到

 楼主| 发表于 2017-3-13 14:41 | 显示全部楼层
MU4Maker 发表于 2017-3-13 09:26
好仔细啊,赞一个!

感谢,参考了您的架构

该用户从未签到

发表于 2017-3-14 00:27 | 显示全部楼层
好厉害,谢谢楼主,顶一个

该用户从未签到

 楼主| 发表于 2017-3-14 00:27 | 显示全部楼层
wangshihong 发表于 2017-3-14 00:27
好厉害,谢谢楼主,顶一个

感谢支持!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

arduino 2560串口无法通信问题
arduino 2560串口无法通信
这样将2560主板和蓝牙模块连接到一起进行通信,结果arduino2560可以通过电脑给蓝牙模
求助各位大佬,proteus8软件为什么搜不到uno板子
求助各位大佬,proteus8软
求各位大佬帮忙看看,小白第一次用就出了这个,泪了
【Arduino】168种传感器系列实验(171)---HLK-V20离线语音模块
【Arduino】168种传感器系
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
esp8266网页配置wifi 及Blinker秘钥,实现远程开灯
esp8266网页配置wifi 及Bl
经过一段时间的学习借鉴,写了一段可以web配网,配Blinker秘钥的程序,借鉴很多大佬,
【Arduino】168种传感器模块系列实验(144)---0.91寸OLED液晶屏
【Arduino】168种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表