Swift 3 arduino Uno HM-10 Ble - iphone 通知

瓦伦潘查尔

我已经为 ios 制作了一个应用程序,它连接到 BLE(Arduino uno 上的 HM-10)。有连接到 Arduino 的温度、光线和湿度传感器。问题是,iPhone 显示的数据与它在 Arduino 串行显示器上显示的数据相同。而我希望在单击“温度按钮”时显示温度传感器数据,并且对于每个其他传感器也是如此。我无法弄清楚的另一件事是,如果应用程序没有运行以防温度升高,我想要通知。下降到某个点。我该怎么做

请帮忙!!

这是Arduino代码(是否可以在一行中打印数据而不是在新行中一次又一次地打印)

int sensePin = A1;  //This is the Arduino Pin that will control Relay #1
int sensorValue = 0;    //The variable we will use to store the sensor input
//int sensePin = A0;  //This is the Arduino Pin that will control Relay #1
int sensorInput;    //The variable we will use to store the sensor input
double temp; 


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); //Start the Serial Port at 9600 baud (default)

}
void loop() {
  // put your main code here, to run repeatedly: 
  sensorValue = analogRead(A1);    //read the analog sensor and store it

  sensorInput = analogRead(A0);    //read the analog sensor and store it
  temp = (double)sensorInput / 1024;       //find percentage of input reading
  temp = temp * 5;                 //multiply by 5V to get voltage
  temp = temp - 0.5;               //Subtract the offset 
  temp = temp * 100;               //Convert to degrees 


  if (temp > 28 ) {
   Serial.print("Current Temp is hot i.e.: ");
   Serial.println(temp);
  }

  else if (temp < 28) {
    Serial.print("Current Temp is cold i.e.: ");
    Serial.println(temp);
  }
   else{
    Serial.print("Current Temp: ");
    Serial.println(temp);
    }

if (sensorValue > 70 ) {
   Serial.print("Current Light is high i.e.: ");
   Serial.println(sensorValue);
  }

  else if (sensorValue < 60) {
    Serial.print("Current Light is low i.e.: ");
    Serial.println(sensorValue);
  }
   else{
    Serial.print("Light seems good: ");
    Serial.println(sensorValue);
    }


  //Serial.print("Current Temp: ");

  //Serial.println(temp);

  //Serial.print("Current Light: ");
  //Serial.println(sensorValue);

  //Serial.end();
  delay(10000);
}

这是Iphone代码

import UIKit
import CoreBluetooth
import QuartzCore

/// The option to add a \n or \r or \r\n to the end of the send message
enum MessageOption: Int {
    case noLineEnding,
         newline,
         carriageReturn,
         carriageReturnAndNewline
}

/// The option to add a \n to the end of the received message (to make it more readable)
enum ReceivedMessageOption: Int {
    case none,
         newline
}

final class SerialViewController: UIViewController, UITextFieldDelegate, BluetoothSerialDelegate {

//MARK: IBOutlets

    @IBOutlet weak var mainTextView: UITextView!

    @IBOutlet weak var messageField: UITextField!
    @IBOutlet weak var bottomView: UIView!
    @IBOutlet weak var bottomConstraint: NSLayoutConstraint! // used to move the textField up when the keyboard is present
    @IBOutlet weak var barButton: UIBarButtonItem!
    @IBOutlet weak var navItem: UINavigationItem!




//MARK: Functions

