Send multiple OBD commands together and get response simultaneously - ios

I'm working on application which connects OBD2 adapter and getting the real time data like speed,rpm,throttle position etc..When I read one command at a time, it works fine like by sending command "010C\r", I get current RPM.
I think that sending multiple commands in one request is not possible.But in other applications like EngineLink HD ,Dashcommand, we found that multiple components are updated at a time like if we are driving the car and check the RPM,Sped and Throttle then they are updating at every 1 second. It looks like real time data.
I'm surprised that how is it possible ?
We have added code like if user wants to show 3 components, then for every component, one thread is generated and it handles request and response of that command. So in this case , 3 threads are generated and we get response but it takes too much time like if we are watching on Speed out of 3 PIDs then speed is updated after 3-4 seconds delay.
We also need to lock the code where it sends the request and get response bcoz OBD2 adapter handles one request and response at a time.
And if we don't lock the code then we get unpredicted results which might be due to common shared stream used by socket communication between the application and obd2 adapter.
But now I want to read multiple commands at a time.
I mean at a point of time, I want to know speed,RPM and throttle position etc..So I want to send above commands in one request and get a response at a time.
How is it possible ? Someone can guide me.

First of all, I don't think you need 3 threads for this. As you said, OBD-II can only handle 1 command at a time, so you can do with 1 thread, that knows which requests it has to make every second.
Simply said, you cannot read multiple commands at a single time. As you've said, you experience some delay. The OBD-II default settings are responsible for this. The default waiting time, (as far as I can recognize) 200 ms. So you can only send 5 commands each second. This is somewhat slow, and some applications manage to get 20 request each second.
You can do this by sending an extra number (number x) at the end of your command. The OBD-II device will wait for x responses from devices in the car. So when you send '010D1', it will wait till 1 answer comes in, and it will directly send it back to you. Then it's easibly possible to handle a command in 50ms or maybe even less.
So that's how that application looks like it requests data 'at the same time'. They can also use some trick to wait till all data is collected, and then display it.
I hope I answered all your questions, otherwise ask some more.
EDIT:
Also for the succesfull commands, this standard time is taken. This is because some commands can have 2 sources which report the same data. For example, the speedometer, and a gps module can both measure the speed. If both are connected to the OBD-II bus, then you will get 2 answers.
With '010D', it will wait 200ms and then report all answers. With '010D1', it will send back the first answer directly when it has 1 answer.

The ELM327 datasheet gives the following information on page 45:
Multiple PID Requests
The SAE J1979 (ISO 15031-5) standard allows
requesting multiple PIDs with one message, but only if
you connect to the vehicle with CAN (ISO 15765-4).
Up to six parameters may be requested at once, and
the reply is one message that contains all of the
responses.
For example, let us say that you need to know
engine load (04), engine coolant temperature (05),
manifold pressure (0B), and engine rpm (0C) on a
regular basis. You could send four separate requests
for them (01 04, then 01 05, then 01 0B, etc.) or you
could put them all into one message like this:
01 04 05 0B 0C
to which, a typical reply might be:
00A
0: 41 04 3F 05 44 0B
1: 21 0C 17 B8 00 00 00

Related

mrtg show average when counter data missing

I'm graphing my power meter with an old laptop in my barn.
This sends data using mqtt to mrtg(cacti)
Lately this laptop has begun to lockup when playing spotify.
This is a separate issue.
However, when I reboot, all the power used in the mean time is shown as being used in a single time period, giving a huge spike, so the rest of the data is hardly visible.
Is it possible to, when the data finally arrives, to intrapolate it on all the missing datapoints?
The laptop sending data was down between Sat 18:00 and Sun 11:00 approx, but of cause the real powermeter keeps running.
I'd rather have a straight line between the two datapoints, it is still loss of data, but is more true than a spike.
Edit: Complication, as Cacti reads the data asynchroneously from mqtt, it keeps getting the latest count even if the data is stale.
I guess I need to get my mqtt->cacti interface to send NaN or U if the timestamp of the data has not changed.
You have 2 options.
Add a timestamp to the message that way you can rebuild the data as the queued messages are delivered when the laptop reconnects to the broker.
Use a QOS 0 subscriptions and ensure that clean session is set to true, this will mean the missing readings are dropped. Zero data is probably easier to interpret from the graph than a large spike.

