Связь AtTiny44 и AtTiny 85

Я работаю над проектом, в котором использую два микроконтроллера : AtTiny44 (внешняя тактовая частота 20 МГц) и AtTiny85 (внутренняя 8 МГц).

Я пытаюсь добиться связи I2C между 85 и 44, при этом 44 выступает в качестве ведущего, а 85 — в качестве подчиненного, а затем передаю данные, считанные с них обоих, на ПК по кабелю FDTI с использованием программного обеспеченияSerial. .

Я начал с написания кода AtTiny85:

   #include <TinyWireS.h>
   #define ADC3 A3

   void setup() {
      TinyWireS.begin(I2C_SLAVE_ADDRESS); // присоединяемся к сети i2c
      TinyWireS.onRequest(requestEvent);
      pinMode(4,OUTPUT);
      digitalWrite(4,HIGH);
      pinMode(ADC3,INPUT_PULLUP);
   }

   void loop() {
      // Это должно быть здесь
      TinyWireS_stop_check();
   }

   // Вызывается, когда ATtiny получает запрос i2c
   void requestEvent() {
     int val=analogRead(ADC3);
     byte valLow = val & 0xff;
     byte valHigh = (val >> 8);
     TinyWireS.send(valHigh);
     TinyWireS.send(valLow);
   }

Благодаря этому я могу отправить данные, считанные с АЦП (контакт A3), на Arduino в виде 2 байтов

Код Arduino:

  #include <Wire.h>

  int check=0;

  void setup() {
     Wire.begin();        // подключаемся к шине i2c (адрес для ведущего необязателен)
     Serial.begin(9600);  // запускаем последовательный порт для вывода
  }

  void loop() {
      Wire.requestFrom(8, 2);    // запрос 2 байтов от ведомого устройства №8

      while (Wire.available()&&check<2) { // ведомое устройство может отправить меньше, чем
                                          // запрошено
        int c = Wire.read(); // получаем байт как int
        check++;
        int d = Wire.read();
        check++;
        int number = d | c << 8; //конвертируем два байта как int
        Serial.println(number);  
     }
     check=0;
     delay(500);
   }

Возможно, переменная check бесполезна, но это не проблема, потому что я получаю правильные показания на последовательном мониторе.

Затем я перешел на AtTiny44; У меня есть встроенный термистор, и мне нужно напечатать на программном обеспечении Serial значение, считанное с него, и значение, считанное с платы AtTiny85.

Это код с использованием TinyWireM:

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

  SoftwareSerial mySerial(0, 1); // прием, Техас

  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();        // подключаемся к шине i2c (адрес для ведущего необязателен)
    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);    // запрос 2 байтов от ведомого устройства №8
   while (TinyWireM.available()&&check<2) { // ведомое устройство может отправить меньше, чем
                                            // запрошено
   digitalWrite(7, HIGH);
   int c = TinyWireM.receive(); // получаем байт как символ
   check++;
   int d = TinyWireM.receive();
   check++;
   int number = d | c << 8;
   mySerial.println(number);  
   }
 check=0;
 delay(500);
 }

Программное обеспечениеSerial работает хорошо (я записываю данные АЦП из 44), но я не могу найти, где проблема в I2C (на мониторе консоли отправляет mySerial.println(number)) выход 0).

Что я пока исключил: ошибку подключения, перекос часов (часы разнесены между собой), подтягивание на шине I2c (они высокие в обоих устройствах)

, 👍-1

Обсуждение

Зачем использовать I2C? Может быть, другие протоколы могут быть быстрее/проще/меньше контактов для этого использования?, @bigjosh

Я не думаю, что существует более простой протокол или с меньшим количеством выводов. Я думал использовать два последовательных программного обеспечения, но они не могут работать вместе одновременно., @Ghesio

Вам кажется, что скорость передачи данных довольно низкая, и, возможно, вам нужно отправлять только в одном направлении по каналу между двумя устройствами? Если да, то, возможно, только один сигнальный провод и земля между ними. Отправитель подает на провод высокий уровень на 1 мс, чтобы сигнализировать «0», и на 2 мс, чтобы сигнализировать «1». Действительно простой последовательный порт., @bigjosh

Да, мне нужно отправить данные только одним способом. Я хотел бы использовать I2C, но меня интересует ваш обходной путь. Можете ли вы указать мне на некоторые подсказки? Кроме того, как я могу управлять запросом данных от ведущего устройства к ведомому устройству в вашем решении?, @Ghesio

Вам нужен главный запрос? Почему бы просто не заставить раба всегда отправлять сообщения вслепую?, @bigjosh

Он также мог бы отправлять вслепую, но как я могу управлять временем между программным последовательным портом и последовательным битом?, @Ghesio

На микросхеме, подключенной к FDTI, выполните смену контактов ISR для пиуна, который подключен к линии передачи данных, идущей от пульта дистанционного управления. Каждый раз, когда уровень сигнала меняется с низкого на высокий, сохраняйте текущее время. Каждый раз, когда оно меняется с высокого на низкое, обратите внимание на разницу между текущим временем и сохраненным временем. Если время ~1 секунда, то получен 0 бит, если время ~2 секунды, то получен 1 бит. переместите их в переменную хранения, пока у вас не будет байта данных. Когда все заработает, вы сможете работать намного быстрее, но отладку с помощью светодиода можно выполнить за 1–2 секунды., @bigjosh

Возможно, ATtiny85 не может справиться с тактовой частотой I2C, генерируемой AtTiny44. Попробуйте запустить их оба на одинаковой тактовой частоте., @Jeff Wahaus