Connecting Yun to Wifi Enabled Data Logger

Hello everyone,

I have a data logger that fits into my OBD2 port of my vehicle. It has an SSID, and IP and Port. However, I cannot get the Yun to connect to it using YunClient class. Basically, what Im ttrying to do is have the Yun connect to this device like an access point.

I assume the Datalogger acts as an access point, because it has an IP, SSID, and Port. It will also show up on my list of WiFi networks on my phone, so I know its transmitting. I’ve already tried my code but the connection never established, and the loop goes on forever because client.connected() is never true.

Am I going about this the wrong way?

In general, is it a difficult thing to connect to an access point using the Yun? There is no password for the Datalogger connection.

#include <Bridge.h>
#include <YunClient.h>

#define PORT 35000

// Define the Client Object
YunClient client;
void setup()
{
  // Bridge Setup to Linux Processor
  Bridge.begin();
  
  Serial.begin(9600);
  
  // Wait for Serial Connection
  while(!Serial); 
}

void loop() 
{
  // Define the IP address of Logger (192.168.0.10)
  IPAddress addr(192, 168, 0, 10);
  
  // Connect to OBD2 Wifi
  client.connect(addr, PORT);
  if (client.connected())
  {
    Serial.println("Connected to the Device.");
    
    // Send ASCII based HEX code to OBD2
    client.print(O10c);

    // give the server time to respond.
    delay (250);
  
    // Read all incoming bytes available from the server and print them
    while (client.available())
    {
      char c = client.read();
      Serial.print(c);
    }
    Serial.flush();

    // Close the connection
    client.stop();
  }
  else
    Serial.println("Could not connect to the server.");  
    
  // Give some time before trying again
  delay (10000);
}
// Push AT commands to OBD2 to Configure
// Extract Information from Logger

@RyanKim19,

Try with your laptop or desktop. Make sure your are on the same subnetwork.
After you get that working, there will be less work.

Jesse

jessemonroy650:
@RyanKim19,

Try with your laptop or desktop. Make sure your are on the same subnetwork.
After you get that working, there will be less work.

Jesse

You mean try to connect it through the local method in browser?

I would need the Yun to programmatically handle all of the networking and communication for my purposes. I wont be able to manually enter the credentials for my project as the Yun will be housed as a stand alone controller for a relay.

RyanKim19:
You mean try to connect it through the local method in browser?

I would need the Yun to programmatically handle all of the networking and communication for my purposes. I wont be able to manually enter the credentials for my project as the Yun will be housed as a stand alone controller for a relay.

@RyanKim19,

As Sonny would say, "Crawl, Walk, Run". If you make it work with your laptop, then that means it can be done. If you cannot, then the problems will be easier to find. Just try it. We can always go back to the Yun.

FWIW, this process is known as, "working with known goods". This means you know that works, so this must work. Then as you add unknowns - one at a time - it will all come together.

Jesse

jessemonroy650:
FWIW, this process is known as, "working with known goods". This means you know that works, so this must work. Then as you add unknowns - one at a time - it will all come together.

I call this process "divide and conquer" and it can work well: break a complex process with multiple unknowns into several pieces, with one complex unknown process in each piece. Get the first piece working (using a platform like a PC with better development/debugging tools) and then start adding the next piece. Moving from the PC environment to the embedded environment is one such complex piece.

I like the "crawl, walk, run" and "divide and conquer" strategies.

My approach to this would be to write a Python program on my PC that could talk to the OBD device and collect data from the Yun (over the USB connection).

When that worked I would just move the Python program to the Linux side of the Yun.

...R

Okay so i did try a few things and I'll list them as follows.

1.) I can connect my PC to the OBD2 Wifi logger, it will establish a connection to the logger, but obviously no internet access since the Logger isn't designed for that purpose.

2.) I went to Local or 192.168...... to configure the Wifi to connect to the logger. I managed to go through all the steps and it restarted the Yun and created this evsearduino.local which is where "it can be found". However, I just assumed the connection was made, since I did not receive an error message, and the unit restarted successfully. I can't verify completely since the network the Yun connected to (the logger) has no internet access, and thus I can't "see" what connections are being made to the logger.

I did notice the Rx LED light up when I turned my ignition on and drove a tiny bit. It only blinked once initially. The logger turns on as soon as its plugged into my OBD2 port, and ignition to the car isnt necessary for power.

3.) I decided to take a look at the network settings for the OBD2, they are as follows:

Imgur

4.) I went back an ran my original code and still no response from the logger as in client.connect() does not return a 1.

@RyanKim19,

awesome work. We now know the IP of your device is 192.168.0.11. And by the way, it can talk to the internet (via 192.168.0.10), give it has an appropriate gateway.

