14
\$\begingroup\$

I'm trying to transmit from an ATtiny85 to a PC using Arduino-esque code over a USB-Serial converter without understanding very much of anything. I was shocked and appalled that it did not work.

I confirmed that the tiny is flickering the voltage on one of its pins, but when I connect that pin to transmit or receive on the USB-serial cable and try to listen using a terminal program, I get nothing.

I'm not sure how to tell which part is broken.

Do I need more than VCC, GND, and TXD to transmit serial?


Details:

The code for the tiny is written in the Arduino environment and similar code successfully blinks all 4 "PORTB" pins, at least according to the LEDs. I use the code from HLT and Saporetti to let me use the Arduino dialect of C++ to program it. The program still comes in under a K.

#include <SoftwareSerial.h>

SoftwareSerial s(0,1); //receive on "0", and transmit on "1" aka "PB1" aka pin 6

void setup() { s.begin(4800); } // assuming 1Mhz, 4800 baud
void loop() { s.println(millis()); } // transmit something at every opportunity

There's a lot of translation involved, but the code is pretty basic. The code that sets the baud rate seems to assume 1MHz, but luckily my attiny has factory default fuses and runs at 1MHz. At any rate, pin 6 is flickering its voltage according to the LED.

So I use the little wires to connect the "ftdi" end of the FTDI USB-serial converter to the tiny: black to GND, red to VCC, orange to 6. I open the program "minicom" on the PC, set the baud rate to 4800 and wait, for nothing. When talking to my Boarduino, it has no trouble.

The FTDI converter cable has the following pinout: black is GND, brown is "CTS", red is VCC (+4.98V), orange is "TXD", yellow is "RXD", green is "RTS".

If I want to transmit from the tiny to the PC, should I be flickering the voltage on "TXD" or "RXD"? In other words is the transmit wire to transmit from the slave to the host, or the host to the slave?

I actually tried both, neither worked. I've fried less than a dollar's worth of equipment so far, and I'm getting cocky, so I just plug wires into the cable. Maybe I'm not supposed to ignore the "CTS" and "RTS" wires?

Do I need to use any other wires? Do RTS and CTS do anything?

The hardware is an ATTiny85-PU (DIP-8 package, running at 1MHz, rated to 20MHz) powered by USB at 4.98V. The host PC is a MacBook, and it successfully does all things arduino, including using ArduinoISP to program the ATtiny to blink its little heart out.

\$\endgroup\$
9
\$\begingroup\$

You can definitely transmit data using just TX & GND.

Firstly, you want to hook up the ATtiny85 TX line to the FTDI RX line (yellow on the TTL-232R). Make sure that the USB adapter can handle 5V - I'm fairly sure even the 3.3V TTL-232R is 5V tolerant.

According to the example page for SoftwareSerial, you need to set the direction of the TX & RX lines in your setup function:

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3
#define ledPin 13

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
byte pinState = 0;

void setup()  {
  // define pin modes for tx, rx, led pins:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
}

The baudrate will be 4800 in your case. The SoftwareSerial library doesn't seem to support CTS & RTS, so just make sure you aren't using them on the host software.

Check out the reference page for more details, where they talk about some potential timing issues which may be exacerbated if you're running at 1MHz using the internal oscillator on the tiny.

