0

I'm working on a project where I use two microcontrollers: an AtTiny44 (20MHz ext clock) and an AtTiny85 (8MHz internal).

What I'm trying to achieve is an I2C communication between the 85 and the 44, with the 44 acting as master and the 85 as slave, then transmit the data read from both of them to a PC with FDTI cable using softwareSerial.

I started with writing the AtTiny85 code:

   #include <TinyWireS.h>
   #define ADC3 A3

   void setup() {
      TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network
      TinyWireS.onRequest(requestEvent);
      pinMode(4,OUTPUT);
      digitalWrite(4,HIGH);
      pinMode(ADC3,INPUT_PULLUP);
   }

   void loop() {
      // This needs to be here
      TinyWireS_stop_check();
   }

   // Gets called when the ATtiny receives an i2c request
   void requestEvent() {
     int val=analogRead(ADC3);
     byte valLow = val & 0xff;
     byte valHigh = (val >> 8);
     TinyWireS.send(valHigh);
     TinyWireS.send(valLow);
   }

With this I am able to send the data read from an adc (A3 pin) to an Arduino as 2 bytes

The Arduino code:

  #include <Wire.h>

  int check=0;

  void setup() {
     Wire.begin();        // join i2c bus (address optional for master)
     Serial.begin(9600);  // start serial for output
  }

  void loop() {
      Wire.requestFrom(8, 2);    // request 2 bytes from slave device #8

      while (Wire.available()&&check<2) { // slave may send less than 
                                          // requested
        int c = Wire.read(); // receive a byte as int
        check++;
        int d = Wire.read();
        check++;
        int number = d | c << 8; //convert two bytes as int
        Serial.println(number);  
     }
     check=0;
     delay(500);
   }

Maybe the check variable is useless, but it's not a problem, because I'm getting the right reading on serial monitor.

I then moved to the AtTiny44; I have an onboard thermistor, and I need to print on softwareSerial the value read from this and the value read from the AtTiny85 board.

This is the code, using TinyWireM:

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

  SoftwareSerial mySerial(0, 1); // RX, TX

  int adc = 2;
  int check=0;

  void setup() {
    pinMode(1, OUTPUT);
    pinMode(0, INPUT);
    pinMode(4,INPUT_PULLUP);
    pinMode(6,INPUT_PULLUP);
    pinMode(7, OUTPUT);
    pinMode(adc, INPUT);
    mySerial.begin(9600);
    TinyWireM.begin();        // join i2c bus (address optional for master)
    while (!mySerial) {
      ;
    }
    mySerial.println("Serial comm started");
    digitalWrite(7, HIGH);
    delay(1000);
    digitalWrite(7, LOW);
 }

 void loop() {
   mySerial.println((int)analogRead(adc));
   TinyWireM.requestFrom(8, 2);    // request 2 bytes from slave device #8
   while (TinyWireM.available()&&check<2) { // slave may send less than    
                                            // requested
   digitalWrite(7, HIGH);
   int c = TinyWireM.receive(); // receive a byte as character
   check++;
   int d = TinyWireM.receive();
   check++;
   int number = d | c << 8;
   mySerial.println(number);  
   }
 check=0;
 delay(500);
 }

The softwareSerial is working good (I get to write the ADC data from the 44) but I can't find where the problem on I2C is (on console monitor mySerial.println(number) sends out 0).

What I excluded so far: connections error, clock skew (the clocks are distant between them), pull-up on I2c bus (they are high in both devices)

  • Why use I2C? Maybe other protocols could be faster/simpler/less pins for this use? – bigjosh Jul 1 '17 at 15:16
  • I don't think there are simpler protocol, or with less pin. I thought of using two softwareSerial but they can't work togheter at the same time – Ghesio Jul 1 '17 at 15:40
  • You data rate seems pretty low, and maybe you only need to send in one direction over the link between the two units? If so, maybe just a single signal wire and a ground between them. Sender drives the wire high for 1ms to signal a "0", 2ms to signal a "1". Really simple bit banged serial port. – bigjosh Jul 1 '17 at 20:11
  • I need to send data in only one way, yes. I'd like to use I2C, but I'm interested in your workaround. Can you point me to some hints? Also how can I manage the master requesting data to the slave in your solution? – Ghesio Jul 1 '17 at 23:44
  • Do you need to have the master request? Why not just have the slave always blindly sending? – bigjosh Jul 2 '17 at 5:31
-1

the 85 as slave

writing a slave, especially an i2c slave, isn't for the faint of heart. typically you use a state machine to help handle that.

one great example is the one presented by nxp in old LPC210x datasheet. AVRs share the same i2c hardware so it is immensely portable to the avr.

  • I know that, but the funny thing is that is the attiny44 master that is not working! – Ghesio Jul 2 '17 at 10:26

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.