Problem with SM130 and Arduino UNO

Hi all, i have recently bougth SM130 module and RFID Evaluation Shield - 13.56MHz to use it with arduino UNO.

The problem is when I pass the MIFARE tag over the antenna nothing happens… the only thing that seem to work is the power led on spakfun board.
I have tested it with sparkfun sample code:

/*
  RFID Eval 13.56MHz Shield example sketch v10
  
  Aaron Weiss, aaron at sparkfun dot com
  OSHW license: http://freedomdefined.org/OSHW
  
  works with 13.56MHz MiFare 1k tags

  Based on hardware v13:
  D7 -> RFID RX
  D8 -> RFID TX
  D9 -> XBee TX
  D10 -> XBee RX
  
  Note: RFID Reset attached to D13 (aka status LED)
  
  Note: be sure include the NewSoftSerial lib, http://arduiniana.org/libraries/newsoftserial/
  
  Usage: Sketch prints 'Start' and waits for a tag. When a tag is in range, the shield reads the tag,
  blinks the 'Found' LED and prints the serial number of the tag to the serial port
  and the XBee port. 

*/
#include <SoftwareSerial.h>

SoftwareSerial rfid(7, 8);

//Prototypes
void check_for_notag(void);
void halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);

//Global var
int flag = 0;
int Str1[11];

//INIT
void setup()  
{
  Serial.begin(9600);
  Serial.println("Start");
  
  // set the data rate for the NewSoftSerial ports
  rfid.begin(19200);
  delay(10);
  halt();
}

//MAIN
void loop()                 
{
  read_serial();
}

void check_for_notag()
{
  seek();
  delay(10);
  parse();
  set_flag();
  
  if(flag = 1){
    seek();
    delay(10);
    parse();
  }
}

void halt()
{
 //Halt tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(147, BYTE);
  rfid.print(148, BYTE);
}

void parse()
{
  while(rfid.available()){
    if(rfid.read() == 255){
      for(int i=1;i<11;i++){
        Str1[i]= rfid.read();
      }
    }
  }
}

void print_serial()
{
  if(flag == 1){
    //print to serial port
    Serial.print(Str1[8], HEX);
    Serial.print(Str1[7], HEX);
    Serial.print(Str1[6], HEX);
    Serial.print(Str1[5], HEX);
    Serial.println();
    delay(100);
    //check_for_notag();
  }
}

void read_serial()
{
  seek();
  delay(10);
  parse();
  set_flag();
  print_serial();
  delay(100);
}

void seek()
{
  //search for RFID tag
  rfid.print(255, BYTE);
  rfid.print(0, BYTE);
  rfid.print(1, BYTE);
  rfid.print(130, BYTE);
  rfid.print(131, BYTE); 
  delay(10);
}

void set_flag()
{
  if(Str1[2] == 6){
    flag++;
  }
  if(Str1[2] == 2){
    flag = 0;
  }
}

And with this code take from http://www.electrojoystick.com/tutorial/?p=659, but program print always “Checksum is bad”:

#include <SoftwareSerial.h>

//setup serial for RFID reader
#define rxPin 3
#define txPin 2
SoftwareSerial rfserial = SoftwareSerial(rxPin, txPin);

//firmware checksum reference
byte firm_chksum = 0x41;

void setup(){
    //set the Serial monitor to preferred baud rate
    Serial.begin(9600);
    //RFID reader is defaulted to 19200 baud rate
    rfserial.begin(19200);

  }

 void loop(){

//read the Firmware
ReadFirmware();
  //delay(2000); //wait for 2 seconds
}

