Now, I know this can’t be all that difficult…I’m just really bad at looking stuff up.
Does anyone know where I can find some code to use the Photon as a simple UART to WiFi bridge? I gotta believe at least several people have done this already, but I’ve spent several hours looking, to no avail.
Any and all help and/or guidance would be very much appreciated.
I did a Serial to Electron Bridge for a home automation project… but the data crossing is minimal… it is not a device to piggyback 3G on top of a Ethernet or Wifi connected device.
Thanks for the reply, Bulldog! Fortunately, I don’t need to implement a cellular connection…at least not for the first go round. The plan is to simply implement a UART to WiFi bridge to connect another (rather dumb) embedded microcontroller device to a WiFi network, so that a PC on the same network can exchange fairly short messages with the device. One could think of it as using the Photon as a simple WiFi adapter, like the Lantronix WiPort, the GridConnect HF-A11 or about a couple dozen similar products.
I was able to find code to do this with an Espressif ESP8285, another WiFi enabled microcontroller with which you may be familiar. It even occurred to me to try to build that code for the Photon and see how many gazillion errors I got, but that sounded a bit too much like despairation
Thanks for the git-back Peekay. It’s plain UART; RXD, TXD and GND, so no hardware handshaking. The interface is intended to be message based, with no streaming involved. And there’s only one Photon involved. Its UART will be connected to our (rather dumb) existing microcontroller based device, called an MDT. The Photon’s WiFi adapter will connect to our WiFi network, so that a PC on that same network can exchange fairly short messages with the MDT. As I mentioned to Bulldog, I’ve already found working code to do this with the Espressif ESP8285, which seems to work quite well. Does that pretty much cover it?
@eugenio, I believe this would be straight forward to port but without AP mode. I could take a crack at it if you can test it once ported. If I understand correctly:
PC <–> WiFi … Photon <–> MDT
The nice thing about the Photon is it can Particle.publish() its IP address so you don’t have to go hunting for it.
// Photon WiFi <-> UART Bridge
// by RoboRemo
// www.roboremo.com
// Disclaimer: Don't use RoboRemo for life support systems
// or any other situations where system failure may affect
// user or environmental safety.
#include "Particle.h"
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
// config: ////////////////////////////////////////////////////////////
#define UART_BAUD 9600
#define packTimeout 5 // ms (if nothing more on UART, then send packet)
#define bufferSize 8192 // I suspect you can make this much smaller in your application
#define PROTOCOL_TCP
//#define PROTOCOL_UDP
// For STATION mode:
// Credentials already configured and stored in Photon
const int port = 9876;
// You must connect the phone to the same router,
// Then somehow find the IP that the Photon got from router, then:
// menu -> connect -> Internet(TCP) -> [IP]:9876
//////////////////////////////////////////////////////////////////////////
#ifdef PROTOCOL_TCP
TCPServer server = TCPServer(port);
TCPClient client;
#endif
#ifdef PROTOCOL_UDP
Udp udp;
IPAddress remoteIp;
#endif
uint8_t buf1[bufferSize], buf2[bufferSize];
uint8_t i1=0, i2=0;
char myIpString[24] = "";
void setup() {
Serial.begin(UART_BAUD); // USB port for debugging
Serial1.begin(UART_BAUD); // MDB is on Serial1 of Photon
Particle.variable("endpoint", myIpString, STRING);
// STATION mode (Photon connects to router and gets an IP)
Particle.connect(); // Start WiFi connection
if (!waitFor(Particle.connected, 30000)) { // Wait 30 seconds for WiFi and Cloud to connect and if not connected, reset the Photon and restart!
System.reset(); // This is quick and dirty and there is better code on many topics to handle WiFi connectivity
}
// WiFi and Cloud connected, publish local IP address and also set a Particle.variable() to access anytime
IPAddress myIp = WiFi.localIP();
sprintf(myIpString, "%d.%d.%d.%d:%d", myIp[0], myIp[1], myIp[2], myIp[3], port);
Particle.publish("MDBip", myIpString, 60, PRIVATE);
#ifdef PROTOCOL_TCP
Serial.println("Starting TCP Server");
server.begin(); // start TCP server
#endif
#ifdef PROTOCOL_UDP
Serial.println("Starting UDP Server");
udp.begin(port); // start UDP server
#endif
}
void loop() {
#ifdef PROTOCOL_TCP
if(!client.connected()) { // if client not connected
client = server.available(); // wait for it to connect
return;
}
// here we have a connected client
if(client.available()) {
while(client.available()) {
buf1[i1] = (uint8_t)client.read(); // read char from client (RoboRemo app)
if(i1<bufferSize-1) i1++;
}
// now send to MDB serial port:
// Serial.write(buf1, i1); // uncomment for debugging
Serial1.write(buf1, i1);
i1 = 0;
}
if(Serial1.available()) {
// read the data until pause:
while(1) {
if(Serial1.available()) {
buf2[i2] = (char)Serial1.read(); // read char from MDB serial port
if(i2<bufferSize-1) i2++;
} else {
//delayMicroseconds(packTimeoutMicros);
delay(packTimeout);
if(!Serial1.available()) {
break;
}
}
}
// now send to WiFi:
//client.write((char*)buf2, i2);
client.write((uint8_t*)buf2, i2);
i2 = 0;
}
#endif // PROTOCOL_TCP
#ifdef PROTOCOL_UDP
// if there’s data available, read a packet
int packetSize = udp.parsePacket();
if(packetSize>0) {
remoteIp = udp.remoteIP(); // store the ip of the remote device
udp.read(buf1, bufferSize);
// now send to MDB serial port:
Serial.write(buf1, packetSize);
// Serial.write(buf1, packetSize); // uncomment for debugging
}
if(Serial1.available()) {
// read the data until pause:
//Serial.println("sa");
while(1) {
if(Serial1.available()) {
buf2[i2] = (char)Serial1.read(); // read char from UART
if(i2<bufferSize-1) {
i2++;
}
} else {
//delayMicroseconds(packTimeoutMicros);
//Serial.println("dl");
delay(packTimeout);
if(!Serial1.available()) {
//Serial.println("bk");
break;
}
}
}
// now send to WiFi:
udp.beginPacket(remoteIp, port); // remote IP and port
udp.write(buf2, i2);
udp.endPacket();
i2 = 0;
}
#endif // PROTOCOL_UDP
}
Would it be much more work to make this talk to another photon instead of a pc? I need to have 2 photons connect their serial ports together to over wifi.
@darkstar2002, it should be easy. However with no flow control, you need to make sure the Serial buffer (64 bytes) doesn’t overflow. You could use @rickkas7’s serial buffer code to help with that: