Tag

, , , , , , , , , , , , ,

Dopo aver visto come controllare Arduino dal proprio computer tramite una connessione seriale, da un dispositivo Android via Bluetooth e da un browser – grazie a una Ethernet Shield – non poteva mancare un’applicazione per controllare Arduino dal nostro iPhone!

L’applicazione è compatibile sia con iPhone che con iPad, ed è scritta per iOS 6.1 – ma dovrebbe girare anche su iOS 5.0.

Per realizzare l’applicazione, useremo l’esempio descritto nello studio su Arduino Server – Parte 2. Per rendere tutto più interessante, vedremo come controllare i nostri “famosi 3 led” in tempo reale, grazie ad alcuni slider per cambiare la luminosità e alle funzionalità offerte da NSURLrequest.

XCode

Se non lo avete ancora fatto, scaricate il pacchetto per sviluppatore XCode da questa pagina: https://developer.apple.com/xcode/ – sono quasi 2G, per cui prendetevela con calma!

Purtroppo per sviluppare applicazioni iOS è necessario disporre di un computer Apple. Se utilizzate un sistema operativo diverso (Windows o Linux) ci sono delle alternative, forse alcune a pagamento, ma vale la pena dare un’occhiata: ad esempio qui.

Se non avete acquistato un Apple Developer Program ($99/y, circa €80 l’anno), è molto probabile che non potrete installare questa app sul vostro dispositivo. Comunque l’app può essere testata anche su computer, grazie all’emulatore di XCode.

iOS

Per creare l’applicazione iOS, apriamo XCode e scegliamo: iOS > Application > Single View Application. Chiamiamo il progetto Arduino Ethernet Controller e salviamo. Sulla sinistra, troviamo due file Storyboard sui quali andremo a disegnare le interfacce per iPhone e iPad. Cominciamo!

Layout

Selezioniamo il file Storyboard per iPhone, e trasciniamo sull’interfaccia un UITextField, tre UISlider e quattro UILabel. Disponiamo gli elementi in modo che siano un po’ carini e ripetiamo il tutto per l’interfaccia iPad. È molto importante, in questa fase, assegnare un tag ai diversi slider: 0 per lo slide che controllerà il LED rosso, 1 per l’arancio, 2 per il verde. Vedremo tra poco a cosa servirà.

Layout iPhone

Layout iPhone

TIP: selezionate uno slider e poi premete: Option+Mela+4, per andare direttamente al pannello degli attributi, quindi cercate la voce tag.

Outlet

Dopo aver disegnato l’interfaccia, andiamo a creare nel codice un riferimento per i vari elementi creati, in modo che l’app possa controllarli. Apriamo il file ViewController.m, e aggiungiamo, all’interno della dichiarazione @interface, una proprietà per ognuno degli elementi grafici:

@property (weak, nonatomic) IBOutlet UITextField *serverTextField;
@property (weak, nonatomic) IBOutlet UISlider *redSlider;
@property (weak, nonatomic) IBOutlet UISlider *orangeSlider;
@property (weak, nonatomic) IBOutlet UISlider *greenSlider;

Una volta dichiarate le proprietà degli elementi grafici, andiamo a sintetizzarle poco dopo, nella dichiarazione: @implementation, in modo che l’app sappia come trattare queste 4 variabili:

@synthesize serverTextField;
@synthesize redSlider;
@synthesize orangeSlider;
@synthesize greenSlider;

Adesso non ci resta che tornare nel file Storyboard, e collegare il nostro ViewController agli gli elementi grafici: tenendo premuto Control, trascinate il mouse dal View Controller ai diversi elementi (UISlider, UITextField) e associateli al nome corretto.

Layout Outlet

Layout Outlet

PS: in genere gli Outlet (gli elementi grafici) associati all’interfaccia, si dichiarano nel file ViewController.h, e non nel .m – ma in questo caso, essendo elementi interni al nostro View Controller – che non saranno condivisi con altri controller – è più corretto dichiararli nel .m.

Variabili

Torniamo adesso al file ViewController.m: abbiamo bisogno di gestire un paio di variabili, perché dobbiamo spiegare ad Arduino quale LED accendere e a quale luminosità; oltre a questo dobbiamo anche ricordarci qual è l’indirizzo del server! Aggiungiamo perciò server, led e luminosità. Come sempre, le dichiariamo in @interface:

@property (nonatomic,retain) NSString *server;
@property (nonatomic,readwrite) float valore;
@property (nonatomic,readwrite) NSInteger colore;

… e andiamo a sintetizzarle in @implementation:

@synthesize server = _server;
@synthesize valore = _valore;
@synthesize colore = _colore;

PS: in certi casi, per non confondersi, è utile sintetizzare le variabili con questa sintassi: valore = _valore, in modo che sia più difficile confondere una proprietà globale con una locale. Nel caso degli Outlet (gli elementi grafici) non era strettamente necessario.

Adesso che è tutto pronto, cominciamo a scrivere il codice vero e proprio!

Setup

All’avvio, la nostra app deve prima di tutto fare un paio di cose: innanzitutto, impostiamo gli slider perché vadano da un minimo 0 a un massimo 100. Poi impostiamo un valore di default per l’indirizzo del server e lo mostriamo sulla UITextField. Completiamo il metodo viewDidLoad con queste impostazioni.

