Category: electronics

My various posts about DIY electronics, and my basic projects.

Motorcycle black box. Part 1 : data acquisition with Arduino Mega.

The objective

Make a black box, a device which would record short clips from camera in loop overwriting oldest clips. That would produce constant stream of short movies which put together would make one long recording containing last 30minutes (or more – depending on storage capacity) of my riding. Among with the recording, telemetric data would be collected such as velocity, RPM, temperature, front and rear brake pressed, depressed, and turn signals, and maybe more. Then this data could be put on the video in overlay.

The motorcycle

Yamaha XJ6SA 2010.

Identify by what means communication between the ECU and the dashboard is performed.

Which cables are used and what is the protocol used? After inspecting the service manual for my bike I was able to eliminate wires which are used for other things (see picture), and I left with only one, which is connecting the dash, the ECU and the immobilizer. Other ones was for flashing some warning LEDs, gathering information from fuel pump, oil switch and so on. So the yellow-blue wire was my first guess and it was correct. On the ecuhacking forum, which was source of very helpful information, guys was talking about something called K-line. I believe it is something widely common in the automotive industry, and for certain it has bunch of ISO standards describing it, but hey, if this is only one wire, and data flowing inside is some kind of serial communication, I bet I could sniff it, and figure out without any standards, which are hard to find and get (there is so much of them, I’ve got confused after few minutes of googling).

Dashboard connections

Dashboard connections

Figure out how to interface this, make some circuit if needed.

Again on the ecuhacing forum I’ve found information that K-line has logic levels relative to 12V, where 0V is logic 0, and 12V logic 1. There has to be some voltage level converter if I want to connect some TTL stuff to it. On the forum some guys were using a L9637 chip which is described as “ISO 9141 INTERFACE” by its datasheet. So I bought a few of these and connected it as follows :

L9637

L9637

Later on I removed the 510 ohm pull up resistor, because after turning engine on there was error showing of on the dash. I guessed that could be this resistor, and it helped. Dunno what was wrong.

Most difficult part for me was to find a place in motorcycle’s wiring to connect to. After some time I managed to insert piece of rigid wire to the back side of ECU connector as depicted below:

ECU connector

ECU connector

5V supply voltage I was drawing from step down voltage converter which I bought on the Internets. It is a PCB with a few discrete parts and quite huge radiator with some coils inside. There is [EDIT] label on it. To the output of L9637 I connected a Saleae logic analyzer, which I also bought. It is quite cheap and has good software for Windows, Linux and MAC OS. I can definitely recommend it, especially if you want to use it with Linux (I use Ubuntu).

Sniff the data, and collect it for further investigation.

My circuit worked the first time. After turning ignition to the ON state this is what I got:

Sealae logic analyzer window

Sealae logic analyzer window

Sealae app, among others, has a “Async serial” analyzer which I used with default configuration, and “use autobaud” checkbox checked. This useful option corrected initial 9600 baud to whatever it thought to be appropriate, and showed 16064 baud. Pretty odd value isn’t it? None the less it is very useful information if I want to read the data with some AVR, or something like that. It turns out, that data comes in packets which are 6B long. First byte is some kind of command, and the rest is the reply i.e the dashboard issues command 0x01 ant then ECU replies with 5 bytes of data. From the ecuhacking I knew that forst byte of the reply would be the RPM, second probably velocity, third an error code, fourth would be engine temperature (that is coolant or oil temperature?) and the very last is the checksum.

Sealae async serial analyzer setup

Sealae async serial analyzer setup

Collect the data in some more useful format.

Although Sealae has an option to store the analyzer’s data in CSV, sooner or later I would have to make some custom electronics anyway. Yet I want to make self contained logger hidden in neat case somewhere in the bike. I want to use a Raspberry PI i own as the main component of the gizmo, but after reading about serial communication with the Pi, I gave up for that time, and connected Arduino Mega. The main problem with PI is that I don’t know how to set it up for so unusual baud rate as 16064 baud (or 15625 as someone suggested). I had limited time, so for now I chose the Arduino. Below the code I uploaded :

