主要利用esp8266,结合oled,舵机和LED进行控制,利用的是tcp协议,通过连接热点实现对于小灯和舵机的亮灭,亮度,转速和控制,并在oled上实时显示。共耗时半天,希望都能有所收获
下面是网络调试助手和arduino的端串口的收发消息
然后是一些调试过程的实拍记录:
连接上路由器:
初始界面
显示制作人:
发送数据打开小灯:下面是代码可供大家调试
/*****************oled设置库 *****************/
#include <ArduinoJson.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <Ticker.h>
/*****************网络设置库 *****************/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Servo.h>
Servo myservo; // 定义舵机对象,最多八个
/*****************网络设置项 *****************/
const char *STAssid ="xxxx"; //需要连接路由器的名称
const char *STApassword="xxxxxx"; //路由器的密码
const char *host= "xxxxxxx"; //外网服务器ip
const int httpPort = 8888; //外网服务器端口
WiFiClient client; //声明客户端对象
bool is=0; //用来做连接到服务器后,仅发送一次问候语
int led=13; //灯io,D7
int led_light=12; //用来调节亮度,D6,输出PWM波
float dutycycle=512/2; /* 设置初始占空比为50% /2*/
int motor_speed=1; //定义舵机的转速
int pos = 0; // 定义舵机转动位置
boolean flag = true; //用来控制oled屏幕的刷新
//oled设置
// JSON
DynamicJsonBuffer jsonBuffer(256); // ArduinoJson V5
// 显示屏 如果引脚不同需要在这里修改
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 14, /* data=*/ 2);
// B 站 API 网址: follower, view, likes
String NAME = "夏友"; //改成自己的名字
String UID = "xxxxxxxxxx"; //改成自己的UID
//小灯、电机状态设置
String led_sta="off";
String motor_sta="off";
void setup() {
Serial.begin(115200);
Serial.println("");
//LED初始化
pinMode(13,OUTPUT);
digitalWrite(13,0);
analogWrite(led_light, dutycycle); /* 设置初始占空比为50% /2*/
//WiFi初始化
WiFi.mode(WIFI_STA); //设置为STA模式
WiFi.begin(STAssid, STApassword); //配置连接信息,开始连接
//运行自定义函数,在未连接到路由器的过程中,打印输出......,直到连接成功
gotoWifi();
// OLED 初始化,显示连接WiFi
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.clearDisplay();
u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
u8g2.setCursor(10, 10);
u8g2.println("Wifi connecting to ");
u8g2.setCursor(10, 30);
u8g2.println(STAssid);
u8g2.setCursor(10, 50);
while( WiFi.status() != WL_CONNECTED ){
delay(500);
u8g2.println("。");
u8g2.println(" ");
}
//delay(1000);
u8g2.sendBuffer();
delay(5000); //初始化延时5秒钟之后准备显示第二组画面
//连接WiFi成功后的oled路由器显示
u8g2.clearDisplay();
u8g2.setCursor(10,10);
u8g2.println("Wifi Connected!");
u8g2.setCursor(10,30);
u8g2.println("IP:");
u8g2.setCursor(10,50);
u8g2.println(WiFi.localIP() );
Serial.println("连接路由器成功");
//此时已经连接到路由器,可以开始连接远程服务器
lianjie();
u8g2.sendBuffer();
delay(5000); //初始化延时5秒钟之后准备显示第二组画面
//第三组画面准备显示
u8g2.clearDisplay();
u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
u8g2.setCursor(10, 19);
u8g2.print("Powered by");
u8g2.setCursor(10, 31);
u8g2.print("CSDN@夏友");
u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
u8g2.setCursor(10, 50);
u8g2.print("csdn-summer_bird");
u8g2.sendBuffer();
delay(5000); //初始化延时5秒钟之后准备显示第二组画面
//再次初始化
u8g2.setFont(u8g2_font_wqy12_t_gb2312b);
}
void loop() {
/****************检测WiFi连接状态****************/
if (WiFi.status() != WL_CONNECTED) {
WiFi.disconnect();
WiFi.begin(STAssid, STApassword);
gotoWifi();
}
else{
if (!client.connected()) { //如果没有连接到服务器
lianjie();
return;
}
else{ //否则,就是连接到服务器
if(is==0){
client.print("hello,server");
is=1;
}
}
}
/*针对信息对oled屏幕上的信息进行刷新并且显示*/
String data_led_motor=Read_Tcp(); //记录LED和舵机的数据
Tcp_Handler(data_led_motor); //读取服务器信息,并处理
while(flag) //oled数据显示
{
Serial.print("data_led_motor is:");
Serial.println(data_led_motor);
// display data
Serial.println("count = 0, display data");
u8g2.firstPage();
do
{
display(data_led_motor, led_sta, motor_sta); //分别输出占空比,小灯亮度,舵机强度
} while (u8g2.nextPage());flag=false;
}
//Tcp_Handler(data_led_motor); //读取服务器信息,并处理************************
}
//读取服务器信息,返回String类型
String Read_Tcp(){
String data = "";
while (client.available() > 0){
char inchar = client.read(); //
data += char(inchar);
delay(10);
flag=true; //修改
}
return data;
}
//处理服务器信息
void Tcp_Handler(String data){
if(data!=""){
Serial.print("收到服务器信息:");
Serial.println(data);
//数据接收处理
/*舵机数据接收处理函数*/
if(data=="led_open"){
digitalWrite(13,1);
led_sta="on";
client.print("open led");
}
else if(data=="led_close"){
digitalWrite(13,0);
led_sta="off";
client.print("close led");
}
else if(data=="more"){
more();
client.print("led_light_more");
}
else if(data=="lower"){
lower();
client.print("led_light_lower");
}
/*舵机数据接收处理函数*/
else if(data=="motor_open"){
motor_speed=1;
driver(motor_speed);
motor_sta="on";
client.print("open motor");
}
else if(data=="motor_close"){
motor_speed=0;
driver(motor_speed);
motor_sta="off";
client.print("close motor");
}
else if(data=="faster"){
driver(motor_speed++);
client.print("motor_faster");
}
else if(data=="slower"){
driver(motor_speed--);
client.print("motor_slower");
}
}
}
//连接路由器
void gotoWifi(){
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
//连接服务器
void lianjie() {
Serial.println("开始连接服务器");
client.connect(host, httpPort);
delay(1000);
}
//小灯亮度提高
void more(){
dutycycle+=100;
if(dutycycle > 1023) {dutycycle = 1023;Serial.print("light_max");}/* 限制占空比至 1023,并提出警告 */
led_sta="on";
Serial.print("Duty Cycle: "); Serial.println(dutycycle/1024*100);
analogWrite(led_light, dutycycle);
delay(1000);
}
//小灯亮度降低
void lower(){
dutycycle-=100;
if(dutycycle < 0) {dutycycle = 0;led_sta="off";Serial.print("light_min");}/* 限制占空比至 1,并提出警告 */
//小灯状态需要时刻监视
Serial.print("Duty Cycle: "); Serial.println(dutycycle/1024*100);
analogWrite(led_light, dutycycle);
delay(1000);
}
//舵机转速处理函数
// 0到180旋转舵机,每次延时15毫秒
void driver(int motor_speed)
{
//速度控制函数
if(motor_speed>10){motor_speed = 10;motor_sta="on";Serial.print("speed_max");}/* 限制转速0-10,并提出警告 */
else if(motor_speed<0){motor_speed = 0;motor_sta="off";Serial.print("speed_min");}/* 限制转速0-10,并提出警告 */
for(pos = 0; pos < 180; pos += motor_speed)
{
myservo.write(pos);
delay(15);
}
// 180到0旋转舵机,每次延时15毫秒
for(pos = 180; pos>=1; pos-=motor_speed)
{
myservo.write(pos);
delay(15);
}
}
//oled显示函数
// OLED 显示数据
void display(String data_led_motor, String led_sta, String motor_sta)
{
Serial.println("ok");
u8g2.clearDisplay();
u8g2.setCursor(5, 11);
u8g2.print("接收数据:" + data_led_motor);
u8g2.setCursor(5, 27);
u8g2.print("pwm占空比:" + String(dutycycle/1024*100));
u8g2.setCursor(5, 41);
u8g2.print("舵机速度:" + String(motor_speed));
u8g2.setCursor(5, 54);
u8g2.print("小灯/舵机状态:" + led_sta + "/" + motor_sta);
}
源程序我也放到了网盘,有需要的自取
网址:https://pan.baidu.com/s/14K37j_AizKk3m3WKlg7p9A
提取码:xwoj