Лента WS2812B мигает вместо того, чтобы беспрерывно светиться с EEPROM
- Войдите на сайт для отправки комментариев
Чт, 12/07/2018 - 23:37
Здравствуйте. Буду благодарен за помощь новичку в ардуино, чтобы исправить проблему.
Я использую Arduino Nano V3.0 AVR ATmega328P и диодную ленту с ШИМ WS2812B.
Задача в том, чтобы в EEPROM памяти сохранялось сколько диодов горело перед выключением питания, и за тем после возобновления питания на ленте загорались столько же диодов, как и до выключения питания.
Столкнулся с проблемой, что лента раз в пол секунды загорается и тухнет (какой делей поставил так и работает) и я не понимаю почему.
Буду благодарен за исправления и разъяснения почему оно так работает.
Заранее благодарен:)
Arduino Nano V3.0 AVR ATmega328P
#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>
#define ledPIN 2
#define redButtonPIN 3
#define greenButtonPIN 4
#define NUMPIXELS 15
uint8_t maxValue EEMEM = 15;
uint8_t currentValue EEMEM;
uint8_t firstByteInEEOROM EEMEM = 0;
uint8_t secondByteInEEOROM EEMEM = 1;
bool isFirstSession = true;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, ledPIN, NEO_GRB + NEO_KHZ800);
void setup() {
if (EEPROM.read(firstByteInEEOROM) == isFirstSession) {
EEPROM.put(firstByteInEEOROM, false);
EEPROM.put(secondByteInEEOROM, maxValue);
}
currentValue = EEPROM.get(secondByteInEEOROM, currentValue);
strip.begin();
strip.show();
pinMode(ledPIN, OUTPUT);
pinMode(redButtonPIN, INPUT);
pinMode(greenButtonPIN, INPUT);
}
void loop() {
outPixels();
redButton();
greenButton();
}
void outPixels(){
uint8_t valuePoints = calculationCurrentValue();
if (currentValue == 0){
displayRedPixels();
delay(70);
displayEmptyPixels();
delay(70);
displayRedPixels();
delay(70);
}
else {
for (uint8_t displayPixel = 0; displayPixel < valuePoints; displayPixel++){
strip.setPixelColor(displayPixel, strip.Color(0, 50, 0)); // R, G, B
strip.show();
}
for (uint8_t displayRedPixel = maxValue-1; displayRedPixel != valuePoints-1; displayRedPixel--){
strip.setPixelColor(displayRedPixel, strip.Color(0, 0, 0)); // R, G, B
strip.show();
}
delay(500);
}
}
uint8_t calculationCurrentValue(){
return 0 + currentValue;
}
void displayRedPixels(){
for (uint8_t displayRedPixel = 0; displayRedPixel < NUMPIXELS; displayRedPixel++){
strip.setPixelColor(displayRedPixel, strip.Color(100, 0, 0)); // R, G, B
strip.show();
}
}
void displayEmptyPixels(){
for (uint8_t displayEmptyPixel = 0; displayEmptyPixel < NUMPIXELS; displayEmptyPixel++){
strip.setPixelColor(displayEmptyPixel, strip.Color(0, 0, 0)); // R, G, B
strip.show();
}
}
void wrightCurrentValueToStorage() {
EEPROM.write(secondByteInEEOROM, currentValue);
}
void redButton(){
uint8_t redValue = digitalRead(redButtonPIN);
Serial.print(redValue);
if (redValue == 1){
if (currentValue > 0){
currentValue--;
wrightCurrentValueToStorage();
delay(500);
}
}
}
void greenButton(){
uint8_t greenValue = digitalRead(greenButtonPIN);
if (greenValue == 1){
if (currentValue < maxValue){
currentValue++;
wrightCurrentValueToStorage();
delay(500);
}
}
}
Ну, вы же указываете, что "какой делей поставил, так и работает". Получается, что все согласно задумке и функционирует. Проблема-то в чем заключается?
Лента не должна мигать раз в пол секунды, а светить постоянно.
041
displayRedPixels();
042
delay(70);
043
displayEmptyPixels();
044
delay(70);
045
displayRedPixels();
046
delay(70);
Ну вот тут и мигает. При EmptyPixels. Всё логично.
В этом случае зачем вам строки 54-57 ?
Оно мигает только если использовать EEPROM память
Мигает сразу при включении питания. И ещё уточнение важное:
в строках
040
if
(currentValue == 0){
041
displayRedPixels();
042
delay(70);
043
displayEmptyPixels();
044
delay(70);
045
displayRedPixels();
046
delay(70);
047
}
мигает красным светом displayRedPixels()
А при подключении питания мигает зелёным светом
Если из этого кода убрать всё что касается EEPROM, то лента работает как надо
строки:
018
if
(EEPROM.read(firstByteInEEOROM) == isFirstSession) {
019
EEPROM.put(firstByteInEEOROM,
false
);
020
EEPROM.put(secondByteInEEOROM, maxValue);
021
}
022
currentValue = EEPROM.
get
(secondByteInEEOROM, currentValue);
080
void
wrightCurrentValueToStorage() {
081
EEPROM.write(secondByteInEEOROM, currentValue);
082
}
их можно убрать и лента не мигает зелёным светом при подключении питания, а стабильно светит зелёным светом
Кнопки как подключены? Подтягивающие резисторы есть?
Резисторов нету.
Использую в качестве кнопок Датчик вибрации SW-420
Тогда сложно предсказывать как у вас вызываются redButton() и greenButton(), которые определяют поведение ленты. И, возможно, они скоро угробят EEPROM.
Подключите кнопки по схеме для pinMode(..., INPUT_PULLUP) - это временно уберет фактор случайности.
Хорошо, попробую, спасибо за ответ.
Только, могли бы вы разъяснить, каким образом они могут угробить EEPROM и почему оно случайно и не предсказуемо работает? Это поможет в дальнейшем понимать как оно работает и не делать других ошибок в этой области.
У вас пины для кнопок настроены на вход без всякой поддтяжки, управление идет логической 1, т.е. питанием. Так вот при такой настройке пина, на нем в результате наводок и помех может появлятся уровень, соответствующий "1". И скорее всего оно таки и есть, т.к. вызывается функция сохранения в эпром, а она вызывается из функций обработок кнопок. Сделайте настройку пинов как подсказали выше, только в таком случае управление надо будет осуществлять нулем. Т.е. надо будет комутировать на землю и в программе сравнивать уже не с 1, а с 0.
А эпром угробиться из-за ограниченного количества перезаписей. 100000.
Спасибо за помощь :) буду пробовать