Tuesday 26 November 2019

GPS & IMU Data Expansion

Following on from the DIY CAN-Bus data logger, I wanted to continue and build the next module in the data-logging chain. I wanted to add a module which could acquire GPS data at high data rates so that it would be useable for track data analysis. The GPS data logged via my mobile phone on previous trackdays had shown promise but the update rate (1 Hz) was too slow and the accuaracy to low to really make the data useful for track use.

I decided to use a GPS breakout board that is capable of 50Hz update rates.
I also added an IMU module to the board to try and see if any useful data on accelerations, pitch & roll angles could be extracted. If not, the module could be disabled or removed in a future revision.

Similar to the datalogger module, the GPS/IMU module uses a Teensy 3.2 controller for the data processing. No data is stored in the GPS/IMU module. The data is collected from the sensors, assembled into CAN messages & transmitted on the bus to be picked up and recorded by the datalogger module.

The module is a bit larger than the datalogger as I have used breakout boards for the GPS & IMU rather than mount the chips directly. A 3v coin cell battery is included to allow 1s hot starts of the GPS module. That way a fix can be acquired very soon after the module is powered on.

Data is currently polled at 20Hz and passed directly to the CAN Bus. This is to simplify the software & prove out the concept. If everything works and the data looks useful I would like to add a Kalman filter to the data.

The pillion seat replacement cover currently installed on the bike makes an ideal mounting point for the GPS antenna. The antenna is mounted on the base plate but underneath the outer fairing. This way the antenna is hidden from view but has a direct line of sight to the sky for optimum reception.

Having tested the unit, the GPS works very well. Even without filtering, the data rate seems fast enough to get relatively stable position & speed data. With the hot start function, position data is available as soon as the datalogger is ready to start.

The IMU module has not been quite as useful. The unit is a Bosch BNO055. While standing still the orientation looks quite good. However, once the bike is moving, accelerating, turning, the unit seems to lose track of which way is up and so the pitch, roll & yaw angles don't make any sense. There is a possibility that I may need to mount the module more securely so that it is held in a stable position but is isolated from spikes in acceleration caused by bumps in the road.

Front End Conversion

It was recently brought to my attention that I have not provided any detail on the front end conversion that I have carried out on the bike.

I may have skipped this topic due to the nature of the blog but at this stage it has become more of a project blog than a pure EFI conversion blog so it seems fitting to include it.

I had planned on doing a front end conversion for a while to improve the stability of the bike. I had spent a bit of time collecting the parts for it and then sometime before starting the bike on injectors, I installed most of it together.

I had grabbed a full K4/K5 GSXR600 front end for decent money. 

I wanted to modify as little as possible in keeping with my "100% reversibility" motto I had at the time. I figured the GSXR steering stem could work in the CBR headstock with a different sized top bearing. The size ended up being pretty non standard but I managed to find one to suit in the US.

I also wanted to keep the smaller front wheel from the CBR rather than use the GSXR wheel. The GSXR axle is bigger than the CBR axle but I could again just swap the bearing size and dust seals to make it work. I did need to make new spacers to put the wheel in the right position. 

The CBR brake disks were too small to fit the GSXR calipers but I couldn't use the GSXR disks with the CBR wheel as some disk offset was required to get the disks lined up in the GSXR calipers. A bit of measuring and research pointed me towards CBR900RR disks. These had the same ID & bolt PCD to fit the CBR wheel while having a large enough OD & offset to put the disk between the GSXR calipers.

First, off came the stock front end.

Then out with the old headstock bearing races.

Move to the new steering stem and insert a new lower bearing on OEM CBR250 dust seal.

The new steering stem required a 30mm ID upper bearing but that made standard tapered roller bearing sizes too big for the 47mm ID CBR250 headstock upper bearing seat. Luckily I found a suspension reseller in the USA that could supply a bearing kit especially for these types of swaps including an oddball size tapered roller bearing 30x47x12 and a 3mm spacer to bring the assembly up to the 15mm stock bearing height and dust seal.

