Dinamik burilish signallari - biz KIT to'plamidan ishlaydigan chiroqlar qilamiz. WS2812 va Arduino tasmasidagi burilish signallari bizning faramiz qanday ishlaydi

Ko'pgina avtoulovchilar o'z avtomobilining ko'rinishini yaxshilash uchun "qaldirg'och" ni LED chiroqlar bilan sozlashadi. Tyuning variantlaridan biri - bu boshqa yo'l ishtirokchilarining e'tiborini o'ziga qaratadigan burilish signalidir. Maqolada chiroqlar bilan burilish signallarini o'rnatish va sozlash bo'yicha ko'rsatmalar berilgan.

[Yashirish]

O'rnatish bo'yicha ko'rsatmalar

LED lampalar - elektr toki ta'sirida porlaydigan yarimo'tkazgichli elementlar. Ularda asosiy element - kremniy. Qaysi aralashmalar ishlatilishiga qarab, lampochkaning rangi o'zgaradi.

Fotogalereya "Dinamik yo'nalish ko'rsatkichlarining mumkin bo'lgan variantlari"

Asboblar va materiallar

O'z qo'lingiz bilan burilish signalini yaratish uchun sizga quyidagi vositalar kerak bo'ladi.

  • lehim temir;
  • yon kesgichlar yoki qisqichlar;
  • lehim temir va lehim materiallari;
  • sinovchi.

Sarf materiallaridan siz shisha tolali oynani tayyorlashingiz kerak. Yarimo'tkazgich elementi joylashtiriladigan bosma platani ishlab chiqarish uchun kerak. Kerakli LEDlar tanlangan. LEDlarning xususiyatlariga va bort tarmog'ining oqimi va kuchlanishining qiymatlariga qarab, himoya rezistorlarining xarakteristikalari hisoblanadi. Hisob -kitoblar yordamida qolgan tarmoq komponentlari tanlanadi (Evgeniy Zadvornov videosi).

Ishning ketma -ketligi

Burilish signallarini qilishdan oldin, siz mos sxemani tanlashingiz kerak.

Keyin, diagramma asosida, bosilgan elektron kartani yasang va kelajakdagi elementlarni joylashtirish uchun unga belgilar qo'ying.

O'rnatish quyidagi harakatlar ketma -ketligidan iborat:

  1. Birinchidan, batareyani manfiy terminalini uzib, avtomobilni quvvatini o'chirish kerak.
  2. Keyinchalik, siz eski yo'nalish ko'rsatkichlarini olib tashlashingiz va ehtiyotkorlik bilan demontaj qilishingiz kerak.
  3. Eski lampochkalarni burab qo'ying.
  4. Qo'shimchalarni elimdan tozalash, yog'sizlantirish, yuvish va quritishga ruxsat berish kerak.
  5. Har bir eski element o'rniga yangi ishlaydigan chiroq o'rnatilgan.
  6. Bundan tashqari, chiroqlarni yig'ish va o'rnatish teskari tartibda amalga oshiriladi.
  7. O'rnatishdan so'ng simlar ulanadi.

Keyingi bosqichda tarmoqqa qo'shimcha barqarorlashtirilgan quvvat manbai ulanadi. Uning kirishi oraliq o'rni orqali quvvat oladi va chiqish diodga ulanadi. Uni asboblar paneliga joylashtirish yaxshidir.

LEDlarni ulashda siz anodning quvvat manbaiga, katod esa minusga ulanganligiga ishonch hosil qilishingiz kerak. Agar ulanish to'g'ri bajarilmasa, yarimo'tkazgich elementlari yonmaydi va hatto yonib ketishi mumkin.


Ishlayotgan yo'nalish ko'rsatkichlarini o'rnatish va sozlash xususiyatlari

An'anaviy LEDlar o'rniga dinamik burilish signallarini o'rnatishingiz mumkin. Buning uchun LED va oqim cheklovli rezistorlar bo'lgan taxta olib tashlanadi va demontaj qilinadi. Repetitorda siz stakanni korpusdan yirtib tashlashingiz kerak. Keyin reflektorni ehtiyotkorlik bilan kesib oling va olib tashlang.

Masofadagi reflektor o'rniga, sariq LEDlar joylashgan SMD 5730 taxtasi o'rnatilgan. Repetitor egri shaklga ega bo'lganligi sababli, taxtani tabaqalash va biroz egish kerak bo'ladi. Eski taxta uchun siz ulagich bilan qismni kesib, nazoratchini ulash uchun lehimlashingiz kerak. Keyin barcha komponentlar o'z joylariga qaytariladi.

Ishlayotgan LED chiroqlarining vaqtini sozlash uchun kalit mikrokontrollerga lehimlanadi. Tegishli tezlik topilganda, o'tish moslamalari kalit o'rniga lehimlanadi. Ikkita pinni erga ulaganda, LED chiroqlari orasidagi minimal vaqt 20 ms ni tashkil qiladi. Kontaktlar yopilganda, bu vaqt 30 ms bo'ladi.


Chiqarish narxi

Siz kunduzi ishlaydigan chiroqlardan ishlaydigan yorug'lik burilish signalini qilishingiz mumkin. Ularning narxi 600 rubldan. Bu holda yorug'lik manbalari sifatida siz har bir ishlayotgan burilish signali uchun 7 dona miqdoridagi "pikselli" RGB LEDlarini olishingiz mumkin. Bir elementning narxi - 19 rubl. LEDlarni boshqarish uchun siz 250 rubl qiymatdagi Arduino UNO sotib olishingiz kerak. Shunday qilib, umumiy xarajat 1060 rublni tashkil qiladi.

