Arduino Tutorial: Networked Temperature Sensor with Swift
In this Arduino Tutorial, you’ll work with a temperature sensor and the companion iPhone app in Swift to connect with it! By Tony Dahbura.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Arduino Tutorial: Networked Temperature Sensor with Swift
30 mins
iOS and Swift Integration
Now comes the iOS! You will build an iPhone app to get your temperatures. To start things off, open the included Xcode project from the tutorial download. You can find it in the folder ArduinoTemperatureSwift Starter. The starter project has the following functionality:
- It provides a simple user interface for the application.
- The supported interface orientation is set to portrait.
- It includes a custom open-source digital-looking font to show temperatures.
- It contains a configuration/settings screen.
- It provides methods to save and load your settings, including the URL and the temperature display format.
Open the project in Xcode and build and run. You should see the following:
This project uses a basic Application model including a flip view for settings. You will handle the communications and parse the results.
Tap the info button at the bottom of the screen and input the URL for your Arduino server:
Click the Done button and on the main screen, tap Update. You should see a message to the debug window telling you that your settings have been saved, but wait… there are no temperatures from your new circuit!
This is where you come in. Open ViewController.swift and locate performRestCall()
. Inside this method, place the code needed to communicate over the network with the Arduino:
var url = NSURL(string: theURL)
if (url == nil || theURL == "") {
showAlert("Invalid or no URL entered!")
return
}
updateButton.enabled = false
var request = NSMutableURLRequest(URL: NSURL(string: theURL)!)
request.HTTPMethod = "GET"
request.setValue("application/json; charset=utf=8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(),
completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if let anError = error {
//error getting data
self.showAlert(error!.localizedDescription)
} else {
//process JSON
self.handleResultsOfWebCall(data)
}
self.updateButton.enabled = true
})
return
})
This code simply takes the URL you provided to talk to the Arduino and sets up a background HTTP request using an Operation Queue. We utilize Swift closures to handle the results of the background web request.
The code receives the results and calls handleResultsOfWebCall(_:)
on the main thread. This method parses and displays the results.
Let’s get to that now!
Find handleResultsOfWebCall(_:)
and add the following implementation inside the method:
var error : NSError?
var jsonResults = NSJSONSerialization.JSONObjectWithData(theData, options: nil, error: &error) as! NSDictionary
if let jsonError = error {
println("JSON Error \(error!.localizedDescription)")
showAlert("Error retrieving results-check the URL or Server!")
} else {
let theSensors = jsonResults["arduino"] as! NSArray
for i in 0..<theSensors.count {
let sensor = theSensors[i] as! NSDictionary
let location = sensor["location"] as! String
let temperature = sensor["celsius"] as! NSString
if (location == "indoor") {
indoorTemperatureCelsius = temperature.floatValue
} else {
outdoorTemperatureCelsius = temperature.floatValue
}
}
lastUpdate = NSDate()
saveSettings()
updateDisplayWithCurrentReadings()
}
This method to see if any data was returned, you use the built-in NSJSONSerialization
handler to get the results into a NSDictionary
object. From there, you read the values returned from the sensors and save them as Celsius values.
Next the settings are saved for display later when the application starts up again. Finally, you call updateDisplayWithCurrentReadings()
to show the temperature values.
Build and run the application, and enjoy!
Congratulations! You have a mobile application and temperature server that lets you read temperatures from sensors you can place anywhere. My setup has one sensor outside of a window and one inside. It’s really nice to be able to check the temperature quickly in the morning before heading out the door.
Where to Go from Here?
Here's the download for the completed Xcode project from this tutorial.
You will notice the display shows the temperatures in different colors, based on the range of the value. This color handling is in the setFieldColor
method. Feel free to change them for your climate.
You also may not like the sensor changing the IP address if it reboots, based on your DHCP settings. If that's the case, modify the Arduino code to include a predefined IP address. This was described earlier in the tutorial, but for reference, you need to add a line near the top of the LEDBlinkAndEthernetTemperatureJSON file, like this:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x7D, 0x54 };
IPAddress ip(192,168,1, 121); //or some value you want
Then replace the if (Ethernet.begin(mac) == 0)
line with:
Ethernet.begin(mac, ip); //in place of Ethernet.begin(mac).
What you've done in this tutorial is easily adapted to many other sensors!
I hope you enjoyed this tutorial and that it has inspired you to continue with your Arduino investigations. In the meantime, if you have any questions or comments, please join the forum discussion below!