Здравствуйте! Родители подарили мне ардуино уно. Обширных знаний в области программирования у меня нет, только базовые уроки по ардуино и эксперименты. Я решил сделать ночник для младшей сестры на ДР (осталась одна неделя). В качестве лампочек взял 2 шт светодиодов ws2812b. Сначала думал сделать только эффект свечи (спасибо сайту), но одного режима как то мало. И я, с помощью примера fade, а так же с помощью примера из библиотеки adafruit, сделал еще 2 режима. В библиотеке от Adafruit есть пример с кнопкой, но там режимы имеют определенную длительность. Помогите пожалуйста разобраться, как собрать три режима и переключать из с помощью кнопки. Если это сложно,в плане объяснения, то я мог бы заплатить некоторые деньги. Спойлер: Эффект свечи Код (C++): #include <Adafruit_NeoPixel.h> // Which pin on the Arduino is connected to the NeoPixels? // On a Trinket or Gemma we suggest changing this to 1 #define PIN 3 // How many NeoPixels are attached to the Arduino? #define NUMPIXELS 2 // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals. // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest // example for more information on possible values. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup() { pixels.begin(); // This initializes the NeoPixel library. } void loop() { pixels.setPixelColor(0, pixels.Color(random(240, 255),random(30, 35),0)); pixels.setPixelColor(1, pixels.Color(random(230, 255),50,0)); pixels.setBrightness(random(170,210)); pixels.show(); // This sends the updated pixel color to the hardware. delay(random(120)); } Спойлер: Радуга Код (C++): #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define PIN 3 // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) Adafruit_NeoPixel pixels = Adafruit_NeoPixel(2, PIN, NEO_GRB + NEO_KHZ800); // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first. void setup() { pixels.begin(); pixels.show(); // Initialize all pixels to 'off' } void loop() { rainbowCycle(300); } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(int wait) { int j; for(j=0; j<255; j++) { // 5 cycles of all colors on wheel pixels.setPixelColor(0, Wheel(((255 / 1) + j) & 255)); pixels.setPixelColor(1, Wheel(((255 / 1) + j) & 255)); pixels.show(); delay(wait); } } uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } Спойлер: FADE #include <Adafruit_NeoPixel.h> // Which pin on the Arduino is connected to the NeoPixels? // On a Trinket or Gemma we suggest changing this to 1 #define PIN 3 // How many NeoPixels are attached to the Arduino? #define NUMPIXELS 2 // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals. // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest // example for more information on possible values. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); int fade = 5; int brightness = 5; void setup() { pixels.begin(); // This initializes the NeoPixel library. } void loop() { pixels.setBrightness(brightness); brightness = brightness + fade; if (brightness == 5 || brightness == 255) { fade = -fade; } pixels.setPixelColor(0, pixels.Color(255, 15, 70)); pixels.setPixelColor(1, pixels.Color(255, 15, 70)); pixels.show(); delay(100); } И подскажите,пожалуйста, как понимать тип данных uint8_t? Насколько я разобрался, это целочисленный тип 8 бит. А как определить что необходимо: uint8_t или uint16_t, к примеру.
примерно так: Код (C++): #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define LEDS_COUNT 2 // количество светодиодов WS2812 #define LED_PIN 3 // пин для подключения WS2812 #define CHANGE_TIME 30 // интервал смены эффектов, сек #define EFFECTS_COUNT 3 // количество эффектов // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) Adafruit_NeoPixel pixels = Adafruit_NeoPixel(LEDS_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first. byte effectNumber; // переменная для хранения номера эффекта unsigned long timeStamp; // переменная для хранения времени последней смены эффекта void setup() { Serial.begin(9600); effectNumber = 1; // задаем эффект (при включении питания) pixels.begin(); pixels.show(); // Initialize all pixels to 'off' } void loop() { Serial.print("Effect:"); Serial.println(effectNumber); while(millis() - timeStamp < CHANGE_TIME * 1000L) // в течение интервала { switch(effectNumber) // включаем заданный эффект { case 1: rainbowCycle(300); break; case 2: fade(); break; case 3: flame(); break; } } // когда интервал превышен effectNumber++; // увеличиваем счетчик if (effectNumber > EFFECTS_COUNT) effectNumber = 1; // защита от дурака timeStamp = millis(); // запоминаем время начала эфекта } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(int wait) { int j; for(j=0; j<255; j++) { // 5 cycles of all colors on wheel pixels.setPixelColor(0, wheel(((255 / 1) + j) & 255)); pixels.setPixelColor(1, wheel(((255 / 1) + j) & 255)); pixels.show(); delay(wait); } } uint32_t wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } void flame() { pixels.setPixelColor(0, pixels.Color(random(240, 255),random(30, 35),0)); pixels.setPixelColor(1, pixels.Color(random(230, 255),50,0)); pixels.setBrightness(random(170,210)); pixels.show(); // This sends the updated pixel color to the hardware. delay(random(120)); } void fade() { byte fadeValue = 5; byte brightness = 5; pixels.setBrightness(brightness); brightness = brightness + fadeValue; if (brightness == 5 || brightness == 255) { fadeValue = -fadeValue; } pixels.setPixelColor(0, pixels.Color(255, 15, 70)); pixels.setPixelColor(1, pixels.Color(255, 15, 70)); pixels.show(); delay(100); }
Спасибо за пример и за исправления моих ошибок. Насколько я смог понять, функции указанные в switch перебираются по счетчику millis. Только я не совсем понял: Код (C++): while(millis() - timeStamp < CHANGE_TIME * 1000L) а возможно ли в принципе сделать переключение по кнопке? я пытался осилить прерывания, но как я понял, там нельзя с delay.
Добрый день! Я думаю,что замахнулся на сложную задачу, для моих знаний, поэтому думаю поставить DIP переключатель на 2 ползунка. Еле доспал до утра с желанием проверить. Написал пробный скетч на 3 диода, DIP переключателя у меня нет, поэтому все на перемычках для макетной платы.Работает! Но...Когда разъединяю перемычку, диод с прошлого режима продолжает гореть. проверьте пожалуйста мой код Код (C++): #define ledR 3 //зеленый диод #define ledG 7 //красный диод #define ledY 8 //Желтый диод #define L 4 // ползунок левый #define R 5 // ползунок правый bool Left = LOW; bool Right = LOW; void setup() { pinMode(ledR, OUTPUT); pinMode(ledG, OUTPUT); pinMode(ledY, OUTPUT); pinMode(L, INPUT); pinMode(R, INPUT); } void loop() { Left = digitalRead(L); Right = digitalRead(R); if(Left == HIGH && Right == LOW) { blink1(); } else if(Right == HIGH && Left == LOW) { blink2(); } else if(Right == HIGH && Left == HIGH) { blink3(); } else { digitalWrite(ledR, LOW); digitalWrite(ledG, LOW); digitalWrite(ledY, LOW); } } void blink1() { digitalWrite(ledR, LOW); delay(100); digitalWrite(ledR, HIGH); delay(100); } void blink2() { digitalWrite(ledG, LOW); delay(50); digitalWrite(ledG, HIGH); delay(50); } void blink3() { digitalWrite(ledY, LOW); delay(60); digitalWrite(ledY, HIGH); delay(60); }
потому что в коде нет принудительного гашения неиспользуемых светиков. Код (C++): #define ledR 3 //зеленый диод #define ledG 7 //красный диод #define ledY 8 //Желтый диод #define L 4 // левый переключатель #define R 5 // правый переключатель #define ON HIGH #define OFF LOW bool Left; bool Right; void setup() { pinMode(ledR, OUTPUT); pinMode(ledG, OUTPUT); pinMode(ledY, OUTPUT); pinMode(L, INPUT); pinMode(R, INPUT); } void loop() { Left = digitalRead(L); Right = digitalRead(R); ledsOff(); if(Left == ON && Right == OFF) { blink1(); } else if(Right == ON && Left == OFF) { blink2(); } else if(Right == ON && Left == ON) { blink3(); } } void blink1() { digitalWrite(ledR, ON); delay(100); digitalWrite(ledR, OFF); delay(100); } void blink2() { digitalWrite(ledG, OFF); delay(50); digitalWrite(ledG, ON); delay(50); } void blink3() { digitalWrite(ledY, OFF); delay(60); digitalWrite(ledY, ON); delay(60); } void ledsOff() { digitalWrite(ledR, OFF); digitalWrite(ledG, OFF); digitalWrite(ledY, OFF); }
Спасибо большое! вроде бы пока все. Сейчас попробую перенести на мои ws2812b. Тяжеловато в голове представить, что за чем должно идти, и как взаимодействовать.
Вот,что в итоге получилось: Спойлер: Код Код (C++): #include <Adafruit_NeoPixel.h> #define PIN 2 #define NUMPIXELS 2 #define R 3 #define L 4 #define ON HIGH #define OFF LOW bool Left; bool Right; int fade = 5; int brightness = 5; Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup() { pixels.begin(); // This initializes the NeoPixel library. pinMode(L, INPUT); pinMode(R, INPUT); } void loop() { Left = digitalRead(L); Right = digitalRead(R); if(Left == ON && Right == OFF) { fading(); } else if(Right == ON && Left == OFF) { rainbowCycle(); } else if(Right == OFF && Left == OFF) { fire(); } } void fading() { pixels.setBrightness(brightness); brightness = brightness + fade; if (brightness == 5 || brightness == 255) { fade = -fade; } pixels.setPixelColor(0, pixels.Color(255, 15, 70)); pixels.setPixelColor(1, pixels.Color(255, 15, 70)); pixels.show(); delay(100); } void fire() { pixels.setPixelColor(0, pixels.Color(random(240, 255),random(20, 30),0)); pixels.setPixelColor(1, pixels.Color(random(230, 255),30,0)); pixels.setBrightness(random(170,210)); pixels.show(); // This sends the updated pixel color to the hardware. delay(random(120)); } void rainbowCycle() { int j; for(j=0; j<255; j++) { pixels.setPixelColor(0, Wheel(((255 / 1) + j) & 255)); pixels.setPixelColor(1, Wheel(((255 / 1) + j) & 255)); pixels.show(); delay(100); } } uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } Все чётко работает, кроме перехода с режима rainbowCycle(), пока полностью цвета не прокрутит, нужный режим не включается. Что то я упустил.
Так как плата ардуино у меня одна,я решил прошить Attiny85. Нашел схему подключения, и архив для добавления плат Attiny в Arduino IDE. Все собрал по схеме, и получаю: Спойлер Arduino: 1.6.7 (Windows 10), Плата:"ATtiny85 @ 1 MHz (internal oscillator; BOD disabled)" E:\arduino-1.6.7\arduino-builder -dump-prefs -logger=machine -hardware "E:\arduino-1.6.7\hardware" -tools "E:\arduino-1.6.7\tools-builder" -tools "E:\arduino-1.6.7\hardware\tools\avr" -built-in-libraries "E:\arduino-1.6.7\libraries" -libraries "E:\arduino-1.6.7\Sketch\libraries" -fqbn=tiny:avr:attiny85at1 -ide-version=10607 -build-path "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp" -warnings=none -prefs=build.warn_data_percentage=75 -verbose "C:\Users\FX-6500\AppData\Local\Temp\arduino_1f4da91d71cd14271afc217905a64678\Blink.ino" E:\arduino-1.6.7\arduino-builder -compile -logger=machine -hardware "E:\arduino-1.6.7\hardware" -tools "E:\arduino-1.6.7\tools-builder" -tools "E:\arduino-1.6.7\hardware\tools\avr" -built-in-libraries "E:\arduino-1.6.7\libraries" -libraries "E:\arduino-1.6.7\Sketch\libraries" -fqbn=tiny:avr:attiny85at1 -ide-version=10607 -build-path "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp" -warnings=none -prefs=build.warn_data_percentage=75 -verbose "C:\Users\FX-6500\AppData\Local\Temp\arduino_1f4da91d71cd14271afc217905a64678\Blink.ino" Плата tiny:avr:attiny4313at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY4313AT1 Плата tiny:avr:attiny84at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY84AT8 Плата tiny:avr:attiny85at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY85AT1 Плата tiny:avr:attiny44at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY44AT1 Плата tiny:avr:attiny85at16e не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY85AT16E Плата tiny:avr:attiny45at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY45AT8 Плата tiny:avr:attiny85at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY85AT8 Плата tiny:avr:attiny85at16p не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY85AT16P Плата tiny:avr:attiny45at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY45AT1 Плата tiny:avr:attiny2313at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY2313AT8 Плата tiny:avr:attiny84at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY84AT1 Плата tiny:avr:attiny44at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY44AT8 Плата tiny:avr:attiny2313at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY2313AT1 Плата tiny:avr:attiny25at1 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY25AT1 Плата tiny:avr:attiny25at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY25AT8 Плата tiny:avr:attiny85at128 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY85AT128 Плата tiny:avr:attiny24at16 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY24AT16 Плата tiny:avr:attiny84at16 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY84AT16 Плата tiny:avr:attiny4313at8 не устанавливает свойство 'build.board'. Автоматически выбрано: AVR_ATTINY4313AT8 Внимание: platform.txt из ядра 'Arduino Tiny' содержит устаревшие tools.avrdude.cmd.path={runtime.ide.path}/hardware/tools/avr/bin/avrdude, автоматически преобразовано в tools.avrdude.cmd.path={path}/bin/avrdude. Ожидайте обновления ядра. Внимание: platform.txt из ядра 'Arduino Tiny' содержит устаревшие tools.avrdude.config.path={runtime.ide.path}/hardware/tools/avr/etc/avrdude.conf, автоматически преобразовано в tools.avrdude.config.path={path}/etc/avrdude.conf. Ожидайте обновления ядра. Внимание: platform.txt из ядра 'Arduino Tiny' содержит устаревшие recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}", автоматически преобразовано в recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{archive_file_path}" "{object_file}". Ожидайте обновления ядра. Внимание: platform.txt из ядра 'Arduino Tiny' содержит устаревшие recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm, автоматически преобразовано в recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{archive_file_path}" "-L{build.path}" -lm. Ожидайте обновления ядра. "avr-g++" -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=1000000L -DARDUINO=10607 -DARDUINO_AVR_ATTINY85AT1 -DARDUINO_ARCH_AVR "-IE:\arduino-1.6.7\hardware\tiny\avr\cores\tiny" "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp\sketch\Blink.ino.cpp" -o "nul" "avr-g++" -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=1000000L -DARDUINO=10607 -DARDUINO_AVR_ATTINY85AT1 -DARDUINO_ARCH_AVR "-IE:\arduino-1.6.7\hardware\tiny\avr\cores\tiny" "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp\sketch\Blink.ino.cpp" -o "nul" "avr-g++" -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -w -x c++ -E -CC -DF_CPU=1000000L -DARDUINO=10607 -DARDUINO_AVR_ATTINY85AT1 -DARDUINO_ARCH_AVR "-IE:\arduino-1.6.7\hardware\tiny\avr\cores\tiny" "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp\sketch\Blink.ino.cpp" -o "C:\Users\FX-6500\AppData\Local\Temp\build1f4da91d71cd14271afc217905a64678.tmp\preproc\ctags_target_for_gcc_minus_e.cpp" exec: "avr-g++": executable file not found in %PATH% Ошибка компиляции. Может Arduino IDE 1.6.7 не подходит? P.S. Вариант решения описан ЗДЕСЬ. Прошил на 8Мгц блинк, delay(1000) не соотвествет 1 сек. Прошил на 1Мгц все четко.
На частоте 8Мгц светодиоды отказываются работать, первый светится белым и все. Решил обмануть судьбу.Скачал Arduino IDE 1.5.0 и пакет для плат Attiny85 (в нем есть частота 16Мгц. на внутреннем кварцевом резонаторе). Уже нет такого количества оранжевого текста. Есть только это: Спойлер Binary sketch size: 2 bytes (of a 8.192 byte maximum) C:\Users\FX-6500\Desktop\arduino-1.5/hardware/tools/avr/bin/avrdude -CC:\Users\FX-6500\Desktop\arduino-1.5/hardware/tools/avr/etc/avrdude.conf -q -q -pattiny85 -cstk500v1 -PCOM3 -b9600 -Uflash:w:C:\Users\FX-6500\AppData\Local\Temp\build1499975240265607459.tmp/Blink.cpp.hex:i avrdude: stk500_getsync(): not in sync: resp=0xff
У меня не тема,а блог школьника неудачника. Но...случайно нажав "записать загрузчик",я обнаружил,что на 8Мгц диод моргает как надо. И самое главное, заработали ws2812b в нужных мне режимах. Конечно,знаний из ситуации я особо не извлек, НО ОНО РАБОТАЕТ!