    override func viewDidLoad() {
        super.viewDidLoad()

        // init serial
        serial = BluetoothSerial(delegate: self)

        // UI
        mainTextView.text = ""
        reloadView()

        NotificationCenter.default.addObserver(self, selector: #selector(SerialViewController.reloadView), name: NSNotification.Name(rawValue: "reloadStartViewController"), object: nil)

        // we want to be notified when the keyboard is shown (so we can move the textField up)
        NotificationCenter.default.addObserver(self, selector: #selector(SerialViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(SerialViewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

        // to dismiss the keyboard if the user taps outside the textField while editing
        let tap = UITapGestureRecognizer(target: self, action: #selector(SerialViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)

        // style the bottom UIView
        bottomView.layer.masksToBounds = false
        bottomView.layer.shadowOffset = CGSize(width: 0, height: -1)
        bottomView.layer.shadowRadius = 0
        bottomView.layer.shadowOpacity = 0.5
        bottomView.layer.shadowColor = UIColor.gray.cgColor


    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    func keyboardWillShow(_ notification: Notification) {
        // animate the text field to stay above the keyboard
        var info = (notification as NSNotification).userInfo!
        let value = info[UIKeyboardFrameEndUserInfoKey] as! NSValue
        let keyboardFrame = value.cgRectValue

        //TODO: Not animating properly
        UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions(), animations: { () -> Void in
            self.bottomConstraint.constant = keyboardFrame.size.height
            }, completion: { Bool -> Void in
            self.textViewScrollToBottom()
        })
    }

    func keyboardWillHide(_ notification: Notification) {
        // bring the text field back down..
        UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions(), animations: { () -> Void in
            self.bottomConstraint.constant = 0
        }, completion: nil)

    }

    func reloadView() {
        // in case we're the visible view again
        serial.delegate = self

        if serial.isReady {
            navItem.title = serial.connectedPeripheral!.name
            barButton.title = "Disconnect"
            barButton.tintColor = UIColor.red
            barButton.isEnabled = true
        } else if serial.centralManager.state == .poweredOn {
            navItem.title = "Bluetooth Serial"
            barButton.title = "Connect"
            barButton.tintColor = view.tintColor
            barButton.isEnabled = true
        } else {
            navItem.title = "Bluetooth Serial"
            barButton.title = "Connect"
            barButton.tintColor = view.tintColor
            barButton.isEnabled = false
        }
    }

    func textViewScrollToBottom() {
        let range = NSMakeRange(NSString(string: mainTextView.text).length - 1, 1)
        mainTextView.scrollRangeToVisible(range)
        //mainTextView.text = "";
    }


//MARK: BluetoothSerialDelegate

    func serialDidReceiveString(_ message: String) {
        // add the received text to the textView, optionally with a line break at the end
        mainTextView.text! += message
        let pref = UserDefaults.standard.integer(forKey: ReceivedMessageOptionKey)
        if pref == ReceivedMessageOption.newline.rawValue { mainTextView.text! += "\n" }
        textViewScrollToBottom()

    }

    func serialDidDisconnect(_ peripheral: CBPeripheral, error: NSError?) {
        reloadView()
        dismissKeyboard()
        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 {
            dismissKeyboard()
            let hud = MBProgressHUD.showAdded(to: view, animated: true)
            hud?.mode = MBProgressHUDMode.text
            hud?.labelText = "Bluetooth turned off"
            hud?.hide(true, afterDelay: 1.0)
        }
    }


//MARK: UITextFieldDelegate

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if !serial.isReady {
            let alert = UIAlertController(title: "Not connected", message: "What am I supposed to send this to?", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default, handler: { action -> Void in self.dismiss(animated: true, completion: nil) }))
            present(alert, animated: true, completion: nil)
            messageField.resignFirstResponder()
            return true
        }

        // send the message to the bluetooth device
        // but fist, add optionally a line break or carriage return (or both) to the message
        let pref = UserDefaults.standard.integer(forKey: MessageOptionKey)
        var msg = messageField.text!
        switch pref {
        case MessageOption.newline.rawValue:
            msg += "\n"
        case MessageOption.carriageReturn.rawValue:
            msg += "\r"
        case MessageOption.carriageReturnAndNewline.rawValue:
            msg += "\r\n"
        default:
            msg += ""
        }

        // send the message and clear the textfield
        serial.sendMessageToDevice(msg)
        messageField.text = ""
        return true
    }

    func dismissKeyboard() {
        messageField.resignFirstResponder()
    }


//MARK: IBActions

    @IBAction func barButtonPressed(_ sender: AnyObject) {
        if serial.connectedPeripheral == nil {
            performSegue(withIdentifier: "ShowScanner", sender: self)
        } else {
            serial.disconnect()
            reloadView()
        }
    }
}

核心蓝牙代码。

import UIKit
import CoreBluetooth
var serial: BluetoothSerial!   // Global serial handler, don't forget to initialize it with init(delgate:)
// Delegate functions
protocol BluetoothSerialDelegate {
// ** Required **

/// Called when de state of the CBCentralManager changes (e.g. when bluetooth is turned on/off)
func serialDidChangeState()

/// Called when a peripheral disconnected
func serialDidDisconnect(_ peripheral: CBPeripheral, error: NSError?)

// ** Optionals **

/// Called when a message is received
func serialDidReceiveString(_ message: String)

/// Called when a message is received
func serialDidReceiveBytes(_ bytes: [UInt8])

/// Called when a message is received
func serialDidReceiveData(_ data: Data)

/// Called when the RSSI of the connected peripheral is read
func serialDidReadRSSI(_ rssi: NSNumber)

/// Called when a new peripheral is discovered while scanning. Also gives the RSSI (signal strength)
func serialDidDiscoverPeripheral(_ peripheral: CBPeripheral, RSSI: NSNumber?)

/// Called when a peripheral is connected (but not yet ready for cummunication)
func serialDidConnect(_ peripheral: CBPeripheral)

/// Called when a pending connection failed
func serialDidFailToConnect(_ peripheral: CBPeripheral, error: NSError?)

/// Called when a peripheral is ready for communication
func serialIsReady(_ peripheral: CBPeripheral)

}

