Category Archives: Software

Supermoto Power Control Module

Since 2010 the Yamaha YZ450F has had electronic fuel injection (EFI). To support the new electrical loads of the bike – more powerful ECU, fuel pump, fuel injector, additional sensors – Yamaha beefed up the stator and added a capacitor to help with start-up transients (this is a battery-less system and still starts first kick!). However, after all of these loads are taken into account, the stator has roughly 50W of additional power available for accessory loads. The two largest loads on a street legal bike are the headlight and radiator fan (with the horn pulling up a close third). Even with a high-efficiency LED headlight the load can be as high as 20W, and a radiator fan (like this one) can draw 24-30W. To overcome these limitations, I decided to design a control unit to:

  • Provide HI/LO functionality for the headlight
  • Control radiator fan speed
  • Automatically dim the headlight when the radiator fan is on

This post details the design process I took to arrive at a functional control unit.

MOSFET Evaluation

While still working on specifications for the final design, I decided to take a detour on a small side project to more closely evaluate MOSFETs and associated driver circuitry. At this point, I hadn’t designed a board to drive any sort of real load, so I was curious about the behavior of the associated electronics. I designed a PCB to evaluate the MOSFET I was considering for the final design (IRFR3806), as well as a MOSFET driver (IRS44273L). I included a BNC connection for the input signal (as I expected to use a function generator to drive it), as well as removable Molex connectors for the supply voltage and drive output, and test points to check the voltages at the input, gate, and drain. I also used an 0805 resistor between the driver output and the MOFSET gate labeled “SLEW” on the silk – I didn’t end up playing with this part, but the idea was I would be able to control how quickly the driver charged the gate by swapping out this resistor for different values.

I happened to be reading the FET chapter in The Art of Electronics while working on this project, so I grabbed a scope shot of the gate voltage:

Always cool to see theory reduced to practice.

The next day I brought my board and fan into work to take advantage of the higher-end equipment I had available. As part of the design I included a current shunt resistor – the Fluke seen in the picture is measuring the voltage across it. With this setup I was able to easily perform a number of tests:

  • Carrier frequency evaluation – because the fan makes a large amount of noise, this frequency could be much lower than the one used for the headlight (I don’t have any pictures of testing that with this board).
  • Duty-cycle to current table

I’ve been spoiled by the MSO4034 at work, makes my TDS320 look a little sad.

Control Module Development

Let’s start with the good stuff, the assembled board:

Assembled! This was a fun one, first board I’ve made with 0402 components.

I ended up switching to a smaller, “lower” power capacity MOSFET for the final design (BSC340N08NS3G). I targeted a rather small enclosure from Digi-Key, in part because I didn’t want some honking enclosure in the headstock and in part because I like a good challenge (and because OSH Park charges $5/in^2, I’m always seeing just how small I can make something). The design is simple, there are two identical output channels and three identical input channels. I used an ATMega168PB, a low-power version of the classic ATMega168A.

Coming soon:

  • Schematics
  • Description of firmware
  • Photos of it working

ThumperTuner – Talking to ThumperFI

ThumperTuner v0.1 (or so it’s called right now) is my software interface to ThumperFI. I’ve gotten to the point where I want to be able to not only test all aspects of ThumperFI (and that includes reading/writing parameters, tables, etc.) but I need an easier way to change parameters while it’s running – and that means utilizing the UART interface that I’m putting the finishing touches on (well, the v0.1 touches).

I decided to use Python, along with wxPython and PySerial, for the software. Why?

As always, there’s an XKCD for that.

On a more serious note, because it’s cross-platform (wxPython and PySerial, too), easy to write and I already sort of know Python. In short, I’m lazy and don’t have the time to learn OS-specific languages right now. AND I’m wanting to spend the least amount of time possible right now developing this so that I can get back to actually testing and developing ThumperFI.

So far I’ve made a good amount of progress for the small amount of Python knowledge I have. I’ve already talked to ThumperFI and have a basic, really terrible looking GUI that functions.

I swear it will look at least a little better than this.

I swear it will look at least a little better than this.

It’s been tough not expanding my scope like crazy, like I always do, but I want to make sure that the program at least functions and has decent error handling (and flexibility for future development – I don’t want to write myself in to a corner and have to refactor everything in the next minor version).

I’ve compromised with myself, I’m not going to let the command interface get too out of hand but I’m writing it in the most flexible way I can think of – there will be a class that interfaces with my program that handles all of the talking, error-handling (ThumperFI uses an ACK/ErrorCode scheme that I might detail in a later post) and data conditioning, and allows me to add more commands later.

Since starting this post I’ve solidified how I’m going to write the command interface, I’ve got the “Hello” and “Engine Parameter” (“H” and “E”) commands working, so I’ll post a snippet of how that works below:

The real magic of this becomes more evident in the command interface class I wrote.

class CommandInterface:
	commands_dict = {
		"H": StringCommand,
		"E": EngineStatusCommand,
		"R": ReadParameterCommand,
		"W": WriteParameterCommand,
		"P": AllParametersCommand,
		"T": TimeCommand
	}

	def SendCommand( self, command, parameter='', data = [] ):
		# Check that the command exists
		self.command = command
		if self.command in self.commands_dict:
			self.Interface = self.commands_dict[command]()

			# Send command string
			try:
				self._serial.flushOutput()
				self._serial.write( self.Interface.CommandString() )
			except:
				raise
			else:
				# Command sent, time to get the response
				if self.CheckResponseCode():
					return self.CollectData()
				else:
					print "Response code failed (not ACK)"
					return False

So far it’s working really well. I want to write and test the more complex methods soon – like WriteParameter and ReadParameter. The cool part is that if I need to add a new command in the future (which I do, BurnEEPROM, and a few others) I just have to add a new sub-class assuming it works similar to the rest of the commands.

I’m also working on the GUI – that’s been interesting. I haven’t really built anything on the front-end for applications before. I’ve done a lot of web programming when I was still building websites for people but that was all HTML/CSS with a PHP backend and some JavaScript/jQuery magic in the front. I’m using wxPython so I’ve just been doing a lot of Googling for “wxPython” + [something related to it] (+[tutorial/example]). That wonderful looking table you see is a small class I wrote to use the FlexGridSizer to build a table based on inserting a row. It keeps track of the value column so you can modify later by just calling something like:

self.parameterPanel.ChangeValue( "map", self._eparam.MAP )

I tested it out and it works really well so far. I need to add the rest of the parameters to that table but I don’t have simulated inputs for most of the rest yet – I’m also working on that right now (whole lot to this whole building-a-fuel-injection-system thing). Once I get the VR simulator finished (along with a MAP simulator) I’ll be in business for firmware development.

To be continued! (whenever the GUI doesn’t look as awful)