NMEA to wifi for less than a tenner?

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
Fiver for the wifi board, couple quid for the serial converter, maybe a couple for a power supply and then a quid for a box?
This works, sort of so far anyway. I've got it talking to a Raspberry Pi which repeats the data to a laptop, nasa NMEA0183 compass will spin the boat on Opencpn round and round :cool:

Should be able to multiplex as well so you can take a AIS feed & GPS feed then send it to a tablet running Opencpn. The AIS display on that program is just great .

Struggling a bit with UDP over internet though, can't get the laptop to see the data over the mobile phone wifi network - and hints anyone? Openplotter (Kplex) in a Pi reads it fine. The ESP can make its own hotspot as well so no need for anything else.

Code below, I'm not a coder so feel free to suggest any enhancements or feel free to copy - shouldn't be too hard to write a web page to set it up.This sends the data out over MQTT as well so if you've a cheap phone on the boat it should be quite easy to set it all up to monitor batteries, temperature, bilges etc..

Enjoy :cool:


ai_acr00018_iso_2.jpg


Code:
/**  This sketch sends broadcast udp message.
*
*
*/




#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <PubSubClient.h>    // mqtt library


#define mqtt_server "10.10.10.1"
#define mqtt_user "User"
#define mqtt_password "Password"
const char* ssid     = "OpenPlotter";
const char* password = "password";
//const char* ssid     = "*****";
//const char* password = "*******";


IPAddress ipBroadCast(10, 10, 10, 255);
unsigned int udpRemotePort=10112;
unsigned int udplocalPort=2390;
const int UDP_PACKET_SIZE = 70;
char udpBuffer[ UDP_PACKET_SIZE];


String  inData;


WiFiUDP udp;
WiFiClient espClient;
PubSubClient client(espClient);
SoftwareSerial mySerial(14, 12);


void callback(char* topic, byte* payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i=0;i<length;i++) {
  char receivedChar = (char)payload[i];
  Serial.print(receivedChar);
  }
  Serial.println();
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      client.subscribe("myfirstin");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}




//================================================================
// Setup hardware, serial port, and connect to wifi.
//================================================================
 
void setup() {
  Serial.begin(115200);
  mySerial.begin(4800);
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  //  Try to connect to wifi access point
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected"); 
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Starting UDP");
 
  // set udp port for listen
  udp.begin(udplocalPort);
  Serial.print("Local port: ");
  Serial.println(udp.localPort());


  client.setServer(mqtt_server, 1883);  //start mqtt 
  client.setCallback(callback);  // set callback routine to monitor incoming mqtt
  client.subscribe("myfirst");


  
}
//================================================================
// Function to send udp message
//================================================================
void fncUdpSend(String inData)
{
  char temp[50];
  inData.toCharArray(temp, 50) ; 
  udp.beginPacket(ipBroadCast, udpRemotePort);
  udp.write(temp, sizeof(temp));
  udp.endPacket();
  Serial.print("sent - ");
  Serial.println(inData);
  }


  
//================================================================
// LOOP MAIN
//================================================================
void loop() {
  
while (mySerial.available() > 0)   {
        char recieved = mySerial.read();
        inData+= recieved; 
   
        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);


            fncUdpSend(inData);


            char temp[50];
            inData.toCharArray(temp, 50) ;
            client.publish("myfirstout", temp);
            inData = ""; // Clear recieved buffer          
        }
    }
  // if (!client.connected()) {
  //  reconnect();
  //}
 //client.loop();
}



https://www.ebay.co.uk/itm/NEW-Node...990999?hash=item238e580ed7:g:pgIAAOSwnTxZbPEf

http://www.ebay.co.uk/itm/Mini-RS23...032828&hash=item1a21362809:g:ll4AAOSwA3dYRL3d
 

prv

Well-known member
Joined
29 Nov 2009
Messages
37,361
Location
Southampton
Visit site
Struggling a bit with UDP over internet though, can't get the laptop to see the data over the mobile phone wifi network - and hints anyone?

In the code you posted, you're sending UDP packets to 10.10.10.255, which is the IPv4 broadcast address for the 10.10.10.0/24 subnet. That's fine for things on the same subnet, but it won't get routed anywhere else, and the concept of broadcasting "to the entire Internet" should be an obvious non-starter. You'll need to know the destination address you want to send the packets to, and ensure there's a route to get there.

