之前就尝试过其他云平台做远程遥控小车,但是某APP 界面无法自定义设计,操作方式无法模拟遥控车按键方式。这次发现使用blinker后,按键界面可以随意拖动位置,并且可以添加很多设备,不用给8266刷固件,使用非常方便。随后制作了远程遥控的水弹车。图传是用了某品牌的网络监控摄像头和APP,所以遥控时需要一个设备观看视频,一个设备遥控。小车增加了车灯,温湿度传感器,摄像头,水弹加激光指示。
以下是视频,视频中的左右扫射动作操作并没有那么容易,因为使用了滑块操作的方式。所以我修改代码只是为了拍摄,后面代码中并没有使用。
B站 【远程遥控战车】
下面这是测试遥控小车时使用的两轮小车
B站 在办公室远程遥控小车
[media=x,500,375] https://www.bilibili.com/video/BV13g4y1a7Z2[/media]
材料使用了4轮小车架,wifiduino+L298+传感器扩展板,4节18650电池,2组并联输出8.4V电压,再接电量显示板。供板子以及水弹供电,上供弹的水弹接继电器,再加一个红点激光头。摄像头使用了小蚁的家用摄像头。三个舵机,一个控制摄像头左右旋转,2个分别控制水弹的左右和上下瞄准,开火方式有点射和扫射,温湿度传感器是家里多一个,看还有接口就接上了。
以下是代码,新手搞的很烂,如有不足请指出。
//4.1增加水弹上下左右
[mw_shl_code=arduino,true]#define BLINKER_PRINT Serial
#define BLINKER_WIFI
#include <Blinker.h>
#include <DHT.h>
#include <Servo.h>
char auth[] = " 识别码 ";
char ssid[] = "shrub";
char pswd[] = "wifi密码 ";
//定义舵机
Servo myservo1;
Servo myservo2;
Servo myservo3;
//视频舵机
#define SERVER1 D3
//定义电机控制端口
#define INA D4 //电机A正反转控制端
#define PWMA D5 //电机A调速端
#define INB D7 //电机B正反转控制端
#define PWMB D6 //电机B调速端
//定义GUN端口
#define GUN D8
//温湿度传感器 使用dht11
#define DHTPIN D9
#define DHTTYPE DHT11
//定义LED端口
#define LED D10
//水弹枪舵机
#define SERVER2 D13
#define SERVER3 D12
#define BUTTON_1 "btn-cargo"
#define BUTTON_2 "btn-carback"
#define BUTTON_3 "btn-carleft"
#define BUTTON_4 "btn-carbright"
#define BUTTON_5 "btn-carstop"
#define BUTTON_6 "btn-led"
#define BUTTON_7 "btn-gun"
#define Slider_1 "ran-server"
#define Slider_2 "ran-gunlr"
#define Slider_3 "ran-gunud"
// 按键控制
BlinkerButton Button1("btn-cargo");
BlinkerButton Button2("btn-carback");
BlinkerButton Button3("btn-carleft");
BlinkerButton Button4("btn-carright");
BlinkerButton Button5("btn-carstop");
BlinkerButton Button6("btn-led");
BlinkerButton Button7("btn-gun");
BlinkerSlider Slider1("ran-server");
BlinkerSlider Slider2("ran-gunlr");
BlinkerSlider Slider3("ran-gunud");
//温湿度传感器
BlinkerNumber HUMI("humi");
BlinkerNumber TEMP("temp");
DHT dht(DHTPIN, DHTTYPE);
float humi_read = 0, temp_read = 0;
void heartbeat()
{
HUMI.print(humi_read);
TEMP.print(temp_read-3);
}
void motospd(int sp1,int sp2)//电机速度控制函数,括号内分别为左右电机速度值,
{
if(sp1>0)
{
digitalWrite(INA, HIGH);
}
else
{
digitalWrite(INA, LOW);
}
if(sp2>0)
{
digitalWrite(INB, HIGH);
}
else
{
digitalWrite(INB, LOW);
}
analogWrite(PWMA,abs (sp1));
analogWrite(PWMB,abs (sp2));
}
// 按下按键即会执行该函数
void button1_callback(const String & state) //直行
{
if (state == BLINKER_CMD_BUTTON_TAP)
{
BLINKER_LOG("get button state: ", state); //按下
motospd(450,450);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED) //持续按下
{
BLINKER_LOG("get button state: ", state);
motospd(500,500);
}
else if (state == BLINKER_CMD_BUTTON_RELEASED) //松开
{
motospd(0,0);
}
}
void button2_callback(const String & state)
{
if (state == BLINKER_CMD_BUTTON_TAP) //按下
{
BLINKER_LOG("get button state: ", state);
motospd(-450,-450);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED)
{
BLINKER_LOG("get button state: ", state);
motospd(-500,-500);
}
else if (state == BLINKER_CMD_BUTTON_RELEASED)//松开
{
motospd(0,0);
}
}
void button3_callback(const String & state) //左转
{
if (state == BLINKER_CMD_BUTTON_TAP) //按下
{
BLINKER_LOG("get button state: ", state);
motospd(-550,500);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED)//持续按下
{
BLINKER_LOG("get button state: ", state);
motospd(-550,500);
}
else if (state == BLINKER_CMD_BUTTON_RELEASED)
{
motospd(0,0);
}
}
void button4_callback(const String & state)
{
if (state == BLINKER_CMD_BUTTON_TAP) //按下
{
BLINKER_LOG("get button state: ", state);
motospd(500,-550);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED)//按下
{
BLINKER_LOG("get button state: ", state);
motospd(500,-550);
}
else if (state == BLINKER_CMD_BUTTON_RELEASED)
{
motospd(0,0);
}
}
void button5_callback(const String & state) //停止按钮
{
if (state == BLINKER_CMD_BUTTON_TAP) //按下
{
BLINKER_LOG("get button state: ", state);
motospd(0,0);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED)//按下
{
BLINKER_LOG("get button state: ", state);
motospd(0,0);
}
}
void button6_callback(const String & state) //车灯
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED , !digitalRead(LED) );
Blinker.vibrate();
}
void button7_callback(const String & state) //停止
{
if (state == BLINKER_CMD_BUTTON_TAP)
{
BLINKER_LOG("get button state: ", state); //按下开火 ,点射模式
Blinker.vibrate();
digitalWrite(GUN , HIGH);
Blinker.delay(250);
digitalWrite(GUN , LOW);
}
else if (state == BLINKER_CMD_BUTTON_PRESSED) //持续按下,扫射模式
{
BLINKER_LOG("get button state: ", state);
Blinker.vibrate();
digitalWrite(GUN , HIGH);
}
else if (state == BLINKER_CMD_BUTTON_RELEASED) //松开
{
digitalWrite(GUN , LOW );
}
}
void slider1_callback(int32_t value) //滑块设置活动范围
{
BLINKER_LOG("get slider value: ", value);
myservo1.write(value);
}
void slider2_callback(int32_t value) //滑块设置活动范围
{
BLINKER_LOG("get slider value: ", value);
myservo2.write(value);
}
void slider3_callback(int32_t value) //滑块设置活动范围
{
BLINKER_LOG("get slider value: ", value);
myservo3.write(value);
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
pinMode(GUN, OUTPUT);
digitalWrite(GUN, LOW);
pinMode(INA,OUTPUT);
pinMode(INB,OUTPUT); //配置电机输出IO口为输出
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
myservo1.attach(SERVER1);//视频舵机
myservo2.attach(SERVER2);//舵机
myservo3.attach(SERVER3);//舵机
myservo1.write(90);
myservo2.write(90);
myservo3.write(170);
Button1.attach(button1_callback);
Button2.attach(button2_callback);
Button3.attach(button3_callback);
Button4.attach(button4_callback);
Button5.attach(button5_callback);
Button6.attach(button6_callback);
Button7.attach(button7_callback);
Slider1.attach(slider1_callback);
Slider2.attach(slider2_callback);
Slider3.attach(slider3_callback);
Blinker.attachHeartbeat(heartbeat);
dht.begin();
}
void loop() {
Blinker.run();
//温湿度传感器
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t))
{
BLINKER_LOG("Failed to read from DHT sensor!");
}
else
{
BLINKER_LOG("Humidity: ", h, " %");
BLINKER_LOG("Temperature: ", t, " *C");
humi_read = h;
temp_read = t;
}
Blinker.delay(2000);
}[/mw_shl_code]
APP的水弹的上下左右瞄准操作使用了滑块组件,感觉操作不是很好,准备随后修改为4个按键长按进行移动。
|