//function for reading the firmware
void ReadFirmware()
{                      
    // checksum checker
    byte chksum_math = 0;
    //firmware command 0x81
    byte ReadFirm[] = {0xFF,0x00,0x01,0x81,0x82};
    //array to hold the incoming data
    byte FirmResponse[12];

    // start of request firmware version
    Serial.println("Requesting Firmware...");

      //Send the firmware command
      for (int i =0; i< 5; i++){
            rfserial.write(ReadFirm[i]);
      }
    //flushing of buffer is required
    Serial.flush();

    //receive data from SM130
    if(rfserial.available() > 0)

      {

        for (int i =0; i< 12; i++){
        //start taking data from rfserial buffer and put into the array
        FirmResponse[i] = rfserial.read();

        //write the response on screen as hex
        Serial.print (FirmResponse[i], HEX);
        //space between each byte
        Serial.print(" ");

           }
       }

       for (int i =1; i<11; i++)
       {
         //add the bytes from the response
         chksum_math +=  FirmResponse[i];

       }
       //what is the checksum??
       Serial.print("Checksum = ");
       Serial.println(chksum_math,HEX);

       //if checksum is good then say it is
       if (firm_chksum == chksum_math){
       Serial.println("Checksum is good");

         //the ascii representation of the firmware
        Serial.println("");
        Serial.println("Ascii Representation");

        //display ascii representation
        for (int i =0; i< 12; i++){

        //write the response on screen
        Serial.write(FirmResponse[i]);
        //space between each byte
        Serial.print(" ");
          }

       }
       else{
         //else say it is not good
         Serial.println("Checksum is bad");

       }

Serial.println("n");
rfserial.flush();
delay(5000);

//end of function
}

How can i check if this is an hardware problem?
Solder SM130 over sparkfun eval board is very simple…so i don’t think the problem is here.

You need to start with telling us which version of the IDE you are using.

    //flushing of buffer is required
    Serial.flush();

Horsecrap!

Hi PaulS, i'm using last version of IDE.

Hi PaulS, i'm using last version of IDE.

In the latest version, serial output is buffered. There is no reason to block, waiting for the outgoing serial buffer to be empty.

So the pieces of code i try is not good for last ide?

How can i check if my SM130 is working?

So the pieces of code i try is not good for last ide?

Maybe, maybe not. There are some stupid things being done in both sketches. Fixed delays, flushing the serial buffer, etc.

In either of the sketches, you can add Serial.print()/Serial.println() statements to see what is happening. When you scan a tag, is there ever a reply from the reader? There appear to be several LEDs on the device. Do any of them light up when you scan a tag?

Do you know that your tags are the right kind for that reader?

No, no one leds light up...

I think tag is the correct one, tag i'm using is this .

Ok now it seems to work, when i send seek command the "search" led light up. The problem is the antenna does'nt detect any MIFARE 1K tag... how can i check if antenna is ok?

Ok missing one capacitor on antenna connection…

Hi, I have the same problem. What have you done to solve it? I'm using arduino uno with IDE 1.0.3 Thanks, Luca

Due to the interest of many (private message) to the SM130 I write here is my code used with Arduino.
I should add that the code has been used with success but not completed because later on I decided to build my own prototyping platform based on PICmicro.

My piece of code:

#include <Wire.h>
#include <SoftwareSerial.h>

#define CMD_NO_DATA 0x00
#define CMD_ERROR 0xFF
#define CMD_RESET 0x80
#define CMD_READ_FMW 0x81
#define CMD_SEEK 0x82
#define CMD_SELECT_TAG 0x83
#define CMD_AUTHENTICATE 0x85
#define CMD_READ_BLOCK 0x86
#define CMD_WRITE_BLOCK 0x89
#define CMD_HALT_TAG 0x93
#define CMD_BAUDRATE 0x94
#define SM130_BUFF_SIZE 22

#define SM130 0x55
//#define I2C

#define READ
//#define WRITE

SoftwareSerial rfid(7,8);