Pete
 

laika

Well-known member
Joined
6 Apr 2011
Messages
8,205
Location
London / Gosport
Visit site
Struggling a bit with UDP over internet though, can't get the laptop to see the data over the mobile phone wifi network - and hints anyone? Openplotter (Kplex) in a Pi reads it fine.

Can you explain the topology here? Are you talking about two completely different set-ups, ie one with the esp connected to your openplotter access point and one with it connected to the phone hotspot and you're using one OR the other? Or do you have openplotter connected to your phone network? Or (as I think Pete has assumed) do you have two separate networks which you want to talk to each other over the Internet?

In the code you posted, you're sending UDP packets to 10.10.10.255, which is the IPv4 broadcast address for the 10.10.10.0/24 subnet. That's fine for things on the same subnet, but it won't get routed anywhere else, and the concept of broadcasting "to the entire Internet" should be an obvious non-starter. You'll need to know the destination address you want to send the packets to, and ensure there's a route to get there.

If the situation is as I think Pete is assuming, what you're trying to do will never work. A network with an address starting "10." is a private address which wouldn't get routed over the Internet. Even if it wasn't most routers will block "directed broadcast".

OTOH If you're saying the esp worked when on the openplotter network but you've reconfigured it for your phone network and now it doesn't work (which I suspect is the case) then that's more straightforward. Your code has hardcoded the broadcast address for the network which (I think) openplotter uses. You need to change it to something which will work for whatever network you're connected to. There are various ways of doing that with various degrees of wrongness but let's just establish that that's what you want to do first...
 

prv

Well-known member
Joined
29 Nov 2009
Messages
37,361
Location
Southampton
Visit site
Or (as I think Pete has assumed) do you have two separate networks which you want to talk to each other over the Internet?

I didn't spot the "wifi" in "can't get the laptop to see the data over the mobile phone wifi network" - I read it as trying to do something over the Internet via 3G/4G and didn't need to think any further because subnet broadcast clearly ain't gonna work for that.

Pete
 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
Can you explain the topology here? Are you talking about two completely different set-ups, ie one with the esp connected to your openplotter access point and one with it connected to the phone hotspot and you're using one OR the other? Or do you have openplotter connected to your phone network? Or (as I think Pete has assumed) do you have two separate networks which you want to talk to each other over the Internet?



If the situation is as I think Pete is assuming, what you're trying to do will never work. A network with an address starting "10." is a private address which wouldn't get routed over the Internet. Even if it wasn't most routers will block "directed broadcast".

OTOH If you're saying the esp worked when on the openplotter network but you've reconfigured it for your phone network and now it doesn't work (which I suspect is the case) then that's more straightforward. Your code has hardcoded the broadcast address for the network which (I think) openplotter uses. You need to change it to something which will work for whatever network you're connected to. There are various ways of doing that with various degrees of wrongness but let's just establish that that's what you want to do first...

The code quoted connects to Openplotter which then sends the data out (kplex - maybe you've heard of it ;) )which happens to be connected to the phone network as well, so on either network you can get to the data. - "Struggling a bit with UDP over internet though," very bad wording on my part, and a bit of stupidity as well, trying to see data on a netword where it isn't broadcast will never be easy.. ;)

As for getting data onto the actual real internet, easiest for me is just to use MQTT then no need to open up ports or anything, which I don't know how to do on a mobile anyway.. Then FRED online node red can graph that or there must be some of the many IOT sites which can do funky stuff. And telling the ESP to do something should be pretty easy over MQTT as well.

Back to something actually maybe useful, yet to try it in this application but programming the ESP to run its own network looks simple so for anyone wanting a cheap way to get ais or gps or whatever data onto their tablet, this should work :cool:
 

agurney

Active member
Joined
10 Jun 2009
Messages
1,518
agurney.com
The code quoted connects to Openplotter which then sends the data out (kplex - maybe you've heard of it ;) )which happens to be connected to the phone network as well, so on either network you can get to the data. - "Struggling a bit with UDP over internet though," very bad wording on my part, and a bit of stupidity as well, trying to see data on a netword where it isn't broadcast will never be easy.. ;)

As for getting data onto the actual real internet, easiest for me is just to use MQTT then no need to open up ports or anything, which I don't know how to do on a mobile anyway.. Then FRED online node red can graph that or there must be some of the many IOT sites which can do funky stuff. And telling the ESP to do something should be pretty easy over MQTT as well.

