Go Down

Topic: arduino uno to attiny85 and analog (Read 1 time) previous topic - next topic

crchisholm

Should it be possible to pass a value (0 to 1023) from arduino uno to attiny85 using the analogWrite() on the Uno and analogRead() on the attiny85.   I have tried just sending some arbitrary value from the uno to the attiny and I seem to receive nothing.  The attiny is being powered by the uno and am receiving on the attiny pin 3 (adc2).  I have tried sending on the several pins on the uno.

There is really no code to share because I have tried just to do very simple coding just to send from the uno and to receive on the a85 and thus far get nothing.   I am sure I don't know what I am doing, so maybe I could get some suggestions as to how to learn what I don't know.   I have had no problem doing other coding on both the uno and the a85 (through usbasp) in the arduino 1.0 environment, but this seems to be beyond me so far.
Charlie R Chisholm

Nick Gammon

Absolutely not. For one thing, analogWrite only writes up to 255. Second, analogWrite writes PWM and analogRead reads voltage levels.

I suggest you send two bytes using Serial.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

crchisholm

Ok, good information.

I actually only need to pass a value of 0 through 5  to the attiny, so I would think I could do that in a single byte.  The only way I know to do that is by using 3 pins (000 - 101 binary)  on the attiny and I need three pins for other tasks, so that won't work.   Is there a way to send a single byte from uno and interpret it as a byte value on the attiny? 
Charlie R Chisholm

Erni

i think you could use a serial connection between Arduino and the Tiny.

I once tried it the other way round, sending a serial signal from the Attiny85 to arduino, and that worked OK, so I guess the other way should be Ok too.

Furthermore you could take a look at TinyWires

http://arduino.cc/forum/index.php/topic,51984.15.html

crchisholm

Thanks Erni....I am starting to look into this.   Please forgive my ignorance, but I have a couple questions.   From what I am seeing so far, it appears that I would include the <wire.h> on the uno which will be the master and <tinywires.h> on the attiny85 which will be the slave.   Is this correct, based on my need to send a byte from the uno to the attiny?

Also, in the example code, the address used for the attiny85 is 38.  I see in several places, that this number may come from the data sheet.  Is that correct?  would it always be 38 for the attiny? 

In wire.h, it appears that I need to supply an address for the attiny.  In the example code, the slave is given the wire address of 4.  Can you tell me were that comes from?   

These questions are probably very elemental (and demonstrate my lack of understanding) but I just need to get my head around this.

Charlie
Charlie R Chisholm

Nick Gammon

I think Erni is talking about async serial, not I2C. See here:

http://www.gammon.com.au/forum/?id=10894

Async serial doesn't have addresses.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

BenF


Is there a way to send a single byte from uno and interpret it as a byte value on the attiny?   

To exchange an arbitrary number of bytes, you would use one of the three serial protocols suppported by both devices (SPI, Async or I2C).

For a single byte (range 0 to 5) you could get away with using a single wire and pass it on as a digital pulse. Say a short pulse represents zero, a long pulse represents five and values in between cover the steps you need.

You could also use PWM (analog write) as you started out with, but read the input as a digital signal. Measure time between rising/falling edges and determine the ratio of high to low. If you smooth the PWM output (through a Resistor-Capacitor filter), you could also read the ratio as an analog value through analogRead.

Erni

As Nick says a was thinking of async serial communication.

This is a test sketch to show the idea.
It uses SoftwareSerial to read the incomming data, and TinyDebug to show the results.
It works, but not very stable, i guess you have to tune the internel osc., using TinyTuner which I haven't done.
For some strange reason mySerial.available() dosn't work ??

I am using Arduino ver. 0021 and the t85 are running at 8Mhz

Code: [Select]

#include <SoftwareSerial.h>

#define rxPin 0
#define txPin 1

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


void setup() 
{

  //Start tinydebug
  Serial.begin(9600);
  Serial.println("Grettings from Attiny85");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);

}

void loop()
{
  // if (mySerial.available())
  Serial.println(mySerial.read()-48);
}


crchisholm

Thanks for the code, Erni.   This is one of the ways I had tried to make this work, but did not know how exactly.  This code will be extremely instructive.   I managed to solve my problem using Wire.h on the uno master and TinyWireS.h on the attiny85, thanks to a lot of help from Nick.   This will be another way that I want to understand so I will play with this.

Charlie
Charlie R Chisholm

crchisholm

#9
May 10, 2012, 03:07 pm Last Edit: May 10, 2012, 03:10 pm by crchisholm Reason: 1
Another user thought it might be usefull for me to post the code I used to solve this problem.  There is not very much relevant code, but I guess for a newbee like myself, it might be helpfull.   The more experienced users may find ways I could have done this better,but at least I know it works.  

The goal was to pass a value 0 thrugh 5 from the atmega328 to the attiny85 so that the attiny counld take some action.   The value, I guess could have been any value between 0 and 255, but I just needed the six above.  This code will show how I did it but not why.  This was just to test the ability to make these two talk to each other.

On the atmega328p (uno or mini)....
Code: [Select]


#include <Wire.h>

void setup()
{
 // initialize the attiny with a starting value  Wire.beginTransmission(38); // transmit to device 38 -- should  match only one slave.

 Wire.begin(); // join i2c bus (address optional for master)
  Wire.write(5);         // sends a byte
 Wire.endTransmission();     // stop transmitting

}

void loop()
{
 for (int i=0; i<6; i++) {
   Wire.beginTransmission(38);   // transmit to device #38
   Wire.write(i);                // sends mode as 0 - 5
   Wire.endTransmission();       // stop transmitting
   delay(1000);    
   }

 
}


on the Attiny....
Code: [Select]
#include "TinyWireS.h"
#define I2C_SLAVE_ADDR  0x26            // i2c slave address (38) -- the number is a bit arbitrary, but needs to be unique on the network.

int recvd;  


void setup() {
 TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave lightMode
 }
 
void loop() {

 // these lines will be used to retrieve a byte (0 - 5) once I can get this to work
 
   if (TinyWireS.available()) {
       recvd=TinyWireS.receive();
       
       // take some action with the value in recvd.
       
     }
 
 }


I used a 4k7 pullup on attiny 5 and 7 and attached them to arduino A4 and A5 respectively.  Of course both processors shared  ground and 5v
Charlie R Chisholm

Go Up