ARDUINO nano+ws2812+RC522, куда воткнуть clearState()

ZloyShaitan

✩✩✩✩✩✩✩
5 Сен 2021
13
0
Приветствую, почтенные)
Есть скетч, который делает следующее:
читает уид карты, сравнивает его с заданным, если уид совпадает и карта находится в зоне действия считывателя достаточное время - зажигает диод на ленте, задорно бибикает, и пишет цвет и номер диода в eprom
Скетч работает, все ок, но беда в том, что для того, чтобы очистить энергонезависимую память, приходится раскомментировать в нем строчку и шить девайсину по новой, а потом снова эту строчку комментировать. и еще раз шить.
Есть желание добавить несколько уидов карт, которые при попадании в зону считывания очищали бы энергонезависимую память.
Т.е., кмк, должен появиться второй массив и где-то в цикле сравнения должно быть условие с clearstate ().
Но вот как это реализовать в уже имеющемся продукте (увы, автор не я, автор исчез с горизонта и вообще абонент не абонент) - дотумкать не могу, в ардуино си делаю не то, что первые шаги, и даже не ползаю, а, пожалуй, учусь держать голову прямо и сидеть)
Так что прошу помощи у отцов и корифеев этого дела

C++:
#include <SPI.h>
#include <MFRC522.h>
#include <JC_Button.h>
#include <Adafruit_NeoPixel.h>
#include <arduino-timer.h>
#include <EEPROM.h>
#include "pitches.h"

#define RST_PIN 9          
#define SS_PIN 10

#define LEDPIN 5
#define NUMPIXELS 10

MFRC522 mfrc522(SS_PIN, RST_PIN);
Adafruit_NeoPixel leds = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
auto timer = timer_create_default();
int cardPresenceflag = 0;
String cardSerials[10] = {"12211254187", "17018859187", "58111114174", "1793824364", "527216717118162192", "52215889206219208", "", "", "", ""}; //МАССИВ СЕРИЙНЫХ НОМЕРОВ МЕТОК
int spotsStatus[10] = {0,0,0,0,0,0,0,0,0,0};
int spotsColor[10][3] = {{100,0,0}, {0,100,0}, {0,0,100}, {100,100,100}, {0,0,255}, {46,43,95}, {139,0,255}, {255,0,0}, {255,127,0}, {255,255,0}}; // ЦВЕТА ТОЧЕК R,G,B
int currentCardId = -1;
unsigned long captureStartTime = 0;
unsigned long captureDurationTime = 50; // Необходимое время удержания карты в зоне действия считывателя
int brightness = 0;
bool brightnessDirection = true;
int brightLedId = -1;

void setup() {
  Serial.begin(115200);
  SPI.begin();
  mfrc522.PCD_Init();
  leds.begin();
  leds.clear();
  leds.show();
//clearState(); // СБРОС EPROM
  loadState();
  timer.every(1000, visualize);
  timer.every(10, brightnessCycle);
  pinMode(7, OUTPUT);
  }

void loop()
{
  timer.tick();
  cardPresenceflag = 0;

  if (mfrc522.PICC_IsNewCardPresent())
  {
    cardPresenceflag = 1;
  }
  else
  {
    if (mfrc522.PICC_IsNewCardPresent())
    {
      cardPresenceflag = 1;    
    }
  }

  if (cardPresenceflag)
  {
    if (mfrc522.PICC_ReadCardSerial())
    {
//Serial.println(getCardSerial(mfrc522.uid.uidByte, mfrc522.uid.size)); // ОТОБРАЖЕНИЕ uid КАРТЫ В ЗОНЕ ДЕЙСТВИЯ СЧИТЫВАТЕЛЯ

      int cardId = getCardId(getCardSerial(mfrc522.uid.uidByte, mfrc522.uid.size));
      if(cardId == -1)
      {
        captureStartTime = 0;
        return;
      }

      if(cardId != currentCardId)
      {
        captureStartTime = millis();
        currentCardId = cardId;
      }
    }
  }
  else
  {
    captureStartTime = 0;
    currentCardId = -1;
  }
}

String getCardSerial(byte *buffer, byte bufferSize) {
  String cardId = "";
  for (byte i = 0; i < bufferSize; i++)
  {
    cardId += String((buffer[i]));
  }
  return cardId;
}

int getCardId(String cardSerial)
{
  int cardId = -1;
  for(int i = 0; i < 10; i++)
  {
    if(cardSerials[i] == cardSerial)
    {
      cardId = i;
      break;
    }
  }
  return cardId;
}

