UART – Neil's Log Book https://nrqm.ca What could possibly go wrong? Tue, 04 Oct 2011 03:58:04 +0000 en-US hourly 1 https://wordpress.org/?v=5.4.1 Un-improving range on the infrared channel https://nrqm.ca/2011/10/un-improving-range-on-the-infrared-channel/ Tue, 04 Oct 2011 03:51:46 +0000 https://nrqm.ca/?p=668 It turned out doing software UART was a terrible idea.  The processor is way too slow to support a reasonable baud rate.  I did figure out how to use a comparator though: the key phrase I was missing was “rail-to-rail.”  That means that inputs can be in the full voltage range from ground to Vcc.  Another handy phrase is “push-pull,” which means that the comparator can output 0 and 1; in contrast, an “open collector” comparator can only output 0, and needs an external resistor to pull the output to 1.

I bought a rail-to-rail push-pull comparator, the MCP6541, and tried it with the receiver circuit, and sure enough it increased the maximum range significantly.  Unfortunately it also increased the minimum range significantly.

Here’s the circuit diagram for the modified receiver circuit:

Infrared receiver with comparator for amplification.

Infrared receiver with comparator for amplification.

The 1 kΩ and 10 kΩ resistors are in a voltage divider configuration to generate a 3.0 V reference against which the input is compared.  If the input is higher than 3.0 V, the comparator outputs 3.3 V, and otherwise the comparator outputs 0 V.

I guess there are a bunch of transistors inside the comparator, and putting them in a chain with the pair of external transistors messes things up.  I don’t know why, but it might be a gain-bandwidth thing (too much gain, lowers the maximum frequency the circuit can operate at).  This is what the output looks like at about 6.5 cm:

'U' character sent over infrared with infrared amplifier.

'U' character sent at 19200 bps over infrared with comparator amplifier.

The jagged bits aren’t there without the comparator.  I used the U character to test because its binary pattern is 01010101.  As you can see, the pattern is there but it’s kind of messed up and it’s dangerously close to 3.0 V.  (Now that I look at this again I see maybe reducing the 3.0 V threshold would improve the minimum range.)

I figured I could put an OPA2134 op-amp voltage follower in between the external transistors and the comparator.  This would de-couple the two sets of transistors, so the weird transistor chaining effect would disappear.  This worked perfectly, once, for no apparent reason at all.  Eventually, after spending a day trying to reproduce my success, I read the op-amp’s datasheet more closely and discovered that it’s not rail-to-rail and should never have worked (it can’t output the full 3.3 V signal, so the comparator’s input was never reaching 3.0 V).

I switched to a JFET op-amp that had rail-to-rail output, and it was able to transmit the ‘U’ character at a good set of ranges, both small and large.  Unfortunately this is the signal it was outputting, at 7.5 cm and at 2 cm:

'U' sent at 19200 bps over infrared with JFET voltage follower at 7.5 cm.

'U' sent at 19200 bps over infrared with JFET voltage follower at 7.5 cm.

'U' sent over infraret with JFET voltage follower at 2 cm.

'U' sent at 19200 bps over infrared with JFET voltage follower at 2 cm.

The observant among you, my imaginary audience, will notice two strange things from this screenshot:

  1. The signal is peaking at almost 4 V.
  2. It’s sending 9 bits at 7.5 cm and 19 bits at 2 cm.

Hoo boy, it didn’t work at all, and it was pure luck that the ‘U’ transmitted correctly at short range (followed, presumably, by a framing error that my system silently ignored).  No other character worked.

I found out that you can use an op-amp as a comparator, so I tried that with my OPA2134:

'U' sent at 19200 bps over infrared with op-amp comparator.

'U' sent at 19200 bps over infrared with op-amp comparator.

Okay!  You can see what it means that the amplifier is not rail-to-rail, it’s only going up to 2.6 V (and that only briefly), but if I remember correctly it received.  Unfortunately the high bits got narrower for some reason as the range decreased, so it didn’t actually do anything to solve the range problem.