// Make some of the delegate functions optional extension BluetoothSerialDelegate {
func serialDidReceiveString(_ message: String) {}
func serialDidReceiveBytes(_ bytes: [UInt8]) {}
func serialDidReceiveData(_ data: Data) {}
func serialDidReadRSSI(_ rssi: NSNumber) {}
func serialDidDiscoverPeripheral(_ peripheral: CBPeripheral, RSSI: NSNumber?) {}
func serialDidConnect(_ peripheral: CBPeripheral) {}
func serialDidFailToConnect(_ peripheral: CBPeripheral, error: NSError?) {}
func serialIsReady(_ peripheral: CBPeripheral) {}
}

final class BluetoothSerial: NSObject,CBCentralManagerDelegate,CBPeripheralDelegate {

// MARK: Variables

/// The delegate object the BluetoothDelegate methods will be called upon
var delegate: BluetoothSerialDelegate!

/// The CBCentralManager this bluetooth serial handler uses for... well, everything really
var centralManager: CBCentralManager!

/// The peripheral we're trying to connect to (nil if none)
var pendingPeripheral: CBPeripheral?

/// The connected peripheral (nil if none is connected)
var connectedPeripheral: CBPeripheral?

/// The characteristic 0xFFE1 we need to write to, of the connectedPeripheral
weak var writeCharacteristic: CBCharacteristic?

/// Whether this serial is ready to send and receive data
var isReady: Bool {
    get {
        return centralManager.state == .poweredOn &&
               connectedPeripheral != nil &&
               writeCharacteristic != nil
    }
}

/// Whether this serial is looking for advertising peripherals
var isScanning: Bool {
    return centralManager.isScanning
}

/// Whether the state of the centralManager is .poweredOn
var isPoweredOn: Bool {
    return centralManager.state == .poweredOn
}

/// UUID of the service to look for.
var serviceUUID = CBUUID(string: "FFE0")

/// UUID of the characteristic to look for.
var characteristicUUID = CBUUID(string: "FFE1")

/// Whether to write to the HM10 with or without response. Set automatically.
/// Legit HM10 modules (from JNHuaMao) require 'Write without Response',
/// while fake modules (e.g. from Bolutek) require 'Write with Response'.
private var writeType: CBCharacteristicWriteType = .withoutResponse


// MARK: functions

/// Always use this to initialize an instance
init(delegate: BluetoothSerialDelegate) {
    super.init()
    self.delegate = delegate
    centralManager = CBCentralManager(delegate: self, queue: nil)
}

/// Start scanning for peripherals
func startScan() {
    guard centralManager.state == .poweredOn else { return }

    // start scanning for peripherals with correct service UUID
    centralManager.scanForPeripherals(withServices: [serviceUUID], options: nil)

    // retrieve peripherals that are already connected
    // see this stackoverflow question http://stackoverflow.com/questions/13286487
    let peripherals = centralManager.retrieveConnectedPeripherals(withServices: [serviceUUID])
    for peripheral in peripherals {
        delegate.serialDidDiscoverPeripheral(peripheral, RSSI: nil)
    }
}

/// Stop scanning for peripherals
func stopScan() {
    centralManager.stopScan()
}

/// Try to connect to the given peripheral
func connectToPeripheral(_ peripheral: CBPeripheral) {
    pendingPeripheral = peripheral
    centralManager.connect(peripheral, options: nil)
}

/// Disconnect from the connected peripheral or stop connecting to it
func disconnect() {
    if let p = connectedPeripheral {
        centralManager.cancelPeripheralConnection(p)
    } else if let p = pendingPeripheral {
        centralManager.cancelPeripheralConnection(p) //TODO: Test whether its neccesary to set p to nil
    }
}

/// The didReadRSSI delegate function will be called after calling this function
func readRSSI() {
    guard isReady else { return }
    connectedPeripheral!.readRSSI()
}

/// Send a string to the device
func sendMessageToDevice(_ message: String) {
    guard isReady else { return }

    if let data = message.data(using: String.Encoding.utf8) {
        connectedPeripheral!.writeValue(data, for: writeCharacteristic!, type: writeType)
    }
}

/// Send an array of bytes to the device
func sendBytesToDevice(_ bytes: [UInt8]) {
    guard isReady else { return }

    let data = Data(bytes: UnsafePointer<UInt8>(bytes), count: bytes.count)
    connectedPeripheral!.writeValue(data, for: writeCharacteristic!, type: writeType)
}

/// Send data to the device
func sendDataToDevice(_ data: Data) {
    guard isReady else { return }

    connectedPeripheral!.writeValue(data, for: writeCharacteristic!, type: writeType)
}


// MARK: CBCentralManagerDelegate functions

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    // just send it to the delegate
    delegate.serialDidDiscoverPeripheral(peripheral, RSSI: RSSI)
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    // set some stuff right
    peripheral.delegate = self
    pendingPeripheral = nil
    connectedPeripheral = peripheral

