Hi, so I have looked through a lot of the Arduino forums and some of which have been helpful and others not so much. I am trying to transfer data from my arduino uno r4 wifi to my xcode project through my HM-10 XC4382 BLE Bluetooth Module. I am trying to essentially scan an RFID tag and transmit the name and UUID to the phone app to acknowledge the tag has been scanned.
Every time I connect to my HM-10 module successfully on my phone but when I try and print the message it shows up as empty. When trying to debug it does show the statement when I scan the RFID tag each time which tells me it is being received but perhaps the format is not compatible with Xcode? Would appreciate any assistance
I have both arduino code and swift code. In my arduino code, I am working with RFID Scanner (from Jaycar) using the MFRC522 library and is connected the following ways:
Apologies if I may have missed some code / context to this question. Thank you!
RFID Module Setup
3.3V - 3.3V
RST - 9
GND - GND
MISO - 12
MOSI - 11
SCK - 13
SDA - 10
HM-10 Setup
5V - 5V
GND - GND
RX - TX (arduino)
TX - RX (arduino)
Current Arduino Code
#include <SoftwareSerial.h> // for the Bluetooth module
#include <MFRC522.h> // for the RFID module
#define SS_PIN 10
#define RST_PIN 9
String uidString;
MFRC522 rfid(SS_PIN, RST_PIN);
SoftwareSerial BLE_Serial(0, 1); // RX, TX
void setup() {
Serial.begin(9600);
BLE_Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial.println("Waiting for command...");
BLE_Serial.println("Waiting for command...");
}
void loop() {
if (rfid.PICC_IsNewCardPresent()) {
readRFID();
}
if (BLE_Serial.available()) {
char data = BLE_Serial.read();
// Serial.println("Hello I am debug");
if (rfid.PICC_IsNewCardPresent()) {
readRFID();
}
else {
// Serial.println("I am not connected to Bluetooth");
}
delay(10);
}
}
void readRFID() {
rfid.PICC_ReadCardSerial();
Serial.print("Tag UID: ");
uidString = String(rfid.uid.uidByte[0]) + " " + String(rfid.uid.uidByte[1]) + " " +
String(rfid.uid.uidByte[2]) + " " + String(rfid.uid.uidByte[3]);
Serial.println(uidString);
boolean authorized = false;
char *name = "";
if (uidString == "220 223 30 204") {
authorized = true;
name = "KeyCard";
}
if (uidString == "243 154 6 14") {
authorized = true;
name = "Bagtag";
}
if (uidString == "118 211 198 33") {
authorized = true;
name = "George";
}
if (authorized) {
char message[50];
sprintf(message, "You have successfully scanned %s", name);
Serial.print("Message: ");
Serial.println(message);
BLE_Serial.print(message);
BLE_Serial.write((char)0); // add null character at the end of the message
delay(200);
}
}
My current Swift Code: Utilising Bluetooth Serial Delegate Method & CoreBluetooth
//
// ScanCompleteViewController.swift
// Clutch-IDS
//
// Created by Joshua Dinkin on 16/4/2024.
//
import Foundation
import UIKit
import CoreBluetooth
import QuartzCore
enum ReceivedMessageOption: String {
case none,
newline
}
class ScanCompleteViewController: UIViewController, BluetoothSerialDelegate, CBPeripheralDelegate {
@IBOutlet weak var mainTextView: UITextView!
@IBOutlet weak var mainLabel: UILabel!
@IBOutlet weak var barButton: UIButton!
@IBOutlet weak var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// init serial
serial = BluetoothSerial(delegate: self)
// UI
mainLabel.text = ""
mainLabel.numberOfLines = 0
reloadView()
NotificationCenter.default.addObserver(self, selector: #selector(ScanCompleteViewController.reloadView), name: NSNotification.Name(rawValue: "reloadStartViewController"), object: nil)
}
@objc func reloadView() {
// in case we're the visible view again
serial.delegate = self
if serial.isReady {
titleLabel.text = serial.connectedPeripheral!.name
barButton.setTitle("Disconnect", for: .normal)
barButton.setTitleColor(.red, for: .normal)
barButton.isEnabled = true
} else if serial.centralManager.state == .poweredOn {
titleLabel.text = "Bluetooth Serial"
barButton.setTitle("Connect", for: .normal)
barButton.setTitleColor(view.tintColor, for: .normal)
barButton.isEnabled = true
} else {
titleLabel.text = "Bluetooth Serial"
barButton.setTitle("Connect", for: .normal)
barButton.setTitleColor(view.tintColor, for: .normal)
barButton.isEnabled = false
}
}
func textViewScrollToBottom() {
let range = NSMakeRange(NSString(string: mainTextView.text).length - 1, 1)
mainTextView.scrollRangeToVisible(range)
}
//MARK: BluetoothSerialDelegate
func serialDidReceiveString(_ message: String) {
// add the received text to the textView, optionally with a line break at the end
mainLabel.text! += message
if let pref = UserDefaults.standard.string(forKey: ReceivedMessageOptionKey) {
mainLabel.text! += "\n"
}
textViewScrollToBottom()
print("Received message: \(message)")
print(UserDefaults.standard.string(forKey: ReceivedMessageOptionKey))
//print("This is the \(message)")
// print(UserDefaults.standard.string(forKey: ReceivedMessageOptionKey))
// print(mainLabel.text)
}
func serialDidDisconnect(_ peripheral: CBPeripheral, error: NSError?) {
reloadView()
let hud = MBProgressHUD.showAdded(to: view, animated: true)
hud?.mode = MBProgressHUDMode.text
hud?.labelText = "Disconnected"
hud?.hide(true, afterDelay: 1.0)
}
func serialDidChangeState() {
reloadView()
if serial.centralManager.state != .poweredOn {
let hud = MBProgressHUD.showAdded(to: view, animated: true)
hud?.mode = MBProgressHUDMode.text
hud?.labelText = "Bluetooth turned off"
hud?.hide(true, afterDelay: 1.0)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
print("Error reading characteristics: \(error)")
return
}
if let value = characteristic.value {
if let dataBLE = String(data: value, encoding: .utf8) {
print("Data from Arduino: \(dataBLE)")
DispatchQueue.main.async {
self.mainLabel.text = dataBLE
}
} else {
print("Failed to convert data to string")
}
}
}
@IBAction func buttonPressed(_ sender: Any) {
if serial.connectedPeripheral == nil {
performSegue(withIdentifier: "ShowScanner", sender: self)
} else {
serial.disconnect()
reloadView()
}
}
}