Softwareserial pin voltage

Hi all,

I was wondering of something. I’m trying to get an ATTiny85 to communicate with an UNO using soft serial but I’m not getting the results I’m expected.

The ATTiny85 is on a breadboard running at 3.3V 8MHz internal oscillator. Ofcourse there is a voltage divider on the Tx pin of the UNO going to Rx pin of the ATTiny. And the GND of both is connected.

Measuring the voltages on the Rx and Tx pins of both, when they are NOT connected I noticed the following:

On both Rx and Tx pins of the UNO (i.e. Rx = D2 and Tx=D3) I get 5V, while on the ATTIny85 I get 3.3V only on the Tx pin (pin 4). On the Rx pin of the Tiny (pin3) I get 0V.

So which is correct? What the voltage of the SoftSerial Rx pin should be? I tried 3 different ATTiny’s and get constant readings on all of them. I have no other UNO to test (but I may get another ATMega328 later in the night).

I have connected an oscilloscope on RX and Tx pins of the Tiny and while I see on the Rx some traffic when I’m sending data, on the Tx I never get to see anything. I do not know what traffic it is though as I have no logic analyzer, I can only see the line on the OSC moving.

Here is the code for both:

Attiny85:

#include <SoftwareSerial.h>
#include <TinyWireM.h>
#include <SparkFunHTU21Dtinny.h>


const int PIR_pin = 1;  /* PIR input */

char RUaddress = '1';  /* The address that we respond to */
bool amIPolled = false;
HTU21D mySensor;
SoftwareSerial mySerial(3, 4); // Rx, Tx
unsigned long TempPollPreviousMillis = 0L;
unsigned int TempPollinterval = 2000;
bool pirActivated = false;


float temperature = 0.0f; /* Will hold the temerature value */ 
float humidity = 0.0f;    /* Will hold the humidity value */



void wait (int a) {
	unsigned long nowMillis = millis();
	while (millis() - nowMillis > a){
		nowMillis = millis();
	}

}




void setup()
{
	mySerial.begin(9600);
	mySensor.begin();
	pinMode(PIR_pin, INPUT); /* Need external pull-down */ 
	
}

void loop()
{
	/* Poll Temperature every <interval> seconds */
	if (millis() - TempPollPreviousMillis > TempPollinterval) {
		temperature = mySensor.readTemperature();
		wait(10);
		humidity = mySensor.readHumidity();
		wait(10);
		TempPollPreviousMillis = millis();
	/* Testing 
		mySerial.print("Temp: ");
		mySerial.println(temperature.value_float);
		mySerial.print("Hum: ");
		mySerial.println(humidity.value_float);
		*/
		pirActivated = analogRead(PIR_pin);

		if (mySerial.available() > 0) {
			char a;
			a = mySerial.read();
			if (a > '0' && a < '5') {
				if (a == RUaddress) {
					amIPolled = true;
				}
			}
			wait(10);
			/* Flush the rest of Serial buffer */
			while (mySerial.available()){
				mySerial.read();
				wait(10);
			} // End Flushing buffer.
		} // End of reading serial.

	} // End of poll cycle

	/* If we are pooled, lets responce with some data.*/ 
	if (amIPolled) {
		mySerial.print(RUaddress);
		mySerial.print(',');
		mySerial.print(temperature);
		mySerial.print(',');
		mySerial.print(humidity);
		mySerial.print(',');
		mySerial.println();
		mySerial.flush();
		wait(10);
		amIPolled = false;
	}


} // loop() end.

And Uno:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600); //For S25 set to 19200
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600); //For S25 set to 19200
  //mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

On both Rx and Tx pins of the UNO (i.e. Rx = D2 and Tx=D3) I get 5V, while on the ATTIny85 I get 3.3V only on the Tx pin (pin 4). On the Rx pin of the Tiny (pin3) I get 0V.

In a TTL serial setup, the normal at rest state both the tx and rx pins are normally high (at the board voltage). It appears that a serial condition has not been set on the ATTIny85.

The SoftwareSerial that the Uno uses activates the internal pull-up resistor for the RX pin. This is done so that when there is no transmitter on the other end the pin won't float and cause spurious interrupts. The software serial code for the '85 core you're using must not have that. You might get a stream of junk characters loaded into the RX buffer on the '85 when it isn't connected to the Uno.

So this should be normal situation. Normally the Tiny Tx is connected to the UNO Rx. Although the voltage is different i guess its not the +5V or +3.3V that matters but the 0V.

Normal? I think it's a bug. But it's only a possible issue when the RX pin isn't connected.

The core I have for the ATtiny85 does activate the pull-up resistor for the RX pin. What core are you using?

I got the one on this page: https://learn.sparkfun.com/tutorials/tiny-avr-programmer-hookup-guide/ This is actually the programmer I'm using to program the chip.

Does the Attiny85 have internal pull-up resistors? I was under the impression that it has not. At least the for the I2C bus using the TinyWireS library, I'm using external pull-ups.

It sounds like your ATtiny85 sketch is using the exact same SoftwareSerial library in the core.

The datasheet for the '85 says that it has internal pull-ups for the input pins. Here’s the thing though. If there are no pull-ups or the pull-ups are disabled then the pin would float. But you said it always reads zero volts when disconnected.

When you measured it was it completely disconnected or was the voltage divider still attached to the '85 RX pin? If the divider was still attached and the resistor to ground was a lot less than the internal pull-up resistor your divider would have pulled the pin down. The internal resistor is something like 30K. If your divider had a 1K resistor to ground you’d have read about 0.1V.

That makes sense... The divider was still in place. And indeed the only combination of resistors I had laying around that would make an output as close to 3.3V as possible were 470Ohm and 220Ohm (well exact values measured by the Fluke were 464 and 216 respectively) so way bellow internal pull ups...

Good catch!

I'm suspecting the low values of the resistors to play some role to the communication issue as well.... I may run the ATTiny at 5V to see whats happening...

One possibility is that your ATtiny85 internal oscillator factory calibration is too far off. I've heard this is sometimes an issue requiring tuning the OSCCAL register. SoftwareSerial at 9600 baud has about a ±5% frequency tolerance. According to the datasheet the default frequency for the oscillator can be off by as much as 10%. Or maybe you have some other problem, I don't know.

Will do some more testing…

Thanks for your help!