Attiny85 - не стартует I2C и не работает Serial, если скорость последнего более 9600

Собственно сабж..
Девайс состоит из attiny85 Digispark и INA226.
Иногда всё запускается при 19200 Бод, выше - вообще не катит..
При 9600 всё ок.
Скетч:

#include <Wire.h>
#include <INA226_WE.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>

SoftwareSerial mySerial(3, 4);
#define I2C_ADDRESS 0x40
INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
//
float Imax_mA = 600.0;
float shunt = 0.1;
float shunt_cal = 0.0;
//
 struct {
  float busVoltage_V = 0.0;
  float current_mA = 0.0;
  byte alarm = 0;
  byte crc;
 } ReadData;
//
struct RXDATA {
  byte cmd;
};
//
uint8_t crc8_asm(const void* data, size_t length, uint8_t crc = 0) {
    const uint8_t* p = (const uint8_t*)data;
    while (length--) {
        uint8_t data = *p++;
        uint8_t counter;
        uint8_t buffer;
        asm volatile(
            "EOR %[crc_out], %[data_in] \n\t"
            "LDI %[counter], 8          \n\t"
            "LDI %[buffer], 0x8C        \n\t"
            "_loop_start_%=:            \n\t"
            "LSR %[crc_out]             \n\t"
            "BRCC _loop_end_%=          \n\t"
            "EOR %[crc_out], %[buffer]  \n\t"
            "_loop_end_%=:              \n\t"
            "DEC %[counter]             \n\t"
            "BRNE _loop_start_%="
            : [crc_out] "=r"(crc), [counter] "=d"(counter), [buffer] "=d"(buffer)
            : [crc_in] "0"(crc), [data_in] "r"(data));
    }
    return crc;
}
//
void setup() {
   pinMode(1, OUTPUT);
   pinMode(A0, INPUT);
   Wire.begin();
   mySerial.begin(9600);
   mySerial.setTimeout(50);
   ina226.init();
   ina226.setMeasureMode(INA226_CONTINUOUS);
// Shunt calibrate
   if (analogRead(A0) < 930)
   {
    shunt_cal = ina226.getShuntVoltage_mV()/100.0;
    EEPROM.put(4,shunt_cal);
    tone(1,2200,500);
    delay(1000);
    noTone();
    digitalWrite(1,HIGH);
    while(1);
   }
   EEPROM.get(4,shunt); 
   if ((isnanf(shunt)==true)||(shunt>0.1)) 
   {
    shunt = 0.1;
    EEPROM.put(4,0.1);
   }  
   EEPROM.get(4,shunt);
   ina226.setResistorRange(shunt);
   ina226.enableAlertLatch();
   ina226.readAndClearFlags(); 
   ina226.setAlertType(INA226_CURRENT_OVER, Imax_mA);
//
   tone(1,1500,250);
   delay(500);
   noTone();
//
}
void loop() {
//
  RXDATA rxdata{};
  if (mySerial.available() > 0) 
  {
    mySerial.readBytes((byte*)&rxdata, sizeof(rxdata)); 
  }  
    switch (rxdata.cmd) {
     case '@':
      sendData();
      break;
    }
// Alarm
  if(analogRead(A0) < 930)
  {
   tone(1,2200,50);
   delay(500);
   noTone();
  } 
}
// End loop
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void sendData() {
  ReadData.busVoltage_V = (ina226.getBusVoltage_V() >= 0 ? ina226.getBusVoltage_V() : 0.0);
  ReadData.current_mA = (ina226.getCurrent_mA() >= 0 ? ina226.getCurrent_mA() : 0.0);
/* ALARM */
//+++++++++++++++++++++++++++++++++++++++++++
  if(analogRead(A0) < 930) {  
    ReadData.alarm = 1; 
  } else {
    ReadData.alarm = 0; 
  }  
//+++++++++++++++++++++++++++++++++++++++++++
// расчёт CRC (без последнего байта)
  byte crct = crc8_asm((byte*)&ReadData, sizeof(ReadData) - 1);
  // пакуем в посылку
  ReadData.crc = crct;
  mySerial.write((byte*)&ReadData,sizeof(ReadData));
}
//

Работу I2C, или её отсутствие определяю осликом по присутствии/отсутствии импульсов на SDA/SCL.
Serial - по отсутствию импульсов на TXD. На RXD всё приходит в лучшем виде.

Вопрос - я слишком много захотел от attiny85, или что-то не так в софте?

Проверьте частоту внутреннего RC генератора. Если большое отклонение от нормы, UART может не работать.

Гм.. А как это сделать?
Я имею ввиду ГДЕ её можно измерить?
Кстати.. В IDE я выбираю Clock: 16 MHz (PLL).
И почему при “высокой” скорости Serial не стартует (или заходит в ступор) I2C ?
Не связана ли вся эта байда с процедурой калибровки шунта?

  if (analogRead(A0) < 930)
   {
    shunt_cal = ina226.getShuntVoltage_mV()/100.0;
    EEPROM.put(4,shunt_cal);
    tone(1,2200,500);
    delay(1000);
    noTone();
    digitalWrite(1,HIGH);
    while(1);
   }
   EEPROM.get(4,shunt); 
   if ((isnanf(shunt)==true)||(shunt>0.1)) 
   {
    shunt = 0.1;
    EEPROM.put(4,0.1);
   }  
   EEPROM.get(4,shunt);
   ina226.setResistorRange(shunt);

