Нужен конвертер с i2c на ws2811/ws2812

Thest

✩✩✩✩✩✩✩
2 Апр 2021
4
0
Есть устройство на esp8266 которое по I2C передает данные в байтах (R, G, B, номер диода от куда идет свет, количество запускаемых диодов, направление запуска, режим радуги, 0, 0, 0).
Необходимо написать код для attiny13 который будет выполнять данные действия. Есть рабочий код для 328 меги на базе microled, но для тиньки пока опыта нет переписать. В дальнейшем нужно будет код переделать для китайского чипа https://www.manuallib.com/download//2023-10-30/MC30F6910 用户手册.pdf который по сути является аналогом тиньки с небольшими изменениями. На тиньке проще протестировать исполнителю, китайские чипы есть в наличии, но т.к. программатор у меня всего один, тесты будут на моем компе.
Почему не сразу управлять esp-ws? Потому-что эта лента очень чувствительна к помехам на дистанции более 5 метров кабеля и появляются рандомные мерцания. I2C по тестам помехи не пропускает, поэтому было решено использовать его для передачи на длинные расстояния, а к китайскому чипу напрямую ленту припаивать.
Территориально я в Краснодаре, но исполнитель может быть с другого города, для тестов китайского чипа найдем способ, видеозвонок/телемост/anydesk..
мой код для меги, который нужно на тиньку залить:
C++:
#include <Wire.h>
#define STRIP_PIN 2  // пин ленты

#define COLOR_DEBTH 3
#include <microLED.h>  // подключаем библу
microLED<0, STRIP_PIN, MLED_NO_CLOCK, LED_WS2812, ORDER_GRB, CLI_AVER> strip;
byte a, b, c, d, e, f, g, h, i, j;
void setup() {
  Wire.begin(8);                 // join I2C bus with address #8
  Wire.onReceive(receiveEvent);  // register event
 // Serial.begin(9600);            // start serial for output
  strip.clear();
  strip.show();
 // Serial.println("Start");
}

void loop() {
  if (g == 1) {
    static byte count = 0;
  count += 3;
    if (f == 1) {
      for (int i = 0; i <= d; i++)strip.send(mWheel8(i * 255 / e - count, 250));
      for (int i = d + 1; i <= e; i++) strip.send(mRGB(0, 0, 0));
    } else if (f == 2) {
      for (int i = 0; i <= d; i++) strip.send(mRGB(0, 0, 0));
      for (int i = d + 1; i < e; i++)strip.send(mWheel8(i * 255 / e - count, 250));
    } else if (f == 3) {
      for (int i = 0; i < d-1; i++) strip.send(mRGB(0, 0, 0));
      for (int i = d; i <= e; i++)strip.send(mWheel8(i * 255 / e - count, 250));
    } else if (f == 4) {
      for (int i = 0; i < d-1; i++)strip.send(mWheel8(i * 255 / e - count, 250));
      for (int i = d; i <= e; i++) strip.send(mRGB(0, 0, 0));
    }
  }

  delay(30);
}

void receiveEvent(int howMany) {
  a = Wire.read();  //  R
  b = Wire.read();  //  G
  c = Wire.read();  //  B
  d = Wire.read();  //  от
  e = Wire.read();  //  до
  f = Wire.read();  //  куда
  g = Wire.read();  //  радуга
  h = Wire.read();  //
  i = Wire.read();  //
  j = Wire.read();  //
 
  /*
  Serial.print(a);
  Serial.print(',');
  Serial.print(b);
  Serial.print(',');
  Serial.print(c);
  Serial.print(',');
  Serial.print(d);
  Serial.print(',');
  Serial.print(e);
  Serial.print(',');
  Serial.print(f);
  Serial.print(',');
  Serial.print(g);
  Serial.print(',');
  Serial.print(h);
  Serial.print(',');
  Serial.print(i);
  Serial.print(',');
  Serial.println(j);
  */
  strip.begin();
  if (g == 0) {
    if (f == 1) {
      for (int i = 0; i < d; i++) strip.send(mRGB(a, b, c));
      for (int i = d + 1; i <= e; i++) strip.send(mRGB(0, 0, 0));
    } else if (f == 2) {
      for (int i = 0; i < d; i++) strip.send(mRGB(0, 0, 0));
      for (int i = d + 1; i <= e; i++) strip.send(mRGB(a, b, c));
    } else if (f == 3) {
      for (int i = 0; i < d; i++) strip.send(mRGB(0, 0, 0));
      for (int i = d + 1; i <= e; i++) strip.send(mRGB(a, b, c));
    } else if (f == 4) {
      for (int i = 0; i < d; i++) strip.send(mRGB(a, b, c));
      for (int i = d + 1; i <= e; i++) strip.send(mRGB(0, 0, 0));
    }

  }
  strip.end();
}
 

bort707

★★★★★★✩
21 Сен 2020
3,079
915
I2C по тестам помехи не пропускает, поэтому было решено использовать его для передачи на длинные расстояния
Длинные, это какие?
Честно говоря, слова об устойчивости и2с звучат бредово. Вы в курсе , как расшифровывается i2c?
IIC(i2c) - inter-integrated circuit - то есть связь внутри одной платы. Оно рассчитано даже не на метры, а на сантиметры.
 

poty

★★★★★★✩
19 Фев 2020
3,268
950
@Thest, соглашусь с @bort707, достаточно будет конвертера уровней.
По факту - памяти на маленьком чипе мало, лента будет короткая, возможны нестабильности по переполнению стека и проч. Работать на протоколах, где отсутствует аппаратная буферизация, будет с паузами (передача данных на ленту - блокирующая операция для таких скоростей, как и приём данных по I2C), значит, вместо защиты от помех Вы получите нестабильный приём. В целом - идея не очень хорошая.
 

Thest

✩✩✩✩✩✩✩
2 Апр 2021
4
0
@poty,можете тогда посоветовать или скинуть пример конвертера? Это на ленте придется ставить понижающий преобразователь и транзистор?

1734427710245.png
Так не работает, где ошибся?
Работает без делителя напряжения, но тогда будут помехи на расстоянии
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
503
149
@Thest,
Может проще вставить в условно 5-ти метровый кабель по одному WS2812 через расстояние, снижающее помехи до приемлемого уровня? Хотя это тоже диванно - теоретизирование. Конечно лучше найти рабочий проект в котором решили вопрос передачи на 5 м.
 

poty

★★★★★★✩
19 Фев 2020
3,268
950
@Thest, так и не будет работать. В схеме эмиттерного повторителя на выходе будет входное напряжение за минусом падения на переходе база-эмиттер.
Я имел в виду конвертор уровней 3,3В - 5В. Поищите хотя бы в других ветках этого форума.
Увеличивать напряжение в линии не нужно, нужно увеличить ток, для чего перед входом (после длинной линии) нужно поставить минимально возможное сопротивление из доступного выходного тока источника. Я бы начал с 1кОм.