2
\$\begingroup\$

The setup:

An ATtiny85 is programmed using the Arduino IDE, it is supposed to read the ambient light from an LDR and turn on/off an LED accordingly. To get a better understanding of what my sensor readings are in different lighting situations I'd like to send the reading to my serial console using TinyDebug, a part of the Arduino-on-ATtiny libraries.

Here's the minimum sketch:

String myString;

void setup() {
  pinMode(0, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(2);
  String myString = String(sensorValue);
  Serial.write(sensorValue);
  Serial.write("\n\r");

  if (sensorValue > 500) {
    digitalWrite(0, HIGH);
  }
  else {
    digitalWrite(0, LOW);
  }

  delay(500);
}

On my serial console all I receive is garbage:

l

x



x

l

{



t

n

z



u

l

|



q

m





n

o
(...)

Changing the codes Serial.write(sensorValue); to Serial.write("hello"); nicely prints out

hello
hello
hello
(...)

so I suppose the serial communication itself works.

Trying to convert the int value to a string and sending that string, ie Serial.write(myString); gives a compiler error:

(...)
sketch_may24b.ino: In function 'void loop()':
sketch_may24b:11: error: no matching function for call to 'TinyDebugSerial::write(String&)'
/Users/cts/Documents/Arduino/hardware/tiny/cores/tiny/TinyDebugSerial.h:728: note: candidates are: virtual size_t TinyDebugSerial::write(uint8_t)
/Users/cts/Documents/Arduino/hardware/tiny/cores/tiny/Print.h:75: note:                 virtual void Print::write(const uint8_t*, size_t)
/Users/cts/Documents/Arduino/hardware/tiny/cores/tiny/Print.h:74: note:                 virtual void Print::write(const char*)

Any idea how I can send my sensor values to my serial console instead?

\$\endgroup\$
6
  • \$\begingroup\$ For reference: String(); \$\endgroup\$
    – jippie
    May 24, 2013 at 10:18
  • \$\begingroup\$ Is utoa(); an option as alternative for String(sensorValue);? It does require you to declare a buffer beforehand though. Some libraries or functions are not supported on ATtiny, but it is not described which exact ones. Trial and error is proposed. \$\endgroup\$
    – jippie
    May 24, 2013 at 10:30
  • \$\begingroup\$ Why are you first converting the integer to a string: String myString = String(sensorValue); only to try and print the integer itself on the next line: Serial.write(sensorValue); ? \$\endgroup\$
    – jippie
    May 24, 2013 at 10:57
  • \$\begingroup\$ @jippie - Don't you mean Serial.write(&sensorValue);? Or can you skip the & (Freaking C++). \$\endgroup\$ May 24, 2013 at 10:58
  • \$\begingroup\$ @ConnorWolf that is not what is in Christian's source. I frowned when I spotted it and I copied it from there. \$\endgroup\$
    – jippie
    May 24, 2013 at 10:59

2 Answers 2

3
\$\begingroup\$

Assuming you're using Arduino-Tiny with the hardware serial port (and I think the soft-serial port too), I think the solution should be as simple as changing your Serial.write(intVar) to Serial.print(intVar)

As far as I can tell, the write function seems to be a lower-level thing, that only works on strings. What I think is happening is that you're passing an int, and the tiny is treating that int as the pointer to a zero-terminated string, and is proceeding to print the contents of a random memory address until it finally hits a zero.

As usual, the solution is to go to the source.

It's worth noting that I'm not sure how the actual serial library (either HardwareSerial.cpp or TinyDebugSerial.h is actually involved in the build process. I suspect it's something done in a makefile or the arduino tool, but I don't see any direct reference from either of the actual serial libraries to the print library, that I believe handles the actual formatting of arguments before passing them off to the serial libraries as a set of bytes.
The whole arduino build process is very confusing, and I have not done much C++ at all, so I'm not familiar with how inheritance works in it.

\$\endgroup\$
2
  • \$\begingroup\$ I agree with your diagnosis and remedy. As for the connection between Serial and Print: Serial is actually an alias of TinyDebugSerial, which inherits from Stream, which inherits from Print. At compile time, anything in the relevant core/variant directory is compiled automatically. \$\endgroup\$ May 24, 2013 at 11:32
  • \$\begingroup\$ @microtherion - I figured it was some weird inheritance thing, and I didn't spend that much time looking at it. I really don't know much C++ at all. I really only use C and python. Thanks! \$\endgroup\$ May 24, 2013 at 12:00
1
\$\begingroup\$

Cause: Why are you first converting the integer to a string:

String myString = String(sensorValue); 

Only to try and print the integer itself on the next line:

Serial.write(sensorValue);

Solution: Change the second line to:

Serial.write(myString);

And/or check of @ConnorWolf's Serial.print(); solution works.

Another option is to:

#include <stdlib.h>
char myString[ 6 ] = { 0 };
utoa( sensorValue , myString , 10 };
Serial.write( myString );

Some Arduino functions/libraries don't work on ATtiny's, but there is no formal list which do or don't. It is pretty much a trial and error thing, hence this utoa(); alternative. I've successfully used utoa on a ATtiny45, 85 and 2313.

\$\endgroup\$
2
  • \$\begingroup\$ From his answer, it sounds like he tried Serial.write(myString);, and got a compiler error. Look at the last code-segment in the OP. \$\endgroup\$ May 24, 2013 at 11:03
  • \$\begingroup\$ Shoot, no easy rep for me today :o( \$\endgroup\$
    – jippie
    May 24, 2013 at 11:06

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.