Sunday, July 30, 2017

Build the Tool You Need - Serial Utility Board

Awhile back I modified a USB-to-Serial converter to be more of a USB-to-UART converter. While it was useful for a little while, I still found it to be a little clumsy to use. I wanted to make something a bit more usable.

Now there are plenty of FTDI chips out there, but I went with Microchip's MCP2200. It's a USB-to-UART device, but it also has some programmable GPIO pins that can be controlled from the PC.

For this board I wanted to address a couple needs: easy connectivity to a breadboard, serial communication at 3.3V or 5V, and providing power to my test circuits.

I combined the first and last items in the PCB layout. I designed it such that the board would span a typical breadboard's power rails, and plug directly into them. I provided jumpers to select which pins ground and power were output on so that I could also plug in along a power rail (I'll show in photos below). I also added a switch to choose between 3.3V or 5V, which is then supplied to the power output pin.

I also put in a female header to make it easy to jumper all the GPIO and TX and RX signals. The header also has dedicated 3.3V and 5V pins so that both voltages are always available to use, regardless of which is selected.

A simple enough board, but now I pretty much just leave it plugged into my breadboard all the time.  More often than not, it's providing whatever voltage I need, and I just have to connect two wires and I'm talking with the PC.




Build the Tool You Need

This is not a project really, just a little board I made as a tool. I got a couple SAMD09 micros from Atmel, which are ARM Cortex M0+ based little guys I thought I'd play with (this was actually quite some time ago). I haven't done a ton with ARM processors and this micro was my way in. Only problems? It's a SOIC package and that programmer cable uses a 0.050" spaced plug.

Now the SOIC package is easy to deal with, you can dead bug it, or get DIP adapter board that'll fit nicely into a breadboard. The cable was the bigger obstacle. Again, it could be dealt with, but setting up the programmer has always kinda annoyed me. You gotta go to the datasheet and find which pins do what for you microcontroller and run the wires individually. And the same goes for your programmer; you gotta find the pinout, and the decide if they're showing you the cable end or the mating end in the diagram. Just a deterrent to getting started on things.

So I just did my own breakout board, with a couple extras: a debug header and a reset switch. That's it, nothing more nothing less. Here's the schematic:
For about $10 I got half dozen PCB's made and shipped to my door. Now whenever I was to use one of these devices, I just pop it in the breadboard and plug in the progarmmer and I'm ready to go.


Saturday, July 29, 2017

Custom Turn Signal Retrofit - Part 5

As usual, the last bit to talk about is the software. The basic function is really really simple. It goes like this:

  1. Hey, I'm on. Cool. Let's really quickly setup the I/O pins and PWM output.
  2. Ok, am I on because the turn signal is on? Let's check.
  3. If so, then load the duty cycle for the turn signal into the PWM, otherwise, let's load the duty cycle for the headlights/running lights.
  4. Guess I'd better check again, let's go back to step 2.
For every blink of the headlight, it'll start from step 1. But we're talking microseconds from a power on condition to turning the LED on. In fact, I'll even go measure it right now.

Yellow: Power in   Blue: PWM Out
Looks like a I need a bit of power supply filtering.
630us it turns out. Actually a bit longer than I would have expected. But still insignificant considering the duration of each blink of the turn signal.

The buttons were actually a lot more work. I would just check them periodically and compare their states to previous states, and then pass the results to a function that would take the appropriate action based on the current state. The buttons themselves are labelled SET and ADJ.

The SET button is used to change states. So at power on it's in the running state and checking the input to determine which brightness to show. Pressing the SET button once moves to the Turn Signal Brightness adjust state (and it gives a blink to denote that the state has changed). Pressing it again changes to the Headlight Brightness adjust state. One more push puts us back in the running state (with a long pause of the LED off to let you know you're going leaving the adjust states).

The ADJ button simply increases the PWM duty cycle, but only when in an adjust state. It doesn't even have to care which adjust state.

You will see in the video below that when I leave the adjust states I actually get a series of blinks before the LED is switched off for a delay to denote the return to the running state. The blinks indicate that one ore more of the brightness levels changed and that they were stored on the microcontroller.

This part actually got me into a little bit of trouble. I neglected to check that the micro has EEPROM. It does not. EEPROM is used for long term data storage, and is retained after the device loses power. I can make all the changes in RAM I want while the device is running, but I'd lose the adjustments every blink. Not cool. Now many devices, this one included, are able to write and read program memory. So I could use a portion of the left over space that the firmware doesn't use and store the brightness levels. But there are some caveats. Program memory has to be written in rows. For the PIC10F322, that's 16 words. Each word is two bytes, making for 32 bytes total. You are generally supposed to read out the contents of the memory first, alter the byte locations you need to change, and write it all back. That would require half the available RAM. Now technically I don't need to, as I can just write all 0xFF or other dummy values to the unused space, and just grab the current brightness levels in RAM and store them where needed. But it's all kind of a hassle.