I tried using the JFET amp as a comparator, but it didn’t output anything at all so I gave up and ignored the project for a few weeks.  My current solution is to pretend there isn’t a problem, and if I run into the  minimum range issue then I can just bend the receiver askew so that the signal is damped enough to receive.  In the meantime, the transmitter now has a wider field of view, which ought to make it easier to place several receivers in range of the control unit.

]]>
Improving range on the infrared channel https://nrqm.ca/2011/09/improving-range-on-the-infrared-channel/ Sat, 03 Sep 2011 19:15:55 +0000 https://nrqm.ca/?p=663 The range on the infrared channel, which I discussed in the last entry, is probably enough; but I’d like to increase it a bit.  With more range I can space modules farther apart if needed, and hopefully be able to have a wider angle between the transmitter and receiver.

Fortunately the signal output by the Darlington transistor pair on the receiver is a pretty clean digital signal.  At full power it ranges from (a little above) 0 V to (a little below) 3.3 V.  As the transmitter gets farther away the digital signal remains but the low voltage increases beyond the UART receiver’s ability to read a 0.  For example, at a large distance the UART signal might range from 2.5 V (logical 0) to 3.3 V (logical 1).

There are several options I’ve considered:

The handy old Schmitt trigger is the most straightforward, but it’s touchy to design and it will add a bunch of parts (an op-amp and a bundle of resistors).  I tried using a comparator chip, which is like the Schmitt trigger but simpler, but I found that it had a big limitation.  It worked, but the inputs can’t exceed Vcc – 1.5 V (the “common mode input voltage range” on the datasheet).  It can’t read a digital signal ranging between 1.8 (or more) and 3.3 V, so it would provide some amplification but not a lot.  I’m targeting 90% of Vcc as my threshold, so it should read anything below 3.0 V as low.  I also considered using another PNP transistor to amplify the difference between Vcc and the input voltage, but: that much amplification is risky noisewise, an extra transistor reduces the bandwidth too much, and the PNP transistor will produce a logically inverted signal.

Another option is to amplify the signal using crazy op-amp magic, but aaaaaaah no.

So I tried thinking like I’m supposed to for once, and I’m going to try a software solution.  AVR processors include an analog comparator, which I can (hopefully) use to amplify the digital signal coming from the infrared optotransistor.  The downside to doing it this way is that it bypasses the UART module, which means that the application needs to receive data manually (I can still use UART to transmit the signal).  Receiving data will tie up the processor, but as long as there’s enough time to run the receiver code it should be okay, I don’t foresee much data traffic.  Here’s a potential flow chart for the receive procedure:

Software receiver flow chart.

Software receiver flow chart.

Some notes:

  • The wait process is a euphemism for “disable the timer, store the data, blah blah blah, then go back to the program until the next start bit.”  This process takes place during the stop bit, so if there’s another byte incoming then it should finish in time to receive the next start bit.
  • Kevin Rosenberg’s awesome tool AVRCalc calculates that the 8-bit timer running at 8 MHz can be used to generate a 57554 Hz interrupt rate using an OCR value of 0x8A.
  • I might need to mess around with the timing so that the AC reads the right bit, but probably not.  There should be plenty of interrupt overhead delay, and the sampling rate is a little slow and will drift toward the end of the bit.
  • I’m not sure how long the analog comparator takes to produce a result but I’m guessing it’s pretty fast because it doesn’t have to do much.  The AVR datasheet doesn’t have much information on it.  I also don’t know if the comparator has a large common mode input range.

Failing that, I can look for an external comparator with a large common mode input range, or just suck it up and use an op-amp.

]]>
Transmitting UART serial over infrared https://nrqm.ca/2011/08/transmitting-uart-serial-over-infrared/ Sat, 20 Aug 2011 04:50:34 +0000 https://nrqm.ca/?p=658 Here’s how I’d like to communicate between modules in the AUV:

UART-over-IR transmitter (left) and receiver (right).

This is how it works:

For the transmitter I’m using a TSAL6100 infrared emitter.  The LED is rated to operate at 100 mA, which the 15 Ω resistor generates (I actually calculated a 22 Ω resistance and bought 22 Ω resistors; two of those in series, in parallel with another one results in around 15 Ω).  I will actually use a 10 Ω resistor to get a bit more power out of the LED.  This is safe because the LED will only be turned on for brief periods.

The transmitter uses a PNP transistor.  When the Tx-o pin is low, current will flow from the emitter (the side with the arrow) into the base (the Tx-o pin) and the transistor will open, sending current to the LED.  When the Tx-o pin is high current will not flow from the emitter and the transistor will be closed.  This effectively inverts the UART signal, which is good because the Tx-o line spends its idle time high and only goes low when sending data.  The LED only turns on when the Tx-o pin is sending a 0.