    // send it to the delegate
    delegate.serialDidConnect(peripheral)

    // Okay, the peripheral is connected but we're not ready yet!
    // First get the 0xFFE0 service
    // Then get the 0xFFE1 characteristic of this service
    // Subscribe to it & create a weak reference to it (for writing later on), 
    // and find out the writeType by looking at characteristic.properties.
    // Only then we're ready for communication

    peripheral.discoverServices([serviceUUID])
}

func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
    connectedPeripheral = nil
    pendingPeripheral = nil

    // send it to the delegate
    delegate.serialDidDisconnect(peripheral, error: error as NSError?)
}

func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    pendingPeripheral = nil

    // just send it to the delegate
    delegate.serialDidFailToConnect(peripheral, error: error as NSError?)
}

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    // note that "didDisconnectPeripheral" won't be called if BLE is turned off while connected
    connectedPeripheral = nil
    pendingPeripheral = nil

    // send it to the delegate
    delegate.serialDidChangeState()
}


// MARK: CBPeripheralDelegate functions

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    // discover the 0xFFE1 characteristic for all services (though there should only be one)
    for service in peripheral.services! {
        peripheral.discoverCharacteristics([characteristicUUID], for: service)
    }
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    // check whether the characteristic we're looking for (0xFFE1) is present - just to be sure
    for characteristic in service.characteristics! {
        if characteristic.uuid == characteristicUUID {
            // subscribe to this value (so we'll get notified when there is serial data for us..)
            peripheral.setNotifyValue(true, for: characteristic)

            // keep a reference to this characteristic so we can write to it
            writeCharacteristic = characteristic

            // find out writeType
            writeType = characteristic.properties.contains(.write) ? .withResponse : .withoutResponse

            // notify the delegate we're ready for communication
            delegate.serialIsReady(peripheral)
        }
    }
}

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    // notify the delegate in different ways
    // if you don't use one of these, just comment it (for optimum efficiency :])
    let data = characteristic.value
    guard data != nil else { return }

    // first the data
    delegate.serialDidReceiveData(data!)

    // then the string
    if let str = String(data: data!, encoding: String.Encoding.utf8) {
        delegate.serialDidReceiveString(str)
    } else {
        //print("Received an invalid string!") uncomment for debugging
    }

    // now the bytes array
    var bytes = [UInt8](repeating: 0, count: data!.count / MemoryLayout<UInt8>.size)
    (data! as NSData).getBytes(&bytes, length: data!.count)
    delegate.serialDidReceiveBytes(bytes)
}

func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
    delegate.serialDidReadRSSI(RSSI)
}

}

这是整个代码:https : //github.com/vari217/aw

吉乔

如果您只想在点击按钮时获取值,则必须阻止 Arduino 在收到来自您的 BT 的标志后执行此操作。

不要在主循环中使用如此多的延迟,10 秒太多了。弄清楚如何处理事件而不是保持循环,您可以处理其他任务。

我没有看到你的整个代码,但从你发布的内容来看,我会遵循这条路径。

对于您的 Arduino,等待读取和假脱机,直到您从您的应用程序中获得请求,如果不使用,不要浪费 CPU 时间。如果您想每 XX 秒缓冲一些值,请放置一个程序,每 XX 秒验证一次传感器并将其保存在 rom 上(如果确实需要)。

如果没有,我的建议是:

char val;         // variable to receive data from the serial port [BT]
char buffer[50];
void setup()
{

  Serial.begin(115200);       // start serial communication at 115200bps

}