Instead I'm taking advantage of one of the features of the device: it has 4 bytes of USER ID space that is effectively the same as program memory, but can be written and read one byte at a time (technically each location is a 14bit value because that's width of program memory, but for practical use, the upper 6 bits are being ignored). Problem solved. Otherwise the project would have been more or less defeated. I would have only been able to hard code brightness values; any changes requiring re-programming the microcontroller. Also would have wasted all that board space for the buttons, and all that time and code handling the user input.

I just took a little video going through the different states and showing the device running both with "headlights on" and off.

Custom Turn Signal Retrofit - Part 4

As usual, it's been awhile since I've posted. But the purpose of this blog is not so much to produce content in a timely manner so much as just a means for me to document (and sometimes revisit) some of my projects as well as an incentive to complete them. So this one has more or less been done for quite some time and sitting on my desk.

We've already covered the important pieces of the circuit, now we just need to put it all together. The resulting schematic is too complicated for just being a turn signal, but this wasn't meant to be entirely a practical solution. You can obviously buy LED bulbs at the store (though they are still surprisingly pricey), but that's not the point of this project. So here we go:
I've additionally included S1 and S2 to the circuit, which you could argue is the whole reason this thing is so complicated. I wanted to be able to dial in the brightness of the bulbs without having to change resistor values or reprogramming the micro. I've done the debouncing in hardware because I didn't want to do it software. And with only two buttons, the effort and space on the board required is minimal.

The last item I think is the ICSP header. It's always handy (and sometimes necessary) to include one of these to make programming and debugging easier. Also best to make it the same as the cable on the programmer you are using, though occasionally you may have to do otherwise. But not having a convenient way to change your software will discourage you from finishing or improving your firmware in the future.

I did make a smallish PCB for this, and for the function it serves, yes, everything is kinda big. But hey, learning experience. Later.

Wednesday, January 25, 2017

Custom Turn Signal Retrofit - Part 3

Now the original problem I had was when water made its way into the bulb housing and corroded/shorted everything. I'll do my best to seal up the housing when I retrofit it... but what if it happens again?

We already do have the output current limited from the previous post, so no big deal right? Short the LED and we still only draw 0.5A. While true, it still has to drop some 14V(engine running). Calculate out the power and you get $W = V * I = 14V * 0.5A = 7W. Ouch. So how do we avoid that?

Well I pondered that for awhile, and came up with a solution, but it does use a lot of parts. Knowing that the LED drops some 10V or so, we can assume the voltage at the collector of the LED driver should be 10V less than the system voltage. Assuming 15V worse case, we can expect no more than 5V. If that voltage rises too far we need to disable the LED driver. I chose to use an 8.2V zener as shown below:
If D1 becomes shorted, Z5 starts to conduct. Q3 turns on and Q2 can no longer drive. It's simple enough I guess. I just don't like that it's more complicated than the driver itself. Oh well.

Another little quirk I almost overlooked (well, only half of it) is making sure that the flashers can't drive the headlights. It only takes a diode, but without it, every time the blinkers flash, so would all the headlights. Probably not ideal.
If you recall from the previous post, the circuit can be powered from either the flasher power or headlight power. D2 and D6 simply prevent either source from powering the other.

And the final thing I want to cover is detecting if the flasher is on. The flasher signal is the power used to drive the bulb itself, and is going to be the car voltage. Our micro is only gonna be 5V. You can't feed that directly into a GPIO pin. You may be tempted to say just use a voltage divider. That would probably actually work, but our input voltage can vary (usually 12-14V as stated before). You don't normally signal with the car off, but you may use the hazards, so we should consider both on and off conditions. This is again a decent job for a zener. I could have used a transistor as well, but I think this choice is slightly less complex(fewer parts). And I never get to use zeners.
Now we can get a reliable ~4.7V input to the micro whenever the signal is turned on. Just two components. R4 is an optional dummy load. The flasher timing unit relies on the turn signal bulbs drawing current in order to switch on and off. You can look up how the bi-metal strip works elsewhere, I won't get into it. The LED draws significantly less current than the incandescent bulbs, so we're probably gonna need to waste a bit of power to keep the timing somewhat similar.

That was a bit of a quick run rhru of the various circuits for this design. But its not a complicated board, though still complicated considering what it actually does. We'll take a look at the full schematic next time.