Forks in place.

The throttle tube housing and starter/kill switch assy needed the placement lugs removed in order to fit onto the new clipon.

First impressions were good

Moving onto the front wheel, first out came the old bearings & seals and off with the original brake disks

The new wheel axle is 25mm OD so the original wheel spacers and bearings would not work. To combat that issue I designed new spacers to suit.

New Centre Spacer

Different size bearings (6905) allowed the wheel to fit straight on the axle and 32x42x7 oil/dust seals to fit. The bearing/seal stack is smaller than standard but that got swept up with the difference in wheel positioning on the GSXR axle.

 A pair of new CBR900RR disks. The photo below gives an indication of the size difference from the standard CBR250RR disks.

The wheel spacers were built into the new axle and nut but as the CBR250 wheel is narrower and includes an offset from centre, I needed additional spacers. These also compensated for the smaller bearing stack.

Everything on and looking fairly well!

Once the main part was fitted it was time to figure out what else needed changing. 

The CBR ignition barrel did fit the GSXR top clamp but the steering lock did not work so I removed the lug from the frame. That may have been the first irreversible action of the project!

The steering damper mounting lug needed to be removed from the GSXR lower clamp to clear the false air inlet ducts.

As the GSXR forks were wider, they fouled the front fairing and false air ducts. Removing a small amount of material from the ducts and fairing fixed that. The fuse box was also removed and replaced with 4off sealed individual fuse holders to make room. 

The brake setup took the longest to get right. I am very particular how I want my brakes to feel and I found the stock CBR brakes felt close to perfect for my liking. 

I was using a post-recall GSXR master cylinder with the standard GSXR600 calipers but I found that combination too soft for my liking although the braking power was excellent. 
I had at one point acquired a set of K2 GSXR1000 calipers by accident which had 2off smaller pistons per caliper than the GSXR600 units so I tried these on the bike and found a massive improvement.

I had a bit of a clearance issue with the post-recall GSXR master cylinder though. The top entry fluid hose fouled on the mirror stay bracket & nose fairing of the CBR so I had to find an alternative. I scoured eBay for radial master cylinders that had either side or bottom entry fluid feed hoses. One attractive option was the Brembo unit from a B14 Yamaha R1. 

Before spending money on yet another part, I did some calculations on all the combinations of all the parts I had to hand to try and quantify the differences in feel and braking power and map the results out to find the best solution.

It turned out the R1 master cylinder coupled with the K2 GSXR1000 calipers worked very well. Subsequent testing proved that so that has become my final setup.

Clearance under the nose fairing was also tight enough to foul most fluid reservoirs so I had originally employed a HRC style hose fluid reservoir. This worked well until one day after a session of heavy braking I felt excessive drag on the front wheel. There was not enough room in the hose reservoir to allow expansion of the heated fluid. I needed to find a proper reservoir to fit. 
After more trawling through eBay the Triumph 675 Daytona reservoir looked suitable so I took a chance on it. It fit perfectly under the nose fairing!

It took some time to get to the optimum setup but the result is worth it. Between the upgraded front end and the new rear shock the bike handles great! Final front end configuration as follows.

Forks Axle & Triple Tree:  K4 GSXR600
Calipers:                             K2 GSXR1000
Wheel:                                CBR250RR
Disks:                                 CBR900RR
Master Cylinder:                B14 R1
Reservoir:                           675 Daytona

Wheel Speed Sensor Bracket

Way back in 2014 when I had mostly completed the front end conversion and installed the Koso dash, I did not pay a huge amount of attention to the dash wheel speed sensor installation. I simply used the supplied sensor & L-bracket and used a longer fairing bolt to fix it inside the front fender and keep it out of sight.