The receiver circuit is based around a TEFT4300 phototransistor.  The current generated by the phototransistor is amplified by another NPN transistor (i.e. a Darlington pair configuration).  The resistor is a pull-up resistor, keeping the Rx-i line high while idle.  When the phototransistor is activated by the transmitter LED (a 0 bit is transmitted), the signal is amplified by the NPN transistor and the Rx-i line is pulled to slightly above ground.

I found that the pull-up resistor in the receiver circuit is a little sensitive.  With a 10 kΩ resistor the receiver is not responsive enough to generate a square wave matching the transmitted signal.  With a 10 Ω resistor the NPN transistor saturates and never reaches the low threshold.  I tried the 1 kΩ resistor and a 390 Ω resistor, and qualitatively decided that the 1 kΩ gave a little more range.

The transistor switching frequencies determine the maximum speed of the UART link.  The NPN and PNP transistors both have bandwidths exceeding 1 MHz under the conditions presented above.  The phototransistor is limited to 180 kHz, which is plenty for this application.  It is sufficient to program an Arduino (57600 bps) or Netduino (115200 bps) wirelessly.  More bandwidth could be obtained using photodiodes, which are very fast but a little more expensive than phototransistors.

I haven’t measured the range of this system yet, but eyeballing it it’s around 15 cm with the 10 Ω resistor on the transmitter.  I could improve this by amplifying the signal at the receiver (e.g. with a Schmitt trigger), but 15 cm is probably enough for my application, as long as it works underwater.

]]>
Poor man’s IrDA for intermodular communication https://nrqm.ca/2011/06/poor-mans-irda-for-intermodular-communication/ Fri, 24 Jun 2011 21:15:56 +0000 https://nrqm.ca/?p=614 If all goes extraordinarily well, the AUV will have the following modules sitting in the hull:

  • Acoustic modem
  • Motor control
  • Depth control (buoyancy control and pressure sensing)
  • Master controller

Rather than wiring everything together, I plan to give each module its own power supply and use an optical communication protocol to connect the modules to the master controller.  The inside of the hull will be cleaner and more solid than if everything was wired together, and waterproofing will be easier.  Here’s how it works:

I’m thinking about the depth controller at the moment, so take that as an example.  The master controller wants to send a depth set point to the depth controller.  In my current design, such as it is, the master controller sends a signal to a high-power infrared emitter via a transistor.  This could be e.g. a UART signal (inverted to be active high).  The infrared emitter lights up the inside of the hull with the signal sent by the master controller.  Everything receives this signal, so the frame will be addressed to the depth controller.  The infrared signal is transduced back to a TTL UART signal using an optical transistor and a pull-up resistor or filter, and the UART signal is fed to the depth controller’s UART receiver.  The depth controller transmits its detected depth back to the controller in a similar manner.  This is a very simple non-modulated (baseband) infrared communication protocol.

I can foresee several issues that demand exploration:

  • The emitter isn’t strong enough: I hope this won’t be an issue in a small, enclosed, dark sphere, but I might be able to arrange all the modules so that the IR components have line of sight.
  • Infrared absorption and reflection: the module casings will need to be transparent to infrared.  I currently plan to have most or all of the casings be made out of clear acrylic, and I will need to test the infrared transmission through air, acrylic and water.
  • Data rate: the two kinds of optotransistors I bought have rise/fall times of 10 and 15 microseconds, leading to a theoretical maximum throughput of 33 to 50 kbps.  I don’t need high-bandwidth communications though, so the data rate can be lowered easily to reduce interference.
  • Grim shadows: I am not designing the AUV to be sea-worthy, in part so I don’t have to deal with crud building up and blocking the optical signal.  The module casings should stay clean, and with only a couple wires inside the hull this is unlikely to be a problem.
  • Collisions: The master controller will initiate all communications, and all communications will be synchronous.  This is effectively a one-wire bus protocol, kind of like I2C with an asynchronous clock.
  • Other UART errors: Specifically framing errors.  Likely each module will have a crystal.  Even without a crystal, so few data will be transmitted at a time that framing errors should not be a problem, but I will probably keep a sanity check on the UART’s frame error detect bit just in case.

My original idea associated each module with a colour instead of an address, so a module would only receive data transmitted on the correct wavelength.  As a friend once said to me, “Rube Goldberg would be proud.”

]]>