self.server = @"192.168.1.10";
serverTextField.text = self.server;
redSlider.minimumValue = 0.0;
redSlider.maximumValue = 100.0;
orangeSlider.minimumValue = 0.0;
orangeSlider.maximumValue = 100.0;
greenSlider.minimumValue = 0.0;
greenSlider.maximumValue = 100.0;

Creiamo infine alcune costanti, che ci serviranno per associare il tag dei nostri slider con il colore a cui fanno riferimento. Sotto la direttiva #import, aggiungiamo questo codice:

#define ROSSO 0
#define ARANCIO 1
#define VERDE 2

Salviamo il progetto. Ora non ci resta che spiegare al nostro ViewController come gestire gli eventi quando tocchiamo il campo di testo o gli slider.

PS: è possibile impostare il minimo e il massimo degli slider direttamente dall’interfaccia, ma farlo da codice permette di avere tutto sotto controllo nel solo file ViewController.m.

UITextFieldDelegate

Se vogliamo modificare l’indirizzo del server, la nostra app deve salvare il valore inserito e aggiornare l’interfaccia. Per fare questo, il nostro ViewController deve essere responsabile del UITextField. Per farlo, aggiungiamo la dichiarazione <UITextFieldDelegate> nel file .h

@interface ViewController : UIViewController <UITextFieldDelegate>

ed aggiungiamo la funzione che controlla la tastiera nel file .m

- (BOOL)textFieldShouldReturn:(UITextField *)textField;
{
  self.server = textField.text;
  [textField endEditing:YES];
  return YES;
}

Adesso torniamo ai file Storyboard e colleghiamo il UITextField a ViewController, tenendo premuto il tasto Control. Abbiniamo il campo di testo alla voce delegate.

UITextFieldDelegate

UITextFieldDelegate

UISlider

Passiamo ora a configurare il comportamento dei nostri tre slider. Restiamo nel file Storyboard e facciamo clic con il tasto destro sugli slider, e trasciniamo Value Changed sopra ViewController. In questo modo il nostro controller è collegato agli slider, e potrà intercettare ogni loro cambiamento.

Slider Value Changed

Slider Value Changed

Scriviamo adesso il codice per intercettare ogni cambiamento degli slider. Nel file .m implementiamo la funzione sliderChanged:

- (IBAction)sliderChanged:(id)sender
{
  UISlider *slider = (UISlider *)sender;
  self.valore = slider.value;
  self.colore = slider.tag;
  [self askServer];
}

Adesso, ad ogni spostamento degli slider salviamo il valore, il colore (in base al tag di ogni slider!) e inviamo una richiesta al nostro Arduino.

Arduino

Per poter inviare una richiesta corretta ad Arduino, dobbiamo per prima cosa creare la stringa di connessione giusta, combinando tra loro i parametri necessari: server, colore ed infine valore. Per avere un codice più leggibile e pulito, svolgiamo questa operazione in una funzione creata ad hoc:

- (NSString *)calcolaRichiesta
{
  NSString *server = [NSString stringWithFormat:@"http://%@/",self.server];
   NSString *colore = [NSString string];
  switch (self.colore) {
      case ROSSO:
      colore = @"rosso";
     break;
     case ARANCIO:
     colore = @"arancio";
     break;
     case VERDE:
     colore = @"verde";
     break;
     default:
     break;
   }
   int valore = (int)self.valore;
   NSString *richiesta = [NSString stringWithFormat:@"%@?led=%@&perc=%d",server,colore,valore];
   return richiesta;
}

Richiesta al server

Analizzando il valore del campo di testo e il tag dello slider selezionato, possiamo quindi ottenere una stringa di connessione corretta: utilizziamo questa funzione nel metodo askServer, che abbiamo utilizzato poco fa ma non abbiamo ancora implementato:

- (void)askServer
{
  NSString *string = [self calcolaRichiesta];
  NSURL *url = [NSURL URLWithString:string];
  NSURLRequest *richiesta = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:.1];
  NSURLConnection *connessione = [[NSURLConnection alloc] initWithRequest:richiesta delegate:self];
  [connessione start];
}

Per ottenere una richiesta al server in tempo reale, utilizziamo la classe NSURLRequest con le impostazioni per ignorare la cache e un intervallo di richiesta di 0.1 secondi, così da non impallare Arduino con troppe richieste sovrapposte.

Per stabilire la connessione utilizziamo NSURLConnection, passando come parametro la NSURLRequest appena creata. NB: NSURLRequest ha bisogno di un URL che otteniamo convertendo la stringa ottenuta con [self calcolaStringa].

Verifica

Una volta creata la nostra applicazione, verifichiamo che non ci siano errori con una build (Mela+B). Se tutto è corretto, selezioniamo in alto a sinistra il simulatore per iPhone, poi proviamo a lanciare l’app con Mela+R. Se abbiamo fatto tutto bene la nostra app è ora in grado di controllare Arduino!!

Arduino iOS App

Arduino iOS App

Video

Note

Programmare un’app per iOS è un compito piuttosto complesso. Nel caso abbiate dubbi o non riusciate a seguire il codice dell’esempio, potete consultare la documentazione Apple oppure cercare su qualche forum ben documentato o su StackOverflow. A presto!

Download: arduino_ios.zip

Annunci