Go Down

Topic: DA LETTURA DA I2C A STRINGA IN ESADECIMALE (Read 998 times) previous topic - next topic

ton_ino

Buongiorno a tutti,

posto un quesito che sarà sicuramente banale, ma data la mia poca esperienza software mi rimetto alla vostra competenza.
Ho realizzato un sistema di controllo accessi con Arduino e leggo da un modulo RFID interfacciato in I2C. Realizzo la lettura dell' UID dell' RFID con il classico wire.read. I dati mi arrivano ovviamente un singolo byte alla volta. Ho bisogno, oltre che accodare i singoli byte in un unica variabile o array, di ottenere la stringa finale con i singoli byte espressi in esadecimale del tipo "A9B2EF4B", in modo poi da manipolarla con le classiche funzioni String ecc.

Spero di aver esposto in modo chiaro il problema.

Grazie in anticipo a tutti.

nid69ita

Libreria String object:

String thisString = String(13, HEX)       

ovvero thisString conterrà "D" (esadecimale di 13)
my name is IGOR, not AIGOR

ton_ino

Grazie per la risposta.

Non mi è chiaro se il metodo descritto accetta in ingresso anche una variabile ed eventualmente di che tipo. Inoltre è giusto conviene convertire ogni singolo byte ricevuto e poi creare l array o operare la convrrsiobe.in esadecimale sulla variabile.finale? Qualche esempio??

Grazie infinite

lesto

una funziona prende SEMPRE in ingresso una variabile. Quel 13 viene trasformato in una variabile e poi mandato in pasto alla funzione

Per sapere che tipo di variabili si prendono in input, si guarda il reference (menù grigio in alto -> main site -> reference).

la conversione si fa quando vuoi, però i sensori di solito buttano fuori valori int (2byte)... rispetta lo standard del sensore!
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

nid69ita

#4
Feb 15, 2013, 09:09 am Last Edit: Feb 15, 2013, 04:03 pm by nid69ita Reason: 1
La funzione è overloaded, ovvero accetta variabili di tipo diverse (peculiarità del C++).
Accetta anche valori long e unsigned long (dal manuale reference, non per esperienza diretta).
Bisogna vedere se i dati che tu vuoi leggere dal sensore, anche se uniti in un unico valore, a quale valore massimo arriva.

Dal tuo esempio "A9B2EF4B" => 2.847.076.171
unsigned long max              => 4.294.967.295

ovvero unsigned long=4 byte come l'esempi che hai fatto.
my name is IGOR, not AIGOR

ton_ino

#5
Feb 15, 2013, 08:03 pm Last Edit: Feb 15, 2013, 10:25 pm by leo72 Reason: 1
Mi scuso per l'insistenza ma le mie lacune in programmazione restano,

