RFID пауза между считыванием

elfrom
Offline
Зарегистрирован: 28.08.2014

Добрый день, склеил несколько стетчей в один.

Кратко скетч считывает ID метку и вместе с датой и температурой выводит в монитор порта. проблема в том что если поднести и убрать метку за это время он успеет несколько раз считать ID , как сделать паузу между считыванием скажем в 2-3 секунды т.к. поднес карту он один раз считал и все убрал поднес опять один раз считал. поднес другую считал и так далее?

вот весь код

#include <SoftwareSerial.h>
#define STX 2
#define ETX 3
#include <Wire.h>
#include "Sodaq_DS3231.h"
SoftwareSerial softSerial(3, 2); // recommended pins for RX on Mega: 10, 11, 12...
int rx_counter;
byte rx_data[14]; // 1+10+2+1
void setup() {
  pinMode(8,OUTPUT);
  rx_counter = 0; // init counter
  Serial.begin(9600);
  softSerial.begin(9600);
  Wire.begin();
  rtc.begin();
}
uint32_t old_ts;
void loop() {
rtc.convertTemperature();             //convert current temperature into registers
DateTime now = rtc.now(); //get the current date-time
    uint32_t ts = now.getEpoch();
    if (old_ts == 0 || old_ts != ts) {
  old_ts = ts;
//Serial.print(now.year(), DEC);
  //Serial.print('/');
}
  
  if (softSerial.available() > 0) {
    rx_data[rx_counter] = softSerial.read();
    if (rx_counter == 0 && rx_data[0] != STX) {
      Serial.println("Out of sync!"); // do not increment rx_counter
    } else {
      rx_counter++;
    }
    if (rx_counter >= 14) {
      rx_counter = 0; // reset counter
      if (rx_data[0] == STX && rx_data[13] == ETX) { // packet starts with STX and ends with ETX
        byte calc_checksum = 0;
        for (int i = 0; i < 6; i++) { // data with checksum
          calc_checksum ^= ascii_char_to_num(rx_data[i*2+1]) * 16 + ascii_char_to_num(rx_data[i*2+2]);
        }
        if (calc_checksum == 0) {
          digitalWrite(8,HIGH);
          Serial.print("ID: ");
       //   for (int i = 1; i <= 10; i++) {
            Serial.write(rx_data[1]);
            Serial.write(rx_data[2]);
            Serial.write(rx_data[3]);
            Serial.write(rx_data[4]);
            Serial.write(rx_data[5]);
            Serial.write(rx_data[6]);
            Serial.write(rx_data[7]);
            Serial.write(rx_data[8]);
            Serial.write(rx_data[9]);
            Serial.write(rx_data[10]);
            Serial.print(" : ");
            Serial.print("Data: ");
            Serial.print(now.year(), DEC);
            Serial.print('/');
            Serial.print(now.month(), DEC);
            Serial.print('/');
            Serial.print(now.date(), DEC);
            Serial.print(' ');
            Serial.print(now.hour(), DEC);
            Serial.print(':');
            Serial.print(now.minute(), DEC);
            Serial.print(':');
            Serial.print(now.second(), DEC);
            Serial.print(" Temp: ");
            Serial.print(rtc.getTemperature()); //read registers and display the temperature
            Serial.println(" C");
          Serial.println();
          //turn led off
          digitalWrite(8,LOW);
        } else {
          Serial.println("Checksum ERROR!");
        }
      } else {
          Serial.println("Incorrect packet!");
      }
    } 
  }
}

// convert a single hex character to its byte value using ASCII table (see https://ru.wikipedia.org/wiki/ASCII)
byte ascii_char_to_num(byte a) {
  a -= '0'; // 0..9
  if (a > 9) a -= 7; // A..F
  return a;
} 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Организуй программу в многопоточный режим. Тогда и можешь задавать каждому вычислительному потоку частоту обращения.

//#1
//#2
//#3
void setup() {
  //#1
  //#2
  //#3
}

void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  //#1 1000 миллисекунд вычислит. поток 1
  static uint8_t PC_1 = 1 ;
  static uint32_t future1 = 0 ;
  if (MILLIS >= future1)   {
    switch (PC1)   {
      case 1: PC_1 = 2;
        future1 = MILLIS + 1000 ;
        // сам код
        break;
      case 2: PC_1 = 3;
        future1 = MILLIS + 1000 ;
        // сам код
        break;
      case 3: PC_1 = 1;
        future1 = MILLIS + 1000 ;
        // сам код
        break;
    }
    MILLIS = millis() ;
  }
  //#2  200 миллисекунд вычислит. поток 2
  static uint32_t future2 = 0 ;
  if (MILLIS >= future2)   {
    future2 = MILLIS + 200 ;
    // сам код
    MILLIS = millis() ;
  }
  //#3  100 миллисекунд вычислит. поток 3
  static uint32_t future3 = 0 ;
  if (MILLIS >= future3)   {
    future3 = MILLIS + 100 ;
    // сам код
  }
}

 