#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(10, 11); // RX, TX
 
void setup() {
    // initialize both serial ports:
    Serial.begin(115200);
 
    // set the data rate for the SoftwareSerial port
    mySerial.begin(16064);
}
 
void loop() {
    static int count = 0;
 
    // read from port 1, send to port 0:
    if (mySerial.available()) {
        int inByte = mySerial.read();
 
        if (inByte == 0x01 && count >= 5) {
            Serial.println(' ');
            count = 0;
        }
 
        Serial.print(inByte, HEX);
        Serial.print (' ');
        ++count;
    }
}

As you can see, RX is set up for pin 10, so the only thing I did was to disconnect the logic analyzer, and connect Arduino pin 10 instead. But nothing happened. This was because the SoftSerial library have a few baud rates predefined, namely the most usual ones. The solution was to modify arduino-1.0.5/libraries/SoftwareSerial/SoftwareSerial.cpp so it looks like that:

// .... line 59
static const DELAY_TABLE PROGMEM table[] =
{
    // baud rxcenter rxintra rxstop tx
    { 115200, 1, 17, 17, 12, },
    { 57600, 10, 37, 37, 33, },
    { 38400, 25, 57, 57, 54, },
    { 31250, 31, 70, 70, 68, },
    { 28800, 34, 77, 77, 74, },
    { 19200, 54, 117, 117, 114, },
    { 16064, 66, 140, 140, 137, }, // added baud rate
    { 15625, 68, 144, 144, 141, }, // added baud rate 2
    { 14400, 74, 156, 156, 153, },
    { 9600, 114, 236, 236, 233, },
    { 4800, 233, 474, 474, 471, },
    { 2400, 471, 950, 950, 947, },
    { 1200, 947, 1902, 1902, 1899, },
    { 600, 1902, 3804, 3804, 3800, },
    { 300, 3804, 7617, 7617, 7614, },
};
// ....

Here is the link you should follow for more info. I haven’t figured it out by myself. After this modification Arduino happily sent me my precious data, which I observed in serial monitor.

Serial data fas seen on arduino serial monitor

Serial data fas seen on arduino serial monitor

This is the data I collected so far (motorcycle standing on central stand, back wheel revolving, velocity comes from the back wheel, ABS LED blinking).

Ignition ON, engine stopped.

1 0 0 0 30 30
1 0 0 0 30 30
1 0 0 0 30 30
1 0 0 0 30 30
...

Ignition ON, engine started, no throttle (~1200 RPM), no gear (N) i.e. wheel not revolving, cold engine:

1 24 0 0 30 54
1 24 0 0 30 54
1 24 0 0 30 54
1 24 0 0 30 54
...

Ignition ON, engine started, little throttle (more RPM), no gear (N) i.e. wheel not revolving, cold engine:

1 34 0 0 53 87
1 34 0 0 53 87
1 34 0 0 53 87
1 34 0 0 53 87
...

1st gear, no throttle (engine warmed up thus less RPM). About 10 km/h

1 17 0 0 5C 73
1 17 1 0 5C 74
1 17 1 0 5C 74
1 17 0 0 5C 73
1 17 1 0 5C 74
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 17 1 0 60 78
1 17 0 0 60 77
1 17 1 0 60 78
1 17 1 0 60 78
1 17 0 0 60 77
1 17 1 0 60 78
1 17 1 0 60 78
1 17 0 0 60 77
1 18 1 0 60 79
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 18 1 0 60 79
1 17 0 0 60 77

23 km/h (6th gear)

1 17 2 0 68 81
1 17 2 0 69 82
1 17 2 0 69 82
1 17 2 0 69 82
1 17 1 0 69 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 1 0 68 80
1 17 2 0 69 82
1 17 2 0 68 81
1 17 2 0 68 81
1 17 1 0 68 80
1 17 2 0 68 81

40 km/h