bool visualize()
{
  if(captureStartTime != 0)
  {
    unsigned long captureTime = (millis() - captureStartTime)/1000;

    if(captureTime <= captureDurationTime && spotsStatus[currentCardId] == 0)
    {
      leds.clear();

      for(int i = 0; i < captureTime/(captureDurationTime/10); i++)
      {
        leds.setPixelColor(i, leds.Color(spotsColor[currentCardId][0], spotsColor[currentCardId][1], spotsColor[currentCardId][2]));
      }

      brightLedId = captureTime/(captureDurationTime/10);
    }
    else
    {
      if(spotsStatus[currentCardId] == 0)
      {
        captureStartTime = 0;
        brightLedId = -1;
        spotsStatus[currentCardId] = 1;
        playSound();
        saveState();
      }
    }
  }
  else
  {
    brightLedId = -1;
    leds.clear();

    for(int i = 0; i < 10; i++)
    {
      if(spotsStatus[i] == 1)
      {
        leds.setPixelColor(i, leds.Color(spotsColor[i][0],spotsColor[i][1],spotsColor[i][2]));
      }
    }

    leds.show();
  }

  return true;
}

bool brightnessCycle()
{
  if(brightnessDirection)
  {
    if(brightness < 200)
    {
      brightness += 10;
    } else {
      brightnessDirection = false;
      brightness -= 10;
    }
  } else {
    if(brightness > 0)
    {
      brightness -= 10;
    } else {
      brightnessDirection = true;
      brightness += 10;
    }
  }

  if(brightLedId != -1)
  {
    leds.setPixelColor(brightLedId, leds.Color(brightness, brightness, brightness));
    leds.show();
  }

  return true;
}

void saveState()
{
  for(int i = 0; i < 10; i++)
  {
    EEPROM.write(i, spotsStatus[i]);
  }
}

void loadState()
{
  for(int i = 0; i < 10; i++)
  {
    byte value = EEPROM.read(i);
    if(value <= 1)
    {
      spotsStatus[i] = value;
    }
  }
}

void clearState()
{
  for(int i = 0; i < 10; i++)
  {
    EEPROM.write(i, 0);
  }
}

void playSound()
{
  tone(7,NOTE_E6,70);
  delay(130);
  tone(7,NOTE_G6,70);
  delay(130);
  tone(7,NOTE_E7,70);
  delay(130);
  tone(7,NOTE_C7,70);
  delay(130);
  tone(7,NOTE_D7,70);
  delay(130);
  tone(7,NOTE_G7,70);
  delay(125);
  noTone(7);
}
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,894
860
Добавить такую карту несложно, но как это обьяснить человеку, не умеющему программировать - ума не приложу.

Наверно, вам проще кнопку добавить, читаемую в Сетап. Если при перезагрузке кнопка нажата - значит чистим еепром. На код кнопки у гайвера примеры есть
 

ZloyShaitan

✩✩✩✩✩✩✩
5 Сен 2021
13
0
@bort707,
Нууу.. не совсем же я деревянный) массив с уидами карт на которые срабатывает скетч - здесь

String cardSerials[10] = {"12211254187", "17018859187", "58111114174", "1793824364", "527216717118162192", "52215889206219208", "", "", "", ""};

сюда и добавляю
значить нужен второй массив, с уидами, по которым будет срабатывать очистка.
и условие в цикле сравнения прочтенного уида с теми, что находятся в первом и втором массиве.
сложности прежде всего в том, что из-за незнания синтаксиса языка, паршиво понимаю, куда именно пихать условие сравнения со вторым (очистительным) массивом.
чуйло чует, что все решается 3-5 строчками кода. но чуйло не может объяснить - как) иначе сюда бы не пришел)))
 

ZloyShaitan

✩✩✩✩✩✩✩
5 Сен 2021
13
0
про кнопку глянул, вродь ничего сложного, но смысл в том, чтобы epprom сбрасывать мог не кто попало, а лицо, облеченное неким признаком власти и могущества - в нашем случае - картой с определенным уидом)
но, на крайний случай, ежли ничего не поможет - буду держать Вашу мудрую мысль в голове)
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630

@ZloyShaitan,
А могли бы вы описать вообще суть сего проекта, не думаю, что идея была иолько светодиоды зажигать? Что это, и для чего предназначено?
 

ZloyShaitan

✩✩✩✩✩✩✩
5 Сен 2021
13
0
@kostyamat,

