很久之前买的一个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
【演示视频】
|
|
|
|
|
|