3

Since there was no example code for using OBD2Kit and Swift I forked it into https://github.com/YannisDC/OBD2Kit and used it as a pod.

I translated some OBJ-C example code but can't seem to downcast the FLWiFiScanTool into the ELM327 type. Why do I keep getting nil?

import UIKit
import OBD2Kit

class ViewController: UIViewController, FLScanToolDelegate {

    @IBOutlet weak var hostIpAddress: UITextField!

    var scanTool: ELM327!

    @IBOutlet weak var statusLabel: UILabel!
    @IBOutlet weak var scanToolLabel: UILabel!
    @IBOutlet weak var rpmLabel: UILabel!
    @IBOutlet weak var speedLabel: UILabel!
    @IBOutlet weak var tempLabel: UILabel!
    var scanning = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.hostIpAddress.text = "192.168.0.10"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func scanButton(sender: UIButton) {
        if !scanning {
            startScan()
        } else {
            stopScan()
        }
    }

    func startScan() {
        if let scanTool = ELM327(host: self.hostIpAddress.text!, andPort: 35000) {
            self.statusLabel.text = "Initializing..."
            scanTool.useLocation = true
            scanTool.delegate = self
            scanTool.startScanWithSensors({() -> [AnyObject] in
                dispatch_async(dispatch_get_main_queue(), {() -> Void in
                    self.statusLabel.text = "Scanning..."
                    self.scanToolLabel.text = scanTool.scanToolName
                })

//                let sensors: [AnyObject] = [    OBD2Sensor.SensorEngineRPM as! AnyObject,
//                                                OBD2Sensor.SensorVehicleSpeed as! AnyObject,
//                                                OBD2Sensor.SensorOxygenSensorsPresent as! AnyObject    ]

                let sensors: [AnyObject] = [    0x0C,
                                                0x0D,
                                                0x13    ]
                return sensors
            })
            self.scanTool = scanTool
            print("So far succesfull")
            scanning = !scanning
        } else {
            self.statusLabel.text = "Not working"
        }
    }

    func stopScan() {
        statusLabel.text = "Stopped"
        let scanTool: ELM327 = self.scanTool
        scanTool.cancelScan()
        scanTool.sensorScanTargets = nil
        scanTool.delegate = nil
        scanning = !scanning
    }

    // MARK: - FLScanToolDelegate


    func scanTool(scanTool: FLScanTool, sensor: FLECUSensor) {
        var sensorLabel: UILabel? = nil
        switch sensor.pid {

        case OBD2Sensor.SensorEngineRPM:
            sensorLabel = self.rpmLabel

        case OBD2Sensor.SensorVehicleSpeed:
            sensorLabel = self.speedLabel

        default:
            sensorLabel = self.tempLabel
        }

        self.showSensorValue(sensor, onLabel: sensorLabel!)
    }

    func showSensorValue(sensor: FLECUSensor, onLabel label: UILabel) {
        let sensorValue: String = "\(sensor.valueStringForMeasurement1(false)) \(sensor.imperialUnitString)"
        dispatch_async(dispatch_get_main_queue(), {() -> Void in
            label.text = sensorValue
        })
    }

}

Edit 1:

I can already scan for the tool now since ELM327 is a FLWiFiScanTool and not the other way around. I can get the toolname so it's connecting but can't seem to get the sensors output.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
YannisDC
  • 207
  • 1
  • 2
  • 9
  • Can `scanToolWithHost` fail? – Avi Aug 02 '16 at 08:17
  • What is `FLWifiScanTool` returning? – Paulw11 Aug 02 '16 at 08:53
  • 1
    Please remove all the "solved" parts from your *question* and post your solution as an *answer*. Thank you. – Eric Aya Aug 03 '16 at 10:24
  • 1
    It's okay to ask and then answer your own question, just don't do both in the Question section. – Abizern Aug 03 '16 at 13:16
  • I've rolled back your question to the last "non solved" version because there was a misunderstanding. What I meant is that you should post your solution *using the "Your Answer" box*. A question should remain a question; solutions go in the answers part of the Q&A, not in the question. Thanks. – Eric Aya Aug 03 '16 at 13:22
  • Okay, you're right. I'll fix it. Thought it was weird – YannisDC Aug 04 '16 at 08:31

1 Answers1

0

I managed to figure it out. The expected sensors array should be one of NSNumbers so I casted the sensors UInt's to NSNumbers. And I also missed the didUpdateSensor part in the scanTool function.

Make sure to use the metric system, this is somehow way more reliable in my case. (My car is using the metric system as well, maybe that's why.)

import UIKit
import OBD2Kit

class ViewController: UIViewController, FLScanToolDelegate {
    var scanTool: ELM327!

    @IBOutlet weak var statusLabel: UILabel!
    @IBOutlet weak var scanToolLabel: UILabel!
    @IBOutlet weak var rpmLabel: UILabel!
    @IBOutlet weak var speedLabel: UILabel!
    @IBOutlet weak var tempLabel: UILabel!
    var scanning = false

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func scanButton(sender: UIButton) {
        if !scanning {
            startScan()
        } else {
            stopScan()
        }
    }

    func startScan() {
        if let scanTool = ELM327(host: "192.168.0.10", andPort: 35000) {
            self.statusLabel.text = "Initializing..."
            scanTool.useLocation = true
            scanTool.delegate = self
            scanTool.startScanWithSensors({() -> [AnyObject] in
                dispatch_async(dispatch_get_main_queue(), {() -> Void in
                    self.statusLabel.text = "Scanning..."
                    self.scanToolLabel.text = scanTool.scanToolName
                })

                let sensors: [AnyObject] = [ OBD2Sensor.SensorEngineRPM as NSNumber, OBD2Sensor.SensorVehicleSpeed as NSNumber, OBD2Sensor.SensorOxygenSensorsPresent as NSNumber ]

                return sensors
            })
            self.scanTool = scanTool
            print("So far succesfull")
            scanning = !scanning
        } else {
            self.statusLabel.text = "Not working"
        }
    }

    func stopScan() {
        statusLabel.text = "Stopped"
        let scanTool: ELM327 = self.scanTool
        scanTool.cancelScan()
        scanTool.sensorScanTargets = nil
        scanTool.delegate = nil
        scanning = !scanning
    }

    // MARK: - FLScanToolDelegate

    func scanTool(scanTool: FLScanTool!, didUpdateSensor sensor: FLECUSensor!) {
        var sensorLabel: UILabel? = nil
        switch sensor.pid {

        case OBD2Sensor.SensorEngineRPM:
            sensorLabel = self.rpmLabel

        case OBD2Sensor.SensorVehicleSpeed:
            sensorLabel = self.speedLabel

        default:
            sensorLabel = self.tempLabel
        }

        self.showSensorValue(sensor, onLabel: sensorLabel!)
    }

    func showSensorValue(sensor: FLECUSensor, onLabel label: UILabel) {
        let sensorValue: String = "\(sensor.valueStringForMeasurement1(true)) \(sensor.metricUnitString)"
        dispatch_async(dispatch_get_main_queue(), {() -> Void in
            label.text = sensorValue
        })
    }

}
YannisDC
  • 207
  • 1
  • 2
  • 9