ну на самом деле все просто: есть такой вид активного отдыха, как страйкбол (он же айрсофт) - это когда взрослые дядьки с игрушечными автоматами сутки напролет скачут по кустам в дорогущем камуфляже и пуляют друг в друга пластиковыми шариками.
так вот в этом самом страйкболе один из популярных типов миссий - захват и удержание точки определенное количество времени. И, чтобы возле каждой точки не ставить дурака с секундомером, который записывает факт удержания в Специальную книжечку, и делается этот девайс. Прибежали на точку - один воЕн с дивайсом приник к пню, с прибитой к нему гвоздями рфид картой, остальные отстреливаются от приближающихся полчищ. Успели удержать - побежали дальше к следующему пню с горящим диодиком на девайсе, символизирующим факт овладения. Но, рано или поздно, загорятся все диодики, а пней может быть больше, чем десять. и чтобы не бежать к организаторам для сброса прогресса при помощи перепрошивки (это еще и ноут на мероприятие таскать, и к юсб ардуины добраться посредством раскурочивания корпуса) - проще сделать орговские карты для сброса еепрома. Вкратце, как-то так.
 

bort707

★★★★★★✩
21 Сен 2020
2,894
860
Хм, разве нельзя сделать не 10 светиков, а 20? Или просто счетчик с цифрами?
Это я про саму задачу. А запрограммировать сброс по карте, конечно, можно, код элементарный, уверен что вы разберетесь.
 

ZloyShaitan

✩✩✩✩✩✩✩
5 Сен 2021
13
0
@Старик Похабыч, @bort707,
Да скетч то уже написан, в первом посте под спойлером.
и железяка работает.
а пост не про то, чтобы еще 10-20-30-100 диодов воткнуь (вряд ли я бы тогда в раздел помощи по программированию полез)
а про то, куда, как и какую функцию воткнуть, которая сравнивала бы считанные уиды со вторым массивом и по совпадению вызывала бы clearstate () один раз, чтобы в бесконечный цикл не улететь и еппром не уговнякать за минуту.
насчет легко, да, возможно но,

в ардуино си делаю не то, что первые шаги, и даже не ползаю, а, пожалуй, учусь держать голову прямо и сидеть)
Так что прошу помощи у отцов и корифеев этого дела
или нынче помогают только за деньги?)))))
 

Lumenjer

★★★✩✩✩✩
10 Дек 2020
220
112
@ZloyShaitan, проверяем первый массив, пользовательский, если совпало - возвращаем айди, если нет - проверяем по второму массиву (adminCardSerials), если совпало - чистим EPROM и возвращаем -2 и играем playSoundEprom().

C++:
#include <SPI.h>
#include <MFRC522.h>
#include <JC_Button.h>
#include <Adafruit_NeoPixel.h>
#include <arduino-timer.h>
#include <EEPROM.h>
#include "pitches.h"
#define RST_PIN 9          
#define SS_PIN 10
#define LEDPIN 5
#define NUMPIXELS 10
MFRC522 mfrc522(SS_PIN, RST_PIN);
Adafruit_NeoPixel leds = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
auto timer = timer_create_default();
int cardPresenceflag = 0;
String cardSerials[10] = {"12211254187", "17018859187", "58111114174", "1793824364", "527216717118162192", "52215889206219208", "", "", "", ""}; //МАССИВ СЕРИЙНЫХ НОМЕРОВ МЕТОК
String adminCardSerials[10] = {"12211254187", "17018859187", "58111114174", "1793824364", "527216717118162192", "52215889206219208", "", "", "", ""}; //МАССИВ СЕРИЙНЫХ НОМЕРОВ МЕТОК ДЛЯ СБРОСА EPROM
int spotsStatus[10] = {0,0,0,0,0,0,0,0,0,0};
int spotsColor[10][3] = {{100,0,0}, {0,100,0}, {0,0,100}, {100,100,100}, {0,0,255}, {46,43,95}, {139,0,255}, {255,0,0}, {255,127,0}, {255,255,0}}; // ЦВЕТА ТОЧЕК R,G,B
int currentCardId = -1;
unsigned long captureStartTime = 0;
unsigned long captureDurationTime = 50; // Необходимое время удержания карты в зоне действия считывателя
int brightness = 0;
bool brightnessDirection = true;
int brightLedId = -1;
void setup() {
  Serial.begin(115200);
  SPI.begin();
  mfrc522.PCD_Init();
  leds.begin();
  leds.clear();
  leds.show();
//clearState(); // СБРОС EPROM
  loadState();
  timer.every(1000, visualize);
  timer.every(10, brightnessCycle);
  pinMode(7, OUTPUT);
  }