Ko'proq yoki kamroq zamonaviy mashinani ko'rganlarning hammasi ikkinchi marta emas, lekin agar rulda haydovchi bo'lsa ham, o'zlari uchun foydali variantlardan birini uzoq vaqtdan beri qayd etishgan ... Odamlar buni dangasa burilish signali yoki odobli yo'nalish ko'rsatkichi. Uning mohiyati shundan iboratki, o'ngga yoki chapga burilganda, haydovchi yo'naltiruvchi ko'rsatkich dastagiga mahkamlamasdan faqat bir marta tegadi. Ya'ni, u shunchaki burilish signali indikatorlarini ishga tushiradi, lekin aynan shu kalitni yoqmaydi. Natijada, qo'li bo'shatilgandan so'ng, yo'nalish ko'rsatkichlari yana 3-4 marta ishlaydi va haydovchi bu vaqtda o'z ishi bilan shug'ullanishi mumkin, ya'ni yo'lga butunlay taslim bo'lishi mumkin. Agar siz chiziqlarni o'zgartirishingiz kerak bo'lsa, bu variant juda foydali. Haqiqatan ham, yo'nalish ko'rsatkichi qo'li to'liq yoqilganda, rulning engil burchagi tufayli avtomatik o'chirish sodir bo'lmaydi, demak siz indikatorning o'zi bilan oldinga va orqaga siltab qo'yishingiz yoki qo'lingiz yonida doimo qo'llab -quvvatlashingiz kerak bo'ladi. burilish indikatorini simulyatsiya qilish uchun uni yoqish. Va agar bunday variant bo'lsa, u shunchaki qo'lni tegdi va unutdi. Umuman olganda, biz ishning mohiyati to'liq ochilgan deb o'ylaymiz, lekin hozirda sizning mashinangizda bunday variantni amalga oshirish mumkinligi haqida aytib o'tish joiz.

Qaysi elektr zanjirlari uchun Arduino uchun muloyim burilish signali mos keladi

Hamma joyda xushmuomalalik bilan burilish signalini ishlab chiqarishni boshlashdan oldin, siz mashinaning elektr zanjirini o'zgartirmasdan, qaysi elektr simlarining sxemalariga mos kelishini tushunishingiz kerak.
Bu erda biz printsipial jihatdan farq qiladigan ikkita asosiy variantni taqdim etamiz. Birinchisi, ularni yuk sifatida ulashda burilish signallari yoqilganda. Ya'ni, yoqish burilish signal chiroqining zanjirining kommutatsiyasi tufayli sodir bo'ladi, u erda yo'nalish ko'rsatkichi dastagi o'zi joylashgan, aynan shu davrni yopadi, shundan so'ng operatsiya sodir bo'ladi. Bunday holda, bizning variantimizdan foydalanish ishlamaydi, chunki dastani lampalar bilan o'chirganda, biz darhol chiroqni o'chirish imkoniyatini o'chirib qo'yamiz, hatto signal qo'lning o'ziga kelsa ham, u boshqa ketmaydi.
Ikkinchi variant - bizniki, nazorat signallari va chiqish quvvati signallari mavjud bo'lganda. Bunday holda, standart o'rni o'rniga, biz sizning e'tiboringizga etkazmoqchi bo'lgan sxemani qo'yishingiz mumkin.

Quvvat yuklarini boshqarish uchun Internetda sotib olinadigan o'rni quvvat moduli

Arduino -dagi dangasa (muloyim) burilish signalining sxemasi va diagrammasi

Shunday qilib, siz Arduino -ni dangasa burilish signallari sifatida bosh birlik sifatida ishlatish haqida bahslashishingiz mumkin, chunki bu ham kamchiliklarga ega bo'lgan ideal echim emas. Aytaylik, kontaktni yoqgandan keyin sizga doimiy quvvat kerak bo'ladi, tezlikni ta'minlash uchun quvvat davrlarini ulash kerak bo'ladi. Shu bilan birga, keraksiz radio komponentlardan o'zini bog'lash, bu erda umuman foydasiz, chunki bu holda siz shunchaki mikrokontrollerni dasturlashingiz va faqat undan foydalanishingiz mumkin. Ammo bu minus ham ortiqcha, chunki har bir kishi Arduino dasturiga ega bo'lishi mumkin va mikrokontrollerlar uchun sizga ham dasturchi kerak bo'ladi.
Dastur yozish eng qiyin vazifalardan biri bo'ladi. Bu erda yangi boshlovchi bo'sh vaqtining bir soati va algoritmlar ishini o'tkazishi kerak bo'ladi, lekin xayriyatki, Internet bor va biz. Mana, eskiz.

