I wrote about a project this morning that used a piece of tinfoil connected to an Arduino to simulate touchscreen presses on a tablet. I tried to do this myself but couldn’t get it to work reliably. I had already written this Android app which I intended to use with the interface technique had it work. I can’t unwrite that code so I’ve decided to share it. There’s a description in the video, and here’s a link to the code repository:

https://github.com/szczys/Android-binary-ASCII-entry-test-app

[via: http://jumptuck.com/]

 

I finally got around to taking some pictures and shooting some video of my assembled clock project. Above you can see it displaying time. Minutes are tracked by the blue LEDs in binary code. Each spire has three digits, when the inner and outer digits are lit it shows a binary five and the next spire starts counting. Hours are displayed as a red LED corresponding to the positions on an analog clock. Here it is 12:54.

After the break you can see the video of the clock in action, as well as a description of what went into the build. You’ll also find some close-up pictures and a bit more info.

The assembled hardware

Here you can get a pretty good look at the assembled clock. If you didn’t see my last post, I made a fast-motion video when soldering the board. I intended to do the same thing with the spires but unfortunately I somehow lost the video I made.

Testing the board before soldering LEDs

On thing I made sure to do before I started soldering the LEDs was to test the board. I programmed the ATtiny44 and then used this little module that I made to test all of the connections.

Since each spire connects to a 1×5 grid of 0.1″ pitch holes a pin header worked perfectly for testing. I just soldered four small LEDs in the same electrical orientation as the multiplex on the PCB. The test code I used lights each LED in sequence, pausing 300 milliseconds before moving tot he next.

The components:

On the front of the board I have two tactile switches at the top. These will be used primarily for setting hours and minutes, but I plan to use long-press, and pressing both at once to add functionality. I think there is room for a couple different display techniques (mimicking analog clock hands, etc.). I also want to add control for the intensity of the LEDs. These look just fine during the day, but at night they seem way too bright.

To the left there’s a 2×3 pin header for ISP programming. At the center of the board is the ATtiny44/84 that drives the clock, and to the bottom right there’s an I2C pin header and power header. Also on this side are the four PNP transistors that are used for multiplexing, and an ill-advised status LED pad. This LED has not been populated because it shares a pin with the minutes button. The two cannot be used at the same time without damaging the microcontroller.

The back side of the board hosts the RTC hardware, sink driver, and USB connector. The USB is only for 5V regulated power, and provides no connectivity. The sink driver (STP16CP05) is my new favorite part. It’s constant current so you just set one resistor value and it takes care of the rest. This greatly simplifies the multiplexing since I’m using two different color LEDs that have different voltage drops.

The RTC hardware includes the chip itself (MCP7940) uses a CR1220 backup battery and a 32.768 kHz clock crystal to keep time. It seems to be running a little fast but there’s a calibration register I’ll look into as I work more on the code.

PCB, parts, and code

I developed the board using Kicad. This was my first Kicad project and I have to say I like it a lot more than Eagle, with which I’m already well versed. I orderd the PCBs from Seeed Studios. It was a great experience and I’m sure I’ll use the service again in the future.

All of the board information, as well as source code is available from my Github repository.

Next project:

I think my next project should probably be to build some type of camera tripod. I’ve shot the last couple of videos at the bench using the setup seen here. It a chunk of scrap wood tied to some stools and the shelf above my soldering station. I use a quick clamp to mount the Flip camera in place. It works, but it’s not very adjustable.

[via: http://jumptuck.com/]

 

I received the boards back from Seeed Studios two weeks and four days after placing my order. I’m shocked by the quick turn-around, especially since I selected the slowest shipping option available which itself could have taken three weeks.

I’ve been pretty busy with work lately but finally found a bit of time to populate a board and get some test code running. I’m happy to report that I made no design errors. Everything seems to work as planned! Well, that is after I discovered the tiny trace bridge between two vias which prevented ISP communications with the chip. A sharp razor blade fixed that right up. I understand that this type of manufacturing error is not uncommon and it doesn’t really bother me.

Above is a fast-motion video I made while populating the second board. I’ll be sending this one to my friend Christian who is going to lend a hand adding features to the firmware. Hand soldering the mostly SMD project wasn’t too hard, but it did take about an hour. If I were making any more than two of these it would be worth it to order a stencil and procure solder paste and an old toaster oven for reflow. Perhaps on the next project.

In my next post I’ll talk about adding the LEDs. This took a long time. The first spire took about 45 minutes, by the twelfth spire I had it down to around twenty. Here’s a peek at the final product:

How did I do hitting the mark from my concept?

[via: http://jumptuck.com/]

 

Woohoo!

So, I spent the last few days tweaking my feedback loop to incorporate phase matching as well as tempo matching.See, before, my code would simply match the motor speed to a designated speed, but it could be completely off beat otherwise.I tried a few different methods for achieving this, and I think I found one that works.

Measurement Methods

Earlier, I measured speed by simply starting a timer at the beginning of every cycle and reading it at the end of every cycle.Similarly, for beat measurement, I start a phase timer as soon as a certain command is sent to the unit and reset it when it runs down to zero.This timer continuously runs down and resets until I tell it to stop.The idea is that the circuit keeps a local copy of the song’s timing so that it doesn’t need constant input from an outside source.

To get it started, I simply let it measure the time elapsed between certain commands that are triggered by my laptop.If I trigger those commands every song beat, it will have an accurate measurement of the song’s BPM.In the future, the beat-detection circuit will send those signals.

The minimum length of time that the timer can measure (as currently implemented) is around .4 milliseconds.With this level of granularity, you’d expect that it could measure the BPM of a song accurately enough such that once synced up, it won’t drift during the length of the song.What I found is that it would rapidly drift away such that it was noticeably off beat within 10-20 seconds.

I believe this is due to unpredictable delays that occur somewhere between my laptop and the circuit.Remember that this signal is being sent through a USB-RS-232 dongle.There’s a lot going on.RS-232 commands are not considered to be time-critical, so the dongle adding delay is likely not outside of its operation spec.

My future BPM detection circuit will be able to send commands with much higher precision, but in the meantime, I simply sent the timing command every single beat so that I effectively manually reset any drift that the circuit might be experiencing at the start of every beat.A little bit of a pain, but tapping a button on my keyboard isn’t too difficult.

The goal of my feedback control system is to get the period of each cycle as close to the target time as possible and to get the phase timer as synchronized to the cycle timer as possible.At the beginning of every cycle, my code looks at the phase timer.If the phase timer is very close to zero, that means that the beat is leading the wipers by a small margin.If the phase timer is very close to its maximum value, that means that the beat is trailing the wipers by a small margin.

Simple Proportional Feedback

If you remember from my last post, I had a feedback loop that looked something like this:

The idea is to calculate how far you are off your target and adjust proportionally to bring you closer to your target.Adding phase control makes it look something like this:

Look familiar?

There’s an important point to be made about this system.Because you only care to be on some beat, you always have the option to speed up or slow down to get back on beat.Because of this, the subtraction of measured phase to desired phase is considered to be subtraction from the closest beat.

Looking at these two loops, you’d expect this problem to be no harder than the previous problem as there are two isolated systems.The issue is that the systems aren’t quite so isolated.

For example, let’s say the system’s timing is correct, but the phase is trailing by a small amount.I could compensate by speeding up slightly, but then the system sees that the speed is too high and tries to slow it down.This throws the phase off again, so the same adjustments are made again and again.The result is an oscillatory system.

Here’s a graph of the process.The x axis is cycles and the y axis is period (measured in units of .4 milliseconds).

In this plot, the “phase” measurement is actually the absolute value of the phase error and is trying to approach zero.

The speed error gain was a lot higher than the phase error gain, so you can see that the system favors speed to phase especially when it’s first starting out and appears to be ignoring phase altogether.This quickly sets it into oscillation, and the system never really settles down as it continues to oscillate upwards of 30 cycles later.

So, what happens if we lower the gain of the phase by a lot?I re-wrote the firmware so that it restricts the gain to either +1 or -1 on the motor’s speed settings (of which there are 255; about 150 or so are reasonably fast).This should prevent oscillations as even at its worst, the speed can only be altered a small amount to account for the phase.Here’s a plot:

As you can see, there are a lot fewer oscillations this time around.You can also see that the phase is being matched very gradually taking tens of cycles.Keep in mind that each of these cycles takes upwards of a second.It could take even longer if the phase was further off to begin with.

The plus side of this method is how stable the system is once it finally settles down.

To speed up the settling, I decided to take the advice of a friend who suggested a slightly smarter feedback system.

Match Speed then Phase

The entire point of doing this feedback system is that I don’t know exactly how fast the wipers will move when given a certain speed setting command.There are a lot of variables that can interfere with the wiper speed such as window wetness, battery voltage, wind, dirt, etc.Because of these, I need to guess a certain speed, and then evaluate how good the guess is before guessing again.

If I knew exactly how fast the wipers would move at a certain speed setting before doing any tests, I could do what’s called a “feed forward” system where I could basically predict the future.

The thing is, once my code has found the speed setting that brings about the desired wiper speed, it’s safe to assume that the same speed setting will produce close to the same speed in the future so long as there aren’t any major changes in atmospheric conditions that can interfere.

This lets me do what is essentially a feed-forward system.I designed my code to take advantage of two facts:

  • The wiper setting that produced a speed will likely produce the same speed if used again.
  • Wipers take negligible time to accelerate.

Basically, once my wipers are satisfied that their speed is correct enough, they can stop entirely and just wait for the beat to catch up.As soon as the beat catches up, they can start immediately at the previously determined speed setting and not be two far off in speed or phase.

So my code now has three parts:First, it completely ignores phase error and tries to match speed.Second, it pauses and allows the beat to catch up.Third, once the beat is caught up, it starts again and uses the feedback method described above.Remember that that method was very stable, it just took too long to get there.With all of the hard work done, it’s perfectly adequate to maintain the already near-perfect beat.

Here’s a plot:

As you can see, the phase drifts wildly for the first 13 cycles or so and then rapidly drops to zero and stays at zero.

Testing

It was warm out today, so I had a chance to test my new algorithm on the real thing:

I was excited to find that the far end of the wiper cycle appears to be directly in the center of the ends time-wise.This came as good news because otherwise, I would need to adjust motor speed mid-cycle and try to guess the location of the far end of the cycle as the wiper motor only provides feedback for the parked position.

I was less excited to see that the parking switch appears to be slightly out of place.Humans are incredibly perceptive to mismatches in beat, so try as I might to ignore it, I couldn’t help but notice that the beat of the song was coming slightly before the beat of the wipers going down.

While it would be convenient if the parking switch were to be moved by a few degrees, I’ll probably have to make some considerations in the future to add an appropriate time lead or lag to counteract the misalignment of the parking switch.These considerations could be made on either the motor driver itself or on the device sending the signals to the motor driver.Either way, I’ll deal with it later.

Conclusion

I am very satisfied with how well this all turned out.Though I’m only part of the way there, getting the motor control down was a major stepping stone and honestly the one I was most worried about.All I need to do to properly finish up this step is to find a way to securely mount the motor driver in the engine bay and test how well it stands up to hot environmental conditions.

Now that the hardware part is more or less completed, what comes next is a bunch of audio processing and coding.Not exactly my favorite thing in the world, but at least it can be done from the comfort of my chair rather than in out in the parking lot.

[via: http://ch00ftech.com]

 

So, using my newly scavenged motor, I set to work doing some firmware coding this weekend.Previously, my code simply took speed setting commands over serial and implemented them on the motor driver.Now, it’s a little more intelligent.

Purpose

Feedback is important when your environment is uncontrolled (or uncontrollable).The most familiar example of a feedback system is the cruise control in your car.You set the desired speed, and it adjusts the gas pedal to account for changing conditions.When you go up hill, it revs the engine higher; when you go down hill, it lets off the gas.

That’s exactly what I need for my wiper driver.depending on atmospheric conditions, the same speed setting might produce different speeds.For example, I found earlier that just wetting the windshield or turning the car off or on can have a drastic impact on the reported speed of the wipers.

With my new code, I only need to send a desired BPM to the driver board and it will attempt to match that BPM by trial and error.If it detects it’s going to fast, it will “let off the gas” and so on.

Method

My wiper system is what you would call a “first-order system”.Basically, it has little to no inertia.When I change the speed setting of the wipers, they change speed immediately.An example of a second-order system would be something like the car itself.When you floor it or slam on the brakes, the car takes a bit of time to react.Second-order systems are a lot harder to control.

In my code, I implemented a very simple feedback loop.Here is a block diagram:

This might be a little funny to look at, so let’s break it down:

changing resistance

This block represents environmental conditions that will change how the motor reacts to its input speed setting (wet windshield, etc)

Previous speed setting

This part is a little confusing.My system is a discrete system which means that rather than making continuous adjustments, it only makes them at certain points. Specifically, once per cycle.The “Delay” block takes the speed setting from the previous cycle and brings it into the current cycle.This is the only type of “memory” that the feedback loop has.

With this delay, it is able to base the next cycle’s speed setting on the previous cycle’s.

Desired acceleration

This signal is the result of subtracting the actual speed from the desired speed and applying a gain.If the actual speed is lower than the desired speed, positive acceleration is needed and vice versa.

The gain stage is very important.Applying gain is basically multiplying the incoming signal by a constant.If the gain is too low, it will take too long for the system to react to change as the desired acceleration will be very small.If the gain is too high, the system could accelerate way too fast and overshoot its target speed.Feedback system designers are always playing with gain levels to try to get optimal performance of their system.

in code form

Rather than dealing with speeds, my code deals with time measurements per cycle, so things are a little switched around: higher time -> lower speed.

int32_t diff = targettime-currenttime; //subtract measured speed from current speed.diff = diff/3; //Apply gain (gain=.333)nextspeed = diff+OCR0A; //OCR0A is the speed setting currently implemented.

Note that nextspeed and OCR0A are inverted; a higher value means a slower speed. That’s why diff is added instead of subtracted.Also note that the time measurements are not in the same scale as the speed settings.Time is measured as time elapsed during the cycle while speed is the duty cycle set from 0-255 where 0 is full duty cycle.

 Performance

I’m very pleased with the performance of my motor under this code.I put together a little demo video showing it off.

In the video, you will see a live plot of the motor speed as it updates.Note that the plotted data is the speed of the previous rotation, so there will appear to be some time lag.You will also see a live output from the Python terminal showing the values that the micro-controller is measuring.Note that the “diff” value is inverted and not on the same scale as the other two.

You’ll also catch a glimpse of my new metal motor driver enclosure.It’s a work in progress at the moment, but I’ll post about it when it’s finished.

Conclusion

So, I’ve got code on my micro controller that will match the BPM sent to it.The next step will be getting it to match the BPM and the phase sent to it.As is, the wipers might be going the right speed, but they probably won’t be reaching the ends of their cycle quite on beat.

[via: http://ch00ftech.com]

 

I took a trip to a junk yard this weekend and got a bunch of awesome stuff!

All for $30!

Salvage

Firstly, let me say that junkyards are exactly as cool as you might expect.There were literally piles of cars to pick through organized by brand.I moseyed over to the Toyota section and set to work.

The first thing I did was grab a bunch of those connectors that I was looking to buy.They were the easiest part to extract, so I figured I’d grab a few.I also grabbed a wiper fluid pump because mine broke like six years ago.I’m not sure if it’s compatible with my car, but I can’t imagine there are too many different types of wiper fluid pump in a single car brand.

Lastly, I wanted to grab a wiper motor.The one in my car works fine, but I thought it would be convenient if I could use the motor inside during development rather than having to do all my coding outside in the cold.

Extracting a wiper motor isn’t super easy.It also doesn’t help when the bolts are likely to be rusted and you don’t own a socket set.The real issue is maneuvering whatever tool you’re using around all of the engine parts.

I found that a rule of junkyards is that there is always a car somewhere that has exactly what you need.For example, a wiper motor out in the open:

“Where is the engine?” you might ask?

Probably in a number of places.

Everything Old is New

When I got the motor home, I was excited to see that it worked!I was less excited to see all the caked up grease, rust, and dirt falling off the motor every time I touched it or turned it on.I suspected this dirt was partly responsible for the spurious data I was getting from the parking switch contacts.They started out working fine, but after a few hours of testing, I had some really gross looking waveforms coming out.There was also a squeaking sound that got louder as time wore on.After years of sitting immobile, a lot of grime had settled that I was suddenly stirring up.

Because I wasn’t looking to use this motor in any real application, I figured it’d be safe to take it apart and see if I could clean the contacts.Using a T-20 Torx driver and careful force from a chisel, I managed to separate the back panel of the motor:

That right section houses the contact brushes and disk.The plastic part you see has a small plastic nub that hooks on to the rotating section opposing it.It wasn’t super easy to get access to the disk.Instead of a bolt holding it down, there was some kind of plastic harpoon-tip style piece that looked like it wasn’t intended to ever be removed.

This tip isn’t needed when both halves are assembled though; everything is held together pretty tightly by the outside housing.I figured it was safe to remove the tip by boring it out with a drill.

No wonder I was having problems.That’s a pretty gross disk.Using some dish soap, an old tooth brush, and some elbow grease, I think I cleaned things up pretty nicely.

I took some of the clean grease that never really got spread out properly (the blue blob on the top right) and applied it evenly to the metal disk to prevent the now-clean contacts from wearing out.

After slapping it all back together, I found that not only are the contacts a lot cleaner, but it also stopped squeaking!

I’ve very rapid progress programming with the help of this motor, but it’s getting late, so I’ll have to clue you in on my new code in another post.

[via: http://ch00ftech.com]

 

I had a chance to test my wipers today under a myriad of conditions.Here are the results where the x axis is speed setting (lower is faster) and the y axis is seconds per cycle:

Setup

So I ran two trials under three different conditions.I forgot to bring my camera with me, so I don’t have any photos.You’ll have to rely on my descriptions.Red is self-explanatory; it’s how I’ve been running all of my tests up to this point.For green, I carefully made sure that none of my wiring would get in the way of moving parts of the car and started the engineAt the 14.4V supplied by the car’s alternator, it had a little more juice to power the motor.For blue, I carefully wired the driver up and tucked it into my motor so that I could safely shut the hood without crushing it.My friend held a hose and kept the windshield wet with a slow and steady stream of water while I ran the test.

Issues

Spontaneous reset

I noticed a new issue this afternoon.After running the test with the car on, I noticed that my circuit kept resetting itself.At first I was worried that this had something to do with voltage fluctuations in the power supplied by the alternator.Under further examination, I think I determined it to be just a result of the vibration of the motor.

My circuit was powered by two wires connecting to the battery terminals via alligator clips clipped straight to the bolts that hold the battery terminals on.These bolts are all caked up with grease and dust from the motor bay, so there was already a lot getting in the way. The added vibrations probably caused short term disconnections that reset the circuit.

I’m still not 100% certain that this is the case.I noticed the circuit resetting a few times while the car was turned off (after having it on for a while) though after fiddling with the battery terminal connections, the problem went away again.I’ll see if this becomes an issue in the future.

Spurious data

As you can see in my plot, there are a few cases where the curve shoots down to zero.This is likely due to the same kind of contact bouncing that I thought I had fixed.While I would rather have no bouncing at all, it’s good that there isn’t any spurious bouncing in the middle of a frame due to bumps on the disk.All of the spurious data seems to register a zero second wiper cycle which means that it probably just bounced a bit as the brush was making or breaking contact with the disk and registering it as the end of the wiper cycle.Making my software debounce timeout a little bit longer should fix this problem entirely.

Conclusion

I was very surprised what a difference wetting the windshield made on the wiper speed.It’s also pretty curious how the wet windshield with the car off lines up so well with the dry windshield with the car on.This is likely a complete coincidence but still interesting though.It makes me want to run the wet windshield test with the car on to see how it compares.

Overall, I am very excited to see how consistent the data seems to be.This means that as long as there aren’t sudden changes in conditions, my circuit shouldn’t have to worry too much about accounting for variances in drag over the course of a single song.

Also, it looks like the fastest performance I can hope for out of my wipers is on the order of 60 bpm (or 120 if I do half-cycle beats).It’s pretty convenient how gradual the slope gets at the higher settings though.That means that I’ll have the ability to fine tune my wiper speed in the range that really matters.

[via: http://ch00ftech.com]

 

So today, I learned the importance of preventing things from bouncing.

The Problem

If you’ll recall with my windshield wiper project, I am using part of the windshield wiper motor to give me information on the wipers’ current location.Two of the five contacts that the motor provides connect to little metal brushes that run along a rotating metal disk.One of the brushes is in constant contact while the other passes over a small hole in the disk once per revolution.

The original purpose of this configuration is to allow the intermittent mode of wiper operation to work almost autonomously.The car will run current into one of these brushes and out the other to power the motor.When one brush reaches the hole, the motor will lose power and stop.This is what causes the wipers to stop at the end of a single wipe in intermittent mode.

Now, these brushes are designed for high current applications, not for precise position measurement.For example, if one of the brushes were to lose contact for 1ms or so, nobody would notice.

Recently, I’ve been trying to capture accurate information regarding how long it takes the wipers to complete a single cycle when setting them to various speed settings.I wrote a script that would try the wipers for one cycle at a speed setting, then change speed.My results look like this: (x axis is speed setting, y is time in seconds)

You get the general gist of what’s supposed to be going on by looking at the logarithmic slope you can see along the top.So what’s up with the rest of the data?

Well, I’m fairly certain that the brushes are “bouncing”.This is a common phenomenon with any kind of metal contact switch.When you smack two pieces of conducting material together, there is a very high probability that they will vibrate and have an intermittent connection for, say, a few hundred microseconds.

Here’s an example of one such vibration as the green signal passes from low to high (note the time scale is 20us per division):

This is an inconceivably small amount of time for a human, but it’s eons for a micro-controller.The micro might see a contact and separation happening a few microseconds apart and assume that the windshield wipers have made a full revolution in that time.I believe this is why there are so many quick measurements in the data I retrieved.The only reason the measurements aren’t on the order of a microsecond is because of how long it took Python to respond to the cluster of tightly packed messages that the micro-controller sent out.

So, I needed to find a way to “de-bounce” my signal.

Solution

There are two potential solutions to this problem:

  1. Solve it in software
  2. Solve it in hardware

Software

De-bouncing is often solved in software by adding short delays after a correct reading.If you know the bouncing period is about 500us and the shortest time you should ever experience between switching on and off under normal use is on the order of 100ms, then you can have your code just ignore everything for 100ms after it receives a positive on or off.

This solution works very well with buttons (in fact, it’s probably what your keyboard is using right now), but it isn’t a perfect solution with my configuration because there’s a chance that the brushes will bounce at a random point in their cycle.Remember how they’re running along a disk?It’s possible that there are small bumps on this disk that could cause problems.By contrast, as a button is held down, nothing really changes.

Also, software is a pain.Hardware is where it’s at.

Hardware

What I really need here is a simple low pass filter.This will essentially smooth out my signal removing any extremely brief bumps.

My original circuit looked something like this:

The idea is that as long as both brushes are touching the disk, the micro-controller input is grounded.As soon as the outer one goes over the hole, the input is pulled up to 5v by the 1k resistor.

To implement a simple low pass filter, I added a resistor and capacitor as follows:

The 10k resistor and 1uF capacitor will have a time constant of (10,000*1E-6=) 10ms.This means that it will take about 50ms for the input to switch from high to low or low to high (about 5 time constants).I changed the 1k to a 470 because I wanted to make sure that the time constant was as close to equal for the pull up and pull down as possible.Keep in mind that for the pull up, you have to sum the 470 and 10k together when calculating the time constant.Ideally, I’d go as low as possible, but once you get down to the 100-200 ohm area, you start running into power dissipation issues because you’re dropping 5V across this resistor when the disk grounds the input.

Luckily, these reworks were fairly easy to implement because of how my circuit was laid out.Here’s an updated schematic.

Results

Though I haven’t had a chance to test it on my car, it definitely worked while testing indoors.Because I didn’t have the wiper motor to play with, I simulated the connections by touching a piece of wire to the ground plane or rubbing it along the ground plane.Here’s an example of the signal passing from low to high (disconnecting the wire from the ground plane):

The green signal is before the low pass filter and the yellow signal is after. As you can see, the green signal appears to bounce a little bit as it is lifted, but the yellow signal takes a while to rise.Here the time scale is 5ms per division, so the whole rise takes around 25-30ms.If this turns out to be too long, I can easily tweak it by swapping out the resistor for a smaller one.

And here’s a video demonstrating how well the fix worked:

I was being a little unfair towards the end of the first segment in how I was rubbing against the edge of the ground plane, but there are still a few incorrect messages towards the beginning where I’m rubbing on fairly smooth copper.

Anywho, the board is updated, and I’ll give it another go on the wipers as soon as I get a chance.

[via: http://ch00ftech.com]

 

So I had a chance tonight to test out my motor driver “in the field”:

I was a little hasty because of the cold (and because my camera’s battery was dying), but I did collect some useful data.And a video!

Setup

So, as you can see above, I don’t really have a case for my circuit yet.That will probably be my next order of business.To keep anything from shorting out, I temporarily sat it on the wiper fluid tank which is made of plastic.

I connected the power terminals directly to the battery and the motor terminals straight to the motor.I didn’t bother connecting the car’s wiper driver to the circuit because I was only interested to see whether or not my circuit would explode under pressure.

I was surprised to find that my motor connectors weren’t quite the right size.The ones on the outer ends of the connector housing fit fine (after I crushed them a bit to ensure a snug fit), but the plastic insulator was too wide for the center connection.I had to attack it with a pair of wire cutters for a bit to get it to fit.

Because there’s already so much insulation in place between the conductors on account of the shape of the plastic motor housing, I’ll probably end up ditching the insulated quick connect terminals for the final version in favor of uninsulated ones.

Data Collection

I wrote a simple Python script that ran through various motor speed settings and recorded how fast the wipers moved.As you’ll recall from my other post, two of the contacts on the motor make up the “parking switch.They are shorted together for about 90% of the wiper cycle and opened for the last 10%.When my circuit detects the short, it sends a simple byte command to my laptop over serial (the character ‘a’) and when the circuit is opened, it sends a ‘b’.The yellow LED also blinks to indicate which state it’s in.

Starting with the wipers in the parked position, the Python script started them at a specific speed setting and timed how long they spent with the switch open and closed by waiting for the bytes to come back from my circuit.After one cycle, it stopped them then started them again with a different speed setting.

My results are in the plot below.Time is on the Y axis and the X axis shows different speed settings.Keep in mind that the speed settings range from 2-255 where 255 is stopped and 2 is full speed.The red line shows how much time the wipers spent with the switch open and the blue line represents time spent with the switch closed.Adding the two up will give you the time of one complete cycle.

Ok, so it’s not the best plot.My code was hastily written, and as soon as the wipers got too fast, the Python had trouble keeping up with them so the whole thing died at a speed of about 25.

Still though, it does show some interesting information.It looks like a sort of logarithmic growth as the wipers get slower and slower.Still though, I really need to do this again to see what happens at the faster settings, because as-is, I’m not even showing anything faster than 30BPM (less than 2 seconds per cycle).

Conclusion

I was definitely in a hurry to get this thing done tonight.It was uncomfortably cold outside, and my camera’s battery was dying.I’ll definitely have to go back and do it again some other time.

Still though, I captured all of the data I really needed.My circuit took the current draw like a champ and didn’t even get warm.I’ll have to spend some time cleaning it up and finding a nice case and mounting point for it before moving forward.

The next step is to get some better data in the >30BPM department.It looks like the setting/speed relationship is not linear, so I’ll definitely need some accurate data to create a proper look up table.I’ll also have to see how a wet windshield changes things.

And here’s the video.Sorry there isn’t any audio.I had my camera configured wrong, and I didn’t realize until it was too late.

[via: http://ch00ftech.com]

 

How’s that for an eye-opening title?While you all were watching football this weekend, I made some progress on my wiper driver.

Design

For those of you just joining us, I am trying to build a synchronous motor driver to replace the normal driver for the windshield wiper motor driver in my car.

If you remember from my other post, the plan here is to place this motor driver inside the engine bay of my car and send commands to it/receive commands from it via RS422 over Ethernet.RS422 is a differential signaling protocol that will help cut out some of the noise present in the normal electrical operation of a car and prevent me from getting data transmission errors.

Relays

The purpose of SW1-SW4 is to allow my driver to sit between the normal driver and the motor.When the micro-controller pulls P15 high, all of the relays will switch over, and my circuit will take the place of the normal driver.When P15 is low (or the circuit is not powered), the normal controller takes over.There are four relays: two for the two speed setting connections and two for the parking switch connections.Ground is connected all the time.

Serial Communication

U2 is an RS-422 transceiver.It connects to the AVR’s UART pins allowing me full duplex communication from the AVR to whatever I have controlling it on the other side of the ethernet cable.For the final version, I will have some sort of micro controller setup, but for the time being, I just wanted to connect it to my laptop somehow.To do this, I built a simple circuit on a breadboard as seen here:

There are two chips on this board: a MAX232 which converts the +3V, -3V serial connection coming from my USB serial adapter to TTL logic, and a RS-422 transceiver (ST491ACN) that converts my TTL signal to a differential signal and passes it to my main board over the ethernet cable.

Fet Driver

My plan is to control my motor through Pulse Width Modulating (PWMing) its power source.Because we’re dealing with such high currents, and an inductive load (think of the windings in a motor as an inductor), special considerations have to made to achieve this.

My first inclination would be to use a simple PFET to switch the motor on and off:

Let’s assume that the “From Micro” signal is somehow buffered so that it can output +12V or 0V.

This circuit presents a problem because my motor is like a huge inductor.As soon as my PFET shuts off, my motor’s inductor is going to fight that sudden change in current and induce a huge potential that tries to pull current through the now off FET.This could call damage to the FET, so we need a better solution:

This diode is what you might call a “freewheel diode”.You’ll notice a bunch of them on the terminals of my relays (because the relays are turned on by activating an electromagnet which is an inductive load).The idea is that it doesn’t affect function while the PFET is on, but it allows the motor to safely suck current from ground instead of trying to force it through the PFET while the PFET is off.

This is a pretty good solution, but it isn’t optimal.Even with good power diodes, you’re still going to have a forward voltage around .3V-.7V or so.When you’re talking about 10Amps of current, a .3V drop is losing you around 3Watts of instantaneous power.While I’m not super concerned about efficiency, I am concerned about my diode being unable to dissipate heat fast enough to keep from melting.Let’s replace that diode instead with an NFET:

The issue with this circuit is a function of how the FETS are being controlled.I previously left out my 12V signal buffer, but decided to leave it in this time to illustrate a problem.

FETs can most simply be though of as digital switches.When they are turned on, they conduct, and when they are turned off, they don’t conduct.In reality, it isn’t quite this simple though.It is possible for a FET to be partially on so that it conducts just a little.This will look in the circuit like a resistor, and when you’re talking about 10A of current, they will dissipate a lot of heat and this could cause issues.

As you switch the FET on and off, you want to really power through this “half-on” state.Every microsecond it spends in this state causes more and more heat to dissipate.Because of this, you really want to yank that gate voltage up and down as quickly as possible.The gate will have some sort of gate capacitance (in my case, around 900pF), so the pull up resistor and that gate capacitance will act like an RC system and slow down the switching action.Slow switch means more time spent “half-on” per switching cycle.

A solution is to use a special chip called a gate driver that is designed to deliver a crap load of current (on the order of 2-2.5Amps) to the gate of the FET.With my FETs, a 2.5Amp current will switch the FET on (bring its gate from 0-12V) in about 1ns.This is a good thing.

Okay, so let’s use a FET driver:

So, this is starting to look good, but there are still some issues.PFETs are typically not as efficient as NFETs.This has to do with quantum physics and the fact that electrons move more readily than “holes” in silicon.A good power P-channel MOSFET is going to cost a lot of money, so let’s ditch that guy and try it with two NFETs:

So, this isn’t going to quite work.An NFET is turned on when its gate potential is at least Vthreshold more volts than its source potential.With this configuration, there is no way to guarantee that with the top side NFET.If the output is very high (for example 10V), the best you could hope for is a 2 volt difference between its source and gate.

To solve this, you need a special kind of FET driver called a “High Side Driver”.This will allow you to drive the high side FET (duh).This is achieved using a capacitor.When the low side driver is switched on, the capacitor charges, and when the high-side driver is switched on, the chip shorts the charged capacitor across the gate and source pins of the high side FET, guaranteeing that it is on.

This method works great except for one caveat, and it’s a small one.Because the high side driver depends on the charge in the capacitor to stay on, it can not stay on indefinitely.Eventually, the charge in the cap will dissipate.All this really means is that you can never attain a duty cycle of 100%.The best you can hope for is 99.9%.This also limits your switching frequency options.The switching frequency must be high enough such that the capacitor does not fully discharge before the end of the switching cycle.

There are a few other considerations here too.You need to be very careful that you never turn both FETs on at the same time.This will cause “shoot through” wherein you basically short your power supply to ground through the FETs.This is very bad.I don’t have to worry about this though, because the FET driver I’m using has integrated protection that makes sure that it switches off one FET before switching on the other.

Construction

The construction process was not too remarkable except for the fact that I forgot to uncheck the “mirror” option when printing out my etch-resist in my printer:

That was only a moderate setback.

I found some standoffs in one of my many drawers, and decided to use them to make my board sit flat:

Those four black boxes on the bottom are my relays.you’ll also note that I reinforced one of the traces on the top with a piece of stranded wire and a lot of solder.This is the output of my FETs, and I wanted to make sure that there was enough copper to carry 10A of current.This board was made with 1oz. copper which isn’t too thick, so special considerations were made.

The white wires coming off the top are just to power my serial interface breadboard because I was too lazy to find another +5V supply.They’re only there temporarily for testing purposes.

Software

I wrote two pieces of software to make this thing work.The first was a simple Python script that passes values over the serial port to my board.The board was set to accept serial bytes and use them to determine the duty cycle of the FET driver.Furthermore, a byte of “0″ switches the relays off and a byte of “1″ switches them on.I used the “serial” package in Python. “Struct” allows me to convert Python datatypes to raw binary bytes for transmission.

import serialimport structser = serial.Serial('/dev/tty.usbserial',9600,timeout=10)print ser.write(chr(0))while(1): command = raw_input("Input command: ")if command == 'on':ser.write('\x01')elif command == 'off':ser.write('\x00')elif int(command) <256:ser.write(chr(int(command)))else:print 'Invalid command'

The code running on the micro controller wasn’t quite so simple.It needs to properly setup the ATTiny2313′s serial interface as well as its PWM signal generator.

I’ll spare you the code, but here are a few details that might help.I wanted my baud rate to be as close to the standard 9600 as possible.My clock was running at 10Mhz (I made sure to deselect the div8 bit of the lower fuse so that it was actually running at 10Mhz as opposed to 10/8Mhz.I then used the formula on page 113 of the data sheet:

And came up with UBRR = 64 (this is actually 9615 baud, but that’s close enough).I set the low byte of UBRR to 64 and the high byte to 0.

I also selected asynchronous operation, 1 stop bit, no parity, and 8 bit characters.The PWM mode was set to MODE 5 (fast PWM).I also used the ATTiny2313′s waveform generator to set and clear the pin going to the FET driver automatically without any need for software interrupts.

This mode operates by incrementing a counter every clock cycle.This counter goes from 0 to 255.When it reaches 255, the pin is cleared and the counter is reset to zero.When it reaches the predetermined threshold value (sent from my Python script), it sets the pin.In this way, 255 is a 0% duty cycle, and 0 would be 100%.A little counter intuitive, I’ll admit.

Testing

Now the fun part about the pencil.I wanted to test my circuit using some sort of test load.Usually, one might use a power resistor, but I decided to use a pencil instead because they’re cheaper and more fun.The lead from a wooden pencil can be removed fairly easily by splitting the wood using a pair of pliers or wire cutters:

I then configured my circuit according to the following block diagram:


And here’s a video of the test.Stick around to the end to see the lead glow:

There were a few things that bothered me about that test.The first is that the output waveform of my FETs seemed to not be very square.I pondered this issue for a while until I realized that it had something to do with my scope probes not being configured correctly.After fixing them, the waveform turned out super square:

See?

The second is that I was only able to supply a max of 5A because that’s all my 12V, 4A wall supply would put out before it completely switched off the output.For a real test, I was going to need something with some real juice behind it.For this, I turned to my uninterruptible power supply:

Hell. Yes.

This battery is normally used to power a few hundred watts of computer equipment in the event of a power failure.Sure, it only lasts for a few minutes (long enough to safely shut down the equipment connected to it), but I wouldn’t need a lot of time.

I replaced my 4A supply with this bad boy and really cranked it up.Here it is clocking along at 11.2A:

Oh yeah, that little dot of light next to the pencil lead is a flame.I caught my desk on fire:

Whoops.

Results

All in all, the driver appears to be a success.While it was pumping out 11Amps of current, the FETs hardly got warm.If anything, the bypass capacitors on the high side FET got a little toasty.This is because they’re working so hard to stabilize the 12V rail.If the heat becomes a problem, I’ll have to replace them with something with a lower DCR (currently, they’re electrolytic, which typically have a high DCR).I’ll also have to strip and re-finish my table.

Next, I’ll be testing the inputs on the motor driver.These are what the other relays are for, and they will let me read the position of the wiper blades (or at least tell me when they’re parked).

[via: http://ch00ftech.com]

© 2011 Geko Geek This is a news aggregator website. Articles and images are copyrighted to their original source authors. Gekogeek takes no responsibility about the articles content Suffusion theme by Sayontan Sinha