Watermark getting stuck

I am ingesting data via pub/sub to a dataflow pipeline which is running in unbounded mode. The data are basically coordinates with timestamps captured from tracking devices. Those messages arrive in batches, where each batch might be 1..n messages. For a certain period there might be no messages arriving, which might be resent later on (or not). We use the time-stamp (in UTC) of each coordinate as an attribute for the pub-sub message. And read the pipeline via a Timestamp label:
pipeline.apply(PubsubIO.Read.topic("new").timestampLabel("timestamp")
An example of coordinates and delay looks like:
36 points wait 0:02:24
36 points wait 0:02:55
18 points wait 0:00:45
05 points wait 0:00:01
36 points wait 0:00:33
36 points wait 0:00:43
36 points wait 0:00:34
A message might look like:
2013-07-07 09:34:11;47.798766;13.050133
After the first batch the Watermark is empty, after the second batch I can see a Watermark in the Pipeline diagnostics, just it doesn't get updated, although new messages arrive. Also according to stackdriver logging PubSub has no undelivered or unacknowledged messages.
Shouldn't the watermark move forward as messages with new event time arrive?
According to What is the watermark heuristic for PubsubIO running on GCD? the WaterMark should also move forward every 2minutes which it doesn't?
[..] In the case that we have not seen data on the subscription in more
than two minutes (and there's no backlog), we advance the watermark to
near real time. [..]
Update to address Bens questions:
Is there a job ID that we could look at?
Yes I just restarted the whole setup at 09:52 CET which is 07:52 UTC, with job ID 2017-05-05_00_49_11-11176509843641901704.
What version of the SDK are you using?
1.9.0
How are you publishing the messages with the timestamp labels?
We use a python script to publish the data which is using the pub sub sdk.
A message from there might look like:
{'data': {timestamp;lat;long;ele}, 'timestamp': '2017-05-05T07:45:51Z'}
We use the timestamp attribute for the timestamplabel in dataflow.
What is the watermark stuck at?
For this job the watermark is now stuck at 09:57:35 (I am posting this around 10:10), although new data is sent e.g. at
10:05:14
10:05:43
10:06:30
I can also see that it may happen that we publish data to pub sub with delay of more than 10 seconds e.g. at 10:07:47 we publish data with a highest timestamp of 10:07:26.
After a few hours the watermark catches up but I cannot see why it is delayed /not moving in the beginning.
This is an edge-case in the PubSub watermark tracking logic that has two work arounds (see below). Essentially, if there is no input for 2 minutes, then the watermark will advance to the current time. But, if data is arriving faster than every 2 minutes but still at a very low QPS, then there isn't enough data to have a keep the estimated watermark up to date.
As I mentioned, there are several work arounds:
If you process more data the issue will naturally be resolved.
Alternatively, if you inject extra messages (say 2 per second) it will provide enough data for the watermark to advance more quickly. These just need to have timestamps, and may be immediately filtered out of the pipeline.
For the record, another thing to have in mind about the previously mentioned edge cases in a direct runner context, is the parallelism of the runner. Having a higher parallelism, which is default especially on multicore machines, seems to need even more data. In my case a setting --targetParallelism=1 helped. Basically transformed a stuck pipeline to in a working one without any other intervention.

Is it possible to request all desired ODB II PIDs via a .dbc file?

What I'm looking to do is request all desired PIDs via a .dbc file made in Vector db Editor++.
I understand enough about CAN communication to be able to do this with 1 or 2 PIDs because the DLC allows up to 8 bytes of data per CAN message. I am also familiar with this resource on querying and responses of PID https://en.wikipedia.org/wiki/OBD-II_PIDs#CAN_.2811-bit.29_bus_format
What I'm having trouble understanding is how diagnostic tools are able to query every PID the manufacturer of a particular vehicle decides to make available, so I feel that this is possible. Yet, if I use a request ID of $7DF, I can only use this message ID alone for my querying, this is the reason why I currently can only fit two PIDs (signals) in that CAN message.
How diagnostic tools are able to query every PID the manufacturer of a particular vehicle decides to make available?
You cannot request whatever you want from ECU (at least in a normal way!). Only the OBD relevant PIDs you can request. All the OBD II PIDs and their definitions, scaling and etc. are available within ISO 15031 part 5. It means that all the PIDs are predefined. So any logger would firstly request mode 01 pid 00 to get all the available PIDs for that vehicle and then starts to scan over it.
if I use a request ID of $7DF, I can only use this message ID alone for my querying.
This is wrong cause 0x7DF has nothing to do with DLC and content of the message. It is only the header of message to tell the ECU from whom you have this request. 0x7DF is the OBD requests and even you can directly request different controllers their available data.
Every can message is 8 byte long. First byte is the mode of the request. Second byte tells the ECU the number of incoming bytes and then you have 6 bytes to send. Because of that they say you can request up to 6 PIDs simultaneously. your problem might be receiving multiple data from OBD which might be a bit tricky using Flow Control and First Frame messages. Here you can find some info about how to receive a message when it is longer that 8 bytes.
regards,

How to do an operation, and if it doesn't complete in 6 seconds to stop it?

I am trying to receive information from a telnet connection in Lua using LuaSocket. I have all of that up and running except when I receive, if I receive anything less than the maximum number of bytes it takes 5 seconds. If I receive anything more than the number of bytes on the screen it takes upwards of half an hour.
My current idea for a solution is to try receiving for instance 750 bytes, then if that doesn't work within 6-7 seconds do 700 bytes, then 650 and so on until I can receive it very quickly. I need to parse the information and find two specific phrases, so if it's possible to do that inside of my telnet connection and just return that instead of the entire screen that would work as well. I also don't need ALL of it, but I need as much of the received information as possible to raise the chances that my information is in that block of it, hence why I'm only decrementing by 50 in my example.
I can't find any functions that allow you to start reading something (doing a function) and then quit it after a certain time interval. If anybody knows how to do this, or has any other solutions to my problem, let me know please! :) Thanks!
here is what I need repeated:
info = conn:receive(x)
with x decrementing each time it takes longer than 6 seconds to complete.
The solution you are proposing looks a bit strange as there are more straightforward ways to deal with asynchronous communications. First of all, you can use settimeout to limit the amount of time that send and receive calls will wait for the results (be careful as receive may return partial results in this case). Second option is to use select which allows you to check if a socket has something to read/write before issuing a blocking command.

Data logged to a file; how do I rotate logs and how do I parse the data to not have 'gaps' in the data?

I've got a web application that, for performance reasons, throws any data sent into a logfile.
I've got two concerns with this approach:
How do I best rotate logs, in order to not lose data?
For each user session multiple requests are logged. Each request has a unique id so there is an easy way for me to tie the requests to the session. The problem is, however, that if I rotate the logs I risk ending up with one request in one log and another request in another log.
How do I arrange my parsing in a way that allows me to parse all requests from a given session? I am willing to define a session timelimit, for example that the requests must, at maximum be 30 minutes apart.
If I had a hourly log rotation at 00 minutes:
What if the user made one request at 13:59 and one at 14:01 - The user would end up having requests in two different logs.
Answer to part 1: If you're on *nix, use syslog/logger. Check the logger(1) and syslog.conf(5) man pages.
Answer to part 2: You're not forced to look at just one log file at a time. less ${SERVICE}* will normally open all the relevant log files together: when you get to the bottom of a page, :n will move you to the next file and :p back.
Alternatively, use a log analyser program. Steve Kemp's post on promptly finding needles in syslog haystacks covers, together with its comments, a lot of ground.

Resources