Int switchPinR = 8; int switchPinL = 7; int ledPinR = 11; int ledPinL = 12; boolean ledOn = noto'g'ri; int i = 0; int z = 0; void setup () (// bu erda o'rnatish kodini bir marta ishga tushirish uchun qo'ying: pinMode (switchPinR, INPUT); pinMode (switchPinL, INPUT); pinMode (ledPinR, OUTPUT); pinMode (ledPinL, OUTPUT); Serial.begin (9600) );) void loop () (// qayta ishga tushirish uchun bu erda asosiy kodingizni qo'ying: // 2 yorliq: if (digitalRead (switchPinR) == HIGH && digitalRead (switchPinL) == HIGH) (digitalWrite (ledPinR, HIGH) ; digitalWrite (ledPinL, HIGH); i = 0; esa (i<7) { ledOn = !ledOn; digitalWrite(ledPinR, ledOn); digitalWrite(ledPinL, ledOn); delay(400); i++; z++; if (digitalRead(switchPinL) == LOW && digitalRead(switchPinR) == LOW && z>= 7) (tanaffus;))) boshqa (digitalWrite (ledPinR, LOW); digitalWrite (ledPinL, LOW); z = 0;) // favqulodda holat HIGH) (goto label;) // O'ngga burilish signali. if (digitalRead (switchPinR) == HIGH) (digitalWrite (ledPinR, HIGH); i = 0; while (i<7) { ledOn = !ledOn; digitalWrite(ledPinR, ledOn); delay(400); i++; z++; if (digitalRead(switchPinR) == LOW && z>= 7) (tanaffus;))) boshqa (digitalWrite (ledPinR, LOW); z = 0;) // Chapga burilish signali. if (digitalRead (switchPinL) == HIGH) (digitalWrite (ledPinL, HIGH); i = 0; while (i<7) { ledOn = !ledOn; digitalWrite(ledPinL, ledOn); delay(400); i++; z++; if (digitalRead(switchPinL) == LOW && z>= 7) (tanaffus;))) boshqa (digitalWrite (ledPinL, LOW); z = 0;)))

Qisqasi, eskizda 2 ta kirish va 2 ta chiqish mavjud. Bunday holda, kirish ijobiy bo'lsa, ya'ni kirishda (8.7) signalning yuqori darajasi bo'lsa, tegishli chiqishda (11.12) ma'lum miqdordagi miltillashni (z yoki i) olamiz. Qisqasi, shunga o'xshash narsa. Ya'ni, agar siz eskizda miltillovchi sonlar va kirishlar soniga bog'liq biror narsani o'zgartirmoqchi bo'lsangiz, unda bu o'zgaruvchilarga e'tibor bering. Agar miltillash uzunligini o'zgartirish zarur bo'lsa, unda sizning e'tiboringiz kechiktirish funktsiyasiga qaratilishi kerak.
Dasturning yana bir xususiyati - favqulodda vaziyat signalizatsiyasiga g'ayrioddiy chiqish. Birinchidan, chap va o'ng ko'rsatkichlar ishlab chiqiladi, keyin xavf haqida ogohlantirish chiroqlari yonadi. Buning sababi shundaki, u faqat kirish 8 va 7 -da bir vaqtning o'zida yuqori bo'lsa, yoqilishi mumkin. Va bu shart faqat ikkinchi tsiklda bajariladi, chunki bir vaqtning o'zida ikkita tugmani bosish mumkin emas. faqat jismonan ishlash. Mikrokontroller tezligi sizga ba'zi tugmachalardan yuqori chiqishni tezroq o'qishga va bu signal emas, balki burilish signalining sharti ekanligiga qaror qilish imkonini beradi. Garchi siz bu haqda bezovta bo'lmasligingiz kerak, bundan tashqari, yo'lda rahmat aytish qiyin bo'ladi.

Dangasa (xushmuomala) burilish signalini mashinada Arduino -ga ulash xususiyatlari

13 -pinni chiqish sifatida ishlatmang, chunki har safar quvvat yoqilganda, bu chiqishga ulanadigan ko'rsatkichlar miltillashi mumkin.
Tekshirish signallaridan quvvat signallariga o'tishda Internetda sotib olingan yoki siz yig'gan tegishli bloklardan foydalaning. Biz allaqachon bunday bloklar - modullar haqida gaplashdik.
12 voltli kuchlanishdan 1 signalini qabul qilganda, kirish oldiga 10 ohmli rezistorni qo'ying.

Bu, aslida, Arduino mikrokontrolleridagi avtomobil uchun dangasa burilish signalini berish uchun ajratish so'zlari, va hozir ham xuddi videoda ...

Men o'tgan yili "Gop" dedim - sakrash vaqti keldi :)
Aksincha, ishlaydigan burilish signallarini va'da qilingan ko'rib chiqishni qiling.
Men silikon naychaga 1 metr qora WS2812B tasmasini (144 LED) buyurtma qildim, buyurtma berishda men "Qora 1m 144led IP67" ni tanladim (balki kimdir substratning oq rangini yoqtirishi mumkin, bunday tanlov bor).

Bir oz ogohlantirish

Menga yarim metrli ikkita bo'lakdan payvandlangan tasma keldi. Buning kamchiliklari - lehimning zaif joyi (kontaktlar vaqt o'tishi bilan uzilishi mumkin) va LEDlar orasidagi bo'shliqning oshishi.
Sotib olishdan oldin, hozirda sotuvchiga murojaat qiling

Kontakt simlari bir necha bo'laklarni ketma -ket ulash uchun har ikki tomonning lentasiga lehimlangan Menga bu kerak emas edi, keyin men simlarni bir tomondan yopib qo'ydim, hamma narsani neytral plomba bilan yopdim va yana bir oz qora elektr lentani o'rab qo'ydim.



Masalan, ikki tomonlama shaffof yopishqoq lenta bilan oynaga biriktirilgan.

O'rnatish tafsilotlari

U sirtni yog'dan tozalab, avval naychaga yopishqoq lenta yopishtirdi (men aytaman, kesmasi to'rtburchaklar bo'lsa ham), kengroq lentaning chiqib ketadigan ortiqcha qismini kesib tashladi, trubaning chetlarini teshiklar orasidagi teshiklarga tiqdi. ship va orqa ustunlarning dekorativ panellarining yuqori qismlari (men aloqa simlarini ulagich bilan bitta panel orqasida yashirdim), uni markazlashtirdim va asta -sekin lentaning himoya qatlamini chiqarib, oynaga bosa boshladim.
Afsuski, video yo'q - tortishish uchun bo'sh qo'llar yo'q edi va har kimning mashinasi boshqacha.
Agar biror narsa aniq bo'lmasa - izohlarda so'rang.
Yozgi issiqlik sinovi muvaffaqiyatli o'tdi - hech narsa chiqmadi yoki suzmadi.
Faqatgina salbiy tomoni shundaki, oynaning burilish burchagi sayoz, LEDlar yuqoriga qarab porlaydi. Quyoshli kunda ko'rish qiyin, lekin bu signallar takrorlangani uchun

Endi elektron to'ldirishga o'tamiz.
Men ishlatganman, lekin yaqinda kashf qilmaganman

Taxminan bir xil narxga biz ko'proq bulka olamiz