void loop()
{
  timer.tick();
  cardPresenceflag = 0;
  if (mfrc522.PICC_IsNewCardPresent())
  {
    cardPresenceflag = 1;
  }
  else
  {
    if (mfrc522.PICC_IsNewCardPresent())
    {
      cardPresenceflag = 1;    
    }
  }
  if (cardPresenceflag)
  {
    if (mfrc522.PICC_ReadCardSerial())
    {
//Serial.println(getCardSerial(mfrc522.uid.uidByte, mfrc522.uid.size)); // ОТОБРАЖЕНИЕ uid КАРТЫ В ЗОНЕ ДЕЙСТВИЯ СЧИТЫВАТЕЛЯ
      int cardId = getCardId(getCardSerial(mfrc522.uid.uidByte, mfrc522.uid.size));
      if(cardId == -1)
      {
        captureStartTime = 0;
        return;
      }
      else if(cardId == -2) {
        captureStartTime = 0;
        playSoundEprom();
        return;
      }
      if(cardId != currentCardId)
      {
        captureStartTime = millis();
        currentCardId = cardId;
      }
    }
  }
  else
  {
    captureStartTime = 0;
    currentCardId = -1;
  }
}
String getCardSerial(byte *buffer, byte bufferSize) {
  String cardId = "";
  for (byte i = 0; i < bufferSize; i++)
  {
    cardId += String((buffer[i]));
  }
  return cardId;
}
int getCardId(String cardSerial)
{
  int cardId = -1;
  for(int i = 0; i < 10; i++)
  {
    if(cardSerials[i] == cardSerial)
    {
      cardId = i;
      break;
    }
  }
  for (int i = 0; i < 10; i++)
  {
    if(adminCardSerials[i] == cardSerial)
    {
        clearState();
        return -2;
    }
  }
  return cardId;
}
bool visualize()
{
  if(captureStartTime != 0)
  {
    unsigned long captureTime = (millis() - captureStartTime)/1000;
    if(captureTime <= captureDurationTime && spotsStatus[currentCardId] == 0)
    {
      leds.clear();
      for(int i = 0; i < captureTime/(captureDurationTime/10); i++)
      {
        leds.setPixelColor(i, leds.Color(spotsColor[currentCardId][0], spotsColor[currentCardId][1], spotsColor[currentCardId][2]));
      }
      brightLedId = captureTime/(captureDurationTime/10);
    }
    else
    {
      if(spotsStatus[currentCardId] == 0)
      {
        captureStartTime = 0;
        brightLedId = -1;
        spotsStatus[currentCardId] = 1;
        playSound();
        saveState();
      }
    }
  }
  else
  {
    brightLedId = -1;
    leds.clear();
    for(int i = 0; i < 10; i++)
    {
      if(spotsStatus[i] == 1)
      {
        leds.setPixelColor(i, leds.Color(spotsColor[i][0],spotsColor[i][1],spotsColor[i][2]));
      }
    }
    leds.show();
  }
  return true;
}
bool brightnessCycle()
{
  if(brightnessDirection)
  {
    if(brightness < 200)
    {
      brightness += 10;
    } else {
      brightnessDirection = false;
      brightness -= 10;
    }
  } else {
    if(brightness > 0)
    {
      brightness -= 10;
    } else {
      brightnessDirection = true;
      brightness += 10;
    }
  }
  if(brightLedId != -1)
  {
    leds.setPixelColor(brightLedId, leds.Color(brightness, brightness, brightness));
    leds.show();
  }
  return true;
}
void saveState()
{
  for(int i = 0; i < 10; i++)
  {
    EEPROM.write(i, spotsStatus[i]);
  }
}
void loadState()
{
  for(int i = 0; i < 10; i++)
  {
    byte value = EEPROM.read(i);
    if(value <= 1)
    {
      spotsStatus[i] = value;
    }
  }
}
void clearState()
{
  for(int i = 0; i < 10; i++)
  {
    EEPROM.write(i, 0);
  }
}
void playSound()
{
  tone(7,NOTE_E6,70);
  delay(130);
  tone(7,NOTE_G6,70);
  delay(130);
  tone(7,NOTE_E7,70);
  delay(130);
  tone(7,NOTE_C7,70);
  delay(130);
  tone(7,NOTE_D7,70);
  delay(130);
  tone(7,NOTE_G7,70);
  delay(125);
  noTone(7);
}
void playSoundEprom()
{
  tone(7,NOTE_E6,200);
  delay(500);
  tone(7,NOTE_G6,200);
  delay(500);
  tone(7,NOTE_E7,200);
  delay(500);
  noTone(7);
}
 
  • Лойс +1
Реакции: ZloyShaitan

Старик Похабыч

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
@ZloyShaitan, Я сейчас как то оказался сильно загружен и некоторые вещи мог упустить.Помогают и так и за деньги . По разному бывает. От задачи тоже зависит, некоторые даже за деньги делать не хочется.
Но раз помогли - то уже хорошо, спасибо помогающему.
 
  • Лойс +1
Реакции: ZloyShaitan