Может стОит добавить сюда проверку на отрицательные значения?
if ((isnanf(shunt)==true)||(shunt>0.1)|| shunt<0.0 )
{

Я ответил, почему может не работать сериал вообще, без привязки к какому-то конкретному коду. Напишите отдельный код, только для проверки сериала.
Проверить тактовую частоту МК можно , к примеру, зажигая диод на определённый интервал, и, сверяя с часами, или , задав на пине сигнал определённой частоты - измерить ёё осциллографом, и сравнить фактическую с задуманной.
Код внимательно не смотрел - нет времени, увы.

точность PLL не проверял, но для RC калибровочные коэффициенты на всех моих 10 штуках нужно в минус и вывести нельзя, он там зашит с завода

Походу, я снова наступил на старые грабли с гальванической развязкой UART.. :cry:
Только проблема, скорее всего другая - пока предполагаю, что велики (или малы :roll_eyes:) номиналы резисторов (выделено красным), да и “жёлтые” тоже под вопросом.
Номиналы выбирал практически “от фонаря”..


Вероятно, на более высоких скоростях банально “не хватает тока”.
Попробовал подключить схему к компу без опт. развязки, через адаптер USB/TTL - 115200 без проблем!

11:02:53.909 → �fAͺ�B�Volt=14.42
11:02:53.909 → mA=101.62

И I2C не падает. Вот это, кстати, самое странное, что сбивало с толку..
Чему никакого объяснения у меня нет..
Вообщем, вечером поколдую с опт. развязкой.

И вроде бы не первый день на форуме. Отчего бы сразу схему не выложить?

Да уж как-то отложилось в мозгу, что здесь больше софтверные обсуждения.
А схемотехника в самую последнюю очередь. Вот и “оплошал”. :slightly_smiling_face:
Ну если Вы готовы обсудить проект в целом, выкладываю схему модуля управления БП.
Силовая часть в данной схеме представлена БП 12V. В оригинале это высоковольтный БП (2KV).


Фрагмент схемы, выделенный пунктиром, находится на отдельной плате.
И в данный момент GND собственно БП с платой контроллера не соединён (там где “крестик”).
В процессе “дорисовки” схемы, появилась мыслЯ - а не тут ли причина проблемы?
В отсутствии соединения с GND БП.
Корпус разъёма DB9 гальванически соединён с “медью” платы, но в данный момент “висит в воздухе”..
Хотя эта “земля” и не выходит на другой конец кабеля (разъём RJ45), но вполне возможно соединена с “экраном” кабеля.
Не является ли, случаем, эта “недоработка” банальным источником помех?
Сейчас проверить нет возможности, вечером начну с этого “пункта”.

Возможно, проблемы с питанием или есть помеха.
При подключении USB подключается 5в от компьютера, поэтому ситуация улучшается
Проверьте источник +5в.
Добавьте по конденсатору, ~10uF, возле тиньки и возле модуля.(желательно low esr)
Резистор 2.2к (на RXD) увеличьте до 5- 10 кОм

470 Ом много для светодиодов опторазвязки. 100 Ом пробуйте.

Нашел. Проблема была в ядре Attiny Core.
Обновил его до последней версии и всё покатило. 115200 Бод без проблем.
Аппаратно ничего не менял.

P.S.

Вот не надо такие советы давать! Особенно тем, кто слабо разбирается в электронике.
Информация для размышления:
a.) 5V / 100 Ohm = 0.05A = 50 mA.
b.)


c.)

Максимальный ток для каждого отдельного вывода ATtiny85 составляет 40 мА,

Мда… Ничего нового. :slightly_smiling_face:

е. 5v - 2v(падение на светодиоде)= 3v \ 470 = 0.6 ma. это мало

там, скорее всего, инфракрасный стоИт, на ём падение меньше

2v это для примера, а так померить реальное падение напряжения на диоде и рассчитать резистор по номинальному току из даташита. Если у ТС работает ну и ладно.

тут ты немножко не прав, светодиод он же как стабилитрон работает значит надо (5 - Vстаб.(1.7) )/100 = 33ма (максимум)
по конкретно твоей оптопаре надо уточнить сколько там напряжение составляет, но выходить надо на эти 25 ма, о чём командир видимо и подсказывал

а ты ожидал чего-то нового?

Гм.. А я не ошибаюсь в том, что 33 > 25 ? :wink:

Мдаааа.. Тушите свет!
3 / 470 = 0,006 А.
0,006 А = 6 мА.

ну пин то не сгорит, а в импульсе твоя оптопара держит больше, ради эксперимента померь напряжение стабилизации, просто интересно инфракрасный там диод или нет, в сторону красного напряжение меньше, в сторону синего больше

А даташит -то глянуть… - 1.7V

А мне вот больше интересно, почему старая версия Core не работает через оптопару, но работает по USB/TTL.