Скетч без особых переделок будет работать и на Wemos при программировании в среде Arduino IDE, а если реализовать небольшой web-сервер, то при подключении к нему по Wi-Fi можно изменять значения таких переменных, как время задержки между миганиями, величина замедления при экстренном торможении va hokazo.
Kelgusida, agar kimdir ESP8266 -da loyihani amalga oshirishni xohlasa, men veb -interfeys orqali sozlamalarni o'zgartirish, ularni EEPROM -ga saqlash va keyin o'qish uchun namuna yuborishim mumkin.
Veb -serverni ishga tushirish mumkin, masalan, burilish signalini yoqish va kontakt yoqilganda tormoz pedalini bosish (sozlash jarayonida tegishli kirishlar holatini so'roq qilish).

Yonish rejimini keskin tormozlash bilan amalga oshirish uchun, a
Eskiz tormoz pedaliga bosilganda sekinlashuv darajasini kuzatadi, agar u 0,5G dan oshsa (keskin tormozlash, lekin tormozlar siqilmasdan), keyin qo'shimcha e'tiborni jalb qilish uchun miltillovchi rejim bir necha soniya yoqiladi.
To'xtashlar, burilish signallari va teskari "ortiqcha" dan Arduino kirishlaridagi nazorat signallari galvanik izolyatorlar - oqim cheklovli rezistorli optokupllar orqali uzatiladi, ular oxir -oqibat Arduino kirishlaridagi LOW darajasini hosil qiladi (ular doimo 10kΩ orqali musbatga tortiladi). rezistorlar).
Quvvat manbai - 5 voltli DC -DC konvertori orqali.
Hamma narsa sendvichga o'ralgan va tegishli qutiga solingan, unda o'q tortish sensori to'g'ri yo'nalishi uchun o'rnatish yo'nalishini belgilab qo'ygan.

Sxema va fotosurat



Yuk ko'taruvchi (musbat) rezistorlar reytingi standart - 10 kOm, optokupl oqimini cheklovchi rezistorlar 1 kOm. Men optokupllarni eski taxtalardan tushirdim, ikkitasi PC123, ikkitasi - PC817.


Birinchi fotosuratda siz ikkita qo'shimcha xulosani ko'rishingiz mumkin, men ularni burilish signallari uchun qildim. Mening mashinamda, rul koloni yoqilganda, erga qisqa tutashuv sodir bo'ladi, men simlarni dastak blokiga va Arduino kirishiga uladim. Agar rulda ustunining dastasi plyusni o'zgartirsa yoki chapga / o'ngga burilish signallarining "+" lampalaridan signal olsa, ularni galvanik izolyatsiya orqali ulang.



Xo'sh, endi eskizning o'zi (Arduino IDE)

#qo'shing #qo'shing // ba'zi umumiy sharhlar // Men bir vaqtning o'zida bir chekkali LEDni o'chirib qo'ydim. ular tokchalarning dekorativ panellarida porlashdi // buning misolida loop uchun ko'rilgan (int i = 1; i<143; i++) //если отключать не нужно, заменяем на for (int i=0; i<144; i++) //задний ход и аварийка у меня не используются, т.к. в первом случае яркость никакая, во втором надо подключать входы к лампам поворотников //поворотники и стоп-сигнал одновременно не включаются, чтобы это реализовать, нужно переписывать соответствующий код скетча (делить ленту на три секции, подбирать тайминги миганий, менять диапазон переменных циклов). //Дерзайте - все в ваших руках // Пин для подключения управляющего сигнала светодной ленты const int PinLS = 2; //Пины для подключения датчиков //если более удобно будет подключать контакты в другом порядке - просто поменяйте значения переменных const int buttonPinL = 3; const int buttonPinR = 4; const int buttonPinS = 6; const int buttonPinD = 5; //начальные статусы входов (подтянуты к плюсу) int buttonStateS = HIGH; int buttonStateD = HIGH; int buttonStateL = HIGH; int buttonStateR = HIGH; // пауза pause_pov1 (в миллисекундах) нужна, чтобы синхронизировать циклы "пробегания" полоски и включения лампочки поворотника // такое может быть, если используется меньше половины светодиодов // в моем случае паузы нет (pause_pov1 = 0) int pause_pov1 = 1; // этой паузой регулируем длительность состояния, когда все светодиоды выключены //я определял опытным путем - включал поворотник, засекал по отдельности время ста мыргов лампочкой и ста беганий полоски, разницу делил на 100, на полученное время увеличивал или уменьшал значение переменной (в зависимости от того, отставали или убегали вперед лампочки) int pause_pov2 = 62; // переменная для получения значения ускорения int ix; Adafruit_NeoPixel strip = Adafruit_NeoPixel(144, PinLS, NEO_GRB + NEO_KHZ800); Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); void setup() { pinMode(buttonPinS, INPUT); pinMode(buttonPinD, INPUT); pinMode(buttonPinL, INPUT); pinMode(buttonPinR, INPUT); strip.begin(); // гасим ленту for (int i=0; i<144; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); accel.begin(); // ограничиваем измеряемый диапазон четырьмя G (этого хватит с большим запасом) accel.setRange(ADXL345_RANGE_4_G); accel.setDataRate(ADXL345_DATARATE_100_HZ); } void loop() { // СТОПЫ: если включены - высший приоритет //Чтобы сделать меняющуюся по ширине полоску в зависимости от интенсивности торможения //(уточнение - никакой светомузыки, ширина полосы после нажатия на тормоз не меняется!) //от плавного торможения до тапки в пол. //Добавляем еще одну переменную, например, ix2, //присваиваем ей значение ix с коэффициентом умножения, //заодно инвертируем и округляем до целого //ix = event.acceleration.x; //ix2 = -round(ix*10); //ограничиваем для плавного торможения в пробках //(чтобы не менялась при каждом продвижении на 5 метров) //if (ix2<10) ix2 = 0; //и для резкого торможения. //Реальный диапазон изменения переменной ix - от 0 до -5 //для максимальной ширины полосы при G равном или большем 0.5 //if (ix2 >50) ix2 = 50; // keyin STOP blokidagi halqalarni o'zgartiring (int i = 1; i<143; i++) на for (int i=51-ix2; i<93+ix2; i++) //Получаем минимальную ширину полоски ~30 см (для стояния в пробке) и максимальную для резкого торможения //конец комментария buttonStateS = digitalRead(buttonPinS); if (buttonStateS == LOW) { sensors_event_t event; accel.getEvent(&event); ix = event.acceleration.x; // проверка резкого торможения - мигающий режим // значение 5 - это 0,5G, минус - торможение if (ix < -5) { for (int is=0; is<15; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(240,0,0)); strip.show(); delay(10 + is*10); for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); delay(10 + is*3); buttonStateS = digitalRead(buttonPinS); if (buttonStateS == HIGH) return; } } // помигали - и хватит, включаем постоянный режим, если педаль тормоза еще нажата // или если не было резкого торможения и предыдущее условие не сработало if (buttonStateS == LOW) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(200,0,0)); strip.show(); while(buttonStateS == LOW){ buttonStateS = digitalRead(buttonPinS); delay(50); } // плавно гасим for (int is=0; is<20; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(190 - is*10,0,0)); strip.show(); delay(10); } // СТОПЫ конец } } else // если СТОПЫ выключены { // ЗАДНИЙ ХОД: если включен - средний приоритет buttonStateD = digitalRead(buttonPinD); if (buttonStateD == LOW) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(63,63,63)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(63,63,63)); strip.show(); while(buttonStateD == LOW){ buttonStateD = digitalRead(buttonPinD); delay(50); } //плавно гасим for (int is=0; is<16; is++) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); strip.show(); delay(10); } } buttonStateL = digitalRead(buttonPinL); buttonStateR = digitalRead(buttonPinR); // если включена аварийка if (buttonStateL == LOW && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(63,31,0)); strip.setPixelColor(il+72, strip.Color(63,31,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ЛЕВЫЙ ПОВОРОТНИК if (buttonStateL == LOW && buttonStateR == HIGH) { for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ПРАВЫЙ ПОВОРОТНИК if (buttonStateL == HIGH && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } //правый поворотник конец } //конец условия else Стоп // задержка для следующего опроса датчиков delay(10); }

Men iloji boricha sharh berishga harakat qildim, lekin agar savollarim bo'lsa, sharhlar qo'shishga harakat qilaman (shuning uchun men uni biriktirilgan faylga emas, balki sharh matniga joylashtiraman). Aytgancha, bu sharhning boshqa nuqtalariga ham tegishli - agar sharhlarda muhim savollar bo'lsa, men uni to'ldiraman.

Va nihoyat, ishning namoyishi (video uchun men demo rejimi bilan eskizdan foydalandim).

Yangilash. Demo rejimidagi eskiz hamma narsani bitta qisqa videoga joylashtirish uchun maxsus tayyorlangan.
Tormoz chirog'i faqat keskin tormozlashda (yuqorida ta'riflanganidek) yonib -o'chib turadi, tiqilinchda va silliq holatda turganida, u haydovchilarni bezovta qilmasdan yonadi.
Qorong'ida yorqinlik ortiqcha emas. oynaning egilishi tufayli chiroqlar orqaga qaraganda yuqoriga yo'naltirilgan.
Standart chiroqlar odatdagidek ishlaydi, bu chiziq ularni takrorlaydi.