Back to something actually maybe useful, yet to try it in this application but programming the ESP to run its own network looks simple so for anyone wanting a cheap way to get ais or gps or whatever data onto their tablet, this should work :cool:


Maybe I'm missing something here, but is all this not just handled automatically by gpsd? You connect NMEA devices to a linux box and read the stream on port 2947.

 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
Maybe I'm missing something here, but is all this not just handled automatically by gpsd? You connect NMEA devices to a linux box and read the stream on port 2947.

I think the plus is you can do away with a Linux box or any kind of box, for a few quid and next to no power stream nmea over wifi to any tablet or laptop which can recieve wifi and view nmea. Or fire something over the Internet for monitoring on the web. No wires required,just some sort of power. The esp8266 will, actually run off 12v, gets a pretty warm though, don't think I'll do that again though it survived a few days before I chickened out :)
 

laika

Well-known member
Joined
6 Apr 2011
Messages
8,205
Location
London / Gosport
Visit site
The code quoted connects to Openplotter which then sends the data out (kplex - maybe you've heard of it ;) )which happens to be connected to the phone network as well, so on either network you can get to the data.

If I understand this correctly, openplotter has two interfaces. One is used as an access point to which the esp is attached and the other connects to your phone network and thence to the Interweb.

In this scenario where you control the router (ie openplotter) yes you can set it up to broadcast from one network to the other, but you almost certainly don't want to do that.

You can undoubtedly solve the immediate problem with kplex config and some thought to avoid data loops. mail me privately to avoid this getting too dull for others.

A note on setting broadcast address though. Ideally you want your code to work unmodified wherever you place your esp. The wrong way to do that is to use the all subnets broadcast address, "255.255.255.255". That's sloppy, bad practice and doesn't take account of the possibility multiple networks on the same medium but usually works.

The correct way is to query the broadcast address of the interface you intend to send the broadcast out of. I note that the esp wifi libraries seem to assume a single interface which simplifies things. I'm not very familiar with arduino but a scan of the esp8266 wifi class docs suggests that the easiest way here might be:
- use localIP() to get the board's address and cast it to a uint_32
- Do the same for the subnetMask()
broadcast address is (localIP & subnetMask) | ~subnetMask
ie localIP & subnetMask will give you the subnet part of the address with zeros in the host part. The complement of subnetmask will give you zeros in the subnet part and 1s in the host part. OR the two together and you get your broadcast address (assuming, which is reasonable to do these days, that that is the broadcast address being used)

Don't try string manipulation with a dotted-quad representation of the IP address. That may work in the common case but it's "wrong".
 

laika

Well-known member
Joined
6 Apr 2011
Messages
8,205
Location
London / Gosport
Visit site
...if you're just sending data to kplex for consumption elsewhere, avoid broadcast over wifi if you can. Use unicast (including udp unicast). Much more reliable
 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
...if you're just sending data to kplex for consumption elsewhere, avoid broadcast over wifi if you can. Use unicast (including udp unicast). Much more reliable

Trying the break UPD, seems OK on here.. Node red fell over trying to view messages every 10mS, these are 100mS-

VYWdL7R.gif


Might not be so reliable in a marina with loads of wifi, dunno, missing a wind message or whatever every now and again won't matter there so think I might stick with what works for now anyway - ta.
 

Vladis

Member
Joined
20 Mar 2011
Messages
54
Visit site
Hello,

There are one or two points that we must take into account to operate the ESP8266 in this way. I am not sure if the module referred to has a built in voltage regulator that accepts the common available 12V we have on boats. Then we must consider the coupling between the instruments, say the gps, and the pin of the ESP8266. The voltage of the input pins should be between 0 and 3.3V. Finally and that part is difficult to notice, the Software Serial library that I see in the given code may rise to Resets if data comes very frequently at the input pin used by that Library. And Nmea183 data comes in bursts that can be as high as 80 characters in length.

In my website you can get a schematics of a circuit based on the Wemos D1 mini (based on the ESP8266 and similar to the one referred to in this post). And you can also download the binary code (not the source though) to make a Nmea183 to WiFi Multiplexer based on the ESP8266. The extra parts will cost a little more but you get a more robust circuit with the proper interfaces.

Luis

http://www.vela-navega.com/forum/viewforum.php?f=6
 
Last edited:

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
Hello,

There are one or two points that we must take into account to operate the ESP8266 in this way. I am not sure if the module referred to has a built in voltage regulator that accepts the common available 12V we have on boats. Then we must consider the coupling between the instruments, say the gps, and the pin of the ESP8266. The voltage of the input pins should be between 0 and 3.3V. Finally and that part is difficult to notice, the Software Serial library that I see in the given code may rise to Resets if data comes very frequently at the input pin used by that Library. And Nmea183 data comes in bursts that can be as high as 80 characters in length.

In my website you can get a schematics of a circuit based on the Wemos D1 mini (based on the ESP8266 and similar to the one referred to in this post). And you can also download the binary code (not the source though) to make a Nmea183 to WiFi Multiplexer based on the ESP8266. The extra parts will cost a little more but you get a more robust circuit with the proper interfaces.

Luis

http://www.vela-navega.com/forum/viewforum.php?f=6

Thanks for the link. Interesting.

In the OP the cost included a serial - TTL converter based on a MAX232epe chip, power that from 3.3v and the levels are OK. Don't think there's any opto isolation though, then again all these chips are so cheap it's not the end of the world if you blow one.
I've had a esp 8266 12e running off 13.7V for a few days and it survived, but don't think it's really the way forward - the onboard voltage regulator was getting a bit on the hot side! Still, regulators are cheap these days or just a car-USB power supply.

I've just been plying around with easyEsp, quite clever and really useful if you don't code much -
https://www.letscontrolit.com/wiki/index.php/ESPEasy

Downside is looks like there is no softserial so you're limited to just one NMEA feed, but the upside is that loads of other sensors are easy to set up , didn't take long to get voltage from a ADS1115 and temperature from some DS18B20's working and outputting over MQTT & UDP. It's all web based programming so no more usb cables to plug in.
I'm using it connected to a raspberry pi wifi network but looks like you can use it as a stand alone with the esp creating it's own access point.

Not as refined as your set up but for anyone wanting to stream temperature or voltage plus one NMEA feed without any soldering then all the bits are available cheap, add a mobile phone with web access and you've a monitoring system broadcasting onto the web. For less than the cost of a London pub lunch :cool:

OvnCCp5.png
 

rogerthebodger

Well-known member
Joined
3 Nov 2001
Messages
13,471
Visit site

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,427
Location
Hopefully somewhere warm
Visit site
As NMEA is really RS 422 I an trying one of these for a couple of my Arduino projects although I also have some of the MAX 232 models you posted
Think you're right - 0183 ended up as rs422 didn't it?, but don't think I have anything onboard which is 422 though, it's all RX, TX & ground.
Doesn't RS422 NEA work OK just using D+ & ground? Being a cheapskate I've never had anything using RS422 to try & NMEA2000 is completely unknown, just something them rich city folks use :)
 