int waitForResponse(unsigned char cmd, unsigned char* response, unsigned int timeout=3000){
	int size=0;
	unsigned int t=millis();
	unsigned char cs=0;
#ifdef I2C
	// Wait for data incoming
	int length=0;
	while(length<=0){
		Wire.requestFrom(SM130, 1, false);
		length=Wire.read();
		if((int)millis()-t>timeout) return -1;
	}
	Serial.println(length, DEC);
	Wire.requestFrom(SM130, length);
	// Parse incoming data
	while(Wire.available()&&size<length){
		response[size]=Wire.read();
		cs+=response[size];
		size++;
	}
	Wire.endTransmission(false);
	// Only if checksum is correct and this is
	// a response to cmd then data is correct
	if(response[1]!=cmd) return -1;
	if(cs!=response[size-1]) return -1;
	return size;
#else	
	// Wait for data incoming
	while(rfid.available()==0){
		if((int)millis()-t>timeout) return -1;
	}
	// Parse incoming data
	while(rfid.available()&&size<SM130_BUFF_SIZE){
		response[size]=rfid.read();
		if(size>=2&&size<=2+response[2]) cs+=response[size];
		size++;
	}
	// Only if checksum is correct and this is
	// a response to cmd then data is correct
	if(response[3]!=cmd) return -1;
	if(cs!=response[size-1]) return -1;
	return size;
#endif
}

int readFirmware(char* firmware){
	char command[5]={0};
	unsigned char response[18]={0};
	sm130Write(command, CMD_READ_FMW, (char*)0, 0);
	if(waitForResponse(CMD_READ_FMW, response)>0){
		memcpy(firmware, &response[4], response[2]-1);
		firmware[(int)response[2]-1]='\0';
	}
	return response[2];
}

bool setBaudrate(unsigned char br){
	char command[6]={0};
	unsigned char response[22]={0};
	char cmdData[1];
	cmdData[0]=br; 
	sm130Write(command, CMD_BAUDRATE, cmdData, 1);
	if(waitForResponse(CMD_BAUDRATE, response)>0){
		return response[4];
	}
	return 0x4F;
}

unsigned char halt(){
	char command[5]={0};
	unsigned char response[6]={0};
	sm130Write(command, CMD_HALT_TAG, (char*)0, 0);
	if(waitForResponse(CMD_HALT_TAG, response)>0){
		return response[4];
	}
	return 0x56;
}

unsigned char authenticate(unsigned char bn, unsigned char keyMode=0xFF, unsigned char* key=NULL){
	size_t l=0;
	char command[12]={0};
	unsigned char response[6]={0};
	char data[8];
	data[l++]=bn; 
	data[l++]=keyMode;
	if(key){	 
		data[l++]=key[0];
		data[l++]=key[1];
		data[l++]=key[2];
		data[l++]=key[3];
		data[l++]=key[4];
		data[l++]=key[5];
	}
	sm130Write(command, CMD_AUTHENTICATE, data, l);
	if(waitForResponse(CMD_AUTHENTICATE, response)>0){
		return response[4];
	}
	return 0x56;
}

bool readBlock(unsigned char bn, char* data){
	char command[6]={0};
	unsigned char response[22]={0};
	char cmdData[1];
	cmdData[0]=bn; 
	sm130Write(command, CMD_READ_BLOCK, cmdData, 1);
	if(waitForResponse(CMD_READ_BLOCK, response)>0){
		if(response[2]==2){
			data[0]=response[4];
			return false;
		}
		// Skip block number byte too
		memcpy(data, &response[5], 16);
		return true;
	}
	return false;
}

bool writeBlock(unsigned char bn, char* data){
	char command[22]={0};
	unsigned char response[22]={0};
	char cmdData[17];
	cmdData[0]=bn;
	memcpy(&cmdData[1], data, 16);
	sm130Write(command, CMD_WRITE_BLOCK, cmdData, 17);
	if(waitForResponse(CMD_WRITE_BLOCK, response)>0){
		if(response[2]>2) return true;
	}
	return false;
}