Men o'tgan yili "Gop" dedim - sakrash vaqti keldi :)
Aksincha, ishlaydigan burilish signallarini va'da qilingan ko'rib chiqishni qiling.
Men silikon naychaga 1 metr qora tasma WS2812B (144 LED) ni buyurtma qildim, buyurtma berayotganda men "Qora 1m 144led IP67" ni tanladim (balki kimgadir substratning oq rangi yoqadi, bunday tanlov bor).

Bir oz ogohlantirish

Menga yarim metrli ikkita bo'lakdan payvandlangan tasma keldi. Buning kamchiliklari - lehimning zaif joyi (kontaktlar vaqt o'tishi bilan uzilishi mumkin) va LEDlar orasidagi bo'shliqning oshishi.
Sotib olishdan oldin, hozirda sotuvchiga murojaat qiling

Kontakt simlari bir necha bo'laklarni ketma -ket ulash uchun har ikki tomonning lentasiga lehimlangan Menga bu kerak emas edi, keyin men simlarni bir tomondan yopib qo'ydim, hamma narsani neytral plomba bilan yopdim va yana bir oz qora elektr lentani o'rab qo'ydim.



Masalan, ikki tomonlama shaffof yopishqoq lenta bilan oynaga biriktirilgan.

O'rnatish tafsilotlari

U sirtni yog'dan tozalab, avval naychaga yopishqoq lenta yopishtirdi (men aytaman, kesmasi to'rtburchaklar bo'lsa ham), kengroq lentaning chiqib ketadigan ortiqcha qismini kesib tashladi, trubaning chetlarini teshiklar orasidagi teshiklarga tiqdi. ship va orqa ustunlarning dekorativ panellarining yuqori qismlari (men aloqa simlarini ulagich bilan bitta panel orqasida yashirdim), uni markazlashtirdim va asta -sekin lentaning himoya qatlamini chiqarib, oynaga bosa boshladim.
Afsuski, video yo'q - tortishish uchun bo'sh qo'llar yo'q edi va har kimning mashinasi boshqacha.
Agar biror narsa aniq bo'lmasa - izohlarda so'rang.
Yozgi issiqlik sinovi muvaffaqiyatli o'tdi - hech narsa chiqmadi yoki suzmadi.
Faqatgina salbiy tomoni shundaki, oynaning burilish burchagi sayoz, LEDlar yuqoriga qarab porlaydi. Quyoshli kunda ko'rish qiyin, lekin bu signallar takrorlangani uchun

Endi elektron to'ldirishga o'tamiz.
Men ishlatganman, lekin yaqinda kashf qilmaganman

Taxminan bir xil narxga biz ko'proq bulka olamiz

