Attiny85 Communication with Arduino UNO

I have been successful in flashing an Attiny85 using the tutorial found here: http://hlt.media.mit.edu/?p=1695. I am using the Attiny85 to determine the color of an object given six options (as in, the color will only be one of 6 possibilities). Once having made its decision, it should transmit that information to another microcontroller, in my case the Atmega328 (the microcontroller used on the Arduino UNO). The Attiny85 should also be able to receive the signal to begin the color sensing process. Therefore I know I need an Rx and Tx pin. Three of the pins are being used as digital outputs to set a Red, Green, and Blue LED high at different times, and another pin to act as an ADC to read in an analog voltage realized at an LDR. Using the reset as an ADC, I should have enough pins.

However, I am having trouble getting the Attiny85 to communicate at all. I tried using softwareSerial, as is shown in the code below, and connecting pin 0 (Rx) on the Arduino to the pin I specified as Tx on the Attiny85, and pin 1 (Tx) to the pin I specified as Rx on the Attiny85. I then opened the serial monitor on my computer, but I don't get anything at all. Is it possible to accomplish what I am trying to do?

I know that you can program the ATtiny85 using bascom and maybe implement USI, but to do that you can't use the Arduino environment to program in C or use the Arduino as an ISP (I think). Any help would be much appreciated. Thanks.

#include <SoftwareSerial.h>

const int rxPin = 6;
const int txPin = 7;

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

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

}

boolean running = true;

void loop()
{ 
  mySerial.println("Hello World"); 
  delay(10);

}

The Attiny85 should also be able to receive the signal to begin the color sensing process.

The signal being "go" or is there information that has to be sent?

// ATMEL ATTINY45 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

Pins 6 and 7 are digital 1 and digital 2. Adjust txPin and rxPin appropriately.

You can find the above info in hardware/attiny/variants/tiny8/pins_arduino.h

It would be easier to just send it a "go" signal, which would entail only sending a high signal to one of the pins on the Attiny85. Therefore I wouldn't need the Rx pin.

Also, I've tried changing the Tx pin to a few different pins, but when using the Arduino UNO as an ISP as is shown by hi low tech, pin 0 is actually the lower left pin. Therefore if I wanted pin 6 to be Tx I would write what is shown below correct?

const int txPin = 1;

I did that, but on my serial monitor, I don't get anything at all. At one point I was receiving a string of ÿ, but I'm not exactly sure how I achieved that.

// ATMEL ATTINY45 / ARDUINO
//
//                        +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//               GND  4|    |5  PB0 (D 0) pwm0
//

I think your outputing Ascci characters, not chars.
The code that you posted, your trying to print "Hello world"? Please explain or show us exactly what your are geting with what code.

make a print screen of what you are getting and post it, along with ANY code being used if it is not the one you posted previously.

try this.

 This example code is in the public domain.
  
  */
 #include <SoftwareSerial.h>
 
SoftwareSerial mySerial(10, 11); // RX, TX
 
void setup()  
 {
   // Open serial communications and wait for port to open:
   Serial.begin(57600);
   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(4800);
   mySerial.println("Hello, world?");
 }
 
void loop() // run over and over
 {
   if (mySerial.available())
     Serial.write(mySerial.read());
   if (Serial.available())
     mySerial.write(Serial.read());
 }

Below is the code that I have flashed to the Attiny85. I called PB4, which is pin 3 of the Attiny, to be the txPin. Per Coding Badly's suggestion, I realized that I don't actually need an rxPin, however, the code will not compile if I don't declare one, so I just called it pin 9, which is not on the chip. I then connected my txPin on the Attiny85 to the rxPin on the Arduino UNO (pin 0). There code on the Arduino UNO is just the code from hi low tech that allows you to use the UNO as an ISP.

I have specified my baud rate for SoftwareSerial on the Attiny85 as 9600. If I match the serial monitor's baud rate to that of the Attiny85, I get a constant string of ÿ's output on the serial monitor. I included a link to my screen shot of this below. If I vary the baud rate of the serial monitor such that it does not match that of the program on the Attiny85, I get different strings of equally meaningless characters (I have included link to me screen shot of this as well). If I change the baud rate on the Attiny85 to something lower, I get the same string, just it updates less often. I have tried changing the baud rate on both the Attiny85 and the serial monitor, but I get the same results.

#include <SoftwareSerial.h>

const int txPin = 4;
const int rxPin = 9;

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

void setup()  {
  

  // set the data rate for the SoftwareSerial port

  //define pin modes for tx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);

}

void loop()
{ 
  mySerial.println("Hello World"); 
  delay(10);
}

Matching Baud Rates: Imgur: The magic of the Internet

Not Matching Baud Rates: Imgur: The magic of the Internet

a_soy_milkshake:
It would be easier to just send it a "go" signal, which would entail only sending a high signal to one of the pins on the Attiny85.

How much time would typically pass between "go" sends? Microseconds? Milliseconds? Seconds? Minutes?

How long does the color determination typically take?

I see you are trying to get SoftwareSerial working at 9600 baud. Is that fast enough? How much data do you plan to transfer?

Therefore I wouldn't need the Rx pin.

I may have a one pin solution up my sleeve.

While we are waiting to see what coding Badly has in his sleve:

