# Pico ESP32 board



## Shdwdrgn (Dec 23, 2014)

I ran across mention of the TTGO Pico-D4 ESP32 board the other day and ordered a couple off Ali to check them out. They arrived yesterday and wow! Knowing the dimensions just doesn't do it justification. This new board is a full-blown ESP32 with all the features, but the board is only 13x19mm in size, fully one half the size of the original ESP32 chip. Part of the space savings is gained by requiring an external antenna for wifi now, but that's a minimal cost and actually a more flexible solution.

Besides the small size, you will also notice the incredibly tiny pad spacing on these boards -- only 1mm between them. Definitely need a tiny soldering iron to work with this device.

There are two versions of this board. The second version has rearranged the pinout slightly and added a metal can over the circuitry, and is probably the better choice. Too bad I didn't notice the newer board when I ordered mine.  Ah well.

Version 1: https://www.aliexpress.com/item/TTG...fi-wireless-Bluetooth-Module/32889146892.html

Version 2: https://www.aliexpress.com/item/TTG...le-ESP32-PICO-D4-IPEX-ESP-32/32869180373.html

Once Summer slows down I plan to get back to porting a DCC loco decoder on an ESP32. So here's a crazy thing -- this new board is so tiny that I could actually build it into the floor of an HO handcar! I was just hoping to find something that would fit inside my HOn3 loco, however it looks like you could probably also fit this into an N-scale loco.

Anyway I just wanted to mention that this new board is out there, in case anyone else needs a good processor for a tiny project. And if you're an arduino person who isn't familiar with the ESP32, take a moment to check the specs, because this is a truly amazing $5 controller.


----------



## Shdwdrgn (Dec 23, 2014)

In case anyone is interested, here's the schematic I've been working on based around version 1 of this chip...


----------



## gunrunnerjohn (Nov 10, 2010)

Hard to read at that resolution.


----------



## Shdwdrgn (Dec 23, 2014)

Ya know, I've been wondering why the program defaults to such a small scale, but I haven't been able to find where to change the setting yet.  Still trying to learn this software.


----------



## gregc (Apr 25, 2015)

also, what does it do? I see a loudspeaker and IR receivers.


----------



## Shdwdrgn (Dec 23, 2014)

OK so the idea is to build a full-featured DCC board around one of these ESP32 pico modules. At the top-left I start with input from the tracks, providing the DCC interrupt signal plus obtaining straight DC track voltage (to supply the motor) and a 3.3V filtered supply to run the other chips.

Below that is a tach input to sync sound output.

Next is a front and rear IR diode pair to provide a simple collision detection and range.