Скетч без особых переделок будет работать и на Wemos при программировании в среде Arduino IDE, а если реализовать небольшой web-сервер, то при подключении к нему по Wi-Fi можно изменять значения таких переменных, как время задержки между миганиями, величина замедления при экстренном торможении va hokazo.
Kelgusida, agar kimdir ESP8266 -da loyihani amalga oshirishni xohlasa, men veb -interfeys orqali sozlamalarni o'zgartirish, ularni EEPROM -ga saqlash va keyin o'qish uchun namuna yuborishim mumkin.
Veb -serverni ishga tushirish mumkin, masalan, burilish signalini yoqish va kontakt yoqilganda tormoz pedalini bosish (sozlash jarayonida tegishli kirishlar holatini so'roq qilish).

Yonish rejimini keskin tormozlash bilan amalga oshirish uchun, a
Eskiz tormoz pedaliga bosilganda sekinlashuv darajasini kuzatadi, agar u 0,5G dan oshsa (keskin tormozlash, lekin tormozlar siqilmasdan), keyin qo'shimcha e'tiborni jalb qilish uchun miltillovchi rejim bir necha soniya yoqiladi.
To'xtashlar, burilish signallari va teskari "ortiqcha" dan Arduino kirishlaridagi nazorat signallari galvanik izolyatorlar - oqim cheklovli rezistorli optokupllar orqali uzatiladi, ular oxir -oqibat Arduino kirishlaridagi LOW darajasini hosil qiladi (ular doimo 10kΩ orqali musbatga tortiladi). rezistorlar).
Quvvat manbai - 5 voltli DC -DC konvertori orqali.
Hamma narsa sendvichga o'ralgan va tegishli qutiga solingan, unda o'q tortish sensori to'g'ri yo'nalishi uchun o'rnatish yo'nalishini belgilab qo'ygan.

Sxema va fotosurat



Yuk ko'taruvchi (musbat) rezistorlar reytingi standart - 10 kOm, optokupl oqimini cheklovchi rezistorlar 1 kOm. Men optokupllarni eski taxtalardan tushirdim, ikkitasi PC123, ikkitasi - PC817.


Birinchi fotosuratda siz ikkita qo'shimcha xulosani ko'rishingiz mumkin, men ularni burilish signallari uchun qildim. Mening mashinamda, rul koloni yoqilganda, erga qisqa tutashuv sodir bo'ladi, men simlarni dastak blokiga va Arduino kirishiga uladim. Agar rulda ustunining dastasi plyusni o'zgartirsa yoki chapga / o'ngga burilish signallarining "+" lampalaridan signal olsa, ularni galvanik izolyatsiya orqali ulang.



Xo'sh, endi eskizning o'zi (Arduino IDE)

#qo'shing #qo'shing // ba'zi umumiy sharhlar // Men bir vaqtning o'zida bir chekkali LEDni o'chirib qo'ydim. ular tokchalarning dekorativ panellarida porlashdi // buning misolida loop uchun ko'rilgan (int i = 1; i<143; i++) //если отключать не нужно, заменяем на for (int i=0; i<144; i++) //задний ход и аварийка у меня не используются, т.к. в первом случае яркость никакая, во втором надо подключать входы к лампам поворотников //поворотники и стоп-сигнал одновременно не включаются, чтобы это реализовать, нужно переписывать соответствующий код скетча (делить ленту на три секции, подбирать тайминги миганий, менять диапазон переменных циклов). //Дерзайте - все в ваших руках // Пин для подключения управляющего сигнала светодной ленты const int PinLS = 2; //Пины для подключения датчиков //если более удобно будет подключать контакты в другом порядке - просто поменяйте значения переменных const int buttonPinL = 3; const int buttonPinR = 4; const int buttonPinS = 6; const int buttonPinD = 5; //начальные статусы входов (подтянуты к плюсу) int buttonStateS = HIGH; int buttonStateD = HIGH; int buttonStateL = HIGH; int buttonStateR = HIGH; // пауза pause_pov1 (в миллисекундах) нужна, чтобы синхронизировать циклы "пробегания" полоски и включения лампочки поворотника // такое может быть, если используется меньше половины светодиодов // в моем случае паузы нет (pause_pov1 = 0) int pause_pov1 = 1; // этой паузой регулируем длительность состояния, когда все светодиоды выключены //я определял опытным путем - включал поворотник, засекал по отдельности время ста мыргов лампочкой и ста беганий полоски, разницу делил на 100, на полученное время увеличивал или уменьшал значение переменной (в зависимости от того, отставали или убегали вперед лампочки) int pause_pov2 = 62; // переменная для получения значения ускорения int ix; Adafruit_NeoPixel strip = Adafruit_NeoPixel(144, PinLS, NEO_GRB + NEO_KHZ800); Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); void setup() { pinMode(buttonPinS, INPUT); pinMode(buttonPinD, INPUT); pinMode(buttonPinL, INPUT); pinMode(buttonPinR, INPUT); strip.begin(); // гасим ленту for (int i=0; i<144; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); accel.begin(); // ограничиваем измеряемый диапазон четырьмя G (этого хватит с большим запасом) accel.setRange(ADXL345_RANGE_4_G); accel.setDataRate(ADXL345_DATARATE_100_HZ); } void loop() { // СТОПЫ: если включены - высший приоритет //Чтобы сделать меняющуюся по ширине полоску в зависимости от интенсивности торможения //(уточнение - никакой светомузыки, ширина полосы после нажатия на тормоз не меняется!) //от плавного торможения до тапки в пол. //Добавляем еще одну переменную, например, ix2, //присваиваем ей значение ix с коэффициентом умножения, //заодно инвертируем и округляем до целого //ix = event.acceleration.x; //ix2 = -round(ix*10); //ограничиваем для плавного торможения в пробках //(чтобы не менялась при каждом продвижении на 5 метров) //if (ix2<10) ix2 = 0; //и для резкого торможения. //Реальный диапазон изменения переменной ix - от 0 до -5 //для максимальной ширины полосы при G равном или большем 0.5 //if (ix2 >50) ix2 = 50; // keyin STOP blokidagi halqalarni o'zgartiring (int i = 1; i<143; i++) на for (int i=51-ix2; i<93+ix2; i++) //Получаем минимальную ширину полоски ~30 см (для стояния в пробке) и максимальную для резкого торможения //конец комментария buttonStateS = digitalRead(buttonPinS); if (buttonStateS == LOW) { sensors_event_t event; accel.getEvent(&event); ix = event.acceleration.x; // проверка резкого торможения - мигающий режим // значение 5 - это 0,5G, минус - торможение if (ix < -5) { for (int is=0; is<15; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(240,0,0)); strip.show(); delay(10 + is*10); for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(0,0,0)); strip.show(); delay(10 + is*3); buttonStateS = digitalRead(buttonPinS); if (buttonStateS == HIGH) return; } } // помигали - и хватит, включаем постоянный режим, если педаль тормоза еще нажата // или если не было резкого торможения и предыдущее условие не сработало if (buttonStateS == LOW) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(200,0,0)); strip.show(); while(buttonStateS == LOW){ buttonStateS = digitalRead(buttonPinS); delay(50); } // плавно гасим for (int is=0; is<20; is++) { for (int i=1; i<143; i++) strip.setPixelColor(i, strip.Color(190 - is*10,0,0)); strip.show(); delay(10); } // СТОПЫ конец } } else // если СТОПЫ выключены { // ЗАДНИЙ ХОД: если включен - средний приоритет buttonStateD = digitalRead(buttonPinD); if (buttonStateD == LOW) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(63,63,63)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(63,63,63)); strip.show(); while(buttonStateD == LOW){ buttonStateD = digitalRead(buttonPinD); delay(50); } //плавно гасим for (int is=0; is<16; is++) { for (int i=1; i<37; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); for (int i=107; i<143; i++) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4)); strip.show(); delay(10); } } buttonStateL = digitalRead(buttonPinL); buttonStateR = digitalRead(buttonPinR); // если включена аварийка if (buttonStateL == LOW && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(63,31,0)); strip.setPixelColor(il+72, strip.Color(63,31,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ЛЕВЫЙ ПОВОРОТНИК if (buttonStateL == LOW && buttonStateR == HIGH) { for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(il+72, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } // если включен ПРАВЫЙ ПОВОРОТНИК if (buttonStateL == HIGH && buttonStateR == LOW) { for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(220,120,0)); strip.show(); delay(pause_pov1); } for (int il=0; il<71; il++) { strip.setPixelColor(71-il, strip.Color(0,0,0)); strip.show(); delay(pause_pov1); } delay(pause_pov2); } //правый поворотник конец } //конец условия else Стоп // задержка для следующего опроса датчиков delay(10); }

Men iloji boricha sharh berishga harakat qildim, lekin agar savollarim bo'lsa, sharhlar qo'shishga harakat qilaman (shuning uchun men uni biriktirilgan faylga emas, balki sharh matniga joylashtiraman). Aytgancha, bu sharhning boshqa nuqtalariga ham tegishli - agar sharhlarda muhim savollar bo'lsa, men uni to'ldiraman.

Va nihoyat, ishning namoyishi (video uchun men demo rejimi bilan eskizdan foydalandim).

Yangilash. Demo rejimidagi eskiz hamma narsani bitta qisqa videoga joylashtirish uchun maxsus tayyorlangan.
Tormoz chirog'i faqat keskin tormozlashda (yuqorida ta'riflanganidek) yonib -o'chib turadi, tiqilinchda va silliq holatda turganida, u haydovchilarni bezovta qilmasdan yonadi.
Qorong'ida yorqinlik ortiqcha emas. oynaning egilishi tufayli chiroqlar orqaga qaraganda yuqoriga yo'naltirilgan.
Standart chiroqlar odatdagidek ishlaydi, bu chiziq ularni takrorlaydi.

