Sunday, January 6. 2013Dual DAC I+Q Generation and Carrier Modulation
I wanted a simple, easily-interfacable QAM source to test some code I had written for the RTL-SDR, so I put together two small boards: one with two SPI DACs to generate the I and Q inputs, and one board with a single analog QAM modulator on it that takes the carrier, I, and Q signals and outputs the modulated carrier.
First, I made the dual DAC board with two MAX515's - simple, 10-bit, SPI DACs. Aesthetically the board was not stunning - I used too large a drill for the through holes, and thus my pads were blown out. However, it was salavgable, so I continued putting it together and testing it by bit-banging the DACs with an FT245R dev board: With that working well, I dead-bugged the modulator, a TRF370417 that will handle carrier freqs of 50 MHz through 6 GHz, to another board: As pretty as that board turned out, it was unfortunately (and predictably) extremely noisy. Oh well, I suppose I will just have to make a proper board for all 3 chips... Saturday, December 15. 2012Reverse Engineering an Audi ECU
The thing that annoys me most about the ECU in my car is that it gives barely any debugging information about sensors and states. It's an older car so some of the sensors started getting a little wacky, but which ones? Fast forward a week and I had decided I needed to pull the code off the ECU to see how it works, then add a few functions of my own. There are a few businesses out there that reflash ECUs for performance increases and such, so if they can do it so can I.
I started by grabbing an ECU for my year and model of car from a junkyard, and opening it up. A quick glance shows that it's very simple: a C167 MCU, which loads its code from an Am29F400B flash at boot. The C167 is a great device for cars, as it has a ton of PWM channels and speaks CANBUS natively, and even includes the ability to load code via CANBUS. I was able to quickly find the datasheet and debugging hints documents, as well as a datasheet for the flash itself. Clearly, my next course of action was to yoink the flash and read it (note that in the above pics, I've already desoldered it from the board). I hacked up a board design to give me easy access to the pins, and cut it using the mill: I did my math right and it came out great the first time. I had quite an internal debate about reading the data though- the elegant way to go about it would have been to write a general FPGA memory reader-writer that would also allow me to do passive memory snooping (ie, latch on address changes and record both the address and data value), but I decided to focus on one project at a time and just wrote a few lines of C for an Atmega board I had handy: It worked nicely! I need to spend some time mapping out the IO addresses, but at first glance, the bootloader has an amusing tamper-protection scheme. The first block of code on the flash loads data into RAM from farther down the flash itself... but adds 1 to each value. Thus, to recover the original instructions, all I had to do was decrement each value by one and pass it into the disassembler again. Epic. Wednesday, November 21. 2012Turbo Controller
My car, an Audi A4 1.8t, opens the wastegate at 8psi above atmospheric pressure, stock. Since clearly more power is better (and building stuff is entertaining), I needed to make something to adjust the boost setting.
In standard turbocharger systems, there is simply a diaphragm that pops at the set pressure, and allows air to flow into the wastegate, reducing the amount of flow through the turbine, thus lowering the output pressure of the compressor. In the audi, there is a valve called the N75 with a two-conductor cable and 3 hoses connected to it: the turbo compressor tap, the wastegate input, and the airbox (for clean air feed under vacuum). I assumed this was simply a solenoid valve, and energizing it causes it to open. As such, my first code revision simply emulated a manual boost controller: at the set pressure (controlled by potentiometer), energize the valve and open the wastegate. ![]() I hacked this all into the car in an evening with an arduino and an N-channel MOSFET (I KNEW that cat5 I ran into the engine compartment would come in handy...) and went for a spin. The results were... unexpected. The car drove just like it did normally and my manifold pressure gauge didn't register anything abnormal, except for one blip where the car unexpectedly made insane power while I was turning a corner. Hmmm. ![]() I plugged the N75 back into the ECU and put my scope on it. Ah! It was being PWM'd! It turns out the the N75 is actually a spring-controlled valve that begins releasing air at it's set pressure of 8psi over ambient. However, the solenoid coil in it can be pushed in either direction to lower or raise the setpoint. So, my logic was backwards: in order to make more boost, you energize the coil to push against the spring. I adjusted my code to PWM the coil, pushing hardest just above 8psi boost then tapering off to the setpoint for a smooth transition. It works great! The car makes significantly more power running 20psi of boost. The only issue with that setup was the placement of my pressure transducer: I connected it to the tap from the intake manifold, post-throttle. This means that the turbo can be ramming out 30psi, but if the throttle is closed we still see vacuum. This wouldn't be a huge issue, except that the ECU's manifold pressure sensor is located pre-throttle, and it (a) sets the mixture and (b) cuts the injectors if it sees a dangerous level of boost (about 22psi). Whenever I would sharply accelerate or take my foot off the gas, the resulting spike from the throttle movement would send the pre-throttle pressure over that limit and cause the injectors to cut then surge back - not very great. I have the system out of the car at the moment to install up front with the new pressure transducer placement just after the turbo. Should be splendid. Wednesday, October 24. 2012FSK Demod and Clock Recovery
I've been working on coding some FSK demodulation and clock recovery in C, since GNUradio's documentation is terrible. My target bitstream is the control channel on the local Motorola Smartzone IIi system, which is 3600 baud. Ideally the code, when finished, will log calls and group associations to make pretty graphs (the system I have doing this currently is a terribly ghetto mess of Windows programs from 1998 and perl.)
The first thing I did was record samples of the stream in two ways: from the soundcard connected to the discriminator tap of my scanner, and from my RTL-SDR dongle. I normalized both outputs into unsigned chars (uint8_t) for simplicity, then coded a quick histogram to make sure my two FSK levels were easily visible. It turns out they are! 8: ###### 16: ######################## 24: ####################################################### 32: ########################################################################################### 40: ################################################################################################### 48: ######################################## 56: ############# 64: ########### 72: ########## 80: ######### 88: ######### 96: ######## 104: ######## 112: ######## 120: ######## 128: ####### 136: ######## 144: ######## 152: ######## 160: ######## 168: ######## 176: ######### 184: ########## 192: ########### 200: ############### 208: ############################# 216: ########################################################### 224: ################################################################################# 232: ############################################################### 240: ################################# 248: ############ The labels on the left are the base value of the bin being graphed, ie "192" is the sum of all samples from 192 to 199, inclusive. As you can see, there are lots of samples at both ends of the plot and very few in the center, which shows that our signal is clean. After I had confirmed that my samples were in fact sensible, I gave some thought to clock recovery. Since both my streams were recorded at 44.1khz in order to be soundcard-compatible, there are just over 12 samples per symbol. However, since the number isn't exactly 12 as well as local oscillator differences, one can't simply determine the center of one symbol then extrapolate ad infinium from there. There are entire books written on clock recovery schemes, but suffice to say this problem is generally solved by a PLL that gets 'nudged' forward or backwards in time based on the rate of change of the signal when the symbol is sampled. However, it's generally advantageous to try the simplest solution first. I hacked up a quick sliding window sampling function that simply tries all 12 available offsets on the given "chunk" of samples (about 1/10th of a second worth), and determines which offset gives the lowest mean signal error. When the chunksize is small enough that the clock error during that period is less than one symbol wide, all the bits are successfully recovered. The process repeats at the next chunk, and no one is the wiser. Clearly this method isn't fast, but I was able to write and test it in an hour. I was able to dump the binary stream from the samples recorded, however it turns out the data is interleaved and I can't find a spec document (Smartzone is a closed standard.) Unfortunately, until I figure that out, I'm stuck. Wednesday, September 5. 2012Embedded WiFi with an RN-XV
I picked up an RN-XV from Sparkfun to see what it would do. I didn't read the docs before I ordered, and I expected to be reading and writing registers and building my own packets. However, I was almost disappointed to learn how much functionality is supported within and how easy it is to get working.
The RN-XV is a carrier board for Roving Networks' RN-171 WiFi module. Since the XV is meant to be pin compatible with the Xbees which use an odd pin spacing, I also ordered an Xbee Explorer Regulated to make connections and power easy (the FTDI cables I have are logic 3.3v but 5v Vcc, so the regulator is needed). I plugged TX to Din, RX to Dout, added power, and BAM! Blinky lights! WiFly Ver 2.32, 02-13-2012 on RN-171 MAC Addr=00:06:66:72:20:58 Auto-Assoc roving1 chan=0 mode=NONE FAILED Unfortunately, it didn't respond to my serial input. After a bunch of tracing and reading, it turns out that the Xbee board does logic level shifting with diodes. The Xbees's have pullup resistors in their Din pins, however the RN modules do not. After adding a 10k resistor from Vcc to Din, I was able to link it to my network and ping things first try. ![]() CMD <2.32> set wlan phrase myWifiPasswd AOK <2.32> join mySSID Auto-Assoc secure chan=11 mode=WPA1 SCAN OK Joining mySSID now.. <2.32> Associated! DHCP: Start DHCP in 775ms, lease=86400s IF=UP DHCP=ON IP=192.168.9.61:2000 NM=255.255.255.0 GW=192.168.9.1 Listen on 2000 ping 4.2.2.1 Ping try 4.2.2.1 <2.32> 64 bytes from 4.2.2.1: seq=1 ttl=251 time=6.56 ms 64 bytes from 4.2.2.1: seq=2 ttl=251 time=6.41 ms <2.32> With the default settings, you can open a socket to the device via wifi on port 2000. Any data that arrives goes out the serial, and any data in the serial goes out the socket. Easy as pie. Now I just need to find something cool to do with it... For the curious: RN-XV Datasheet (pinout), RN-171 Manual and Command Set Saturday, May 5. 2012Hybrid Rockets: v2
Inspired by the wild success of the previous rocket engines, I machined some cases and nozzles from aluminium to see what would happen. What happened was exactly what was expected: epic thrust, followed shortly by epic structural failure.
I machined this beautiful nozzle on the lathe and was extremly proud of it. I knew that, being aluminium, it wouldn't last more than a few seconds assuming ignition was acheived, but it sure was awesome until that point. ![]() And lo, it failed just like expected (through the thin parts), but not before making an absolutely epic flame plume and a noise I can't quite describe other than LOUD. But check out that ablation! ![]() ![]() Since we still had fuels but no more nozzles nor cases, we decided we better burn through a few more home depot plumbing engines. We succeeded wildly at this goal as well. ![]() ![]() After that was through, we realized we had the new o2 regulator that might make the 10' black iron 'engines' work a bit better. With much haste, the motor was connected and ignited. ![]() ![]() Unfortunately I didn't get any pictures of the actual firing as I was hiding behind the most dense objects I could find, in this case the o2 tanks. Suffice to say the cloud of deathgas was too thick to see through and expansive enough to cover an airport. Great success! We still only got about 1' of the PVC burning, we're going to step up to either multiple o2 injectors, or liquid o2. Friday, April 27. 2012Hybrid Rockets: v1
If you've followed my blog for a while (years) you'll note I like rockets. In the more recent years there had been a significant lack of proper exothermic reactions, and this needed to change.
I started matlabbing and thinking of good ways to do liquid-propellant motors, but thought that perhaps I should attempt the more-simple hybrid rocket engines first. On a Saturday morning I hit Home Depot and purchased all the things one needs to make a simple hybrid motor: oxygen, a rubber hose or plastic stock, and enough pipe fittings to put a small hole on the end. ![]() Here you can see I have some rubber hose (the fuel) inside a metal pipe. When the oxygen passes through the hose, the pair REALLY want to burn. Below, the whole setup assembled: ![]() The home depot ox tank comes with a tiny regulator, which later became a problem. However the setup on a whole is extremely simple. Ignition was achieved by inserting a bit of rubber through the nozzle and touching the tube inside, flowing a small amount of ox through the system, and lighting the rubber with a torch. Worked first time! ![]() As stated, we soon needed more oxygen. Luckily Ken had his welding setup on hand.... ![]() As you can see from Ken's face, much more mass flow happened... ![]() Of course, things quickly progressed from there. Ken noted he had an idea, and quickly returned with a 10' length of black iron pipe and a similar piece of PVC that fit inside. He drilled holes in two caps, threaded them on, and we were ready to roll. ![]() Fortunately enough for us, we could only get enough oxygen flow for about 6" of PVC to burn. Regardless, that produced a TON of black deathsmoke, heat, and noise. Had we had a larger flow regulator, the thing would have killed everyone in town. We'll have to order one for next time. Thursday, September 29. 2011Sonerai IIL Running Happily
Finally got the motor back on the plane after tearing it down and putting it back together. It's much happier now...
Vimeo link: here. Saturday, February 19. 2011Finished My PPL
A video look around the flight home from my private pilot checkride in RI.
Monday, October 11. 2010Launching Ellenville
Launching my Gemini 134 from the west site in Ellenville:
Tuesday, July 13. 2010Landing the FP202
The poor thing sounds like a weedwacker, but sure is fun...
Tuesday, April 20. 2010My first "real" aircraft!
The hang glider is fun, but I really wanted to fly something I could GO places with. I bought a Fischer Flying Products FP-202 ultralight on Craigslist for $2000. It was hilarious.
![]() The plane had sat for a number of years in a barn. It wouldn't start without copius amounts of ether, some wood was cracked, there were some holes in the fabric. But it was mine. By spring, I had replaced the main jet in the carb as well as de-gunking everything, patched the holes, and taxied around a bit. ![]() I lined up on the runway at 8B5, applied full power, and off I went: ![]() I did two patterns and landed splendidly. It was epic! ![]() I really miss that plane... I ended up selling it for $4100 to fund my private pilot's license. I'd really love to buy another one some day and drop an electric motor in it... Monday, February 15. 2010Jet Powered Hovercraft
Chris and I decided we needed to build a propane powered jet engine using a turbo from a car. Given my previous successes with hovercrafts, of course we needed to step the game up.
![]() Our combustion chamber takes air from the compressor, swirls it around with liquid propane, then burns it, creating a huge expansion of the inputs. The gases then pass out into the turbine section of the turbo, spinning the compressor faster, and so on. The brass nozzle you see is the propane connection. The sparkplug is to start the combustion, but the flame is self-sustaining once it's running. ![]() We rigged the combustion chamber to the output of the shop vac, connected the spark coils, and let a little gas flow. Much to our surprise, a significant roar was produced! We were even more pleased when the roar continued after we switched off the sparkplug. Below, Eric inspects the turbo. ![]() When we put it all together, the unit was spinning at upwards of 120 krpm, and blasting the rhododendrons around across the yard. We also used it for snow clearing. While we still had it running (ie before it was scavenged for parts), two exciting things happened. Once, when we drilled out the propane fittings to get more gas through. This made the engine run at a higher compression of course. Right as Ken reached across the motor to poke a gauge, the cold air manifold from the compressor separated from the combustion chamber, and the resulting gas instantly melted all the hair off Ken's arm. However perhaps more amusing was the time the bearing's oil seal failed during a full-thrust run. 60psi hot, thin motor oil sprayed into the turbine housing and instantly turned to smoke. The sheer amount of black death coming out the back of that jet engine is an image I won't soon forget. epic. Tuesday, November 17. 2009Hang Glider Upgrade
While fun, the hang glider I built wasn't exactly the best-flying device in the world. But it just so happened that the local hang glider pilots were amused enough at me for it that they found me a used "real" hang glider to buy for $300!
![]() My Gemini 134 and I have flown quite a few interesting places since then, including actual hang glider launches, ski hills, beaches, and flat grass fields with a winch. I'd really like to put an electric motor on the back of the harness some day, if I can find the time... Here's a pic of me at the practice hill in Cooperstown on a student glider: ![]() Tuesday, August 11. 2009That Time I Owned a Paraglider
After the hang glider adventures, I still wanted to fly different things, but didn't yet have enough money for any sort of "real" aircraft. So I did what anyone in my position ought to: bought an old paraglider and harness on eBay for $700!
There aren't any great flying sites in central MA, but I did get some sweet local flights in down hills and with a winch I built before selling it. Certainly an enjoyable piece of fabric. Tuesday, August 26. 2008On Handy Type of Virtualization
Over the past two weeks I’ve been doing some work with virtualization in the context of Virtual Private Server setups – one physical host machine houses several “nodes” that do the actual processing.There are really two types of setups in this field: shared kernel and and separate kernel.
In a strictly shared kernel setup (like FreeBSD), the root kernel simple creates a new process tree for its nodes, and marks each process with both a process id (pid) AND it’s node id. This is obviously quite efficient, however it lacks the ability to do some of the handy things a separate kernel system provides. In a separate kernel system (like Xen on linux, or even VMware), much more ram is neccesary since separate copies of all the binaries are loaded into memory. However, that means you can have different kernel version in different setups for testing, as well as better control over “virtual” hardware presented to those node kernels (I am keanly reminded of the networking restrictions FreeBSD jails have, as shared kernel nodes). Most real operating systems support one setup or the other, however there are a few libraries out there that run on several OSs to allow for both options. Here’s what I’ve found. Linux - After installing the Xen package, linux supports separate kernel nodes quite well. Despite some of the inherent inefficiencies of such a system, this setup is widely used and provided by companies such as slicehost and linode. FreeBSD - Out of the box, FreeBSD includes support for Jails. This concept was written in 1995 to basically extend the functionality of a chroot environment. However, there are quite a few shortcomings: each jail is IDENTIFIED by its IP address, rather than a jail id or something of that sort. As such, each jail can have only ONE IPv4 address, and no IPv6. Further, there is no resource control to limit a jail to memory usage, cpu usage, or disk space (see end of paragraph for hacks). Also, a jail cannot do complicated firewalling or tunnels, but that is inherent to a shared kernel system so it can’t be blamed solely on FreeBSD’s implementation. It’s a shame out of the box jails suck so much, since BSD in general is a great system. There are a few patches to provide more jail control, however none are in the current source tree. Solaris - Supporting 5 different types of virualization, Solaris really takes the cake. Everything works perfectly to any level of configuration. That said, Solaris x86 really is a scary beast. Even if you manage to get it installed, your hardware may still crash once a month when it throw a particular hook. If you’re using Sparc hardware however, this is most certainly the way to do things. (update 2011: the x86 builds are much more solid now) In any event, I’m working on getting the patches to FreeBSD installed for jail control, as well as getting some nicer Sparc hardware to use Solaris. Friday, August 8. 2008All Sorts of Tunnels
Recently I’ve gotten back into my routing craze… since I can’t get IPv4 space anywhere, I got two 6over4 tunnels and a /48 from Hurricane Electric. My Cisco 7500 is linked up and serves up tunnels to all of my boxes, splitting up the (enormous) address space and doing intelligent routing with BGP in places I have more than one link. It's way over engineered, but at least I get to play with such things in case I ever get to work on a large system.
Also, I was bored last night and wrote JustLOLs.com, an aggregator for lolcats and loldogs. Thursday, May 29. 2008The glider works!
This picture doesn’t show it well due to the long grass, but I am in fact flying.
![]() (I stalled right after this picture was taken, but that’s beside the point!) This isn’t even with good wind – when the wind was favorable, I flew near half way down the hill. Despite the police, high-tension power lines inducing current in the glider frame, and fussy wind, I left the ground! ![]() ![]()
« previous page
(Page 2 of 4, totaling 70 entries)
» next page
|
Email me:
jack {@} crepinc.com Recent Projects: Analog HF Transmitter Audi ECU Reverse Engineering Dual DAC QAM Modulator FPGA QAM Modulator Geiger Counter Gyro-Stabilized DSLR Platform Hybrid Rocket Engines Turbocharger Controller WWVB Rx and Tx Older Projects: Balancing Bot Capacitor Array CNC Mill DCIR Renderer Electric Gokart Hovercraft Low Alt. Temp. Model Shopping Cart Locker Trebuchet My Twitter occasionally shows projects I'm working on. My GitHub has code from a few projects on it. Quicksearch |