1 2B 4 0 70 9F
1 2B 3 0 70 9E
1 2B 3 0 72 A0
1 2B 3 0 72 A0
1 2B 4 0 72 A1
1 2B 3 0 72 A0
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1

60 km/h

1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 41 4 0 74 B9
1 41 6 0 74 BB
1 41 4 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 41 5 0 74 BA
1 40 5 0 74 B9
1 40 5 0 74 B9

80 km/h

1 56 7 0 77 D4
1 55 6 0 77 D2
1 56 7 0 77 D4
1 55 6 0 77 D2
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 7 0 77 D4
1 56 6 0 77 D3

Future

Due to uncertainty Raspberry PI serial communication I plan to make custom PCB with AVR in form of shield to Raspberry Pi. It will have two purposes. First it will acquire the data in some similar manner as depicted above, and will pass it to Pi by I2C or SPI (probably with velocity in some more usable form), among with some other data such as brakes and turn-lights, an maybe even outdoor temperature (I always wanted to have this information, especially in spring and autumn). And secondly it will drive some relay to cut the power to Pi which draws 2W of power even when shut down. Of course it also should send some signal first to Raspberry to shut it down correctly. If someone know something more about Pi’s UART and custom baud rates in particular, please let me know. Maybe there is a way to read K-line directly without AVR.

 

Old post about canon remote

So I came up with an idea of Cannon DSLR remote control. They are relatively cheap to buy on ebay, or other local online auction sites like allegro.pl here in Poland. But I wanted to build something by my self. As a complete amateur I wanted to make something small, and simple, thus DIY IR remote control for my camera was born. The protocol was reverse engineered by some smart people over the internet, so all I needed to do was to design the PCB, solder the stuff together, write a program and flash it. Below are the links:

My design is based on ATtiny2131a which in my opinion is a little too powerful, but first tests with ATtiny13 revealed some issues with internal oscillator. The timing of the clock signal is crucial when generating a carrier wave. Carrier should have 32.6kHz frequency for the best results. Deviations from this frequency has significant impact on IR operational range. Without an oscilloscope I was unable calibrate internal oscillator correctly, thus I’ve chosen chip with an external one (in fact the clock frequency was the most difficult issue I’ve got and I spent most of the time dealing with it). After soldering 4MHz quartz into place, at first I set it up for divide by 8 prescaler operation thus giving me 0.5MHz clock signal, but it also failed. I really don’t know why, but it seems, that prescaler is somehow unstalble, or has some sort of overhead (I’m an amateur after all. If someone could explain it, I would be grateful). Finally after setting the chip to operate at full speed (prescaler turned down) I was able to trigger the shutter, but range of operation was still small (circa 3m / 10ft).

I’ve chosen not to drive my IR led directly from AVR pins (like guy in aforementioned links did), but rather use a transistor used as a switch. I assume in that way I’m able to drive bigger current for the IR diode making it to produce stronger flashes. Next to the IR diode you can see a status diode, which indicates to the user, that device is sending a signal. Also I wanted it to be fully reprogrammable thus the connector on the board is present.

The last thing I did was the power down mode. Circuit, when turned on draws ~5mA even, when idling, so I presume the CR2032 battery would not last for long. For prolonging battery life I turn the AVR into power down mode after 3 seconds, and I wake it up via ping change interrupt when button is pressed. AVR in power down mode draws no current at all according to my multimeter (which simply is not precise enough to detect it), but according to the AVR specs it should take about 0.1uA.

Total cost was something about $5-7, with AVR and casing being the most expensive parts.

Below you can find a link to archive with all the necessary files to duplicate my design. Archive include Eagle files (both PCB and schematic), avr-gcc source files with CMake scripts and ATtiny2131a binary). The code was developed in Eclipse.

  • LINK

Feel free to post your thoughts on this design. I would greatly appreciate your comments on what I’ve could do better, or what I’ve done worng (although the device works well, but there always is room for improvement). For example I would be glad to hear how to extend the range which, as I mentioned, is only about 3m / 10ft.

Links