Below that is the speaker and simple amplifier for sound output. There are a couple different arrangements I want to try out, but the one pictured is about the simplest design you can have (probably won't provide very good quality sound though, but it will get me started).

Center-bottom I have an L293D to drive the motor. The transistor is set as a not-gate so a single output line can control direction. I bridge the inputs and outputs across both halves of the driver chip which allows up to 1000mA of current for the motor (heatsink required!).

At the bottom-left is a series of 74HC595 serial drivers. With three inputs you can daisy-chain this chip to add as many outputs as you need, in sets of 8. For driving LEDs and such these chips have plenty of speed. The idea here is to have a single chip on the mainboard with socket headers around it, then small daughter boards that can be stacked and add another chip and set of outputs. The direct outputs won't drive much more than LEDs (35mA max), but I could also make a daughter board with transistors to provide more current for motors, smoke units, etc. as needed.

Coming back up the right side are sockets for an SD memory card and the serial programming port for the ESP32. The memory card will be used to hold configuration parameters (like how many 74HC595 chips you've added), plus the sound files.

The only thing missing that I still want to add at some point are the inputs for a camera module. Is there anything else you can think of that I missed?


----------



## Shdwdrgn (Dec 23, 2014)

Finally figured out how to change the image size when I save. The image above has been expanded, should be easier to read now. It also includes both versions of the speaker drivers I found.

I breadboarded the circuit yesterday, nothing fried when I applied power.  Found some sample code for both the SD card and sound features, maybe I can give them a test tonight. I also found some steam loco sound clips online and was able to cut out slow and fast chuff sounds. The final data is stored as a raw file so very easy to cycle through it and expand/compress the clips to match the loco speed. At some point I'll have to try and fit a tach sensor to one of the drivers so I can really sync up the sound, but for now I'll be happy if I can get any decent sound quality to come out of it.


----------



## Shdwdrgn (Dec 23, 2014)

Making progress on the breadboard. I had to fight for a day trying to get the 595 chip to work properly... combination of two wires revered and some bad code, but I finally got it straightened out. Last night I hooked up the SD card socket and that worked right away. Tonight I hope to get a speaker hooked up and try to pipe out one of my sound files. I have an idea for merging overlapping sounds (for example, a bell ringing while the loco is chuffing) and a simple configuration for using different sound files at different loco speeds. But I have to get the basics in place first!

Once I finish getting sound to work the only hardware left that I haven't actually used before is the IR diodes. I also need to experiment with using some of the 'off-limits' pins to control devices. Some of those pins actually can be used if you meet certain criteria, which my requirements do fall under, so we'll see. All in all it's looking promising though. Once these code segments are working then I'll get back to testing the ESP32 with the DCC decoder software and then start putting it all together.


----------



## Shdwdrgn (Dec 23, 2014)

Well it took me a couple days to get to it, but I have sound "working". And I say it like that because... wow... it is _really_ crappy sound. Basically I'm working with an 8-bit sound file at 8kHz, which doesn't sound bad at all on the computer. Then I tried to pipe it through an amplifier made of a 3904 transistor and a resistor. We're talking sun-baked, blown-out speaker quality that has a bird nest and a dead rat in it.

But hey... I MADE SOUND! 

So I'll be playing around with different simple amps on a separate breadboard, see if I can coax out some decent quality without requiring a boxcar to house it. If anyone has suggestions on a fairly small circuit that works well, I'd be happy to hear (remember I'm working with a 3.3v supply). I've never been much of an analog guy, so I'm lost here and just googling for ideas.

I've been ordering some surface-mount components and started playing with a PCB layout program today. The main board will have a 74hc595 chip to handle lights and simple outputs, but the chip can be daisy-chained to add more. With that in mind I designed a daughter-board today so I can stack as many as needed for any particular application. The board comes out to about 1" x 0.5", but I think I can shrink it a bit more. Eventually I need to start tackling the main computer board though, see if I can get that laid out to a reasonable size. As a benchmark, the tender of my HOn3 loco allows for up to 7/8 by 2-1/4 inches, which seems like a lot of space until you actually start laying out the components. We'll see how it goes.

Oh, I found a nice 1-amp 3.3v voltage regulator that accepts up to 25v input, and it comes as a surface-mount device. A couple capacitors to smooth it out, and it will easily supply all the electronics. I'm considering making a separate board that holds the bridge rectifier, regulator, and the optical isolator for receiving the DCC signal, then allow it to be added wherever you have the space.

Still more to play with tonight, so that's enough for now.


----------



## Shdwdrgn (Dec 23, 2014)

I tried a couple more complex amplifier circuits, but they both sounded MUCH worse that the simple circuit. Decided to spend some time playing with the code to play the sounds but was pretty much getting static when averaging two sound bytes together. Did some reading and found the proper way it to ADD the sound bytes together, then clip them at the max value. Well ok I can distinguish the two sounds now, but it still doesn't sound right. Did some more reading and experimenting -- OH! The bytes stored in memory range from 0-255, however to properly add the sounds together you need to convert those bytes to a positive and negative range (-127 to +127), then add them together, then readjust the values back to the original range of 0-255 to output to the speaker. Seems a bit convoluted, however sound waves are just sine waves that swing from positive to negative, so the 'addition' must take that into account. Using this method results in an output where each sound being played is still as clear as playing one sound by itself.

My original assessment of the sound coming out of this speaker was based on a chuff-chuff sound clip, which is really just a white noise sound. I made a clip of a bell ring yesterday and started using that for testing, and that sound is much clearer. Think I'll try to grab a whistle next and see how it works out playing three sounds at once.

I've seen some tiny speakers on ebay that are supposed to have a better bass quality to them, think I'll get one of those and see if it helps bring out a richer tone for my outputs. I know with car stereos you get better sound quality by adding multiple speakers of different sizes, would be interesting to see what happens with multiple train-size speakers.

[EDIT] Funny thing, I started looking around and found a speaker from a computer. It's almost identical to the one I was using -- 1" diameter, 8 ohm at 1W -- however it has a much stronger speaker and noticeably better sound output. I also realized that if I hold it up to my ear, the chuff sound is actually very recognizable. I think the problem I'm seeing is that the bass tones need amplified to properly hear them.


----------



## gregc (Apr 25, 2015)

don't understand why you would average sound bytes together?

the sound file should be "played" out at the sample rate it was captured at. sounds like averaging two sound bytes together, playing out a single byte when there were two would cut the sample rate in half

how many bits is the DAC on the esp? 

if it's 16-bits, then each 8-bit sound byte needs to be sign extended. a value of -1 == 0xff needs to be extended to 16-bits, 0xffff. every 8-bit sound byte that is negative or >= 0x80 needs to be prefixed with 0xFF (e.g. 0x83 -> 0xff83). this may take care of itself by simply converting a signed 8-bit value to a signed 16-bit value

if the amplitude is too low, you can scale up the value by multiplying by some constant (> 1) when converting to a 16-bit value.


----------



## Shdwdrgn (Dec 23, 2014)

The DAC is only 8-bit, thus the reason to subtract 128 and store it in a signed integer. I should probably check if the arduino compiler has a signed 8-bit variable, in which case I should be able to read each byte and do the addition directly, without any further math.

I originally tried to average the bytes together because... well I've never worked with sound before and it seemed logical at the time?

Also check the edit on my previous post. Turns out I AM getting a decent chuff sound but I need to boost the bass.


----------



## gregc (Apr 25, 2015)

if the DAC is 8-bits, i don't understand why you need to subtract 128? you shouldn't have to do any conversion from an 8-bit sound value to an 8-bit dac value.

a value of 0xFF is -1 if signed and 255 if unsigned. subtracting 128 from 0xff, results in a large positive signed value.

a loudspeaker outside of an enclosure will have poor bass response. simply lay the speaker, cone side down on a table top and it should sound better. it needs to be mounted in an air tight encloser.


----------



## Shdwdrgn (Dec 23, 2014)

The data read off the memory card is 8-bit unsigned (0-255). The DAC itself also takes an input of 8-bit unsigned. However when adding together the sound bytes, you must first convert that number to a signed value (-127 to 128). If you add the unsigned values together you get garbage.

As an example... an unsigned value of 128 is actually the zero-crossing and should be no output. If you add 128 + 128 you get 256 (clipped back to 255) so you get full volume rather than no volume. Converting those values to signed, your two bytes of 128 become 0 + 0, maintaining the zero crossing value. So basically I read an unsigned byte from the memory card, convert it to signed, add the sound bytes together, then convert back to an unsigned value to send to the DAC. Basically the subtraction and addition of 128 to the values does the same thing as changing the variable types back and forth from unsigned to signed and back to unsigned.

Turns out I can double my speaker output by adding a 1uF capacitor across the input resistor. Still looking for a simple bass booster though, I may have to add a real op-amp to accomplish that.


----------



## gregc (Apr 25, 2015)

Shdwdrgn said:


> The data read off the memory card is 8-bit unsigned (0-255). The DAC itself also takes an input of 8-bit unsigned.


reading or writing data to hardware -- memory or DAC -- doesn't matter whether it's signed or unsigned. The DAC doesn't care whether the variable type is signed or unsigned. 0 is zero, 1 is just positive and 0xFF is just negative.



Shdwdrgn said:


> However when adding together the sound bytes, you must first convert that number to a signed value (-127 to 128). If you add the unsigned values together you get garbage.


signed 8-bit values are from -128 (0x80) to +127 (0x7f). a signed 8-bit cannot represent 128. the zero crossing is the value 0. the sign bit is the 8th bit. that's why 8-bit values cannot represent 128 (0x80). the sign bit is 1 for negative value 0x80 - 0xff

if you're going to do math, averaging, on 8-bit values, you should uses a larger (e.g. 16-bit) variable type. -100 + -150 = -250 which is not an 8-bit signed value. taking the average will give you the wrong result. but doing the math as 16-bit values, properly saturating and converting to 8-bit works. this is basic signal processing.



Shdwdrgn said:


> As an example... an unsigned value of 128 is actually the zero-crossing and should be no output. If you add 128 + 128 you get 256 (clipped back to 255)


128 + 128 = 0x80 + 0x80 = 0x100 or 0 if done with 8-bit math. there's no "clipping" in math. Values wraparound. 127 (0x7f) + 1 = -128 (0x80)


----------



## Shdwdrgn (Dec 23, 2014)

I am actually using a 16-bit signed variable to add up the values together, and maybe adding the bit values rather than the byte values would work properly, it just didn't work right the way I was trying it. While I have no trouble understanding how bit values work, I never worked long enough with them directly to actually learn all the commands for getting out the values I need here.

In your example of 128+128 by hex values, you end up with a value of 0. Except since the DAC uses an input range of 0-255, and not -128 to 127, ending up with a value of 0x00 still means you are setting the DAC to one extreme or the other, rather than ending up with a value of 127, which to the DAC is the midline value or zero. However if the addition is done with a signed byte value, then the unsigned value of 128 becomes a signed value of 0, which then adds together to still equal zero, and when you convert it back to an unsigned value you end up with 128 again. There's just no way around it, the value MUST be converted to a signed value before the math occurs. Yes there is probably a better way to do the conversion between signed and unsigned, but subtracting and then adding 128 gives the same result.


----------



## gregc (Apr 25, 2015)

you may be right, but this would make things very complicated. if you generate a sine wave, the values will be positive and negative. To output them to a DAC as you describe, additional processing is necessary for every sample written to the DAC.

an 8-bit DAC or codec designed for audio applications will output a minimum voltage with a value of 0x80 and a maximum voltage with 0x7f. otherwise the signal processing become unnecessarily complicated.

if this is the case, it would be easier to recompute the file with the values needed for your DAC to avoid the additional real-time processing.

you could test this by generating samples for a sine wave into your code and look at the output with a scope.


----------



## Shdwdrgn (Dec 23, 2014)

I can already tell you the output. The DAC is configured to output a linear voltage between 0-3.3v based on the value you give it. It can also be set so the output is based on an outside voltage source (not to exceed 3.3v). However you set it up, it does not output negative voltages. I suppose a proper amplifier could be adjusted to split the output at 1.65v and create a full sine wave, but speakers work just fine without the negative component.


----------



## gregc (Apr 25, 2015)

of course the output of any device is limited to the voltage supplied to the device. However, the loudspeaker must be driven with + and - voltages. The cone must move both forward of and behind its neutral position, positive and negative pressure.

i've never seen a loudspeaker driven with a transistor, as you show in your schematic (right). It's more common to use a large capacitor as in the schematic (left), but not with a resistor to Vcc.

I think we used something similar to a TDA7052 which are relatively inexpensive on ebay in our speakerphones.

this chip is essentially two amplifiers, one inverted, each connect to one terminal of the loudspeaker. when one side goes, high, the other side goes low. This can result in +/- Vcc across the loudspeaker.


----------



## Shdwdrgn (Dec 23, 2014)

There's certainly plenty of volume coming out of it now, my wife said it sounded pretty good from upstairs yesterday (I had no idea it was THAT loud). I found a 3" 25ohm computer speaker and that again about doubled the apparent volume. Makes me wonder if it's the higher resistance or the larger speaker that caused the volume change, but really at this point I think that is TOO much volume for a model loco. It just really amazes me that with three small components and only a 3.3V source I can get so much sound.

On the schematic from the first page I am currently using a fixed 220ohm resistor at the input and added a 1uF capacitor across it. I have seen a number of schematics suggesting the input should go *through* a capacitor, but I guess with my positive-only setup the signal just doesn't go through. Like I said, I was never any good with analog circuits, and transistors absolutely killed me, so I'm happy to use other people's schematics, and I do remember just enough to make small changes.

I looked at the datasheet for that chip. Unfortunately it requires a minimum 4.5V power source so that won't work here, but I'll do some searching and see if I can find any others that work at lower voltages and perhaps have a built-in bass boost circuit. Considering the miniscule size of the speaker in my cell phone compared with the quality of the sound output, I'm sure something can be done to improve the output quality here.

I'm currently trying to look into how to do speed compression of the audio output (to sync with loco speed) without affecting the pitch, however I've run into a different problem in that the SD card library I was using is horribly slow, requiring about 30us to read each byte. Considering I need to output a new audio signal every 125us, that timing is just impossible if I need to read multiple bytes for the compression. Got a timing program set up and there is a much newer SD library available, so I'll do some comparisons when reading 4k of data.

I also need to actually hook my circuit up to the track one of these days and confirm if the input pin I chose works properly with interrupts to read the DCC signal. I think DCC and audio are the only items that will need to rely on interrupts, so hopefully it won't bog down the processor too much. There's still a ton of code that needs to be added but I'm hoping to pass off the interrupts to the second CPU core. Good thing this chip has a lot of speed behind it!


----------



## gregc (Apr 25, 2015)

Shdwdrgn said:


> I have seen a number of schematics suggesting the input should go *through* a capacitor, but I guess with my positive-only setup the signal just doesn't go through.


the capacitor needs to be much larger (e.g. > 100 uF)













Shdwdrgn said:


> I'm currently trying to look into how to do speed compression of the audio output (to sync with loco speed) without affecting the pitch, ...


why don't you drop a sample every so often ... every Nth sample or N out of every M?

if this were tonal or voice, some filtering would be required, but a chuff is just noise.



Shdwdrgn said:


> however I've run into a different problem in that the SD card library I was using is horribly slow, requiring about 30us to read each byte. Considering I need to output a new audio signal every 125us, that timing is just impossible if I need to read multiple bytes for the compression. Got a timing program set up and there is a much newer SD library available, so I'll do some comparisons when reading 4k of data.


i read that the esp-32 had 520 kb of memory. why don't you cache the file into RAM at startup and write it to the DAC from RAM?


any chance you could post the chuff file?


----------



## Shdwdrgn (Dec 23, 2014)

This is the chuff file I'm working with: http://sourpuss.net/projects/trains/DCCpp/chuff_slow3.raw
I was playing with it a bit at work today, and there are some effects I think I can add to make the sound better. A bit of reverb was nice, made it sound less flat on the computer speakers, will be interesting to see if I can tell the difference on the ESP setup.

I need to play with it on a more controlled basis but in general for a given speed of 1-63 I am dropping that same number of samples each round. There is still some rise and fall of the tone, but overall the speed seems decent (not actually matched against a running loco yet). I'm getting set up now to start running some speed tests against the SD card. I also have a bell sound randomly ringing, and when the chuff speed gets up into the low teens you can *really* hear it affecting the bell tone -- which means that the slow speed of the SD reads is affecting the timing of the playback. Hopefully the speed tests tonight will yield some promising results.

Yes the ESP32 has a lot of memory, but remember I have to also leave space for the DCC components, and eventually for my own drivers to interpret track conditions and try to follow set routes... and I'm afraid THAT could really eat up some memory. So I'm trying to keep things as lean as possible. The other issue was mentioned in the bug report I was reading on the SD driver -- both internal flash and the SD interface use the same hardware on the processor. They *should* both read at equal speeds (I think 300Mbps was mentioned) which means there is simply no reason with a properly working interface that I shouldn't be able to open up 3-4 sound files at the same time and just read the contents as they are needed. At the moment I am working with files that are only around 4-8k in length, but in the future I may want to have longer samples, a higher play rate, or a new device may be released that allows for 12-bit or even 16-bit playback. By simply reading the information one byte at a time I future-proof the code against memory bloat.

Regarding the circuit... yeah the biggest cap I tried was actually 100uF. I have values up to 3300uF on hand though, will play around with that later on.


----------



## gregc (Apr 25, 2015)

Shdwdrgn said:


> This is the chuff file I'm working with: http://sourpuss.net/projects/trains/DCCpp/chuff_slow3.raw


i guess i misunderstood. I had the impression that the sound file was in a conventional format with negative values. The plot shows that its zero is at 128, which makes this file compatible with the DAC.










i thought you did math to shift the value to make it compatible with the DAC. Of course, if you do any math on the file, the values need to be shifted and then shifted back to this format.


----------



## Shdwdrgn (Dec 23, 2014)

Spent last night and time today trying to figure out a compiler problem. When I tried to compile with the latest library it completely failed. I thought it might be related to needing updates to a couple other libraries, so I decided to do a whole new build of the arduino IDE with a fresh load of the whole ESP32 package. Turned out that when I compiled the same code (or even a 'hello world') under the new build, the code would load up to the ESP but refused to run. Finally traced it back to a change in the way the uploads are done, so once I had a copy of the new command line structure I was able to get the new code running.

The results were disappointing... Under the old code from over a year and a half ago, to read 4096 bytes from the SD card required 69288 microseconds, or about 16.9us per byte. Yeah that certainly is too slow for my needs. So once I finally got the new libraries compiled I checked the results again... 75034us. All that work and I ended up with worse results. Sure it's plenty of time if you only need one byte per cycle, but if you have to drop a number of bytes each cycle then you quickly run out of time.

So one other thing occurred to me. Somewhere along the line I think I read there is a command to skip to the byte you need. If I can find that again then I won't need to drop any bytes, I just need a variable to keep a rolling pointer so I know what byte I want next. That is probably going to be the easiest fix, but it may cause another problem... If I want to maintain the pitch when I speed up the playback, I probably need to analyze the frequencies in the part I'm dropping. Oh well, one problem at a time...


----------



## gregc (Apr 25, 2015)

Shdwdrgn said:


> Sure it's plenty of time if you only need one byte per cycle, but if you have to drop a number of bytes each cycle then you quickly run out of time.
> 
> If I want to maintain the pitch when I speed up the playback, I probably need to analyze the frequencies in the part I'm dropping.


i played with your chuff file on my laptop. generating a .wav file at 44kHz from it and overlaying multiple chuffs periodically to to simulate the chuffs from both cylinders and at higher rates

one approach for skipping samples from a waveform table at non-integer rates (e.g 1.3) i learned from Hal Chamberlin articles in Byte Magazine is to add a float value to float accumulator and use the integer portion of the accumulation as the index into the source waveform.

it makes sense that at higher speeds, a chuff needs to be shorter, but i don't think a higher pitched version of the original chuff with fewer samples sounds right. (dropping samples proportionally increases the pitch of the re-sampled waveform).

when i do this, the chuffs sound like a drum beat (the magnetohydrodynamic drive in hunt for red october). Now i'm curious how the sound decoders do this.

i assume the for each speed step to the motor they re-sample some source file, or perhaps have multiple chuff files sampled at various speeds, picking the closest to the speed they are at.


----------



## Shdwdrgn (Dec 23, 2014)

I would assume multiple files, but there are apparently formulas to do the compression properly... I just haven't *found* those formulas yet.  There's also the option of making an intermediate chuff file that cuts out the long section of nearly dead space because at some speed the sound becomes a regular rhythm.

Did some more work on reading files from the SD card last night. Not only is there a seek() command to jump to a specific location, but you can read in a whole block (512 bytes) at once for substantial speed increases. It looks like the entire block can be read in less than 1000us, but if you try to read smaller chunks there is a noticeable delay as you go into a new block (I assume it is just buffering the whole block, even if you don't read it). Anyway, using buffer arrays there should be no problem reading in whole chunks of each sound file, and it wouldn't even need to be much of a buffer. It looks like I could read in the whole 512 byte block in the time it takes to play through about 6-8 sound samples, leaving plenty of time for other activities.

Afraid I haven't had a lot of free time to work on it this week, beyond getting the compiler updated. There's a hint of Fall in the air and I'm scrambling to finish up some outdoor projects.


----------



## gregc (Apr 25, 2015)

Shdwdrgn said:


> Did some more work on reading files from the SD card last night. Not only is there a seek() command to jump to a specific location, but you can read in a whole block (512 bytes) at once for substantial speed increases. It looks like the entire block can be read in less than 1000us, but if you try to read smaller chunks t


assume your writing in C using read/fread. it's always more efficient to read the raw block size of the device.


----------



## Shdwdrgn (Dec 23, 2014)

Been playing with some circuit board designs, thinking I might send off one of these boards to be made soon. First I made a power board, ideally being small enough to tuck into the loco. Since most of the steamers I'm familiar with pick up power through their drivers, I thought it would be nice to have a board that handles the power conversion and picks up the DCC signal. The board contains a bridge rectifier, 800mA 3.3v converter, the 6n137 to filter the DCC signal, and an L293DD to drive the loco motor. All of the heavier gauge wires would be contained within this board. Between the loco and tender (where I would place the computer board) I would then only need low-current wires -- 3.3v, ground, DCC signal, and two wires to control the motor speed and direction... plus any wires for lights, smoke, etc. I've managed to build this on a 1 x 0.5 inch board. Would like to get that down to only 7/8 or 3/4 inch wide though, but it's small enough to fit in the cabs of my two standard-gauge locos.

Then I tackled another project. I have an arduino board with headers around three sides that works great to directly drive servos. I built the DCC decoder portion by bending in the legs of the 6n137 and soldering parts directly to it. Two wires come in from the track, three wires go to the arduino (ground, power, signal -- exactly the same pinout as the servos). I finished it up by covering the chip with shrink tubing. Since then I have collected all the surface-mount part to build the same circuit, so I tried laying it out on a double-sided board. The result is a board that is .320 x .360 inches, just a hair wider than the three-pin connector on a servo motor. This board only contains the chip and four components, so it's pretty simple, but it makes it dead-simple to get the DCC signal from the track to an arduino.

Hope to get some boards made soon, then I can try out the new fine-tip soldering iron on surface-mount parts and see just how steady my hands are.


----------



## Shdwdrgn (Dec 23, 2014)

Huh, I never came back to mention that I had actually sent off my first board to be made. This is the last one mentioned above -- the inline 6n137 circuit to allow an arduino to read DCC off the track. I'm hoping to see the new boards in a couple weeks, but in the meantime I've been doing some reading on working with surface-mount components and solder paste. It seems the most common method is to heat the board in a small toaster oven! Sounds easy enough, but I had to buy a new one because you can't prep food in it because the solder fumes will release poisonous gases.

Walmart hooked me up. $20 got me a nice little unit with heaters above and below, manual control for temperature and on/off, and two rack positions. The next step is finding the temperature probe that came with my multimeter and see if it is suitable for these temperatures. The idea is to bring up the temperature to a little under the melting point of the solder paste, let it coast there for a couple minutes to allow the board and components to heat evenly, then punch the temperature up over the melting point briefly. Once you see the solder melt, turn off the heat, wait a few seconds, then open the door and let everything start cooling down.

Hey that sounds complicated! I wish I had an arduino to do all that work for me. 

Actually I think after doing it once or twice the process should be really easy to get the timing right. And I'll have to do some experimenting since this board has components on both sides, but I think I have a plan. And by the time I get to a more complicated board I plan to have a second container of solder paste that works at a higher temperature so I can do each side individually.

Since I already have an arduino set up to run servos via DCC, once I get the first board put together I can test the circuit right away and see if it works. I'm excited, I think this is the first custom circuit board I've done since the 80's!


----------



## gunrunnerjohn (Nov 10, 2010)

Any board with parts on both sides I've just hand soldered.

Did you get the paste masks made? It can be problematic with fine pitch parts if you just slather the solder paste on. You also have to precisely position the fine pitch parts the first time or you smear the paste.


----------



## Shdwdrgn (Dec 23, 2014)

No I didn't get the masks made, at the time I didn't know what they were. If I do another run of this board I'll probably go ahead and have them created then. The smallest part I have is some 0603 resistors (although apparently 0805 is more commonly used for home-hobbyist use). I didn't plan on following what seems to be a standard suggestion of just laying down a bead of solder paste over the whole area for each part. I thought a toothpick under the magnifying glass would work pretty well. Besides the one chip on the front, there are only three resistors and a diode on the back, so not a whole lot to do on this board.

I was thinking I could put solder paste under most of the chip pins, then use my regular solder to tack down two opposite corners. That way I can flip the board with the chip attached, and still have the paste do most of the work on that component. Anything I should worry about with that plan?

And *ugh*... I realized last night that I'm missing the 1.5K resistor for this board. Got one ordered that claims fairly fast shipping, will see what happens.


----------



## gunrunnerjohn (Nov 10, 2010)

With only a handful of parts, I have to wonder if it's worth it to screw around with solder paste? I personally limit myself to 0603 sized parts, that allows me to hand solder them for prototypes.


----------



## Shdwdrgn (Dec 23, 2014)

It's worth it only because I've never done much of anything with surface mount components before and I want to get this all figured out. And if this board works as expected then I can make up a bunch and sell them to people who want to build their own DCC arduino decoders using only plug-n-play equipment (for which there is no available option currently for the opto-isolator unless you breadboard it).

Also this is the smallest of the series of boards I want to make. If I get it figured out for this board then I can move on to the next board which will have more parts on it.


----------



## Shdwdrgn (Dec 23, 2014)

The circuit boards came in yesterday, and today I got a chance to set up the toaster oven. Had to play with that a bit to figure out the heat cycle so I could get the board to soak at the right temp before bringing it up to melt the solder. Got that worked out so then it was time to put one together.

So this is the first time I've worked with solder paste. Got it on all the pads, smeared the parts around to make sure they were coated too, then heated the board. Things did not go as planned. First off, apparently my rosin core solder melts at the same temp -- I thought it melted at a much higher temp, so the 6n137 I had already soldered on one side... fell off. OK, not the end of the world. The next problem was one of the resistors decided to spin 90 degrees, so I had to re-heat the board enough that I could snatch off the part with tweezers, let it cool down enough to try and position it again, then re-heat the board. Took a few tries, but I got it in place. And finally, the other two resistors are too close together, and I got a solder bridge between them. Will have to change the board design for the next run, but I was able to clean it up by hand and separate the joints again.

Got the chip soldered back in place, put on the header pins and the 3-wire connector, and plugged it into my arduino. WOO-HOO it worked! Was able to send commands to run the turnout servos and the new board picked up the commands with no problem.

The only issue left is that I didn't have a 1.5k resistor to limit the track current coming into the chip, so I dropped in a 1k chip. As with the breadboarded circuit, 1k was also too small here and the resistor warmed up quite a bit. The 1.5k resistors are on order though, along with some 2.2k (just in case).

So my first professional circuit board is a success, I just need to work on my technique for getting the parts soldered in the oven. Once I figure out which limiting resistor works best here I'll start filling in more boards (I have ten of the 6n137 chips), I'll see if some of the local train club members want to try them out and see how they work out for other equipment.


----------



## gunrunnerjohn (Nov 10, 2010)

How about shots of the finished board?


----------



## Shdwdrgn (Dec 23, 2014)

Sorry, yeah I'll try to post some pics tomorrow but I left my camera at work on Friday and my cell phone just won't do a good close-up.


----------



## Shdwdrgn (Dec 23, 2014)

Here's the back side of the board with all the tiny components on it. I need to choose a different format for the diode as the pads were much larger than needed.









This one shows the particular arduino board that I'm using for servo control. There are five pins that aren't suitable for servos (the ones missing a pin in the yellow header). The optoisolator has to go on pin 2 to trigger an interrupt. That leaves 17 pins which can run servos (I use 16 in my sketch to keep the count easier). Because the servos pull a lot of current, I can't run the board from a USB port, however there are heavy traces on the bottom side connecting all of the header pin V+ and ground lines, and I found I could plug a filtered 5v supply directly in to the headers to run the board. In practice I expect to connect a 5V feed to each one of the three header groups, ensuring all of the servos are able to draw as much current as needed.









So the optoisolator board comes out to about $1.14 in parts. The arduino is around $5 and I've been picking up the servos for about $1. I 3D-print the servo mounting brackets, and they probably cost less than 50 cents each. I already have a 5V 3.5A regulated power feed on my test track, so that pretty much covers all of the costs of controlling 16 turnouts.


----------



## gunrunnerjohn (Nov 10, 2010)

Not sure what that diode is, but there are much smaller form-factor diodes that will handle an amp or more. Given it's usage, that's probably overkill for where it's used.

Is the opto board the one you're building, or are you building the other board as well?


----------



## Shdwdrgn (Dec 23, 2014)

I'm sure you are right that other diodes would be suitable for the purpose. I've always seen the 4148 used in this particular circuit and wasn't sure about the power flowing through it or what might be a suitable replacement, so I just kept like for like. As far as I can tell it just clips half the DCC wave, and the resistor in front of it limits the current coming through. Beyond that I don't really know what extremes might be seen in a DCC system so I couldn't even make a guess at what specs I would need to meet for a replacement part... but if you have any suggestions, I'd be willing to grab an order and test them out.

I'm only building the opto board. The arduino is labeled as a "nano strong". I first saw it appear last year, but the price still seems to be around $5 each. I think it was intended to be using with the RGB programmable light strips which also use the same plug, but it also worked well for my purposes.


----------



## gunrunnerjohn (Nov 10, 2010)

The In4148 is a bog standard low current (300ma) silicon switching diode. This one is probably a nicer package to work with. Those round glass packages have always been a PITA for me to work with. 

Vishay ES07B-GS08


----------



## Shdwdrgn (Dec 23, 2014)

I agree that round packages are a bear... however the part you listed is rather expensive -- 24 dollars for 100 of them? I'm getting the SMD 4148s for $1.29 for 100. However if I only need to look for a low-current switching diode, then that simplifies things greatly. I don't really know much about the different types of diodes, other than there ARE different types that perform different tasks, so I wasn't sure how interchangeable this one would be.

[EDIT] Found another cheap one, but it comes in a DO-214A package which turns out to be rather big. I did find the 4148 in a SOD323 package though, so it's flat and slightly smaller than the glass one although about twice the price. I'll keep looking around.


----------



## gunrunnerjohn (Nov 10, 2010)

All you need is a switching diode that handles a couple hundred MA, the use there is very noncritical.

I don't think I'll match your penny package price, but you can probably find a reasonably priced one that's better and smaller than that one.

The SOD323 package is reasonably easy to work with, and for 2-3 cents a part, I can't imagine that's a major impediment! The labor to deal with a more difficult part is a lot more than that!


----------



## Shdwdrgn (Dec 23, 2014)

Yep I agree, although I didn't actually have any problem with the glass diode once I stuck it down in the solder paste. But a flat part would be a lot easier to work with in the future.

From going through different diode options it looks like maybe the SOD323 and the 0805 package are the same size? I'm using 0603 resistors, so the 0805 should be a piece of cake.


----------



## gunrunnerjohn (Nov 10, 2010)

Yep, the SOD323 looks to be about 0805 size. My personal lower limit for anything I build nowadays is 0603. They're still manageable, but any smaller and it gets very tricky. I tried to use some 0201 stuff once, and I kept losing them on the workbench! I know they're all still scattered around there, I just can't find them!


----------



## Shdwdrgn (Dec 23, 2014)

Yikes, I haven't even seen any listings on ebay of 0201 parts! I agree about the 0603, I had to try and move one part while the solder was melted and that was plenty difficult.

Been getting in some different parts for the power board which I plan to make next. This will be the optoisolator again, plus a bridge rectifier and 3.3v regulator, plus the L293DD to control the loco motor. Basically everything needed to get power to the arduino and the wheels, on a board small enough to fit inside the cab so you only need to run tiny wires to the tender to finish hooking up the arduino. Started with some electrolytic caps for buffering around the regulator, but I found some tantalums that are the same value while only about 1/3 the size. Hopefully they work as well.


----------



## gunrunnerjohn (Nov 10, 2010)

I don't have too much difficulty with 0603 parts, I made 20 of these boards by hand, didn't take all that long.


----------



## Shdwdrgn (Dec 23, 2014)

Motion sensor? As in X-Y spatial motion, IR detectors, or something else?

I need to order more of the 6n137 chips, but otherwise have a huge pile of the resistors and diode on hand. I'm anxious to assemble more, but want to wait until I figure out the right resistor for that one location.


----------



## gunrunnerjohn (Nov 10, 2010)

No, my "motion sensor" was much more primitive, I just monitor motor voltage. If there is no voltage, we're not in motion. 

It sounds really easy, but it takes a bit more than you might imagine to manage it, the motor sensing has to be totally isolated from anything else in the circuit. Also, since there was no telling how the output would be used, that's isolated as well using a relay.

I use this for O-gauge diesel stuff to do things like Rule-17 lighting, automatic cab light control (on when stopped), and dual-level smoke control.


----------



## Shdwdrgn (Dec 23, 2014)

Found a better deal on AliExpress for the 137 chips, only 16 cents each instead of 35 cents that I spent on the original order. I've also redesigned the board to stagger the parts and give a little more spacing, plus added pads for the optional capacitor. For now the original board seems to be working just fine though.

I soldered eight more boards over the weekend, and got jumper wires added to four of them to take to the train club meeting tomorrow. Two of those I wanted to include the capacitor on, but my only choices were some ceramic disc caps or some 0402 SMD caps I bought before understanding that number referred to the size. AT first I thought I'd drop one of the smd caps across the over-sized diode pads, but the parts are too small to reach. However they were the perfect size for just bridging across pins 2-3 right on the chip. Want to see something entertaining? Try watching someone holding an 0402 component with tweezers and soldering it by hand!

So far all of the boards are working the first time I test them. My first real job was assembling circuit boards and inspecting them after they were soldered. Apparently I still have an eye for spotting solder defects. 

I've also been working on another part of the setup... I have a raspberry pi 3 configured as an access point for the railroad wifi, and it provides a platform for later down the road where I can write some programming to directly control the DCC locos. One of the stumbling points was that I wanted it to also connect to other available networks to provide an internet connection (and allow me to remote connect into the Pi to work on the software), however that turned out to be a major problem with the USB wifi dongle I had. Finally gave up and bought a different one last week. Plugged it in, and everything just worked. I guess that's the difference between a $2 device and a $10 device. Now I just have to get busy building some DCC boards for my other locos, figure out how to add track sensors, and get some servos attached to my turnouts. It's gonna be a busy Winter!


----------