Now, If you look at your original code in the first post, you had 192.168.0.10 - not 192.168.0.11.

So at this point, I imagine you got some sort of instructions with this ODB2 device. Can you put those online, or point to a URL where they can be read?

In the meantime, try connecting to 192.168.0.11.

TIA
Jesse

Hi Jesse, Yeah I was aware that I hate 0.10 and not 0.11. I had actually tried both with no success.

The reason I started with 0.10 is that it was the only set of instructions for the device seemed to instruct to use 0.10. I then noticed that on my phone the IP showed up as .11 and changed it appropriately.

The device was bought from Amazon, however it did not come with much or any documentation.

http://www.amazon.com/Panlong-Diagnostic-Scanner-Android-Windows/dp/B00LKXJ3DQ

It simply states to connect ones device to the OBD2 SSID.

RyanKim19:
Hi Jesse, Yeah I was aware that I hate 0.10 and not 0.11. I had actually tried both with no success.

The reason I started with 0.10 is that it was the only set of instructions for the device seemed to instruct to use 0.10. I then noticed that on my phone the IP showed up as .11 and changed it appropriately.

The device was bought from Amazon, however it did not come with much or any documentation.

http://www.amazon.com/Panlong-Diagnostic-Scanner-Android-Windows/dp/B00LKXJ3DQ

It simply states to connect ones device to the OBD2 SSID.

AWESOME. Let's hack this thing and get it online.

Near the middle of that link/webpage you posted, just be below Product Description are these instruction:

Network Setup Instructions for OS X
1.Go to your iPhone/iPad/iPod touch Settings > General > Network > Wi-Fi;
2.Change settings for the WiFiOBD Network to the following: select "Static", enter IP address: 192.168.0.11, and Subnet Mask: 255.255.255.0;
3.Scan for the WiFiOBD device, and join the network;
4.Start the App and enter 192.168.0.10 as the IP address and 35000 as the port number.

  • Ignore the part that says OS X
  • Ignore the part about the iPhone/iPad/iPod touch

On (3.) it is saying that the SSID for the OBD2 is WiFiOBD (but that might be a software parameters), but I believe you have already connected to it (from what you have said). There appears to be NO Id or password needed to connect to this device. You are right, it is not clear if the IP is .10 or .11
So the place to start is to make sure the ODB2 devices is working as an AP (Access Point). If so, the Yun will be able to see it as an AP. It not, then, since you have already connected to the ODB with your laptop/desktop you should be able to know the IP by the process of elimination. That is, when you connect with your laptop, your laptop has an IP assigned to it. So, while you are connected to the ODB go to your command line (or network interface) an see what your IP is. You will have .10 or .11.

Sorry, I just looked at your code again. It says:

    // Send ASCII based HEX code to OBD2
    client.print(O10c);

However, your number is written in Octal, not Hex

Then again, I don't have the output from your last run. Can you check this? And perhaps post the output from your last try to connect to the ODB device ?

Jesse

Thanks very much Jesse for your help thus far.

By output, do you mean the output on the serial monitor? If so, it simply executes the else statement and prints out "cannot connect to server". If not, please let me know and I will grab what is needed to try an crack this nut open.

Im aware the way im sending codes to it isnt really in Hex, but for now im more concerned about just establishing connectivity. I modified the sketch since then by using a buffer such as this.

