Декоративное светодиодное освещение

Я не пробовал, только в png.

Через конвертер png-версию прогоните в svg )

Попробую.

Обрати внимание - 0.014 секунды

Ну дык это объяснимо: растровый формат против векторного. И количество полигонов в генерации 3D модели. С вектора их несоизмеримо меньше создается.

Исходник был подходящий под цель, но формат не тот.

Попробую, сейчас хочу монтажный ободок для укладки ленты и светорассеивающей накладки нарисовать-продумать.

Попробовал-быстро всё получилось.
…не думал, что такая разница во времени будет при разных форматах картинки.



В общем с накладкой сменной ясно, с хомут-футляром пока неясно куда крепёж рисовать. Внутри эстетично, но поле желательно внутри иметь белое и ровное.

моё почтение)))

Почему не знаю, но могу посоветовать нарисовать в QCAD вектор .dxf и растянуть его import с помощью linear_extrude. У меня всегда работает, только так модели и создаю.

Маленькая ремарочка: нужно рисовать целиковый чертеж, т.е. без отделенных сегментов, “эксклавов” так сказать. В случае с цветочком надо нарисовать контуры вокруг черного и рамку вокруг всего рисунка. Если потребуется именно аппликацию из отдельных сегментов сделать, то придется эти сегменты делать отдельными файлами - иначе у OpenSCAD какой-то косяк, он не может создать объекты.

Иногда можно смухлевать, создать тончайшие мостики между сегментами, чтобы получился единый контур, но эти тоненькие мостики не были видны/не воспринимались слайсером как зазор или подлежащая печати стенка. Правда это больше подходит для соединения нескольких частей модели тонкой стенкой, которую принтер проигнорирует. А вот если это тонкий вырез то принтер воспримет это как две очень близко расположенные стенки, которые таки спекутся, но будут печататься дольше, нежели наполнение

Так выяснили экспериментально. Формат рисунка желательно в вектор переводить.

VID_20250308_112615


В целом смотрится интересно, по крайней мере в дневное время.

2 лайка

Внутри - круглая матрица?

Нет, отрезок ленты на 18 светодиодов приклеен к внутренней боковой поверхности хомута-футляра.

Понятно. Ну, если нужен корпус, то вот светильник такого же типа - с обручным расположением светодиодов.

Ультратонкая потолочная лампа MARPOU.

В локальных сторах таких не встречал. Только всякие “Эры” дурацкие.

Нет, это чисто опыты со светом, не более.
…Ещё один нюанс: если поднять футляр над плоскостью отражения света, появится ореол вокруг него. Хорошо видно в сумерки.


VID_20250308_193258
VID_20250308_193206

эмби лайт прям))

идея: в центре рисунков заложить глухие перегородки, если потребуется - оклеить фольгой. Для более четкой границы цветов

П.с. надо над анимациями поработать. Это же типа ws2811/2812? Можно гораздо более плавные переходы сделать.

И вполне может пригодится:

// RGB цвет
struct tRGB { uint8_t R, G, B; };

// HSV цвет
// H = 0..1530 - оттенок (255*6), S = 0..255 - насыщенность, V = 0..255 - яркость
struct tHSV { int32_t H, S, V; };

// переход от HSV к RGB
tRGB fHSVtoRGB (struct tHSV hsv) {
  int Vmin = hsv.V * (255 - hsv.S) / 255;
  switch ((hsv.H / 255) % 6) {
    case 0: return { hsv.V, (Vmin + ((hsv.V - Vmin) * (hsv.H % 255) / 255)), Vmin }; break;
    case 1: return { (hsv.V - ((hsv.V - Vmin) * (hsv.H % 255) / 255)), hsv.V, Vmin }; break;
    case 2: return { Vmin, hsv.V, (Vmin + ((hsv.V - Vmin) * (hsv.H % 255) / 255)) }; break;
    case 3: return { Vmin, (hsv.V - ((hsv.V - Vmin) * (hsv.H % 255) / 255)), hsv.V }; break;
    case 4: return { (Vmin + ((hsv.V - Vmin) * (hsv.H % 255) / 255)), Vmin, hsv.V }; break;
    case 5: return { hsv.V, Vmin, (hsv.V - ((hsv.V - Vmin) * (hsv.H % 255) / 255)) }; break;
    default: return { 0, 0, 0 };
  }
}