void loop() {

  if( Serial.available() )       // if data is available to read
  {
    val = Serial.read();         // read it and store it in 'val'
  }

  if( val == 'T' )               // if 'T' was received read temperature
  {
    sensorInput = analogRead(A0);    //read the analog sensor and store it
    temp = (double)sensorInput / 1024;       //find percentage of input reading
    temp = temp * 5;                 //multiply by 5V to get voltage
    temp = temp - 0.5;               //Subtract the offset 
    temp = temp * 100;               //Convert to degrees 


    if (temp > 28 ) {

      sprintf(buffer, "Current Temp is hot i.e.: %d", temp);
      Serial.println(buffer);
    }

    else if (temp < 28) {
      sprintf(buffer, "Current Temp is cold i.e.: %d", temp);
      Serial.println(buffer);
    }
    else {
      sprintf(buffer, "Current Temp %d", temp);
      Serial.println(buffer);
    }
  }

  if( val == 'L' )               // if 'L' was received read light 
  {
    sensorValue = analogRead(A1);    //read the analog sensor and store it
    if (sensorValue > 70 ) {
      sprintf(buffer, "Current Light is high i.e.: %d", sensorValue);
      Serial.println(buffer);
    }
    else if (sensorValue < 60) {
      sprintf(buffer, "Current Light is low i.e.: %d", sensorValue);
      Serial.println(buffer);
    }
    else {
      sprintf(buffer, "Light seems good: %d", sensorValue);
      Serial.println(buffer);      
    }
  }
  val = '';
}

对于您的快速代码,类似这样的:

@IBAction func getTemperature(sender: AnyObject)
{
  var str:NSString = "T"
  data = str.dataUsingEncoding(NSUTF8StringEncoding)!
  peripheral.writeValue(data, forCharacteristic: arrCharacteristics!.objectAtIndex(1) as CBCharacteristic , type: CBCharacteristicWriteType.WithoutResponse)
}

@IBAction func getLight(sender: AnyObject)
{
  var str:NSString = "L"
  data = str.dataUsingEncoding(NSUTF8StringEncoding)!
  peripheral.writeValue(data, forCharacteristic: arrCharacteristics!.objectAtIndex(1) as CBCharacteristic , type: CBCharacteristicWriteType.WithoutResponse)
}

对于您关于通知的问题,我会遵循@Paulw11 的建议,iOS 背景存在一些陷阱,而遵循教程是实现它的最佳方式。

对于有关单行打印的问题,请查看sprintf我的代码中使用的函数。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

iPhone hm-10通信。ble设备未在iPhone中列出

来自分类Dev

是否可以将HM-10或HM-11 BLE模块与Arduino一起与iOS设备(ANCS)通信?

来自分类Dev

HM10 与 Arduino 和 Android BLE 之间的低功耗蓝牙大数据传输

来自分类Dev

是否可以将HM-10或HM-11 BLE模块与Arduino一起使用以与iOS设备(ANCS)通信?

来自分类Dev

HM-10 蓝牙与 iPhone 配对

来自分类Dev

HM-10 BLE模块自动重连

来自分类Dev

Arduio HM-10 BLE 扫描仪开发

来自分类Dev

注册推送通知Swift 3 + iOS 10

来自分类Dev

Windows 10无法识别Arduino Uno

来自分类Dev

在iOS 10中添加本地通知-Swift 3

来自分类Dev

带有HM-10的Arduino并不总是会收到发送的完整消息

来自分类Dev

Arduino Uno R3 + SIM900

来自分类Dev

该arduino uno r3的ISCP引脚在哪里?

来自分类Dev

从Arduino UNO R3套件读取数据

来自分类Dev

RS485 Breackout和Arduino Uno Rev.3

来自分类Dev

Arduino Uno步进方向

来自分类Dev

Arduino-uno项目

来自分类Dev

如何将推送通知令牌存储到外部数据库-iOS 10,Swift 3

来自分类Dev

在通知标题中显示功能的结果(Swift 3,iOS10)

来自分类Dev

Azure 通知中心似乎不适用于 ios 10 和 swift 3

来自分类Dev

Swift 3:过滤 IOS 通知

来自分类Dev

iPhone BLE/GATT 接口

来自分类Dev

Android Ble延迟通知

来自分类Dev

在 BLE 中实现通知

来自分类Dev

Arduino Uno PWM引脚冲突

来自分类Dev

Arduino Uno PWM引脚冲突

来自分类Dev

与Mac的Arduino Uno蓝牙通信

来自分类Dev

Arduino UNO上的const太大

来自分类Dev

如何从arduino uno导入数据