agurney

Active member
Joined
10 Jun 2009
Messages
1,518
agurney.com
Think you're right - 0183 ended up as rs422 didn't it?, but don't think I have anything onboard which is 422 though, it's all RX, TX & ground.
Doesn't RS422 NEA work OK just using D+ & ground? Being a cheapskate I've never had anything using RS422 to try & NMEA2000 is completely unknown, just something them rich city folks use :)

I'm not a rich city person, but I use rs485/422 to monitor my home solar inverter (on the same pi that's handling the boat stuff)
 

rogerthebodger

Well-known member
Joined
3 Nov 2001
Messages
13,471
Visit site
Think you're right - 0183 ended up as rs422 didn't it?, but don't think I have anything onboard which is 422 though, it's all RX, TX & ground.
Doesn't RS422 NEA work OK just using D+ & ground? Being a cheapskate I've never had anything using RS422 to try & NMEA2000 is completely unknown, just something them rich city folks use :)

Yes it can defending on the exact spec of the device.

I have RS232 devices driving my simrad instruments and auto pilot. I also have my SH GX 2000 DSC radio driving a RS232 to USB converter to input DSC messages into my PC.

The main difference is the RS232 was designed as point to point where RS422 is a 1 sender to several receivers as NMEA but I do have RS232 driving more than on receiver. Its all a matter of try it if it works OK if not ifs head scratching time.

Thats why I have both types and it one does not work will try the other.
 
Top