云天 发表于 2022-1-23 22:25:24

自制手机App控制Wifi视频车


很久之前买的一个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 ENA5    //MOTO_A PMW
#define IN17
#define IN28
#define ENB6    //MOTO_B PMW
#define IN312
#define IN413
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;
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 = tempData;
      flagCount++;
    }
    else
    {
      rxData = tempData;
      n++;
    }
    if(flagCount == 2)
    {
      rxData == UART_FLAG;
      UARTReveived = 1;
      n = 1;
      flagCount = 0;
      tempData = 0;
      Serial.flush();
    }
}
if(UARTReveived == 1)
{
    if(rxData == MOTO)
    {
       switch(rxData)
       {
         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 == SERVO)
    {
      servoSet(rxData, rxData);
      UARTReveived = 0;
    }
    else if(rxData == MOTOSPEED)
    {
      CHNSpeed(rxData, rxData);
      UARTReveived = 0;
    }
}
   

}

注意:Serial.print()会对串口数据接收造成干扰,慎用!


【手机App】



1、需要用到两个扩展:(1)wifi扩展——用于程序初始化时,直接连接Wifi热点。(2)TCP扩展——向Wifi模块发送指令



2、界面设计
TCP扩展参数(右侧)
3、逻辑设计


【演示视频】
https://www.bilibili.com/video/BV1rr4y1e7Ez?share_source=copy_web

阿邱 发表于 2022-2-16 17:52:20

冒昧一问,摄像头怎么连接的?

云天 发表于 2022-2-16 21:04:52

阿邱 发表于 2022-2-16 17:52
冒昧一问,摄像头怎么连接的?

摄像头连接到WIFI模块,模块上有USB接口。

阿邱 发表于 2022-2-18 16:33:11

云天 发表于 2022-2-16 21:04
摄像头连接到WIFI模块,模块上有USB接口。

谢谢了
页: [1]
查看完整版本: 自制手机App控制Wifi视频车