/*
	Read all data block.
	data must be 752 size.
	Operation is successful if 47 blocks have been read.
*/
int readAllData(char* data, unsigned char keyMode=0xFF, unsigned char* key=NULL){
	size_t index=0;
	int ok=0;
	for(int i=1; i<64; i++){
		if((i+1)%4==0) continue; // Skip keys block
		if(i%4==0||i==1){
			authenticate(i, keyMode, key); // Authenticate each sector
		}
		if(readBlock(i, &data[16*index])){
			ok++;
		}
		index++;
	}
	return ok;
}

bool seek(){
	char command[5]={0};
	unsigned char response[12]={0};
	sm130Write(command, CMD_SEEK, (char*)0, 0);
	return waitForResponse(CMD_SEEK, response)>0;
}

bool selectTag(){
	char command[5]={0};
	unsigned char response[12]={0};
	sm130Write(command, CMD_SELECT_TAG, (char*)0, 0);
	return waitForResponse(CMD_SELECT_TAG, response)>0;
}

/*
	Read data from SM130 and return COMMAND that generate data
*/
unsigned char sm130Read(unsigned char* response){
	int i=0;
	unsigned char cs=0;
#ifdef I2C
	Wire.requestFrom(SM130, SM130_BUFF_SIZE);
	while(Wire.available()&&i<SM130_BUFF_SIZE){		
		response[i]=Wire.read();
#else
	while(rfid.available()&&i<SM130_BUFF_SIZE){
		response[i]=rfid.read();
#endif
		if(i>=2&&i<=2+response[2]) cs+=response[i];
		i++;
	}
	if(i==0) return CMD_NO_DATA;
	if(cs!=response[i-1]) return CMD_ERROR;
	return response[3];
}

/*
	Write command to SM130 and return bytes count wrote.
*/
size_t sm130Write(char* command, unsigned char cmd, char* data, size_t dataLength){
	size_t i=4;
	command[0]=0xFF;
	command[1]=0x00;
	command[2]=dataLength+1;
	command[3]=cmd;
	if(data&&dataLength){
		memcpy(&command[i], data, dataLength);
		i+=dataLength;
	}
	command[i]=calcChecksum(command, i);
#ifdef I2C
	Wire.beginTransmission(SM130);
	size_t ret= Wire.write((uint8_t*)command[2], i+1);
	Wire.endTransmission();
	return ret;
#else
	return rfid.write((uint8_t*)command, i+1);
#endif
}

unsigned char calcChecksum(char* data, size_t length){
	unsigned char cs=0;
	size_t i;
	// Skip first 2 bytes
	for(i=2; i<length; i++){
		cs+=data[i];
	}
	return cs;
}

bool needWrite=true;

void setup()  
{
	Serial.begin(9600);
#ifdef I2C
	Wire.begin();
#else
	rfid.begin(19200);
#endif
	delay(100);
	char firmware[16]={0};
	if(readFirmware(firmware)) Serial.println(firmware);
	halt();
	delay(2000);
	seek();
}

void loop()                 
{
	unsigned char response[SM130_BUFF_SIZE]={0};
	unsigned char cmd=sm130Read(response);
	if(cmd==CMD_ERROR){
		Serial.println("Command ERROR");
		delay(3000);
		seek();
	}
	else if(cmd==CMD_SEEK){
		if(response[2]>2){
			switch(response[4]){
				case 0x01: 
					Serial.print("MIFARE Ultralight ");
					break;
				case 0x02: 
					Serial.print("MIFARE 1K ");
					break;
				case 0x03: 
					Serial.print("MIFARE 4K ");
					break;
				case 0xFF: 
					Serial.print("Unknown Type ");
					break;
			}
			size_t l=response[2]-2;
			while(l--){
				Serial.print(response[5+l], HEX);
			}
			Serial.println(' ');
			delay(1000);
			seek();
		}
	}
}

I just compile the last code and upload to the Arduino and it'ś works.

The next step I think it’s to dump all the card to a file by serial.