\$\endgroup\$
  • \$\begingroup\$ Thanks! The reference page made it clear that 4800 was too fast, so I dropped to 300 baud and things are "better". The pinMode doesn't affect transmit, but I added it anyways to make things clearer. I'm now trying slowing changing the delay between bits until something is received. Minicom is just showing ? marks right now. Worst case, my 16mhz and 20mhz oscillators arrive Friday. \$\endgroup\$ – Jack Schmidt Sep 27 '10 at 18:07
  • \$\begingroup\$ Do you think it could be the voltage problem? Adjusting the timing still hasn't worked, and I'm getting a lot of question marks, so something is being transmitted. Can I fix it just by lowering the Vcc to the tiny to 3V, that is, can I just hook it up to some batteries instead of USB? Do I connect ground to both the USB ground and the battery ground? \$\endgroup\$ – Jack Schmidt Sep 27 '10 at 18:28
  • \$\begingroup\$ Oh, also thanks for pointing out the yellow wire is for my tiny to transmit on. The orange wire seems to flicker a lot (hooked to a LED from the PC). Is the PC transmitting, or does it stay "on" most of the time? \$\endgroup\$ – Jack Schmidt Sep 27 '10 at 18:31
  • \$\begingroup\$ Yes, should stay HI when idle and flicker when transmitting - I'm not sure if the FTDI is capable of supplying enough current to drive an LED. The AVR will be fine, but I'd remove the LED from the FTDI-TX line. Crystal should fix up the timing issues (but you need to set the fuses to switch over from the internal oscillator). \$\endgroup\$ – Peter Gibson Sep 27 '10 at 23:18
  • \$\begingroup\$ Still working on it, but I'm convinced it is a timing problem or a horrible Arduino-on-ATTiny software problem. A few middle 2-3 bytes are being received (but not displayed) and the rest are garbled as 0x80. I'm gonna write my own (trivial) AVR soft serial send function while I wait for the crystal. Is there some easy/cheap way to see what is being sent? 300 baud is still pretty fast for my old eyes. \$\endgroup\$ – Jack Schmidt Sep 28 '10 at 18:32
7
\$\begingroup\$

So the answer does appear to be: you can just hook up the wires, indeed just GND (black) and RXD (yellow), and everything works as long as the software is good.

Things that did not matter:

  • Internal oscillator works just fine. It appears relatively stable to my limiting testing. At 9600 baud whatever problems it has are negligible.

  • Using USB power on the signals works just fine. You can use a separate voltage source (sharing a common ground), but the FTDI cable reads both 3V and 5V signals perfectly. I connected a battery pack, - to GND of both the FTDI and the tiny, + to the tiny's VCC, and this worked just fine. However just using the VCC (red) of the FTDI (USB power 5V) is much simpler and just as effective.

Things I did wrong:

  • The Yellow FTDI "RXD" line receives bits from the microcontroller, so it connects to the transmit in on the microcontroller. I could have figured this out myself by connecting the transmit and receive lines (orange and yellow) to LEDs or an Arduino and checking which voltage flickered when I transmitted from the PC.

  • Neither SoftwareSerial nor NewSoftSerial works out of the box with an ATtiny. While the ATmega328p and the ATtiny85 share a lot of similarities, there are enough differences that just getting the old software to compile for the new chip is not sufficient.

  • Slower baud rates do not cure things. 300 baud requires more complicated delay routines since the number of cycles between bits is significantly more than an 8bit counter. 9600 baud works just fine, and higher baud rates are doable.

  • Be careful of writing timing critical code in C, especially in inline functions. The time it takes to execute will depend on how the compiler optimizes it. In particular, when calibrating the delay by just changing it up and down, you will get a different answer than when using a (compile time detectable) constant delay, because the assembly generated can be fairly different. It's not that C is "slow", but rather that it was too fast. At one point I was sending 1s faster than 0s (presumably they are more aerodynamic).

  • To start a transmission, you bring the line LOW (the start bit) and then you need to make sure the line is at the right voltage at each of the next 8 sample points, and then make sure the voltage is HIGH at the 9th sample. NewSoftSerial mentions doing a half-length delay on the start bit, but this did not work well for me. I used a 75% delay on the start and a 125% delay on the end.

  • The real concern about voltage might be that some "serial" (especially RS232) is ±12V, not 0V/5V. I spent a lot of time trying to understand how I could adjust the voltage from 5V to 3.3V, but I think that was completely irrelevant.

At any rate, transmitting serial is easy, but getting the timing "perfect" appears pretty important. For me, this was just a matter of coding the transmit in assembly so that I could count the cycles.

\$\endgroup\$
  • 2
    \$\begingroup\$ +1 for 1's being more aerodynamic :) The FTDI TTL232R outputs logic level uart signals (0-5V), if you were interfacing directly with a standard serial port, you'd need an interface IC such as the MAX232, which converts the voltage levels both ways. \$\endgroup\$ – Peter Gibson Sep 30 '10 at 23:24
  • \$\begingroup\$ Congratulations for getting it working. Thank you for your detailed post, I hope this helps many other people with their ATtiny projects. \$\endgroup\$ – davidcary Nov 18 '10 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.