elfrom
Offline
Зарегистрирован: 28.08.2014

Спасибо, использовал эту часть таймера

         static uint32_t future3 = 0 ;
	  if (MILLIS >= future3)   {
	    future3 = MILLIS + 100 ;
	    // сам код
	  }

в свой код

#include <SoftwareSerial.h>
#define STX 2
#define ETX 3
#include <Wire.h>
#include "Sodaq_DS3231.h"
SoftwareSerial softSerial(3, 2); // recommended pins for RX on Mega: 10, 11, 12...
int rx_counter;
byte rx_data[14]; // 1+10+2+1
void setup() {
  pinMode(8,OUTPUT);
  rx_counter = 0; // init counter
  Serial.begin(9600);
  softSerial.begin(9600);
  Wire.begin();
  rtc.begin();  
}
uint32_t old_ts;
void loop() {
rtc.convertTemperature(); //convert current temperature into registers
DateTime now = rtc.now(); //get the current date-time
uint32_t ts = now.getEpoch();
  if (old_ts == 0 || old_ts != ts) {
  old_ts = ts;
}






 static uint32_t future3 = 0 ;
 if (MILLIS >= future3)   {
      future3 = millis() + 2000 ;








  if (softSerial.available() > 0) {
    rx_data[rx_counter] = softSerial.read();
    if (rx_counter == 0 && rx_data[0] != STX) {
      Serial.println("Out of sync!"); // do not increment rx_counter
    } else {
      rx_counter++;
    }
    if (rx_counter >= 14) {
      rx_counter = 0; // reset counter
      if (rx_data[0] == STX && rx_data[13] == ETX) { // packet starts with STX and ends with ETX
        byte calc_checksum = 0;
        for (int i = 0; i < 6; i++) { // data with checksum
          calc_checksum ^= ascii_char_to_num(rx_data[i*2+1]) * 16 + ascii_char_to_num(rx_data[i*2+2]);
        }
        if (calc_checksum == 0) {
          digitalWrite(8,HIGH);
          Serial.print("ID: ");
       //   for (int i = 1; i <= 10; i++) {
            Serial.write(rx_data[3]);
            Serial.write(rx_data[4]);
            Serial.write(rx_data[5]);
            Serial.write(rx_data[6]);
            Serial.write(rx_data[7]);
            Serial.write(rx_data[8]);
            Serial.write(rx_data[9]);
            Serial.write(rx_data[10]);
          Serial.print(" :Serial: ");
            Serial.write(rx_data[5]);
            Serial.write(rx_data[6]);
          Serial.print(" :Number: ");
            Serial.write(rx_data[7]);
            Serial.write(rx_data[8]);
            Serial.write(rx_data[9]);
            Serial.write(rx_data[10]);
            Serial.print(" : ");
            Serial.print("Data: ");
            Serial.print(now.year(), DEC);
            Serial.print('/');
            Serial.print(now.month(), DEC);
            Serial.print('/');
            Serial.print(now.date(), DEC);
            Serial.print(' ');
            Serial.print(now.hour(), DEC);
            Serial.print(':');
            Serial.print(now.minute(), DEC);
            Serial.print(':');
            Serial.print(now.second(), DEC);
            Serial.print(" Temp: ");
            Serial.print(rtc.getTemperature()); //read registers and display the temperature
            Serial.println(" C");
            Serial.println();
          digitalWrite(8,LOW);//turn led off
        } else {
          Serial.println("Checksum ERROR!");
        }
      } else {
          Serial.println("Incorrect packet!");
      }
    } 
  }
}
}
// convert a single hex character to its byte value using ASCII table (see https://ru.wikipedia.org/wiki/ASCII)
byte ascii_char_to_num(byte a) {
  a -= '0'; // 0..9
  if (a > 9) a -= 7; // A..F
  return a;
} 

Сделал пропуск(где ваш код)

в итоге он выводит в порт с той задержкой что считать успел т.е. если карту подержали 2 секунды и за это время он успел прочитать ее 2-3-n раз он с только раз данные и выводит, но с задержкой в заданное время,

быть может мой вопрос не корректен как сделать проверку если данные считаны этой карты то все больше повторять считывание не нужно?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее всего вам надо принять первую посылку, а вот остальные просто принять и забыть. Проще очистить буфер. Через 2 секунды сделать так же . Первую принять, а остальные в мусор. Потому что softSerial хватает все что пришло аппаратно. 

elfrom
Offline
Зарегистрирован: 28.08.2014

Проблема как раз в очистке буфера , если в старой версии программы очистить буфер можно было через .flush(); то в новых данный трюк не проходит( не подскажете команду очистки?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
while (softSerial.available() > 0) {
    rx_data[rx_counter] = softSerial.read();
   }
// или где-то так.