byte Atcommands[] = {'01','0C};

I then send the buffer or array i guess using the client.print

I also wondered if the OBD-II reader was properly functioning as an access point. I just assumed this position however after seeing it show up on my laptop and smartphone as a network that I can, and did connect to.

RyanKim19:

byte Atcommands[] = {'01','0C};

Ignoring the missing closing single quote, that still isn't going to compile. Using single quotes like you are, the compiler will insist on single characters (the exception is an escape sequence that starts with a backslash, but that still equates to a single character.) You have two characters inside the single quotes, which won't compile with Arduino.

Perhaps you meant to not have the single quotes, and want numerical literals. In that case, you still have a problem, because 0C is not a valid number: starting with zero like that, means an octal number, which can only consist of the digits 0 to 7.

If you want a hex adjectival constant, you need to prefix it with 0x (or 0X) giving you 0xC, for example.

Thanks Shapeshifter. The way I understand it however is that the client.print() function requires the arguement passed to it to be in byte form...thus why i implemented it like that. However, I really want to pass it Hex as the OBD2 expects to receive the PID commands (Parameter ID) to be in Hex based ASCII. So I wasn't even sure if client.print() was the right method to invoke because it was in the form of a byte which i was not sure if the OBD2 controller was able to decode back into Hex (I doubt it can).

Is it looking for individual bytes, specified as hexadecimal values? For example, a single byte with the value 0x7b, which is decimal 123?

Or is it looking for an ASCII string like "7b" (note the double quotes) in which case it is two bytes, the first has the value 0x37 (decimal 55) and the second is 0x62 (decimal 98) and there is a trailing NULL byte.

I had assumed the prior format, but now I'm thinking the latter based on your mention of ASCII?

Yes it would be the latter. From what I've learned, most OBD2 loggers have an ELM 327 Microcontroller inside the unit which support OBDII commands. Ive included the ELM327 datasheet, of particular interest or relevance is page 30-31. Each command is a pair of ASCII bytes for isntance 010C in my example.

Well, that makes it much easier, especially having a datasheet. :wink:

Take a look at the top right of page 31, where it talks about sending a mode 1, PID 0 command. You would simply code this as:

client.println("01 00");

Normally, the compiler treats any numerical literal that begins with 0 as octal, but in this case it's a character string, not a number, so the compiler makes no such assumptions. What you type is what you get.

While the datasheet uses single quotes in a lot of their examples, the compiler will require that you use double quotes. The chip requires a carriage return at the end, so that's why I used println() instead of print() in this example. There is a chance that the chip may receive a line feed instead of a carriage return, so if this doesn't work try this:

client.print("01 00\r");

The '\r' inserts an explicit carriage return character (0x0D), and using print() doesn't automatically add a line terminator.

Another (longer) example: at the top right of page 45, there is a command that requests multiple PIDs:

client.println("01 0B 04 0C 05");

Ah thank you.

Now back to my original issue, is there a way to indentify what channel the OBD2 is operating on? I read that Channel 11 is the maximum channel to be used by the Yun.....

I just still am not sure why im not able to connect to the OBD2 programatically.

RyanKim19:
Now back to my original issue, is there a way to indentify what channel the OBD2 is operating on? I read that Channel 11 is the maximum channel to be used by the Yun…

OK, let’s back up a second. Is the Yun actually connected to the access point? It thought it was, but if not, there’s no point in trying to do ANYTHING in the sketch until you have a solid network connection between the two devices.

Load the WiFi Status bridge example, and see what it reports. It should output something like this on the serial monitor:

Current WiFi configuration
SSID: Wireless Network Name
Mode: Client
Signal: 67%
Encryption method: WPA PSK (TKIP)
Interface name: wlan0
Active for: 11594 minutes
IP address: 192.168.42.114/255.255.255.0
MAC address: 90:A2:DA:F7:0B:10
RX/TX: 171839/3078 KBs

Is the SSID the correct SSID for the adapter? Does it show an active connection? Does it have a valid IP address?

If the answer to any of those is no, there’s no point in working on the sketch until they are all yes.

Here is an example of the output if the connection is not active:

Current WiFi configuration
SSID: ClientModeSSID
Mode: Client
Signal: 0%
Encryption method: -
Interface name: wlan0
Active for: 0 minutes
MAC address: 90:A2:DA:F0:32:D2
RX/TX: 0/0 KBs

I just still am not sure why im not able to connect to the OBD2 programatically.

Once you are properly connected to the access point (which is NOT a function of the sketch but is handled by the Linux side) then we can work on the sketch. The YunClient should be able to connect as long as it is using the proper IP address of the adapter, and the proper port number.

After verifying a good connection, you can try a quick experiment to verify connectivity: using SSH, or the YunSerialTerminal sketch and the USB serial port, try the Telnet command from the Linux command line:

telnet <addr> <port>

where is the adapter’s IP address, and is the port number. Does it make a connection, or print an error message. If an error message, what does it say?

For example, you have this in the sketch above: (just the salient lines of code)

#define PORT 35000
IPAddress addr(192, 168, 0, 10);
client.connect(addr, PORT);

The corresponding telnet command to do this exact same connection is:

telnet 192.168.0.10 35000

ShapeShifter:
OK, let's back up a second. Is the Yun actually connected to the access point? It thought it was, but if not, there's no point in trying to do ANYTHING in the sketch until you have a solid network connection between the two devices.

::::SNIP::::

@ShapeShifter,

from what I have read, he HAS NOT connect with the YUN, at least not passed it data.
He HAS connect via his desktop, See #6.

I presumeD, the initial handshake was the problem. Else, yes, walk back through the connectivity issue. I'll be reading - getting used to my new glasses.

Jesse

@Shapeshifter, Jessemonroy

Yes I was not able to achieve any connectivity besides using the local or in browser method. I dont have access to my vehcile currently, but will in a couple hours which then I will try your outline methods.

I assumed the Yun was able to connect via the local or in browser method, but couldn’t verify. I will report back with you method and post the results ASAP now that I have a method to verify a connection.

Thanks for your continued assistance to both.