Arduino 和 Android Kotlin 上带有 PN532 模块的 NFC P2P
我正在尝试使用 PN532 模块从 Android 向 Arduino 发送字符串消息。当我将智能手机(打开应用程序)靠近模块时,会显示“点击发送”UI,但在我点击屏幕后,手机会告诉我再次靠近两个设备。当我再次接近它们后(屏幕上仍然显示“再次接近设备”消息),没有任何反应,arduino 打印出“失败”。
这是 Kotlin 代码:
package com.cerowski.nfcclient
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.cerowski.nfcclient.databinding.ActivityMainBinding
import com.cerowski.nfcclient.ui.main.SectionsPagerAdapter
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import java.io.File
import java.io.UnsupportedEncodingException
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {config(); sendid();
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = binding.viewPager
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = binding.tabs
tabs.setupWithViewPager(viewPager)
val fab: FloatingActionButton = binding.fab
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
fun config(){
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
var msgtext="";
val msg = TextView (this)
if (dir!=null) {
if (!file.exists()) {msgtext = "config not found, attempting to create..."; file.createNewFile(); if(file.exists()) {msgtext = "config created successfully"; file.writeText(idgenerator())} else {msgtext = "problem creating file"}}
else {msgtext = (file.readText())}
} else {msgtext = "app directory not found"}
}
fun idgenerator() : String {
val allowedChars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..16)
.map { allowedChars.random() }
.joinToString("")
}
fun sendid() {
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
//var bytes = file.readBytes();
//var nfcmsg = NdefMessage(bytes);
//var msgtext="";
var nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter != null) {
val msg: String = file.readText().toString()
val languageCode: ByteArray
val msgBytes: ByteArray
try {
languageCode = "en".toByteArray(charset("US-ASCII"))
msgBytes = msg.toByteArray(charset("UTF-8"))
} catch (e: UnsupportedEncodingException) {
return
}
val messagePayload = ByteArray(
1 + languageCode.size
+ msgBytes.size
)
messagePayload[0] = 0x02.toByte() // status byte: UTF-8 encoding and
// length of language code is 2
// length of language code is 2
System.arraycopy(
languageCode, 0, messagePayload, 1,
languageCode.size
)
System.arraycopy(
msgBytes, 0, messagePayload, 1 + languageCode.size,
msgBytes.size
)
val message: NdefMessage
val records = arrayOfNulls<NdefRecord>(1)
val textRecord = NdefRecord(
NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, byteArrayOf(), messagePayload
)
records[0] = textRecord
message = NdefMessage(records)
nfcAdapter.setNdefPushMessage(message, this);
}
else {Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();}
}
}
这是我的 Arduino Uno 与 PN532 模块的代码(红色的,如果你在线搜索照片):
// Receive a NDEF message from a Peer
// Requires SPI. Tested with Seeed Studio NFC Shield v2
#include "SPI.h"
#include "PN532_SPI.h"
#include "snep.h"
#include "NdefMessage.h"
PN532_SPI pn532spi(SPI, 10);
SNEP nfc(pn532spi);
uint8_t ndefBuf[128];
void setup() {
Serial.begin(9600);
Serial.println("NFC Peer to Peer Example - Receive Message");
}
void loop() {
Serial.println("Waiting for message from Peer");
int msgSize = nfc.read(ndefBuf, sizeof(ndefBuf));
if (msgSize > 0) {
NdefMessage msg = NdefMessage(ndefBuf, msgSize);
msg.print();
Serial.println("\nSuccess");
} else {
Serial.println("Failed");
}
delay(3000);
}
NFC 模块上的小开关位于正确的位置,并且模块连接到板应该是这样的(对于SPI),所以我不知道是什么原因导致它失败。
非常感谢任何帮助。
I am trying to send a string message from Android to Arduino with the PN532 module. When I approach the smartphone (with the app open) to the module, the "tap to beam" UI shows up, but after I tap on the screen, the phone tells me to approach the two devices again. After I approach them again (with the "approach the devices again" message still displayed on the screen), nothing happens and arduino prints out "failed".
Here is the Kotlin code:
package com.cerowski.nfcclient
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.cerowski.nfcclient.databinding.ActivityMainBinding
import com.cerowski.nfcclient.ui.main.SectionsPagerAdapter
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import java.io.File
import java.io.UnsupportedEncodingException
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {config(); sendid();
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = binding.viewPager
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = binding.tabs
tabs.setupWithViewPager(viewPager)
val fab: FloatingActionButton = binding.fab
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
fun config(){
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
var msgtext="";
val msg = TextView (this)
if (dir!=null) {
if (!file.exists()) {msgtext = "config not found, attempting to create..."; file.createNewFile(); if(file.exists()) {msgtext = "config created successfully"; file.writeText(idgenerator())} else {msgtext = "problem creating file"}}
else {msgtext = (file.readText())}
} else {msgtext = "app directory not found"}
}
fun idgenerator() : String {
val allowedChars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..16)
.map { allowedChars.random() }
.joinToString("")
}
fun sendid() {
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
//var bytes = file.readBytes();
//var nfcmsg = NdefMessage(bytes);
//var msgtext="";
var nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter != null) {
val msg: String = file.readText().toString()
val languageCode: ByteArray
val msgBytes: ByteArray
try {
languageCode = "en".toByteArray(charset("US-ASCII"))
msgBytes = msg.toByteArray(charset("UTF-8"))
} catch (e: UnsupportedEncodingException) {
return
}
val messagePayload = ByteArray(
1 + languageCode.size
+ msgBytes.size
)
messagePayload[0] = 0x02.toByte() // status byte: UTF-8 encoding and
// length of language code is 2
// length of language code is 2
System.arraycopy(
languageCode, 0, messagePayload, 1,
languageCode.size
)
System.arraycopy(
msgBytes, 0, messagePayload, 1 + languageCode.size,
msgBytes.size
)
val message: NdefMessage
val records = arrayOfNulls<NdefRecord>(1)
val textRecord = NdefRecord(
NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, byteArrayOf(), messagePayload
)
records[0] = textRecord
message = NdefMessage(records)
nfcAdapter.setNdefPushMessage(message, this);
}
else {Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();}
}
}
And here is the code for my Arduino Uno with the PN532 module (the red one, if you search for photos online):
// Receive a NDEF message from a Peer
// Requires SPI. Tested with Seeed Studio NFC Shield v2
#include "SPI.h"
#include "PN532_SPI.h"
#include "snep.h"
#include "NdefMessage.h"
PN532_SPI pn532spi(SPI, 10);
SNEP nfc(pn532spi);
uint8_t ndefBuf[128];
void setup() {
Serial.begin(9600);
Serial.println("NFC Peer to Peer Example - Receive Message");
}
void loop() {
Serial.println("Waiting for message from Peer");
int msgSize = nfc.read(ndefBuf, sizeof(ndefBuf));
if (msgSize > 0) {
NdefMessage msg = NdefMessage(ndefBuf, msgSize);
msg.print();
Serial.println("\nSuccess");
} else {
Serial.println("Failed");
}
delay(3000);
}
The little switches on the NFC module are in the right positions and the module is connected to the board as it should be (for SPI), So I do not know what is the thing that causes it to fail.
Any help is much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先检查它是否 a) 可用、b) 启用以及 c) 注册和注册。实现回调。在 Java 中:
在
Build.VERSION_CODES.Q
中已弃用意味着仍然可用;也许<=
。这些回调还可能为您提供更多详细信息,甚至失败的原因。
否则,您将发送一条 NDEF 消息,并且它不知道下一步要做什么...
类似地,您也可能能够生成正确的错误消息。
另请参阅: https://developer.android.com/training/beam-files /发送文件
First check if it's even a) available, b) enabled and c) register & implement the callbacks. In Java:
Deprecated in
Build.VERSION_CODES.Q
means still available; maybe<=
.These callbacks might also provide you with more detail, why it even fails.
Else you'll send a NDEF message and it will not know what to do next ...
Alike this you might also be able to produce a proper error message.
Also see: https://developer.android.com/training/beam-files/send-files