Tag Archives: atmega328p

Hacking DCC, Part 1

So, this is interesting.  I finally got a chance to use my oscilloscope for actual scientific purposes!

I figured it would be possible, but I wasn’t quite sure how, to use the ATMEGA328P’s timers to create two opposing square waves.  Turns out, it’s pretty easy to make one waveform, but to output both…

Actually, it turns out that’s pretty easy too.  All it takes is a FOC1B to make OC1B spin on a different cycle, 180° in opposition to OC1A.  OC1A and OC1B output on PB1 and PB2, respectively.

Square waves in opposition

Cool.  The pink signal is OC1A, and the green one is OC1B.  This picture is actually from a little bit later in the game, when I was manipulating the signal to send pulses of varying length.  The longer pulses represent 0, and the shorter ones represent 1.

What on Earth will happen when I hook up PB1 and PB2 to an H-bridge, and give it 15 volts or so?  It becomes a modulated AC signal, that can be used to transmit power and data down the same two wires! 🙂

But I did notice, after all this, that OC1B is a little bit delayed.  But I think I can live with a delta of 569 nanoseconds.

OC1B follows OC1A slowly

Next, I need to sort out how to disrupt the signal entirely, for approximately 454 microseconds.

Not for the faint of heart: here’s some code.  I do the JavaScript thing in my day job, Bitwise AVR register manipulation is a little bit… weird… if you ask me.

void startDcc() {
    // Toggle both OC1A and OC1B on compare match
    TCCR1A &= ~(_BV(COM1A1) | _BV(COM1B1));
    TCCR1A |= (_BV(COM1A0) | _BV(COM1B0));

    // Set waveform generation mode to CTC
    // Using OCR1A for comparison
    TCCR1A &= ~(_BV(WGM11) | _BV(WGM10));
    TCCR1B &= ~(_BV(WGM13));
    TCCR1B |= (_BV(WGM12));
    // Set clock source to 8x prescaler
    TCCR1B &= ~(_BV(CS12) | _BV(CS10));
    TCCR1B |= (_BV(CS11));

    // Force output compare on OC1B
    TCCR1C |= (_BV(FOC1B));
    // Set default waveform (string of 1's)
    // Set pin modes to output
    // PB2, PB1
    DDRB |= (_BV(DDB2) | _BV(DDB1));
    PORTB &= ~(_BV(PORTB2) | _BV(PORTB1));

    TIMSK1 |= (_BV(ICIE1) | _BV(OCIE1A));

Interface board gets some feature creep

Yes, the parts count keeps going up.

A board I’m working on that’ll sit atop a Raspberry Pi.  It’ll replace the mass of jumper wire that’s currently serving the same purpose.  This board is primarily for the robot, but I have a couple of other usecases in mind.  Besides, I get three copies of the board from the PCB house, so I might as well make it slightly multi-purpose.

Now it has an I2S audio codec chip.  I’ve never tried to do anything with digital audio before, so I’ll probably end up with a Version Two at some point in the future.


So far, it’s got:

  • Yet another ATMEGA328p microcontroller.  This one could easily be something with less horsepower, as it’s just there to manage the power supply and try to make sure bad things don’t happen.
  • Connection for “Motion Controller” board
  • Connection for I2C peripherals (the camera pan/tilt and a few other accessory things will attach to this bus)
  • Microphone input
  • Speaker output
  • Power toggle button

I think I should go to bed though, before this gets too many more features!

Mini Weather Station v2

Last winter, I built a device that I called “Mini Weather Station.”  It is a small plastic enclosure which contains a thermometer, barometer and hygrometer.  And of course, a microcontroller, realtime clock and a 2.4GHz radio module.


It worked reasonably well for a few months, even though it had a few minor design flaws.


Yeah, that little piece of red wire is a sign of one of those minor design flaws.  The other problem isn’t as obvious from the photo.  I had originally intended the microcontroller to run at 1MHz on its internal oscillator.  But when I did, the barometer stopped playing nice with the microcontroller.  While I am able to run everything at 8MHz for a little while, the µc starts to become unreliable as the battery depletes.

Last time, I thought the battery was dead.  So I replaced it with a fresh one.  But, no matter how fresh the battery, it’s no longer transmitting.  The culprit seems to be some corrosion on a few of the radio module’s solder joints.

While I’m disappointed that the board has failed so soon, it’s given me an opportunity to address the design problems.

EAGLE screen shot

Here, I have a new board design with space reserved for a 4MHz ceramic resonator, a new expanded debugging header, and a completely redesigned board layout to better suit the orientation of the finished PCB in the plastic enclosure.

This still won’t solve the corrosion problem, though.  I found something called a “conformal coating”: a nasty chemical which claims to protect against moisture, corrosion, fungus, thermal shock, and static discharges.  I haven’t bothered with it before, mostly because I didn’t know that it was even a thing.  But even though it’s starting to cost me far too much money, this whole fake engineering thing is about trying new things and learning, with eye protection and safety gloves, of course.

With any luck, this iteration will prove to be far more reliable than the last one!