<div dir="ltr"><div dir="ltr"><br></div><div dir="ltr"><br></div><div dir="ltr">Hi Michael,<div><br></div><div>So I've written something to poll the SOC%.</div><div><br></div><div>At this stage I'm trying to debug. I'm running my code - I configured for my BMWI3 module and my car.</div><div><br></div><div>I set log level debug v-bmwi3, log level verbose canlog, and log level canopen.</div><div><br></div><div>I can see that can1 is running - I'm sending some packets (I had it poll once per 60 seconds and indeed I'm sending one packet per minute). </div><div><br></div><div>can can1 status says:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><font face="monospace">OVMS# can can1 status</font></div><div><font face="monospace">CAN: can1</font></div><div><font face="monospace">Mode: Active</font></div><div><font face="monospace">Speed: 500000</font></div><div><font face="monospace">DBC: none</font></div><div><font face="monospace">Interrupts: 5557</font></div><div><font face="monospace">Rx pkt: 5548</font></div><div><font face="monospace">Rx err: 0</font></div><div><font face="monospace">Rx ovrflw: 0</font></div><div><font face="monospace">Tx pkt: 9</font></div><div><font face="monospace">Tx delays: 0</font></div><div><font face="monospace">Tx err: 0</font></div><div><font face="monospace">Tx ovrflw: 0</font></div><div><font face="monospace">Wdg Resets: 0</font></div><div><font face="monospace">Err Resets: 0</font></div><div><font face="monospace">Wdg Timer: 0 sec(s)</font></div><div><font face="monospace">Err flags: 0x00000000</font></div></blockquote></div><br><div class="gmail_quote"><div class="gmail_attr">I put "ESP_LOGD(TAG, "BMWI3: got SOC=%3.1f%%", soc);" in my code after parsing the SOC.</div><div class="gmail_attr"><br></div><div class="gmail_attr">But I'm not seeing that log message in the console.</div><div class="gmail_attr"><br></div><div class="gmail_attr">Can I enable a trace of CAN1 (without drowning my box!). Can I see what gets transmitted?</div><div class="gmail_attr"><br></div><div class="gmail_attr">Thanks,</div><div class="gmail_attr">Steve</div><div class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr">On Sat, 12 Dec 2020 at 13:49, Michael Balzer <<a href="mailto:dexter@expeedo.de">dexter@expeedo.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
Steve,<br>
<br>
use the <font face="monospace">vehicle_obdii</font> module to get
into OBD polling on the OVMS.<br>
<br>
You begin by defining the poll requests to be sent in at least one
array of type <font face="monospace">OvmsVehicle::poll_pid_t</font>.
A request consists of<br>
<ul>
<li>the transmission address (CAN ID), this may be a specific
address or the broadcast address 0x7df<br>
</li>
<li>the expected response address (CAN ID), or 0 in case of a
broadcast</li>
<li>the type of the request; OBD also calls this "mode", e.g.
0x22, there are preprocessor definitions for all supported
types, e.g. 0x22 = <font face="monospace">VEHICLE_POLL_TYPE_OBDIIEXTENDED</font></li>
<li>optionally the PID to access (depending on the request type,
may be none / 8 bit / 16 bit)</li>
<li>the poll interval; this may be specified for up to 4 vehicle
states (normally used to switch intervals according to the car's
operation mode, like sleeping / driving / charging)</li>
<li>optionally the CAN bus to use for the request<br>
</li>
</ul>
For your example of polling the SOC, this would be:<br>
<ul>
<li>transmission address:<font face="monospace"> 0x6F1</font></li>
<li>response address: <font face="monospace">0x607</font></li>
<li>type: <font face="monospace">0x22</font> or <font face="monospace">VEHICLE_POLL_TYPE_OBDIIEXTENDED</font></li>
<li>PID: <font face="monospace">0xDDBC</font></li>
<li>poll interval: as you like, e.g. <font face="monospace">{ 0,
10, 60 }</font> -- assuming for sleeping, driving, charging<br>
</li>
</ul>
End the array with an all zero entry. The poller will automatically
loop over the list.<br>
<br>
Call <font face="monospace">OvmsVehicle::PollSetPidList()</font> to
set the array to be used, call <font face="monospace">OvmsVehicle::PollSetState()</font>
to set the vehicle state (defining the poll intervals).<br>
<br>
Override <font face="monospace">OvmsVehicle::IncomingPollReply()</font>
with your result processing. The method will be called by the
framework for each response part. The framework also supplies
polling state variables you can use (see <font face="monospace">vehicle.h</font>).
A typical pattern to collect multiple frames is:<br>
<br>
<font face="monospace">void
OvmsVehicleRenaultTwizy::IncomingPollReply(<br>
canbus* bus, uint16_t type, uint16_t pid, uint8_t* data, uint8_t
length, uint16_t mlremain)<br>
{<br>
string& rxbuf = twizy_obd_rxbuf;<br>
<br>
// init / fill rx buffer:<br>
if (m_poll_ml_frame == 0) {<br>
rxbuf.clear();<br>
rxbuf.reserve(length + mlremain);<br>
}<br>
rxbuf.append((char*)data, length);<br>
if (mlremain)<br>
return;<br>
<br>
// complete:<br>
switch (pid) {<br>
…<br>
</font><br>
This pattern collects the payload in a string buffer, regardless of
the length.<br>
<br>
Decoding and converting the payload to metrics is up to you, but
normally is simple.<br>
<br>
For your example:<br>
<br>
<font face="monospace"> …<br>
// complete:<br>
switch (pid) {<br>
case </font><font face="monospace">0xDDBC: {<br>
unsigned int soc_raw = ((unsigned int)rxbuf[0] << 8) |
(unsigned int)rxbuf[1];<br>
float soc = soc_raw / 10.0f;<br>
StdMetrics.ms_v_bat_soc->SetValue(soc);<br>
break;<br>
}<br>
</font><br>
<br>
On your question:<br>
<br>
<blockquote type="cite"><font face="monospace">2020-11-15
10:34:36.474 <-- 607␣F1␣03␣7F␣22␣78␣⏎ // this is
some unrelated packet?<br>
</font></blockquote>
<br>
Actually it's related, it's the first reply of the device and means
"I'm busy, but stand by, results will come soon". The poller handles
these.<br>
<br>
If you want to follow the poller operation, activate debug logging
for the vehicle module: <font face="monospace">log level debug
vehicle</font><br>
<br>
There's more on the poller, but that should get you going.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am 12.12.20 um 10:19 schrieb Steve
Davies:<br>
</div>
<blockquote type="cite">
<div dir="ltr"><img src="https://ci5.googleusercontent.com/proxy/eHdzSgZvpklVborpbW6cV6J1tIPPGMHtsB3WJYJCb977xUPj0DE3NoGMGVrTjWXibblsqPsb-35zx5RbnoZO0ryZvc4gt1rsb-2eO1DUIWrujGcp2FguZauQw_qmRQ=s0-d-e1-ft#https://api2.activeinboxhq.com/1.0/anon/rr/3cfa1c481eaefb97aafad7ab1f4ae783" style="display: none;" width="1" height="1">Hi,
<div><br>
</div>
<div>Can I ask someone to help me get started with pulling data
off the OBD-2 on the I3.</div>
<div><br>
</div>
<div>I have info on what works via an LM327 and I know the pids,
but it would help me for some pointers as to how to do it on
the OVMS.</div>
<div><br>
</div>
<div>You know - the goal to get the first one working.</div>
<div><br>
</div>
<div>Here's an example definition - the SOC of the main
battery. This is extracted from decompiling a definition file
for ediasbas/ediasblib:</div>
<div><br>
</div>
<div>(The "_EN" text is translated using Google cloud translate
so the German is the original)</div>
<div><br>
</div>
<div>The "job" is defined like so:</div>
<div><br>
</div>
<div> <font face="monospace"> {<br>
"SERVICE" : "22",<br>
"ID" : "0xDDBC",<br>
"DIV" : "-",<br>
"INFO" : "aktueller Anzeige Soc",<br>
"RES_TABELLE" : "RES_0xDDBC_D",<br>
"ARG_TABELLE" : "-",<br>
"EINHEIT" : "-",<br>
"DATENTYP" : "-",<br>
"ARG" : "ANZEIGE_SOC",<br>
"LABEL" : "-",<br>
"ADD" : "-",<br>
"MUL" : "-",<br>
"INFO_EN" : "current advertisement Soc",<br>
"L/H" : "-",<br>
"RESULTNAME" : "-",<br>
"NAME" : "-",<br>
"SG_ADR" : "-"<br>
},<br>
</font></div>
<div><br>
</div>
<div>The "results" are defined like so:</div>
<div><br>
</div>
<div><font face="monospace"> "RES_0XDDBC_D" : [<br>
{<br>
"DIV" : "10.0",<br>
"INFO_EN" : "current advertisement Soc",<br>
"DATENTYP" : "unsigned int",<br>
"EINHEIT" : "%",<br>
"INFO" : "aktueller Anzeige Soc",<br>
"MASKE" : "-",<br>
"RESULTNAME" : "STAT_ANZEIGE_SOC_WERT",<br>
"L/H" : "high",<br>
"MUL" : "1.0",<br>
"ADD" : "0.0",<br>
"NAME" : "-"<br>
},<br>
{<br>
"NAME" : "-",<br>
"ADD" : "0.0",<br>
"MUL" : "1.0",<br>
"L/H" : "high",<br>
"RESULTNAME" : "STAT_MAXIMALE_ANZEIGE_SOC_WERT",<br>
"INFO" : "obere Grenze des Anzeige Soc",<br>
"MASKE" : "-",<br>
"INFO_EN" : "upper limit of the display Soc",<br>
"EINHEIT" : "%",<br>
"DATENTYP" : "unsigned int",<br>
"DIV" : "10.0"<br>
},<br>
{<br>
"RESULTNAME" : "STAT_MINIMALE_ANZEIGE_SOC_WERT",<br>
"L/H" : "high",<br>
"MUL" : "1.0",<br>
"NAME" : "-",<br>
"ADD" : "0.0",<br>
"DIV" : "10.0",<br>
"INFO_EN" : "lower limit of the display Soc",<br>
"EINHEIT" : "%",<br>
"DATENTYP" : "unsigned int",<br>
"INFO" : "untere Grenze des Anzeige Soc",<br>
"MASKE" : "-"<br>
}<br>
],<br>
</font></div>
<div><br>
</div>
<div>I read it that three unsigned ints (16 bits each) are
returned.</div>
<div>Each is divided by 10 to return a "%".</div>
<div><br>
</div>
<div><br>
</div>
<div>I traced an app that can retrieves this parameter using an
LM327 based OBD2 interface.</div>
<div><br>
</div>
<div>That app initialises the LM327 like so:</div>
<div><br>
</div>
<div><font face="monospace">2020-11-15 10:34:28.831 --> ATD
Return all settings to default<br>
2020-11-15 10:34:28.849 --> ATE0 Disable command echo<br>
2020-11-15 10:34:28.861 --> ATH1 Show CAN message headers<br>
2020-11-15 10:34:28.875 --> ATAL Allow long messages<br>
2020-11-15 10:34:28.887 --> ATPBE101 Set programmable
param 0x2c to 0xE1, 0x2d to 0x01<br>
- 2c=0xE1:<br>
- 11 bit IDs<br>
- variable data-length code<br>
- 11 or 29 bit received IDs<br>
- use data format ISO 15765-4 (CAN)<br>
- 2d=0x01<br>
- Use rate divisor of 1<br>
2020-11-15 10:34:28.901 --> ATSPB Use protocol USER1 CAN
(as set above I think)<br>
2020-11-15 10:34:28.949 --> ATBI Bypass initialisation -
apparently a bad idea... ?<br>
2020-11-15 10:34:28.964 --> ATSH6F1 Set header bytes to
0x6F1 ( 0x06F1 ? )<br>
2020-11-15 10:34:28.978 --> ATAT0 Disable adaptive timing
- wait up to ATSF time<br>
2020-11-15 10:34:28.992 --> ATSTFF Maximum wait</font><br>
</div>
<div><font face="monospace"><br>
</font></div>
<div><br>
</div>
<div><font face="arial, sans-serif">Then, when it fetches this
PID it does the following:</font></div>
<div><font face="monospace"><br>
</font></div>
<div><font face="monospace">2020-11-15 10:34:35.101 -->
ATCRA607⏎ // Listen for 0x607<br>
2020-11-15 10:34:35.114 <-- OK⏎⏎><br>
2020-11-15 10:34:35.115 --> ATCEA07⏎
// "extended address" 0x07 [matches 607?]<br>
2020-11-15 10:34:35.127 <-- OK⏎⏎><br>
2020-11-15 10:34:35.129 --> ATFCSH6F1⏎
// Flow control header<br>
2020-11-15 10:34:35.141 <-- OK⏎⏎><br>
2020-11-15 10:34:35.143 --> ATFCSD07300800⏎
// Flow control data<br>
2020-11-15 10:34:35.156 <-- OK⏎⏎><br>
2020-11-15 10:34:35.157 --> ATFCSM1⏎
// Flow control mode<br>
2020-11-15 10:34:35.170 <-- OK⏎⏎><br>
<br>
2020-11-15 10:34:36.367 --> 22␣DD␣BC⏎
// asking for "extended" PID 0xDDBC<br>
2020-11-15 10:34:36.474 <-- 607␣F1␣03␣7F␣22␣78␣⏎
// this is some unrelated packet?<br>
2020-11-15 10:34:36.539 <--
607␣F1␣10␣09␣62␣DD␣BC␣02␣4C␣⏎ // reply --> 0x24C = 588
= 58.8 SOC<br>
607␣F1␣21␣03␣A6␣00␣69␣FF␣FF␣⏎
// 0x03A6 = = 93.4%, 0x0069 = 10.5%<br>
2020-11-15 10:34:37.598 <-- ⏎><br>
<br>
Remember the LM327 takes the sent bytes and wraps with into
a full CAN message - though I'm not sure exactly how that
comes out - I presume that "extended address" goes in
somewhere.<br>
<br>
--> 22 DD BC is the PID<br>
<-- 2 part reply. First has the SOC. Second has 0x03A6
(934) and 0x0069 (105)<br>
<br>
First int is 588 or 58.8% which is the physical SOC of the
battery.<br>
934 is 93.4 which is the physical SOC level which the car
displays as "100%" (i3 keeps some headroom "reserved").<br>
105 is 10.5 which is the physical SOC level that the car
displays as 0%.<br>
</font></div>
<div><font face="monospace"><br>
</font></div>
<div><font face="monospace">I'd appreciate some help to give me
a head-start to be able to retrieve this attribute on the
OVMS box.</font></div>
<div><font face="monospace"><br>
</font></div>
<div><font face="monospace">Thanks,</font></div>
<div><font face="monospace">Steve</font></div>
<div><font face="monospace"><br>
</font></div>
</div>
<br>
<fieldset></fieldset>
<pre>_______________________________________________
OvmsDev mailing list
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank">OvmsDev@lists.openvehicles.com</a>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre cols="72">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26</pre>
</div>
_______________________________________________<br>
OvmsDev mailing list<br>
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank">OvmsDev@lists.openvehicles.com</a><br>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" rel="noreferrer" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
</blockquote></div></div>