// смешивает два HSV в пропорциях, переход по спектру в ближайшую сторону t = 0..1023 (целочисленный параметр)
tHSV fMixHSVint (struct tHSV st, struct tHSV tg, int t) {
  tHSV A = st, B = tg;
  if (A.S == 0) A.H = B.H;
  if (B.S == 0) B.H = A.H;
  if (A.V == 0) {
    A.H = B.H;
    A.S = B.S;
  }
  if (B.V == 0) {
    B.H = A.H;
    B.S = A.S;
  }
  int dH = B.H - A.H;
  int H = A.H + ((abs(dH) < 765) ? dH : ( (A.H < 765) ? (dH - 1530) : (1530 + dH) )) * t / 1024;
  int S = A.S + (B.S - A.S) * t / 1024;
  int V = A.V + (B.V - A.V) * t / 1024;
  return { (H > 1530) ? (H - 1530) : ( (H < 0) ? (H + 1530) : H ), (S > 255) ? 255 : ( (S < 0) ? 0 : S), (V > 255) ? 255 : ( (V < 0) ? 0 : V) };
}

Да в фастледе это уже всё есть ))
А ежели вкрячить туды wled, то еще и синхронизировать с десятком таких же получится.

Не, я на неопикселе пробую. Пока просто вариант скетча от ёлки, без продумывания вариантов анимации применительно к кольцу.

Это ws2812b.



Допечатал опорные съёмные вставки для зазора между футляром и плоскостью отражения.

Чего то фантазия с цветосочетанием кончилась :slight_smile:
Добавил датчик присутствия копеечный:


Если шевелиться меняется без анимации пара цветов, раз в 2-4 секунды:

…с анимацией ничего кроме градиента по диагонали не пишется :frowning:
VID_20250309_120909

Спойлер
/////////////////////////////////////
// примеры для ws2812b
//RCWL-0515 СВЧ-датчик движения
//Arduino UNO
#include "Adafruit_NeoPixel.h"

#define line_ 18 //число пикселей в ленте
uint8_t dataPin = 8;// вывод для подключения
Adafruit_NeoPixel strip = Adafruit_NeoPixel(line_,dataPin , NEO_GRB + NEO_KHZ800);// Создаем переменную strip для управления нашей лентой.
// выводы датчика  
int minus=5;//gnd
int Sensor = 6;//out
int plus=7;//vcc 
int T=2050;//пауза выдержки триггера датчика 

byte R=0; byte G=0; byte B=0;//составляющие цвета пикселя
byte R1=0;byte G1=0;byte b1=0;//
byte R2=0;byte G2=0;byte b2=0;//
int t=10;// пауза между кадрами
byte effekt=1;// номер эффекта
byte M=10;//коэффициент мощности свечения пикселя 


///RGB
void setup() {
strip.begin();
 pinMode (Sensor, INPUT);
 pinMode (minus, OUTPUT);
 pinMode (plus, OUTPUT);
 digitalWrite(minus, LOW);
 digitalWrite(plus, HIGH);
 delay(T);// пауза для исключения срабатывания датчика после включения питания  
}
void loop() {
/// 
  R1=random(1,11);G1=10-R1;b1=random(1,11);
  R2=b1;G2=R1;b2=random(1,5);
  ///
  for (int ti = 0; ti < line_; ti++) {//перебор номеров кадров в ленте
    for (int ni = 0; ni < line_; ni++) {//перебор номеров пикселей в ленте
     cvet_(ti,ni);// функция определения цвета пикселя в зависимости от его номера в ленте и момента времени (кадра анимации)   
     strip.setPixelColor(ni, R*M, G*M, B*M);
    }
  // strip.show(); 
   delay_(t);
  }
 ///
 }
///////////////////////////////////////
void cvet_ (int it,int in){
 
 switch (effekt) {
     case 1:  
    {if(in-2<(line_+2*it)/2&&in+2>(line_-2*it)/2&&it<line_/2){R=R1;G=G1;B=b1;}else{if((in>it||in<line_-it)&&it>=line_/2){R=R1;G=G1;B=B1;}else{R=R2;G=G2;B=b2;}} }//
      break; 
     default:
      { R=0;G=0;B=0;}//выключаем пиксели если не выбран эффект
  } 
}
/////////////////////////////////////////////////
void delay_(int t0){
long Y=millis(); 
 while(millis()-Y<t0){
  if(digitalRead(Sensor)==1){ //если сработал датчик...
 strip.show();//меняем цветосочетание на светильнике
 digitalWrite(plus, LOW);   // отключение сенсора от питания
 delay(50);                 // пауза
 digitalWrite(plus, HIGH);  // подключение сенсора к питанию
 delay(T);               // пауза чуть более длительности выдержки триггера датчика в 2-3 сек. после прекращения движения
 } 
 }
}
/////////////////////////////////////////////////

Восход/закат можно изобразить - по вертикали, с нарастанием/спадом общей яркости (value в HSV).