Salve ragazzi, sto impazzendo con un programmino per gestire delle stringhe di TAG RFID e memorizzarle sulla EEPROM
Il listato è il seguente:
#include <SoftwareSerial.h>
#include <EEPROM.h>
#define rxPIN 10
#define txPIN 11
#define greenLED 8
#define redLED 9
SoftwareSerial tag(rxPIN, txPIN); //oggetto per la comunicazione seriale con il TAG reader
int numtags = 0; //Numero dei tag presenti in memoria
char* allowedTags[10]; //Vettore di tag caricati dalla EEPROM sulla RAM
char readtag[10]; //Vettore temporaneo per il caricamento dalla EEPROM
char tagValue[10]; //Valore letto dal RFID reader
int checksumOK; //Variabile booleana per controllare lo stato del checksum dopo la lettura
void setup()
{
tag.begin(9600); //Inizializzo la porta di comunicazione sulla quale si leggerà il tag
Serial.begin(9600);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
readfromEEPROM(); //Carica i tag dalla EEPROM
}
void loop()
{
wait();
checksumOK = ReadAndCheck();
writeonEEPROM();
}
//Funzioni personalizzate
void wait()
{
while (tag.available() < '0') //Se non ricevo TAG, rimani in attesa e fai lampeggiare i LED verde e rosso
{
for (int i=0; i<=50; i++)
{
digitalWrite(greenLED, HIGH);
digitalWrite(redLED, HIGH);
if (tag.read() == '2')
return;
delay(10);
}
for (int i=0; i<=50; i++)
{
digitalWrite(greenLED, LOW);
digitalWrite(redLED, LOW);
if (tag.read() == '2')
return;
delay(10);
}
}
}
int ReadAndCheck()
{
byte val = 0;
byte checksum = 0;
byte bytesRead = 0;
byte tempByte = 0;
byte tagBytes[6]; // Tag formato da 5 byte + 1 per il checksum
while (bytesRead < 12)
{
delay(15);
val = tag.read();
if (bytesRead < 10) // Append the first 10 bytes (0 to 9) to the raw tag value
{
tagValue[bytesRead] = val;
//Il valore inviato è in codifica ASCII. Per il controllare se la chiave è accettata, il valore rimarrà invariato. Per il calcolo del checksum il valore verrà convertito in HEX
}
//-----INIZIO CONVERSIONE IN HEX PER IL CALCOLO DEL CHECKSUM
//val = 'F'; Considerando F tra apici ('F'), considero il valore DECIMALE della cifra (posizione nella tabella ASCII - per esempio F corrisponde a 70)
if ((val >= '0') && (val <= '9'))
val = val - '0'; //conversione in base 10: val=val - il valore DECIMALE della cifra 0 derivante dalla tabella ASCII (questo perche da 0 a 9 in tabella le cifre sono sequenziali)
else if ((val >= 'A') && (val <= 'F'))
val = 10 + val - 'A'; //conversione in base 10: val=val - il valore DECIMALE della cifra A derivante dalla tabella ASCII (questo perche da A a F in tabella le cifre sono sequenziali)
//-----INIZIO CALCOLO DEL CHECKSUM
//Ogni due cifre HEX, aggiungi un byte a tagBytes (RICORDA: IN HEX OGNI CIFRA PESA MEZZO BYTE!)
if (bytesRead & 1 == 1) // & --> Operatore AND bit a bit -- Se bytesread è un numero dispari esegui il blocco IF
{
//Con le istruzioni successive compongo in un byte due cifre HEX
tagBytes[bytesRead >> 1] = (val | (tempByte << 4)); // | --> Operatore OR bit a bit
if (bytesRead >> 1 != 5) //Il checksum va calcolato solo sui primi 5 byte della cidifica HEX. L'ultimo byte è riservato per il checksum
checksum ^= tagBytes[bytesRead >> 1]; // Calculate the checksum... (XOR)
}
else
tempByte = val; // Se bytesread è pari, memorizzo la cifra HEX in una variabile temporanea per poi comporla nel byte tagBytes successivamente
bytesRead++; // Ready to read next digit
}
//-----FINE CALCOLO CHECKSUM
//CONTROLLO ESATTEZZA DEL CHECKSUM
if (bytesRead == 12) //Se la lettura è completa
{
tagValue[10] = '\0'; // Terminatore di stringa di caratteri
Serial.println(); //Vado a capo
Serial.print("Tag Letto: ");
Serial.println(tagValue);
Serial.print("Checksum ricevuto: ");
Serial.println(tagBytes[5], HEX); //Stampo il valore della cella 5, in HEX, contenente il checksum trasmesso
Serial.print("Checksum calcolato: ");
Serial.print(checksum, HEX);
if (tagBytes[5] == checksum) //Se il checksum calcolato è uguale al checksum trasmesso stampa ok altrimenti stampa errore
{
Serial.println(" -- CHECKSUM OK.");
return 1;
}
else
{
Serial.println(" -- CHECKSUM ERROR.");
return 0;
}
}
}
void readfromEEPROM()
{
numtags = EEPROM.read(0); //Nella locazione 0 è memorizzato il numero dei tag presenti in memoria
Serial.print("Tag presenti in memoria: ");
Serial.println(numtags);
int i = 0, j, m;
while (i < numtags)
{
m=0; //m mi serve per poter scrivere il dato sul vettore temporaneo
for (j=((i*10)+1); j<=((i*10)+10); j++)
{
readtag[m] = EEPROM.read(j);
m++;
}
readtag[10] = '\0';
allowedTags[i] = readtag;
Serial.println(i);
Serial.println(allowedTags[i]);
i++;
}
}
void writeonEEPROM()
{
int i=0, j=0, m=0;
allowedTags[numtags] = tagValue;
numtags++;
EEPROM.write(0, numtags);
while (i < numtags)
{
m=0;
for (j=((i*10)+1); j<=((i*10)+10); j++)
{
EEPROM.write(j, allowedTags[i][m]);
m++;
}
i++;
}
}
Il problema riguarda il puntatore vettore "char* allowedTags[10]". Quando viene eseguita la funzione ReadAndCheck(), il valore delle componenti di questo vettore vengono cambiate. Per esempio se inizialmente il valore di allowedTags[0] è "58ADE3423D", dopo l'esecuzione di ReadAndCheck(), esso diventa "58ADE3423D58ADE3423D". Non riesco a capire il perchè.
Ho individuato anche la parte della funzione che crea questo problema:
//-----INIZIO CALCOLO DEL CHECKSUM
//Ogni due cifre HEX, aggiungi un byte a tagBytes (RICORDA: IN HEX OGNI CIFRA PESA MEZZO BYTE!)
if (bytesRead & 1 == 1) // & --> Operatore AND bit a bit -- Se bytesread è un numero dispari esegui il blocco IF
{
//Con le istruzioni successive compongo in un byte due cifre HEX
tagBytes[bytesRead >> 1] = (val | (tempByte << 4)); // | --> Operatore OR bit a bit
if (bytesRead >> 1 != 5) //Il checksum va calcolato solo sui primi 5 byte della cidifica HEX. L'ultimo byte è riservato per il checksum
checksum ^= tagBytes[bytesRead >> 1]; // Calculate the checksum... (XOR)
}
else
tempByte = val; // Se bytesread è pari, memorizzo la cifra HEX in una variabile temporanea per poi comporla nel byte tagBytes successivamente
bytesRead++;
Come al solito, vi ringrazio anticipatamente per l'aiuto che, spero, mi darete
Buonanotte, ilPeppins