There were obvious issues with this installation. Because the fairing bolt was M6 and the L-bracket was designed to accept an M8 bolt, the fit was very sloppy. I was also tightening the bracket onto the back face of the cast fork lower which was never meant to have anything seated on it and so was not finished flat. I was able to improve the situation using 2off DIN 9021 washers either side of the bracket but the installation was then very awkward to fit and adjust having many parts that needed to be held in place and barely having enough space to get a hand in between the fender & wheel.
Also, every time the fender or forks needed to be removed, the sensor position needed to be manually set again on assembly.

Recently I have acquired an FDM 3D printer and so it presented a good opportunity to make a nicer and more user friendly bracket to hold the wheel speed sensor in the correct position and make removal & installation much easier.
I also decided to replace the supplied Koso sensor with another, smaller sensor which would help to make the installation tidier.

My idea was to design a one-piece bracket that would be sandwiched between the front fender and the cast fork lower. The bracket would need to be located using both fairing bolts which would ensure the sensor would always be installed in the correct position.
Replacing the standard Koso sensor with the smaller unit also had the advantage that the smaller sensor has a threaded body and therefore can be installed by sandwiching the bracket between 2off lock nuts. This makes the installation tidier and makes gap adjustment relatively easy.

The Koso sensor is a simple hall effect sensor fed by 5V and whose signal is pulled high when a magnetic object passes by. The sensor I chose to replace it is one from RS Components (stock #304-172). The below image shows the size difference between the sensors.

Sensor Comparison

The basic design of the bracket is straightforward. The "ears" which are clamped between the fender & fork leg were kept as thin as possible while still having enough stiffness to keep the sensor in position. Steel compression limiters were also added to the mounting holes to allow the fairing bolts to be torqued down properly without risking damaging the plastic bracket.
The sensor is located inside a round bore which incorporates a recessed internal hex for one of the sensor lock nuts. The second lock nut is then tightened onto a flat at the nose of the bracket.

Bracket & Sensor CAD

The bracket was printed in ABS plastic. This may be exchanged for ASA to increase environmental resistance in the near future depending on how the ABS copes with general use. The stainless steel compression limiters were pressed into the printed part.

The bracket was then installed on the bike and the sensor gap adjusted to c.0.8mm.

Installed Sensor

The new sensor installation is much tidier and makes the front end easier to work on.

The observant among readers may have noticed that the bracket in the CAD model does not match the printed bracket in the photos. That is because the CAD represents a later design revision. The bracket was originally designed to centre the sensor on the low head cap screws used as "teeth". However when I tested it, I found the smaller sensor tip was sometimes detecting the hex recess in the head of the bolt and so provided either unreliable or double frequency pulses to the dash.
The issue was fixed by moving the sensor position radially outwards by 3mm. This made sure the sensor tip would only see a single solid "tooth" at each cap screw, resulting in reliable signal. 

Friday 10 May 2019

On-board Data Logging

Since last year, I have wanted to implement an on-board data logging system for the bike for a number of reasons.

  1. On-board logging would mean all trips could be data logged automatically without needing to consciously connect to the ECU and start logging.
  2. Logging the engine data as broadcast via CAN-Bus would enable logging at a higher frequency than is available through the RS232 connection. 50Hz vs c.15Hz
  3. The CAN-Bus data broadcast from the ECU also gives access to far more data channels than are available to log via RS232 which includes many very useful diagnostics channels and calculated channels which I feel really should be included in the RS232 data stream such as injector deadtime.
  4. Having data log capabilities external to the ECU opens up the flexibility to add more data inputs either via CAN-Bus or analogue inputs. These could be additional engine sensors that are not currently required by the ECU to run the engine (oil pressure, oil temperature, EGT) or else they could also include chassis data such as brake pressure, GPS & IMU data, wheel speed, etc.

I found that most units on the market that would log CAN-Bus data were just too expensive for my needs so decided to use the opportunity to build on my existing skills and build my own.
I decided to use the Teensy 3.2 development board as the heart of the logger mainly due to the on-chip CAN-Bus interface but also because of its small package size and ease of programming via Arduino IDE.

The circuit layout and PCB design for the Teensy including the peripherals needed was relatively straight-forward. I was familiar with the CAN-Bus interface on the Teensy from other projects and, as a MicroSD socket and coin cell holder were the only other major components required, the physical aspect of the logger did not take long to complete.

Modelled Assembly

PCB Layout

PCB Board

Assembled Board

While the physical aspect was completed quite quickly, the software side of things took a bit of time to get to a state that worked well enough. While I was familiar with the CAN-Bus reading aspect, I had not had any experience with logging data to an SD Card so I went through a few iterations of code before settling on an approach that worked.
As I do not come from a software/coding background, any of my microcontroller projects always start with existing code that does something similar to or a particular aspect of what I want and then modify it to my needs.

The software workflow is relatively simple. On power-up, the microcontroller would read the date & time from the RTC and create a new data file on the SD card using the RTC timestamp in it's filename. This ensures unique filenames are used and makes the data easier to manage later.
Once the file is created, the controller reads any data contained in the CAN-Bus recieve buffer and adds it to the appropriate position in a data struct. At defined intervals corresponding to the desired logging frequency, the data contained in the struct is written to the SD card. In between writing the data to the SD card, the controller cycles through reading the CAN-Bus buffer and passing the recieved data to the struct as quickly as possible.
The cycle of data read & write is continued until power is removed from the module (i.e. ignition off). This does mean that there is the potential to lose some data not written to the card on power down but the period spanned by the lost data is unlikely to be more than 2-3 log intervals and is deemed acceptable for the purposes of the project.

Software Main Loop Basic Workflow

Writing data to the SD card was very straightforward as long as the number of parameters and logging frequency was kept low but problems started cropping up when more parameters were added to the datastream and the rate was pushed higher than c.10Hz.

I began by wanting to log data to a human readable .csv file on the SD card purely for convenience. However, with the number of data channels I wanted to log I ran into issues with SD card write latency at write speeds above c.10Hz which was causing me to lose a number of data points every now and then while the program waited for the SD card to finish writing. I could help the issue by adding data to a single long data string and then writing that to the SD in one go. However, the data string took up too much memory with the number of channels I was trying to log so it was not really a viable option. This also didn't completely eliminate the issue.

In the end, after experimenting with minor changes to the same basic method, I opted to write the data to the SD card in binary format and then post process the data after it had been downloaded from the SD card to create human readable .csv files with headers.
By writing the data in binary format, I was able to use a C struct to contain the data variables which was much easier to update within the software and also very easy to simply write the entire struct to the log file whenever it was needed. It also seems to have made the SD write latency issues disappear. I have not yet verified data frequency consistency over a long period of time and at higher logging rates at the time of writing but I have verified writing over 60 data channels to the card at 20Hz for several minutes without any loss of data. While logging directly to .csv file, I was getting data inconsistencies even with only 10off data channels and 10Hz logging rate.

The post processing script was written in GNU Octave which is an open source alternative to Matlab. The script is written in a way that it reads information about the C struct (variable names, units and precision) from a text configuration file so that it knows how to interpret the binary data. The script then reads the raw binary file, arranges the data into a matrix which matches the configuration file input and writes the processed data matrix to a .csv file along with header lines that define the channel names & units. The necessity to have a configuration file which matches the logger C struct means that I need to be particularly meticulous when it comes to documenting changes to the logger software and I need to have good version control.

Version 1.0 of the logger software & post processing script leaves some room for improvement but I am happy that I have an easy to use and reliable datalogger that I can fit to the bike and use while I work on further improvements.

Some improvements which I have in mind are:
  1. Remove the CAN message processing from the Teensy software and log raw message values. The post processing script will be capable of doing the data conversion as well as the binary to decimal conversion. Removing the processing from the logger just means that I can free up some processing power & main loop time to help increase reliability at higher data rates. Logging single bytes also will have the advantage of reducing the size of the struct as it currently pads variables out to the largest precision value (32-bit float). If all variables to be logged are full CAN message data sizes (64-bit) there will be no need for any additional padding.
  2. Add one or more data buffers to the logger software. This should help logging reliability and increase the potential logging rate by not requiring the SD card to be ready for writing on each data write loop. 

I 3D printed an enclosure for the board in ABS plastic. The case is not fully sealed as I have left a slot in the side to allow me to remove & insert the SD card without opening the case.

To complete the logger connection to the bike, I made up a short adapter harness which is sleeved & booted at the connector end. The adapter harness is then cable tied to the PCB board via 2off small slots which I had cut in the board for this very purpose. This just serves to provide some strain relief for the header pins & socket. I also printed a wire seal from TPU as an experiment to help seal the area where the harness exits the case. I also added a label to the harness to identify the module. Because.... well... it looks nice.

Bike interface connector

Adapter harness in position

Case with cable seal

Monday 6 May 2019

Making an Exhaust Silencer

It has been quite a while since I updated this! Apologies. I need to be more diligent in posting updates.

During my last track day of 2017, the exhaust silencer on the TSR system suffered a mild failure where the perforated tube broke off from the main body and dropped down into the link pipe.

I treated this failure as a perfect opportunity to get a new silencer for the bike. I had thought that the silencer that came with the TSR system looked tired and was also too long to suit the look of the bike.

Naturally, option #1 was to purchase a ready made exhaust silencer from an aftermarket supplier and do a straight swap. Unfortunately, I found that the entry diameter for the TSR silencer is not very common (45mm) and while it was possible to purchase a direct fit silencer from one or two aftermarket manufacturers, all the exhaust designs were either far too short or had far too large an exit diameter to suit my taste. I did not want the silencer to look like a race style or a stubby.

Option #2 was to request one of the UK-based exhaust manufacturers to make a silencer with a bespoke entry design to suit the TSR link pipe. This seemed like a good route to begin with but as the design progressed, it became clear that the entry pipe design would be compromised by an external diameter change to allow the manufacturer's standard tooling to fit. The silencer would have had a swaged neck in the entry pipe which I felt would have looked unsightly on the finished product.

Option #3 was to attempt to repair the original silencer myself. I found a local supplier from whom I could purchase carbon tube in the correct diameter (also not standard) as well as the perforated tube and packing material for reasonable cost so the decision was made to have a go at doing it myself.

The optimum aesthetic length of the silencer was chosen by applying some basic photoshop "skills" to a photo of the bike and I decided to reduce the silencer length from 450mm to 350mm. This made the silencer look much more in proportion to the rest of the bike in my opinion but without making it look like a short stubby silencer.


When the old TSR silencer was dismantled, a few items stuck out as needing to be changed.

  1. The rivet holes in the old end caps had been damaged so most were oversize. To provide a better surface for the rivets to hold on to, a new strip of stainless steel would be added inside the end caps
  2. The old perforated tube was smaller than the silencer entry diameter and was only tack welded to the end cap in 2 places. It was also not supported at the exit end of the silencer which allowed it to vibrate and eventually break the tack welds and fall down into the link pipe. I sized the replacement perforated tube to be nicely supported on the exit end. As this still left the diameter of the perforated tube smaller than the entry diameter, I flared the end of the perforated tube to match and welded it fully around its circumference.
  3. The sleeve of the TSR silencer had been riveted directly to the end caps. I wanted to add rivet straps at each end both to provide a barrier between the rivets and the carbon sleeve and to provide a decorative finish to the silencer.

First the silencer assembly was modelled in 3D to ensure all parts fit as intended.

Modelling the exhaust assembly allowed me to get the rivet straps just right. The profile was laser cut from stainless steel sheet and bent into shape.

The perforated tube was flared and welded to the entry cap.

 The silencer was first dry assembled using clecos and test fitted to the bike.

Then the parts were riveted together.

And the packing material added.

Overall, the repaired silencer looks much better in my opinion and makes for a cleaner look than the old TSR silencer. The sound from the exhaust is not significantly different from before so that is a plus. There are a few things I would improve on or do differently if I was to do the job again but I am happy with the end result.