Men +97 sotib olishni rejalashtiryapman Sevimlilarga qo'shing Menga sharh yoqdi +89 +191

Renault Clio avtomobilining farasi misolida, Audi kabi ishlaydigan burilish signalini yaratishni ko'rib chiqing. Keling, bitta qurilmada burilish signallari va DRLni yaratamiz.

Buning uchun sizga nima kerak: ws2812b LEDlardan tashkil topgan LED tasmasi Arduino nano -boshqaruvchi(har qanday boshqa shakl faktorida ishlatilishi mumkin) USB chiqishi bo'lgan mobil telefonlar uchun avtomobil zaryadlovchi. Arduino tekshirgichi 5V kuchlanishga muhtoj bo'lgani uchun, biz bu zaryadlovchini 12V dan 5V gacha kuchlanish konvertori sifatida ishlatamiz. 5V KR142EN5V (KREN5V) yoki boshqa import qilingan analog uchun kuchlanish stabilizatori. 3 qarshilik 10 kOm, tortishish qarshiligi sifatida.

Ulanish diagrammasi

Arduino tekshirgichi avtomobil tarmog'iga 12V -> 5V konverter orqali ulanishi kerak, shunda kontaktlarning zanglashiga kontaktdan voltaj tushadi. Hozirgi burilish signalining ijobiy simini KREN5V voltaj regulyatoriga ulash lozim. Ushbu maqolada faqat bitta burilish signalining ulanishi va dasturiy ta'minoti muhokama qilinadi, ikkinchi burilish signalini berish uchun siz ham xuddi shunday ikkinchi LED tasmasini Arduino -ning istalgan bepul raqamli chiqishiga ulashingiz kerak (masalan, 7), shuningdek bizning misolimizga ko'ra, uni dasturiy ta'minotda kodlang.

Boshqaruvchi dasturiy ta'minot

