Skip to content

Commit 2e899d0

Browse files
committed
Initial commit
0 parents  commit 2e899d0

File tree

8 files changed

+641
-0
lines changed

8 files changed

+641
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.pio
2+
.vscode

platformio.ini

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; PlatformIO Project Configuration File
2+
;
3+
; Build options: build flags, source filter
4+
; Upload options: custom upload port, speed and extra flags
5+
; Library options: dependencies, extra library storages
6+
; Advanced options: extra scripting
7+
;
8+
; Please visit documentation for the other options and examples
9+
; https://docs.platformio.org/page/projectconf.html
10+
11+
;[platformio]
12+
;default_envs = nodemcuv2
13+
14+
[env:lolin32]
15+
platform = espressif32
16+
board = lolin32
17+
framework = arduino
18+
build_flags =
19+
;-DIOTWEBCONF_DEBUG_DISABLED
20+
-DESP32
21+
lib_deps = prampec/IotWebConf@^3.2.0
22+
23+
[env:nodemcuv2]
24+
platform = espressif8266
25+
board = nodemcuv2
26+
framework = arduino
27+
build_flags =
28+
-DIOTWEBCONF_DEBUG_DISABLED
29+
lib_deps = prampec/IotWebConf@^3.2.0
30+
31+
[env:esp01_1m]
32+
platform = espressif8266
33+
board = esp01_1M
34+
framework = arduino
35+
build_flags =
36+
-DIOTWEBCONF_DEBUG_DISABLED
37+
lib_deps = prampec/IotWebConf@^3.2.0
38+
39+
[env:esp12e]
40+
platform = espressif8266
41+
board = esp12e
42+
framework = arduino
43+
build_flags =
44+
-DIOTWEBCONF_DEBUG_DISABLED
45+
lib_deps = prampec/IotWebConf@^3.2.0
46+
47+
[env:esp01]
48+
platform = espressif8266
49+
board = esp01
50+
framework = arduino
51+
build_flags =
52+
-DIOTWEBCONF_DEBUG_DISABLED
53+
lib_deps = prampec/IotWebConf@^3.2.0

readme.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# MSPWIfiBridge
2+
3+
With MSPWIfiBride, flight controllers with MSP protocol can be easily configured wirelessly via Wifi.
4+
5+
- MSP error checking
6+
- Easy to use web configuration
7+
- Station and access point mode
8+
- TCP and UDP support
9+
- OTA updates
10+
11+
## Supported Hardware
12+
13+
- NodeMCU V2/3
14+
- ESP-01(M)
15+
- ESP 12E/f
16+
- ESP32 (Not tested!)
17+
18+
## Wiring
19+
Connect the UART of the ESP module to a UART of the flight controller. Attention: The small ESP8266 modules only tolerate 3.3 V supply voltage.
20+
Set the UART of the flight controller to MSP, with the configured baud rate, default is 115200 baud.
21+
22+
## Configuration:
23+
After flashing, connect to the network "MSPWifiBridge".
24+
Wifi key: 123456789
25+
If there is no automatic forwarding to the configuration page, go to http://192.168.4.1 manually.
26+
Standard login data:
27+
Username: admin
28+
Password: 123456789
29+
30+
## Flashing
31+
Use Visual Studio Code and PlatformIO to compile and flash the code yourself or use the precompiled binary files under releases and use "NodeMCU Flasher" https://github.com/nodemcu/nodemcu-flasher/
32+
For the NodeMCU modules you can simply use the integrated USB port, for the small modules without USB you need a USB/serial converter (FTDI232 or similar).
33+
GPIO0 must be pulled to GND during power up to enter bootloader mode.

src/config.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include "config.h"
2+
3+
const char Configuration::protocolValues[][STRING_LEN] = {"tcp", "udp"};
4+
const char Configuration::baudrateValues[][STRING_LEN] = {"9600", "19200", "38400", "57600", "115200"};
5+
6+
SelectTParameter<STRING_LEN> Configuration::protocolParam =
7+
Builder<SelectTParameter<STRING_LEN>>("Protocoll").
8+
label("Protocoll").
9+
optionValues((const char*)protocolValues).
10+
optionNames((const char*)protocolValues).
11+
optionCount(sizeof(protocolValues) / STRING_LEN).
12+
nameLength(STRING_LEN).
13+
defaultValue("TCP").
14+
build();
15+
16+
IntTParameter<uint16_t> Configuration::portParam =
17+
Builder<IntTParameter<uint16_t>>("Port").
18+
label("Port").
19+
defaultValue(5761).
20+
min(1).
21+
max(65535).
22+
step(1).
23+
placeholder("5761").
24+
build();
25+
26+
SelectTParameter<STRING_LEN> Configuration::baudrateParam =
27+
Builder<SelectTParameter<STRING_LEN>>("Baudrate").
28+
label("Baudarate").
29+
optionValues((const char*)baudrateValues).
30+
optionNames((const char*)baudrateValues).
31+
optionCount(sizeof(baudrateValues) / STRING_LEN).
32+
nameLength(STRING_LEN).
33+
defaultValue("115200").
34+
build();
35+
36+
ParameterGroup Configuration::protocollGroup = ParameterGroup("protocoll", "Protocoll");
37+
ParameterGroup Configuration::serialGroup = ParameterGroup("serial", "Serial");
38+
39+
Configuration::Configuration() {
40+
dnsServer = new DNSServer();
41+
webServer = new WebServer(80);
42+
iotWebConf = new IotWebConf(NAME, dnsServer, webServer, INITAL_WIFI_PASSWORD, CONFIG_VERSION);
43+
44+
#if defined(ESP8266)
45+
httpUpdater = new ESP8266HTTPUpdateServer();
46+
#elif defined(ESP32)
47+
httpUpdater = new HTTPUpdateServer();
48+
#endif
49+
}
50+
51+
void Configuration::setupWebConfig(void) {
52+
protocollGroup.addItem(&protocolParam);
53+
protocollGroup.addItem(&portParam);
54+
serialGroup.addItem(&baudrateParam);
55+
56+
iotWebConf->setStatusPin(STATUS_PIN);
57+
iotWebConf->setConfigPin(CONFIG_PIN);
58+
iotWebConf->setupUpdateServer(
59+
[this](const char* updatePath) { httpUpdater->setup(webServer, updatePath); },
60+
[this](const char* userName, char* password) { httpUpdater->updateCredentials(userName, password); }
61+
);
62+
iotWebConf->addParameterGroup(&protocollGroup);
63+
iotWebConf->addParameterGroup(&serialGroup);
64+
iotWebConf->setConfigSavedCallback([this]{saved();});
65+
iotWebConf->getApTimeoutParameter()->visible = true;
66+
iotWebConf->init();
67+
delay(2000);
68+
69+
webServer->on("/", [this]{handleRoot();});
70+
webServer->on("/config", [this]{iotWebConf->handleConfig();});
71+
webServer->onNotFound([this]{iotWebConf->handleNotFound();});
72+
}
73+
74+
void Configuration::doLoop()
75+
{
76+
iotWebConf->doLoop();
77+
}
78+
79+
IPAddress Configuration::getIP() {
80+
IPAddress ip;
81+
if (iotWebConf->getState() == NetworkState::ApMode || iotWebConf->getState() == NetworkState::NotConfigured) {
82+
ip = WiFi.softAPIP();
83+
} else {
84+
ip = WiFi.localIP();
85+
}
86+
return ip;
87+
}
88+
89+
void Configuration::handleRoot()
90+
{
91+
if (iotWebConf->handleCaptivePortal()) {
92+
return;
93+
}
94+
String s = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/>";
95+
s += "<title>MSPWifiBridge</title></head><body>";
96+
s += "<h2>Welcome to MSPWifiBridge</h2>";
97+
s += "You can reach me under ";
98+
s += protocolParam.value();
99+
s += "://";
100+
s += getIP().toString();
101+
s += ":";
102+
s += portParam.value();
103+
s += "<br>Go to <a href='config'>configure page</a> to change values.";
104+
s += "</body></html>\n";
105+
106+
webServer->send(200, "text/html", s);
107+
}
108+
109+
void Configuration::saved()
110+
{
111+
Serial.println("Configuration was updated.</br>");
112+
}

src/config.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include <IotWebConf.h>
4+
#include <IotWebConfTParameter.h>
5+
6+
#if defined(ESP8266)
7+
#include <ESP8266HTTPUpdateServer.h>
8+
#elif defined(ESP32)
9+
#include <IotWebConfESP32HTTPUpdateServer.h>
10+
#endif
11+
12+
13+
// --- These values may be changed
14+
#define CONFIG_VERSION "0.3"
15+
#define TCP_PORT 5761
16+
#define NAME "MSPWifiBridge"
17+
#define INITAL_WIFI_PASSWORD "123456789"
18+
// ---
19+
20+
#define STRING_LEN 128
21+
#define NUMBER_LEN 32
22+
#define CONFIG_PIN 0
23+
#define STATUS_PIN LED_BUILTIN
24+
25+
using namespace iotwebconf;
26+
27+
class Configuration {
28+
private:
29+
static const char protocolValues[][STRING_LEN];
30+
static const char baudrateValues[][STRING_LEN];
31+
static ParameterGroup protocollGroup;
32+
static ParameterGroup serialGroup;
33+
34+
#if defined(ESP8266)
35+
ESP8266HTTPUpdateServer *httpUpdater;
36+
#elif defined(ESP32)
37+
HTTPUpdateServer *httpUpdater;
38+
#endif
39+
40+
DNSServer *dnsServer;
41+
WebServer *webServer;
42+
IotWebConf *iotWebConf;
43+
44+
void handleRoot();
45+
void saved();
46+
public:
47+
static SelectTParameter<STRING_LEN> protocolParam;
48+
static IntTParameter<uint16_t> portParam;
49+
static SelectTParameter<STRING_LEN> baudrateParam;
50+
51+
Configuration();
52+
void setupWebConfig(void);
53+
void doLoop(void);
54+
IPAddress getIP();
55+
};

src/main.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <Arduino.h>
2+
#include <WiFiClient.h>
3+
#include <WiFiUdp.h>
4+
5+
#if defined(ESP8266)
6+
#include <ESP8266Wifi.h>
7+
#elif defined(ESP32)
8+
#include <Wifi.h>
9+
#endif
10+
11+
#include "config.h"
12+
#include "msp.h"
13+
14+
#define UART_TIME_OUT 5
15+
#define STANDARD_BAUD 115200
16+
17+
typedef enum {
18+
TCP,
19+
UDP
20+
} Protocoll_e;
21+
22+
WiFiServer *wifiServer;
23+
WiFiClient wifiClient;
24+
WiFiUDP *wifiUdp;
25+
IPAddress ipAddress;
26+
Configuration config;
27+
Protocoll_e protocoll;
28+
MSP mspUart;
29+
MSP mspWifi;
30+
31+
void setup() {
32+
config.setupWebConfig();
33+
34+
unsigned long baudRate = atoi(config.baudrateParam.value());
35+
if (baudRate != 0) {
36+
Serial.begin(baudRate);
37+
} else {
38+
Serial.begin(STANDARD_BAUD);
39+
}
40+
41+
Serial.println("Protocoll: ");
42+
if (strcmp(config.protocolParam.value(), "udp") == 0) {
43+
wifiUdp = new WiFiUDP();
44+
wifiUdp->begin(config.portParam.value());
45+
protocoll = UDP;
46+
Serial.println("UDP");
47+
} else {
48+
wifiServer = new WiFiServer(config.portParam.value());
49+
wifiServer->begin();
50+
protocoll = TCP;
51+
Serial.println("TCP");
52+
}
53+
}
54+
55+
void loop() {
56+
config.doLoop();
57+
58+
if (protocoll == TCP) {
59+
60+
if (!wifiClient.connected()) {
61+
wifiClient = wifiServer->available();
62+
return;
63+
}
64+
65+
while (!mspWifi.isframeValid() && wifiClient.available()) {
66+
mspWifi.readByte((uint8_t)wifiClient.read());
67+
}
68+
69+
70+
} else if (protocoll == UDP) {
71+
int packetSize = wifiUdp->parsePacket();
72+
if (packetSize > 0) {
73+
ipAddress = wifiUdp->remoteIP();
74+
while (!mspWifi.isframeValid() && wifiUdp->available()) {
75+
mspWifi.readByte((uint8_t)wifiUdp->read());
76+
}
77+
}
78+
}
79+
80+
if (mspWifi.isframeValid()) {
81+
Serial.write(mspWifi.frame, mspWifi.getLength());
82+
}
83+
mspUart.setCliMode(mspWifi.isCliMode());
84+
mspWifi.reset();
85+
86+
while (!mspUart.isframeValid()) {
87+
if (Serial.available()) {
88+
mspUart.readByte((uint8_t)Serial.read());
89+
} else {
90+
delay(UART_TIME_OUT);
91+
if (!Serial.available()) {
92+
break;
93+
}
94+
}
95+
}
96+
97+
if (mspUart.isframeValid()) {
98+
if (protocoll == TCP) {
99+
wifiClient.write(mspUart.frame, mspUart.getLength());
100+
} else if (protocoll == UDP) {
101+
wifiUdp->beginPacket(ipAddress, config.portParam.value());
102+
wifiUdp->write(mspUart.frame, mspUart.getLength());
103+
wifiUdp->endPacket();
104+
}
105+
106+
}
107+
mspWifi.setCliMode(mspUart.isCliMode());
108+
mspUart.reset();
109+
}

0 commit comments

Comments
 (0)