I tried your sketch using this core:
http://code.google.com/p/arduino-tiny/
Arduino ver. 1.01
Attiny85 @ 8MHz

And it works perfect!

As far I remember there were problems wit SoftareSerial when using ver. 1.0

Erni,

When I use those cores, my code won't compile, it throws a lot of errors, the first being that INPUT was not declared in the scope. I'm using the exact same sketch.

I copy/pasted right form your posting, so I suspect your core is not installed correct.
Try enabling vebose output from compiling, and post it here, that might tell us what is wrong.

Are you using Arduino version 1.01 ?

I got it compile. You were probably right that I installed the core incorrectly. Now it loads onto the Attiny85. However, I checked my order history from newark, and realized that my Attiny85 is 20MHz. The files here though: https://github.com/damellis/attiny/zipball/Arduino1 which are provided via this tutorial: http://hlt.media.mit.edu/?p=1695 , include the 20MHz Attiny85, but with an external clock, which I am not using.

Here is the chip I have: http://www.newark.com/jsp/search/productdetail.jsp?SKU=68T3808

Also, choosing the 8MHz will let me flash code, but my serial monitor output is the same string of ÿ.

Coding Badly,

The color sensing will come in spurts, so in secession it will receive the "go" signal and need to sense up to 6 colors, maybe within 3 seconds of each other, so 18 seconds total. An individual color determination takes approximately 2 seconds.

If the Attiny85 is the 20MHz it only mean that this is the max frequence.
When it comes fresh from the factory it runs 1 MHz, so unless you have changed the fuses (burned bootloader) your attiny is running at 1MHz.
It should not affect the scketch you are trying to run.

So how are you using your UNO as serial/usb converter.

  1. removed the chip or
  2. put a jumper wire from reset to ground.

BTW if you only need to transmit from the tiny, you don't need a library like SoftwareSerial, you can use TinyDebugSerial.

An example

void setup()  {
  Serial.begin(9600);
}

void loop()
{ 
 Serial.println("Hello World"); 
  delay(10);
}

This will output on pin PB3

If I use TinyDebugSerial do I include it like softwareSerial.h. SoftwareSerial is included with the Arduino Software I know. Is there anything specific that I need to to in order to utilize TinyDebugSerial? Thanks for all your help.

The Tiny will run up to 20 MHz with a crystal. You're not using a crystal, which means that it runs at the internal 8 MHz oscillator. Additionally, if you haven't changed the default fuses, it's set up for clk/8, so runs at 1 MHz.

Also, if you disable the reset pin to use it as an analog input, you can no longer serial-program the chip; you have to use "high voltage" programming, which requires a special programmer (most ICSP programmers can't do this.)

I find that I end up using SPI for the Tinys for all communications. This requires three wires (clock, data in, data out) and you either don't need to use chip select, or you can use the data-in wire as also chip-select by pulling it low for a bit before you send the start of a new packet (and write code to expect this on the receiving Tiny.)

Another option, which I like more these days, is to use a Tiny84A, which has more pins, and still an ADC, or a Tiny2313, which has even more pins, but no ADC, or a full Atmega328p. The few extra dollars for the mega328p aren't particularly noticeable if you only build one or a handful, but the time you save by having enough pins is huge :slight_smile:

No you don't have to include anything (it is in the Tiny core). My example above is all that is needed.
It also means that you cannot change the TX pin it is PB3 1).

  1. ofcource there are exeptions, like if you use a Xtal

Erni, so I used your sketch and the links to the cores you sent me. However, out of the pin, to the arduino, I'm only getting the same garbage from the serial monitor.

I read that you can change the frequency of the chip by choosing your board and frequency and choosing burn bootloader in the tools menu. I put a link to a picture of this here: Imgur: The magic of the Internet

The code on the UNO itself shouldn't matter though correct? It should still receive data on the RX pin and print to the serial regardless right? Or do I need to have code on the UNO that reads in the data and then outputs it to the serial monitor?

EDIT:
So I found the quote below explaining what the y character means. I confirmed this by loading the code below onto the Arduino UNO and printing:

I received: -1

to the serial monitor. However, I do not understand why there is no data to read. I'm printing the string "Hello World", so it seems that it should see some sort of data.

The y with the two dots over it is caused by printing a -1 as an ASCII character. The -1 comes from trying to read data from the serial port, when there is no data to read.

//Arduino UNO Read Data COM Test
int incomingByte = 0;   // for incoming serial dat

void setup()  {
  Serial.begin(9600);
}

void loop()
{ 
  
    incomingByte = Serial.read();

    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
 
}

a_soy_milkshake:
The code on the UNO itself shouldn't matter though correct? It should still receive data on the RX pin and print to the serial regardless right? Or do I need to have code on the UNO that reads in the data and then outputs it to the serial monitor?

If you are using the Uno as a serial-to-USB converter you need to hold the Uno processor in reset. Put a jumper between RESET and GND.

This will help...

When I do that I get no output on the serial monitor. If I remove the jumper I see the same character garbage. The sketch I'm using now is very simple and should just print out hello world.

void setup()  {
  Serial.begin(9600);
}

void loop()
{ 
 Serial.println("Hello World"); 
  delay(10);
}