forse postando un pò di codice ci capiamo meglio. In realtà nn si tratta di un sensore ma di un modulo reader RFID (l'SL018 della Stronglink) tramite il quale devo leggere il codice UID di card di tipologia MIFARE. In genere questo codice è appunto 4 Byte. Di seguito vi riporto il codice tramite il quale si riesce a leggere l'id e stamparlo sulla seriale:

Code: [Select]
/**
*  @title:  StrongLink SL018/SL030 RFID reader demo
*  @author: marc@marcboon.com
*  @see:    http://www.stronglink.cn/english/sl018.htm
*  @see:    http://www.stronglink.cn/english/sl030.htm
*
*  Arduino to SL018/SL030 wiring:
*  A3/TAG     1      5
*  A4/SDA     2      3
*  A5/SCL     3      4
*  5V         4      -
*  GND        5      6
*  3V3        -      1
*/

#include <Wire.h>

#define TAG 17 // A3

char* mifare[] = { "1K", "Pro", "UltraLight", "4K", "ProX", "DesFire" };

void setup()
{
 // Init serial port to host and I2C interface to SL018/SL030
 Serial.begin(19200);
 Wire.begin();

 // Flash red led (only on SL018)
 ledOn(true);
 delay(500);
 ledOn(false);

 // Prompt for tag
 Serial.println("Show me your tag");
}

void loop()
{
 // Wait for tag
 while(digitalRead(TAG));

 // Read tag ID
 readID();

 // Wait until tag is gone
 while(!digitalRead(TAG));
}

void ledOn(boolean on)
{
 // Send LED command
 Wire.beginTransmission(0x50);
 Wire.send(2);
 Wire.send(0x40);
 Wire.send(on);
 Wire.endTransmission();
}

int readID()
{
 // Send SELECT command
 Wire.beginTransmission(0x50);
 Wire.send(1);
 Wire.send(1);
 Wire.endTransmission();

 // Wait for response
 while(!digitalRead(TAG))
 {
   // Allow some time to respond
   delay(5);
   
   // Anticipate maximum packet size
   Wire.requestFrom(0x50, 11);
   if(Wire.available())
   {
     // Get length of packet
     byte len = Wire.receive();
     
     // Wait until whole packet is received
     while(Wire.available() < len)
     {
       // Quit if no response before tag left
       if(digitalRead(TAG)) return 0;
     }

     // Read command code, should be same as request (1)
     byte command = Wire.receive();
     if(command != 1) return -1;

     // Read status
     byte status = Wire.receive();
     switch(status)
     {
[b]        [b]case 0: // Succes, read ID and tag type
       {
         len -= 2;
         // Get tag ID
         while(--len)
         {
           byte data = Wire.receive();
           if(data < 0x10) Serial.print(0);
           Serial.print(data, HEX);[/b][/b]
         }
         // Get tag type
         byte type = Wire.receive();
         if(type > 0 && type < sizeof(mifare))
         {
           Serial.print(" Mifare ");
           Serial.print(mifare[type - 1]);
         }
         Serial.println();
       }
       return 1;

     case 0x0A: // Collision
       Serial.println("Collision detected");
       break;

     case 1: // No tag
       Serial.println("No tag found");
       break;

     default: // Unexpected
       Serial.println("Unexpected result");
     }
     return -1;
   }
 }
 // No tag found or no response
 return 0;
}


La mia domanda è, quale modifica apportare a questa parte di codice

 
Code: [Select]
case 0: // Succes, read ID and tag type
       {
         len -= 2;
         // Get tag ID
         while(--len)
         {
           byte data = Wire.receive();
           if(data < 0x10) Serial.print(0);
           Serial.print(data, HEX);



per creare una stringa col contenuto dell' UID (del tipo EF4B34FF) che attualmente viene solo stampato sulla seriale?? L'obiettivo è inviarla successivamente su in UDP su una socket, procedura che già conosco partendo da una variabile di tipo char o string.

Scusatemi la brutalità dell'esempio, ma forse è l'unico modo per darvi un idea chiara del problema.

Grazie a tutti

EDIT by mod: per favore, racchiudi il codice all'interno degli appositi tag code

nid69ita

Secondo te in quanti hanno il tuo hardware per poter testare il tuo codice?
come viene ricevuto l'indirizzo? dal byte di destra o da sinistra?
Code: [Select]

case 0: // Succes, read ID and tag type
        { len -= 2;
          int cnt=0;
          unsigned long ulAddr=0;
          while(--len)           // Get tag ID
          { byte data = Wire.receive();
            if(data < 0x10)
            {  Serial.print(0);
            }
            else
            { Serial.print(data, HEX);
              ulAddr=ulAddr + data<<cnt;  //shift a sinistra di cnt bits, spero
              cnt=cnt+8;                        // indica quanti byte ricevuti, anzi di quanto shiftare a sinistra
            }
         } // alla fine del while ulAddr deve contenere i 4 byte
         String xx=String(ulAddr,HEX);


NON l'ho provato, buttato giù in 2 minuti, probabilmente non corretto. Almeno è uno spunto.
my name is IGOR, not AIGOR

Go Up