2019-03-19 04:07 AM
We've connected CR95HF with arduino uno via UART but it seems to give random outputs on the serial monitor.
The arduino code:
#include <SoftwareSerial.h>
SoftwareSerial BTserial(4, 5);
void setup() {
// put your setup code here, to run once:
pinMode(5,OUTPUT);
digitalWrite(5,HIGH);
delay(5000);
digitalWrite(5,LOW);
delay(250);
digitalWrite(5,HIGH);
delay(200);
BTserial.begin(57600);
Serial.begin(9600);
BTserial.write(0x55);
Serial.println(BTserial.read());
BTserial.write(0x55);
Serial.println(BTserial.read());
BTserial.write(0x55);
Serial.println(BTserial.read());
BTserial.write(0x55);
Serial.println(BTserial.read());
BTserial.write(0x55);
Serial.println(BTserial.read());
delay(1000);
BTserial.write(0x01);
BTserial.write((byte)0x00);
Serial.println(BTserial.read());
delay(1000);
BTserial.write(0x02);
BTserial.write(0x02);
BTserial.write(0x01);
BTserial.write(0x0D);
Serial.println(BTserial.read());
delay(1000);
}
void loop() {
BTserial.write(0x04);
BTserial.write(0x03);
BTserial.write(0x26);
BTserial.write(0x01);
BTserial.write((byte)0x00);
Serial.println(BTserial.read());
delay(1000);
}
The Serial Monitor:
2019-03-23 02:04 PM
Hi,
the UART should use the following parameters:
Make sure to properly follow the startup sequence as described in the CR95HF Datasheet § 3.2:
On my side, I use the following startup sequence (delay unit is ms)
Init:
retry = 5
Send_nIRQ_IN_Pulse
while (Send_Echo == Error) && (retry --!= 0);
if retry ==0
abort
End_init
Send_nIRQ_IN_Pulse
/* Start up sequence */
Delay(1); /* wait t0 */
/* Send null char to have nIRQ_IN/UART_TX low for more than 10µs (t1) */
UartTx(0x00)
Delay(11); /* wait t3 */
End_Send_nIRQ_IN_Pulse:
Let me know if this solve your issue.
Rgds
BT
2019-04-02 01:59 PM
@Brian TIDAL_O I don't think so it solved much.
New Code:
#include <SoftwareSerial.h>
SoftwareSerial BTserial(4, 5);
void setup() {
BTserial.begin(57600);
Serial.begin(9600);
// put your setup code here, to run once:
delay(1);
BTserial.write((byte)0x00);
delay(11);
delay(2000);
BTserial.write(0x55);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
BTserial.write(0x55);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
BTserial.write(0x55);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
Serial.println(BTserial.read());
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
BTserial.write(0x55);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
BTserial.write(0x55);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
delay(1000);
BTserial.write(0x02);
BTserial.write(0x02);
BTserial.write(0x02);
BTserial.write(0x01);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
delay(1000);
}
void loop() {
BTserial.write(0x04);
BTserial.write(0x02);
BTserial.write(0x26);
BTserial.write(0x07);
if (BTserial.available()){
float c = BTserial.read();
Serial.println(c);
}
delay(1000);
}
Serial Monitor:
can you help me out with a working library for arduino?
2019-04-02 03:54 PM
Hi,
would you please share more details about your HW setup:
I am not sure to understand why you are using float to read the CR95HF UART output.
From what I can see in your serial monitor trace:
So from what I see, the UART is working properly. You have to fix the ProtocolSelect command (e.g 02020200h) and fix the reception of command response:
Note: you don't need to repeat the sending of echo command when you receive a correct answer. As soon as you get 0x55 answer, you can exit the initialization phase and go to the main job.
Rgds
BT
2019-05-05 08:21 PM
I'm using a BM019 board now for evaluation purpose. The board is connected via SPI with a ESP8266 mod - Nodemcu board. The Inventory command runs for a few cycles and then anomalies stars to follow. We're coding using Arduino IDE. Here's my code:
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
const int SSPin = 4; // Slave Select pin
const int IRQPin = 5; // Sends wake-up pulse
byte TXBuffer[40]; // transmit buffer
byte RXBuffer[40]; // receive buffer
byte NFCReady = 0; // used to track NFC state
void setup() {
pinMode(IRQPin, OUTPUT);
digitalWrite(IRQPin, HIGH); // Wake up pulse
pinMode(SSPin, OUTPUT);
digitalWrite(SSPin, HIGH);
Serial.begin(9600);
Serial.println("Started");
SPI.begin();
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32);
// The CR95HF requires a wakeup pulse on its IRQ_IN pin
// before it will select UART or SPI mode. The IRQ_IN pin
// is also the UART RX pin for DIN on the BM019 board.
delay(10); // send a wake up
digitalWrite(IRQPin, LOW); // pulse to put the
delayMicroseconds(100); // BM019 into SPI
digitalWrite(IRQPin, HIGH); // mode
delay(10);
}
/* IDN_Command identifies the CR95HF connected to the Arduino.
This requires three steps.
1. send command
2. poll to see if CR95HF has data
3. read the response
If the correct response is received the serial monitor is used
to display the CR95HF ID number and CRC code. This rountine is
not that useful in using the NFC functions, but is a good way to
verify connections to the CR95HF.
*/
void IDN_Command()
{
byte i = 0;
// step 1 send the command
digitalWrite(SSPin, LOW);
SPI.transfer(0); // SPI control byte to send command to CR95HF
SPI.transfer(1); // IDN command
SPI.transfer(0); // length of data that follows is 0
digitalWrite(SSPin, HIGH);
delay(1);
// step 2, poll for data ready
// data is ready when a read byte
// has bit 3 set (ex: B'0000 1000')
digitalWrite(SSPin, LOW);
while(RXBuffer[0] != 8)
{
RXBuffer[0] = SPI.transfer(0x03); // Write 3 until
RXBuffer[0] = RXBuffer[0] & 0x08; // bit 3 is set
}
digitalWrite(SSPin, HIGH);
delay(1);
// step 3, read the data
digitalWrite(SSPin, LOW);
SPI.transfer(0x02); // SPI control byte for read
RXBuffer[0] = SPI.transfer(0); // response code
RXBuffer[1] = SPI.transfer(0); // length of data
for (i=0;i<RXBuffer[1];i++)
RXBuffer[i+2]=SPI.transfer(0); // data
digitalWrite(SSPin, HIGH);
delay(1);
if ((RXBuffer[0] == 0) & (RXBuffer[1] == 15))
{
Serial.println("IDN COMMAND-"); //
Serial.print("RESPONSE CODE: ");
Serial.print(RXBuffer[0]);
Serial.print(" LENGTH: ");
Serial.println(RXBuffer[1]);
Serial.print("DEVICE ID: ");
for(i=2;i<(RXBuffer[1]);i++)
{
Serial.print(RXBuffer[i],HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.print("ROM CRC: ");
Serial.print(RXBuffer[RXBuffer[1]],HEX);
Serial.print(RXBuffer[RXBuffer[1]+1],HEX);
Serial.println(" ");
}
else
Serial.println("BAD RESPONSE TO IDN COMMAND!");
Serial.println(" ");
}
/* SetProtocol_Command programs the CR95HF for
ISO/IEC 15693 operation.
This requires three steps.
1. send command
2. poll to see if CR95HF has data
3. read the response
If the correct response is received the serial monitor is used
to display successful programming.
*/
void SetProtocol_Command()
{
byte i = 0;
// step 1 send the command
digitalWrite(SSPin, LOW);
SPI.transfer(0x00); // SPI control byte to send command to CR95HF
SPI.transfer(0x02); // Set protocol command
SPI.transfer(0x02); // length of data to follow
SPI.transfer(0x01); // code for ISO/IEC 15693
SPI.transfer(0x0D); // Wait for SOF, 10% modulation, append CRC
digitalWrite(SSPin, HIGH);
delay(1);
// step 2, poll for data ready
digitalWrite(SSPin, LOW);
while(RXBuffer[0] != 8)
{
RXBuffer[0] = SPI.transfer(0x03); // Write 3 until
RXBuffer[0] = RXBuffer[0] & 0x08; // bit 3 is set
}
digitalWrite(SSPin, HIGH);
delay(1);
// step 3, read the data
digitalWrite(SSPin, LOW);
SPI.transfer(0x02); // SPI control byte for read
RXBuffer[0] = SPI.transfer(0); // response code
RXBuffer[1] = SPI.transfer(0); // length of data
digitalWrite(SSPin, HIGH);
if ((RXBuffer[0] == 0) & (RXBuffer[1] == 0))
{
Serial.println("PROTOCOL SET-"); //
NFCReady = 1; // NFC is ready
}
else
{
Serial.println("BAD RESPONSE TO SET PROTOCOL");
NFCReady = 0; // NFC not ready
}
Serial.println(" ");
}
/* Inventory_Command chekcs to see if an RF
tag is in range of the BM019.
This requires three steps.
1. send command
2. poll to see if CR95HF has data
3. read the response
If the correct response is received the serial monitor is used
to display the the RF tag's universal ID.
*/
void Inventory_Command()
{
byte i = 0;
// step 1 send the command
digitalWrite(SSPin, LOW);
SPI.transfer(0x00); // SPI control byte to send command to CR95HF
SPI.transfer(0x04); // Send Receive CR95HF command
SPI.transfer(0x03); // length of data that follows is 0
SPI.transfer(0x26); // request Flags byte
SPI.transfer(0x01); // Inventory Command for ISO/IEC 15693
SPI.transfer(0x00); // mask length for inventory command
digitalWrite(SSPin, HIGH);
delay(1);
// step 2, poll for data ready
// data is ready when a read byte
// has bit 3 set (ex: B'0000 1000')
digitalWrite(SSPin, LOW);
while(RXBuffer[0] != 8)
{
RXBuffer[0] = SPI.transfer(0x03); // Write 3 until
RXBuffer[0] = RXBuffer[0] & 0x08; // bit 3 is set
}
digitalWrite(SSPin, HIGH);
delay(1);
// step 3, read the data
digitalWrite(SSPin, LOW);
SPI.transfer(0x02); // SPI control byte for read
RXBuffer[0] = SPI.transfer(0); // response code
RXBuffer[1] = SPI.transfer(0); // length of data
for (i=0;i<RXBuffer[1];i++)
RXBuffer[i+2]=SPI.transfer(0); // data
digitalWrite(SSPin, HIGH);
delay(1);
if (RXBuffer[0] == 128)
{
Serial.println("TAG DETECTED");
Serial.print("UID: ");
for(i=11;i>=4;i--)
{
Serial.print(RXBuffer[i],HEX);
Serial.print(" ");
}
Serial.println(" ");
delay(500);
}
else
{
Serial.print("NO TAG IN RANGE - ");
Serial.print("RESPONSE CODE: ");
Serial.println(RXBuffer[0],HEX);
}
Serial.println(" ");
}
void loop() {
if(NFCReady == 0)
{
IDN_Command(); // reads the CR95HF ID
delay(1000);
SetProtocol_Command(); // ISO 15693 settings
delay(1000);
}
else
{
Inventory_Command();
delay(100);
}
}
Here's the Serial Monitor:
2019-05-06 02:39 PM
Hi,
1/ you should reset the value of RXBuffer[0] before each while polling loops otherwise you will have unexpected results as the previous content of the buffer will be used for the test...
RXBuffer[0] = 0;
while(RXBuffer[0] != 8)
{
RXBuffer[0] = SPI.transfer(0x03); // Write 3 until
RXBuffer[0] = RXBuffer[0] & 0x08; // bit 3 is set
}
2/ the RXBuffer size should be large enough to receive the maximum frame size (528 bytes: see ST25R95 Datasheet § 4.3)
3/ the length computation should follow §4.3 of the ST25R95 Datasheet
4/ For every command (i.e. IDN, ProtocolSelect, etc.) you should read the data according to the length value
5/ I would recommend to use a dedicated function for SPI polling and for reading the result of a command. This would simplify the code structure and would avoid copy of code.
Rgds
BT
2019-05-11 12:40 AM
Did all the changes you suggested, still the problem exists. This code was written for an Arduino UNO and it works absolutely well with it as we have tested it with an UNO as well. But with Nodemcu this problem follows. Kindly help me out with the full code to solve this problem as we've already bought 50 CR9fHF chips and we have to make it work with a Nodemcu.
2019-05-12 01:04 PM
Hi,
would you please share details about your hardware setup:
would you please share your code and the traces when the problem occurs?
If you are using SPI, can you try to replace the SPI polling mechanism by an IRQ_OUT polling (i.e just read the IRQ_OUT value until it goes low)?
Can you try to put a logic analyzer on the interface (if using SPI, make sure to trace MOSI/MISO/SCLK/SS and IRQ_OUT)
Thanks
BT
2019-07-09 09:42 AM
Hi,
I dont know if this thread is still active but currently I'm working in a project with the same sensor (BM019). The official code for Arduino works great on Arduino Uno, but unfortunately not on a ESP8266 and I think is something related with the SPI. The clock speed is in Arduino 16Mhz and as I set the following:
SPI.setClockDivider(SPI_CLOCK_DIV32)
The speed for the bus would be 500Khz. In the esp8266 I think the speed is 80Mhz, but I set the speed manually with this:
SPI.beginTransaction(SPISettings(15000, MSBFIRST, SPI_MODE0)); //15khz
I think that this sensor dont handle high speeds I dont find the threshold on the datasheet, despite that apperently change clock speeds in esp8266 doesnt seems to affect the behavior. I made a couple of tests with a logic analyzer and got a weird behavior for the ESP.
And this is the correct behavior for the Arduino
Apart from the clock speed, looks like works completly different on the ESP, my first thought was that the data overlap because of the default high speed of the ESP but seems that do the same at any speed.
Thanks in advice
2019-07-10 04:48 AM
Hi,
I would suggest to create a new thread as this one was initially related to an UART communication issue. Please make sure to describe your HW setup (i.e. ESP8266 MCU connected to BM019 module over SPI), the serial communication setup and your SW setup.
Regarding your question about the SPI clock frequency, the max value is defined in the CR95HF Datasheet: 2.0 MHz. Make sure to check the various SPI parameters as defined in §6.4 SPI characteristics of the Datasheet.
I had a look to the screen shots: I believe the logic analyzer is not properly configured as the MOSI and MISO values do not make any sense. Make sure to trace SCK, MISO, MISO, SPI_SS, IRQ_IN, IRQ_OUT and to provide the logic analyzer channel configuration (i.e. what is D4, what is D5, etc.). If possible, attach the logic analyzer log file rather than screen shots. Which logic analyzer do you use?
The typical startup sequence is to send a echo command, receive the echo answer and then send an IDN command:
MOSI 00 55 02 XX 00 01 00 02 XX XX XX XX XX XX XX XX XX XX XX XX ...
MISO XX XX XX 55 XX XX XX XX 00 0F 4E 46 43 20 46 53 32 4A 41 53 ...
IRQ_OUT -------------______------------------------------_________________________________________ ...
ECHO IDN
ECHO RSP IDN RSP
Rgds
BT