Pikselli LEDlar bilan ishlash uchun sizga kutubxona kerak bo'ladi ... Siz uni quyidagicha o'rnatishingiz mumkin: Sketch -> Kutubxonani ulash -> Kutubxonalarni boshqarish. Keyin, qidirish menyusiga Adafruit_NeoPixel.h kutubxonasining nomini kiriting va o'rnatish tugmasini bosing. Shundan so'ng, eskizni dasturga joylashtiring va koddagi LEDlar sonini o'zgartiring (biz 22 dioddan foydalanamiz):

#qo'shing // kutubxonani ulang
Adafruit_NeoPixel tasmasi = Adafruit_NeoPixel (22, 8, NEO_GRB + NEO_KHZ800);
int t, t1, t2, t3, t4, p2, p1 = 0; // vaqt o'zgaruvchisi
bo'sh o'rnatish () (
pinMod (2, Kirish);
pinMode (3, INPUT);
pinMode (4, INPUT);
digitalWrite (2, LOW);
digitalWrite (3, LOW);
digitalWrite (4, LOW);

strip.begin ();
strip.show ();

}
void loop () (
if (digitalRead (2) == LOW) (// Agar burilish signali o'chirilgan bo'lsa
uchun (int i = 0; i< 23; i++) {
strip.setPixelColor (i, strip.Color (255,255,255)); // R = 255, G = 255, B = 255 - LEDning oq rangi, yoqilganda biz chiroqlar yonadi
}
strip.show ();
}

if ((digitalRead (2) == HIGH) & (t == 1)) (// burilish signali yoqilganligini tekshiring
uchun (int i = 0; i< 23; i++) {
strip.setPixelColor (i, strip.Color (0, 0, 0)); // barcha diodlarni o'chiring
}
strip.show ();
uchun (int k = 0; k< 3; k++){ // цикл до трех - сигнал «перестроения» , при кратковременном включении мигает 3 раза,

uchun (int i = 0; i< 23; i++){

agar (digitalRead (2) == YUQORI) (k = 0;) // agar burilish signali yonib -o'chib turganda biz boshqa kalit signalini olsak, hisoblagichni qaytish signali yana kamida 3 marta miltillashi uchun qayta o'rnating.
strip.setPixelColor (i, strip.Color (255, 69, 0)); // R = 255, G = 69, B = 0 - LED rangi

kechikish ((t4) / 22);
strip.show ();

}
agar (digitalRead (2) == YUQORI) (t4 = t4 + 20;) // agar barcha diodlar sariq rangda yonsa, lekin o'rni signallari hali ham yoniq bo'lsa, biz yonish vaqtini oshiramiz
agar (digitalRead (2) == LOW) (t4 = t4-20;) // agar barcha diodlar sariq rangda yonsa, lekin o'rni signallari hali ham yoniq bo'lsa, biz yonish vaqtini oshiramiz

uchun (int i = 0; i< 23; i++){

strip.setPixelColor (i, strip.Color (0, 0, 0)); // R = 0, G = 0, B = 0 - LED rangi

kechikish ((t3) / 22);
strip.show ();

}
agar ((digitalRead (2) == LOW)) (t3 = t3 + 20;)
if ((digitalRead (2) == HIGH)) (t3 = t3-20;)
}

if ((digitalRead (2) == HIGH) & (t == 0)) (// burilish signalining yoqilganligini tekshiring

t1 = millis (); // qachon yoqilganingizni eslang
uchun (int i = 0; i< 22; i++) {
strip.setPixelColor (i, strip.Color (255, 69, 0)); // burilish signalini birinchi marta yoqganingizda, barcha diodlarni sariq rangda yoqing
}
strip.show ();
while (digitalRead (2) == HIGH) ()
t2 = millis (); // burilish signali qachon o'chirilganligini eslang
t4 = t2-t1;

uchun (int i = 0; i< 22; i++) {
strip.setPixelColor (i, strip.Color (0, 0, 0)); // burilish rölesidan signal yo'qolganda diodlarni o'chiring
}
strip.show ();
while (digitalRead (2) == LOW) (
agar ((millis () - t2)> 2000) (tanaffus;)
}
agar ((millis () - t2)<2000) {
t3 = millis () - t2; // burilish signallari o'chadigan vaqt
t = 1; // bayroq, biz bilamizki, vaqt qiymati saqlangan.
}
}

if (digitalRead (4) == HIGH) (// maxsus signallar
uchun (int j = 0; j< 16; j++) {
uchun (int i = 0; i< 22; i++) {
strip.setPixelColor (i, strip.Color (255, 0, 0)); // R = 255, G = 0, B = 0 - LED rangi
}
strip.show ();
kechikish (20);
uchun (int i = 0; i< 22; i++){

}
strip.show ();
kechikish (20);
}

uchun (int j = 0; j< 16; j++) {
uchun (int i = 0; i< 22; i++) {
strip.setPixelColor (i, strip.Color (0, 0, 255)); // R = 0, G = 0, B = 255 - LED rangi
}
strip.show ();
kechikish (20);
uchun (int i = 0; i< 22; i++){
strip.setPixelColor (i, strip.Color (0, 0, 0)); // R = 0, G = 0, B = 0 - LED rangi
}
strip.show ();
kechikish (20);
}
}

if (digitalRead (3) == HIGH) (// strobe
uchun (int j = 0; j< 24; j++) {
uchun (int i = 0; i< 22; i++) {
strip.setPixelColor (i, strip.Color (255, 255, 255)); // R = 255, G = 255, B = 255 - LED rangi
}
strip.show ();

kechikish (15);
uchun (int i = 0; i< 22; i++){
strip.setPixelColor (i, strip.Color (0, 0, 0)); // R = 0, G = 0, B = 0 - LED rangi
}
strip.show ();
kechikish (15);
}
kechikish (500);

Kod yordamida ikkinchi burilish signali uchun ham xuddi shunday qiling.

Farimiz qanday ishlashi haqida video

Maqola sizga yoqdimi? Do'stlar bilan bo'lishish uchun: