| 
 
| 很久之前买的一个Arduino—Wifi视频车,手机App在我的手机上不能用了。我决定自己重新用MIT App Inventor2编写一个上位机。下面简单记录一下整个过程。
 
 【Wifi视频车结构】
 
 
 
  
 
 
  
 注意事项:
 1、Wifi模块占用了Arduino的TX、RX引脚,所以给Arduino下载程序时要拔下。
 2、扩展板上有个主开关,被拆并用热熔胶粘住,如松了无电。
 3、视频http地址:http://192.168.1.1:8080/?action=stream
 4、TCP控制IP地址:192.168.1.1,端口:2001
 5、Wifi路由地址:192.168.1.1,连接上Wifi模块AP热点,修改ssid为robots
 
 【扩展板】
 
  扩展板电机与Arduino引脚对应关系:
 5引脚电机1使能,6引脚电机2使能。 7引脚, 8引脚电机1接口,12引脚,13引脚电机2接口。
 【Arduino程序】
 
 通信协议:
 
 前进:FF000100FF
 后退:FF000200FF
 左转:FF000300FF
 右转:FF000400FF
 停止:FF000500FF
 
 舵机水平:FF0101(角度)FF
 舵机垂直:FF0102(角度)FF
 
 调速左轮:FF0201(速度)FF
 调速右轮:FF0202(速度)FF
 调速两轮:FF0203(速度)FF
 
 
 复制代码#include <Servo.h>
Servo servoX;
Servo servoY;
#define BAUDRATE 9600
#define ENA  5    //MOTO_A PMW
#define IN1  7
#define IN2  8
#define ENB  6    //MOTO_B PMW
#define IN3  12
#define IN4  13
void carGoFwd()
{
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW);
  //Serial.print("forward");
  delay(5);
}
void carGoBwd()
{
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH);
  //Serial.print("Backward");
  delay(5);
}
void carTurnL()
{
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH);
  //Serial.print("TurnL");
  delay(5);
}
void carTurnR()
{
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW);
  //Serial.print("TurnR");
  delay(5);
}
void carStop()
{
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,LOW);
  //Serial.print("carStop");
  delay(5);
}
//CAR SPEED
void CHNSpeed(int wheelDIR, int wheelSpeed)
{
  // Serial.print("CHNSpeed");
  int pwm = 100+wheelSpeed;
  if(wheelDIR == 0X01) //LEFT WHEEL
  {
    analogWrite(ENA,pwm);
  }
  else if(wheelDIR == 0X02) //RIGHT WHEEL
  {
    analogWrite(ENB,pwm);
  }
  else if(wheelDIR == 0X03) //RIGHT WHEEL
  {
    analogWrite(ENA,pwm);
    analogWrite(ENB,pwm);
  }
}
//SERVO TURN
void servoSet(int servoNum, int pos)
{
  //Serial.print("servoSet:");
  //Serial.println(pos);
  if(pos > 180) pos = 160;
  else if(pos < 0) pos = 0;
  switch(servoNum)
  {
    case 0X01:
    servoX.write(pos);
    //Serial.print("X:");
    //Serial.print(pos);
    break;
    case 0X02:
    servoY.write(pos);
    //Serial.print("Y:");
    //Serial.print(pos);
    break;
  }
}
#define UART_FLAG 0XFF
#define MOTO 0X00
#define SERVO 0X01
#define MOTOSPEED 0X02
#define FORWARD 0X01 //MOTO COMMAND
#define BACKWARD 0X02
#define TURNLEFT 0X03
#define TURNRIGHT 0X04
#define CARSTOP 0X05
int n = 1;
int flagCount = 0;
int tempData = 0;
int UARTReveived = 0;
int rxData[5];
void setup() {
  // put your setup code here, to run once:
  Serial.begin(BAUDRATE);//SERIAL INIT
  analogWrite(ENA,150);//INIT MOTOSPEED
  analogWrite(ENB,150);
  pinMode(IN1, OUTPUT);//DEFINE MOTO PINS MODE
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  servoX.attach(9);//定义舵机控制口
  servoY.attach(10);
  servoX.write(90);//输出舵机初始位置为90度
  servoY.write(90);//输出舵机初始位置为90度
  carGoFwd();
  delay(2000);
  carStop();
}
void loop() {
  // put your main code here, to run repeatedly:
 if(Serial.available())
  {
     tempData = Serial.read();
     //Serial.println(tempData);
    delay(3);
    if(tempData == UART_FLAG && flagCount < 2)
    {
      rxData[0] = tempData;
      flagCount++;
    }
    else
    {
      rxData[n] = tempData;
      n++;
    }
    if(flagCount == 2)
    {
      rxData[4] == UART_FLAG;
      UARTReveived = 1;
      n = 1;
      flagCount = 0;
      tempData = 0;
      Serial.flush();
    }
  }
  if(UARTReveived == 1)
  {
    if(rxData[1] == MOTO)
    {
       switch(rxData[2])
       {
         case FORWARD:
         carGoFwd();
         break;
         case BACKWARD:
         carGoBwd();
         break;
         case TURNLEFT:
         carTurnL();
         break;
         case TURNRIGHT:
         carTurnR();
         break;
         case CARSTOP:
         carStop();
         break;
       }
       UARTReveived = 0;
    }
    else if(rxData[1] == SERVO)
    {
      servoSet(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
    else if(rxData[1] == MOTOSPEED)
    {
      CHNSpeed(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
  }
    
  
}
 
 注意:Serial.print()会对串口数据接收造成干扰,慎用!
 
 
 【手机App】
 
 
  
 1、需要用到两个扩展:(1)wifi扩展——用于程序初始化时,直接连接Wifi热点。(2)TCP扩展——向Wifi模块发送指令
 
  app_invertor.zip 
 
 2、界面设计
  TCP扩展参数(右侧)
 3、逻辑设计
 
  
  xiaoR.zip 【演示视频】
 
 
 | 
 | 
|  | 
|
|  | 
|  |  |