This library is archived and is no longer being maintained. It can be still be downloaded and used, but is read-only and cannot be contributed to. For more information, you can view this repository on GitHub.
Arduino Ciao is a easy-to-use and powerful technology that enables Arduino sketches to communicate intuitively with the "outside World". It aims to simplify interaction between microcontroller and Linino OS allowing a variety of connections with most common protocols, social networks, third-party services and applications.
Arduino Ciao - from now-on simply "Ciao" has been designed and developed to be modular and easily configurable. Its goal is to support several Connectors capable of interacting with system resources (filesystem, console, etc...) and to communicate with the most common and useful protocols (MQTT, XMPP, HTTP, SMTP, etc..) and applications (Jabber,Twitter, Facebook, etc.).
Ciao is made of two main parts:
This architecture is currently available on the following products:
To communicate with the "outside world" the Ciao Library interacts with Ciao Core: the key component of the Ciao technology on the MPU (microprocessor) side. Ciao Core runs over Linino OS, it is developed in Python® and it has been designed to enable communication with "outside world" via several modules called Connectors. Such connectors communicate with Ciao Core using JSON strings sent over a TCP socket.
Ciao Core, thanks to this smart and effective design, is able to:
A Connector is a standalone module that on one hand communicates with Ciao Core to send/receive data to/from the microcontroller, and on the other connects to external services and/or applications through specific protocols. Connectors are the tools of Ciao to connect to the World. Main Connectors like RestServer, Shell, MQTT are pre-installed with Ciao, other connectors and Third party connectors are available in the Connectors Repository, and installable via opkg, see the installation section for more information.
Rest connector
This connector allows to make “http” requests. Below the steps that you should follow to use the Rest connector:
You can find Rest Connector configuration file at the following path: /usr/lib/python2.7/ciao/connectors/rest/rest.json.conf
1{2 "name" : "rest",3 "description" : "REST connector for the Ciao Core",4 "authors": ["Arduino Team <swdev@arduino.org>;"],5 "repository" : "https://github.com/arduino-org/Ciao",6 "version" : "0.0.1",7 "params" : {8 }9}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key: In this Connector there aren’t parameters to set.
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable Rest connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/rest.ciao.json.conf
1{2 "name" : "rest",3 "enabled": true,4 "type" : "managed",5 [...]6}
The key enabled must be set to true (boolean value). This is the only parameter you are required to edit in order to enable the Rest Connector. Once done Ciao Core will be ready and configured to use Rest Connector.
1#include <Wire.h>2#include <Ciao.h>3#define CONNECTOR "rest"4#define SERVER_ADDR "192.168.1.1" // change ip address with your server ip address5int buttonState; //this variable tracks the state of the button, low if not pressed, high if pressed6int ledState = HIGH; //this variable tracks the state of the LED, negative if off, positive if on7long lastDebounceTime = 0; // the last time the output pin was toggled8long debounceDelay = 50; // the debounce time; increase if the output flickers9String command = "/arduino/mode/13/output";10int previous_value = LOW;11void setup() {12 Ciao.begin();13 Ciao.write(CONNECTOR, SERVER_ADDR, command);14 pinMode(2, INPUT);15}16void loop() {17 //sample the state of the button - is it pressed or not?18 buttonState = digitalRead(2);19 //filter out any noise by setting a time buffer20 if ( (buttonState == HIGH) && (previous_value == LOW) && (millis() - lastDebounceTime) > debounceDelay ) {21 if (ledState == HIGH) {22 command = "/arduino/digital/13/0";23 ledState = LOW;24 }25 else {26 command = "/arduino/digital/13/1";27 ledState = HIGH;28 }29 lastDebounceTime = millis(); //set the current time30 CiaoData data = Ciao.write(CONNECTOR, SERVER_ADDR, command);31 if (!data.isEmpty()) {32 Ciao.println( "State: " + String (data.get(1)) );33 Ciao.println( "Response: " + String (data.get(2)) );34 }35 else {36 Ciao.println ("Write Error");37 }38 }39 previous_value = buttonState;40}
Rest Server connector
This connector allows to make “http” requests. Below the steps that you should follow to use the Rest connector:
You can find Rest Server Connector configuration file at the following path: /usr/lib/python2.7/ciao/connectors/restserver/restserver.json.conf
1{2 "name" : "restserver",3 "description" : "REST server connector for the Ciao Core",4 "authors": ["Arduino Team <swdev@arduino.org>;"],5 "repository" : "https://github.com/arduino-org/Ciao",6 "version" : "0.0.2",7 "params" : {8 "port" : 809 },10 "log" : {11 "level" : "info"12 }13}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key:
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable Rest Server connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/restserver.ciao.json.conf
1{2 "name" : "restserver",3 "enabled": true,4 "type" : "managed",5 [...]6}
The key enabled must be set to true (boolean value). This is the only parameter you are required to edit in order to enable the Rest Server Connector. Once done Ciao Core will be ready and configured to use Rest Server Connector.
1/*2 supported boards:Yun,Tian.3 Possible commands to send from the xmpp client:4 "/arduino/digital/PIN" -> to read a digital PIN5 "/arduino/digital/PIN/VALUE"-> to write a digital PIN (VALUE:1/0)6 "/arduino/analog/PIN/VALUE" -> to write in a PWM PIN(VALUE rang:0-255);7 "/arduino/analog/PIN" -> to read a analog PIN8 "/arduino/servo/PIN/VALUE" -> to write angle in a SERVO PIN(VALUE range:0-180);9 "/arduino/mode/PIN/VALUE" -> to set the PIN mode (VALUE: input / output)10 Example:11 "/arduino/mode/13/output"-> pinMode(13, OUTPUT)12 "/arduino/digital/13/1" -> digitalWrite(13, HIGH)13*/14
15#include<Ciao.h>16#include<Servo.h>17Servo servo;18
19void setup() {20 Ciao.begin();21}22
23void loop() {24 CiaoData data = Ciao.read("restserver");25 if (!data.isEmpty()) {26 String id = data.get(0);27 String sender = data.get(1);28 String message = data.get(2);29 message.toUpperCase();30 String command[3];31 splitString(message, "/", command, 3);32 execute(command, id);33 }34}35
36void execute(String cmd[], String id) {37 if (cmd[0] == "DIGITAL") {38 digitalCommand(cmd, id);39 }40 elseif(cmd[0] == "ANALOG") {41 analogCommand(cmd, id);42 }43 elseif(cmd[0] == "SERVO") {44 servoCommand(cmd, id);45 }46 elseif(cmd[0] == "MODE") {47 setMode(cmd, id);48 }49 else50 Ciao.writeResponse("restserver", id, "sorry, i don't understand :(");51}52
53void servoCommand(String cmd[], String id) {54 int pin, value;55 pin = (cmd[1]).toInt();56 if (cmd[2] != "-1") {57 value = (cmd[2]).toInt();58 if (value <= 180 && value >= 0) {59 servo.attach(pin);60 servo.write(value);61 Ciao.writeResponse("restserver", id, "Servo D" + String(pin) + " set to " + String(value) + " degrees");62 }63 else64 Ciao.writeResponse("restserver", id, "Invalid angle value");65 }66
67 else68 Ciao.writeResponse("restserver", id, "Invalid command");69}70
71void digitalCommand(String cmd[], String id) {72 int pin, value;73 pin = (cmd[1]).toInt();74 if (cmd[2] != "-1") {75 value = (cmd[2]).toInt();76 digitalWrite(pin, value);77 if (value == 1)78 Ciao.writeResponse("restserver", id, "Pin D" + String(pin) + " ON");79 elseif(value == 0)80 Ciao.writeResponse("restserver", id, "Pin D" + String(pin) + " OFF");81 }82 elseif(cmd[2] == "-1") {83 value = digitalRead(pin);84 Ciao.writeResponse("restserver", id, "D" + String(pin) + " value = " + String(value));85 }86}87
88void analogCommand(String cmd[], String id) {89 int pin, value;90 pin = (cmd[1]).toInt();91 if (cmd[2] != "-1") {92 value = (cmd[2]).toInt();93 analogWrite(pin, value);94 Ciao.writeResponse("restserver", id, "D" + String(pin) + " set to analog");95 }96 elseif(cmd[2] == "-1") {97 value = analogRead(pin);98 Ciao.writeResponse("restserver", id, "A" + String(pin) + " value = " + String(value));99 }100}101
102void setMode(String cmd[], String id) {103 int pin;104 pin = (cmd[1]).toInt();105 if (cmd[2] == "INPUT") {106 pinMode(pin, INPUT);107 Ciao.writeResponse("restserver", id, " pin D" + String(pin) + " set in INPUT mode");108 return;109 }110 if (cmd[2] == "OUTPUT") {111 pinMode(pin, OUTPUT);112 Ciao.writeResponse("restserver", id, " pin D" + String(pin) + " set in OUTPUT mode");113 return;114 }115 Ciao.writeResponse("restserver", id, "invalid mode");116}
File System connector
This Connector allows to read and write a file on Linux side from an Arduino sketch. Below the steps that you should follow to use the File connector:
You can find File Connector configuration file at the following path: /usr/lib/python2.7/ciao/connectors/file/file.json.conf
1{2 "name" : "file",3 "description" : "File System connector for Ciao",4 "authors": ["Arduino Team <swdev@arduino.org>;"],5 "repository" : "https://github.com/arduino-org/Ciao",6 "version" : "0.0.1",7 "params" : {8 "root" : "/root",9 "eol" : "\n",10 "read_line" : false,11 "read_max_size" : 1024,12 "default_write_access_mode" : "w"13 },14 "log" :{15 "level" : "debug"16 }17}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key:
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable File connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/file.ciao.json.conf
1{2 "name" : "file",3 "enabled": true,4 "type" : "managed",5 [...]6}
The key enabled must be set to true (boolean value). This is the only parameter you are required to edit in order to enable the File Connector. Once done Ciao Core will be ready and configured to use File Connector.
1#include <Ciao.h>2int buttonPin = 5;3int pressed = 0;4void setup() {5 //init Ciao6 Ciao.begin();7 pinMode(buttonPin, INPUT);8}9void loop() {10 //Read digital input11 pressed = digitalRead(buttonPin);12 //Write value into a file in root folder. Root folder is specified into the connector13 //configuration file: /usr/lib/python2.7/ciao/connectors/file/file.json.conf14 //Else you can specify the absolute path for the file, eg: /tmp/my-file.log15 Ciao.write("file", "button.txt", (String)pressed, "w");16 //Delay the operations because IO is slow17 delay(1000);18}
Shell connector
This Connector allows to execute Shell commands for Linux side from an Arduino sketch. Below the steps that you should follow to use the File connector:
You can find File Connector configuration file at the following path: /usr/lib/python2.7/ciao/connectors/shell/shell.json.conf
1{2 "name":"shell",3 "description":"Shell connector for the Ciao Core",4 "authors":["Arduino Team <swdev@arduino.org>;"],5 "repository":"https://github.com/arduino-org/Ciao",6 "version":"0.0.1",7 "params": {8 "working_directory":"/root",9 "read_max_size":102410 },11 "log":{12 "level":"debug"13 }14}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key:
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable Shell connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/shell.ciao.json.conf
1{2 "name":"shell",3 "enabled":true,4 "type":"managed",5 [...]6}
The key enabled must be set to true (boolean value). This is the only parameter you are required to edit in order to enable the Shell Connector. Once done Ciao Core will be ready and configured to use Shell Connector.
1#include <Ciao.h>2
3void setup() {4 //init Ciao5 Ciao.begin();6 Serial.begin(9600);7}8void loop() {9 //Run commands in Linino OS to get date10 CiaoData data = Ciao.write("shell", "date");11 if (!data.isEmpty()) {12 //Get data back13 String usage = data.get(2);14 Serial.println(usage);15 }16 delay(10000);17}
MQTT connector
This Connector allows to communicate using MQTT in an Arduino sketch. Below the steps that you should follow to use the MQTT connector:
You can find MQTT Connector configuration file at the following path: /usr/lib/python2.7/ciao/connectors/mqtt/mqtt.json.conf
1{2 "name" : "mqtt",3 "description" : "MQTT (v3.1) connector for Ciao Core",4 "version" : "0.0.1",5 "ciao": {6 "host" : "127.0.0.1",7 "port" : 89008 },9 "params" : {10 "host" : "YOUR_MQTT_IP_OR_HOSTNAME",11 "port" : 1883,12 "username" : "USERNAME_IF_REQUIRED",13 "password" : "PASSWORD_IF_REQUIRED",14 "clean_session": true,15 "qos": 2,16 "subscribed_topic": [ "TOPIC_TO_SUBSCRIBE" ],17 "client_id": "",18 "lwt_topic": "",19 "lwt_message": ""20 }21}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key:
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable MQTT connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/mqtt.ciao.json.conf
1{2 "name" : "mqtt",3 "enabled": true,4 "type" : "managed",5 [...]6}
The key enabled must be set to true (boolean value).
This is the only parameter you are required to edit in order to enable the MQTT connector. Once done your LininoOS will be ready and configured to use Ciao Core and MQTT connector.
1#include <Ciao.h>2
3#define LED 134String TOPIC = "topic_subscribed";5
6void setup() {7 pinMode(LED, OUTPUT);8 Ciao.begin();9}10
11void loop() {12
13 CiaoData data = Ciao.read("mqtt");14
15 if (!data.isEmpty() && !data.isError()) {16
17 String id = data.get(0);18 String sender = data.get(1);19 String message = data.get(2);20
21 message.toLowerCase();22
23 if (message == "ciao" )24 Ciao.write("mqtt", TOPIC, "Hello, i'm Arduino :-) ");25 else if ( message == "led on") {26 digitalWrite(LED, HIGH);27 Ciao.write("mqtt", TOPIC, "LED ON");28 }29 else if ( message == "led off") {30 digitalWrite(LED, LOW);31 Ciao.write("mqtt", TOPIC, "LED OFF");32 }33 else34 Ciao.write("mqtt", TOPIC, "Sorry i don't understand :-( ");35 }36}
XMPP connector
This Connector allows to communicate using XMPP in an Arduino sketch. Below the steps that you should follow to use the XMPP connector:
You can find XMPP configuration file at the following path: /usr/lib/python2.7/ciao/connectors/xmpp/xmpp.json.conf
1{2 "name" : "xmpp",3 "description" : "XMPP connector for the Ciao Core",4 "version" : "0.0.1",5 "ciao": {6 "host" : "127.0.0.1",7 "port" : 89008 },9 "params" : {10 "host" : "YOUR_XMPP_IP_OR_HOSTNAME",11 "domain" : "ACCOUNT_DOMAIN",12 "port" : 5222,13 "username" : "USERNAME",14 "password" : "PASSWORD",15 "tls" : false,16 "ssl" : false17 }18}
The parameters at the beginning are for internal use, do NOT edit them (name, description, version, ciao) unless you know exactly what you are doing.
The configurable part is the one identified by "params" key:
Each Ciao connector must have a configuration file for the Ciao Core, this simple file is mandatory to enable the connector.
To enable XMPP connector please edit the file at the following path: /usr/lib/python2.7/ciao/conf/xmpp.ciao.json.conf
1{2 "name" : "xmpp",3 "enabled": true,4 "type" : "managed",5 [...]6}
The key enabled must be set to true (boolean value).
This is the only parameter you are required to edit in order to enable the XMPP connector. Once done your LininoOS will be ready and configured to use Ciao Core and XMPP connector.
1/*2 Arduino Ciao example3
4 This sketch uses ciao xmpp connector. It sends back “hello world” message to the xmpp client when receives “ciao” from it.5
6 Be sure to set the xmpp client in the "USER" field used to receive the response by MCU.7
8 Possible commands to send from the xmpp client:9 "ciao" -> random answers in 5 different languages10*/11
12#include <Ciao.h>13
14#define LED 1315String USER = "user@domain";;16
17void setup() {18 pinMode(LED, OUTPUT);19 Ciao.begin();20}21
22void loop() {23
24 CiaoData data = Ciao.read("xmpp");25
26 if (!data.isEmpty() && !data.isError()) {27
28 String id = data.get(0);29 String sender = data.get(1);30 String message = data.get(2);31
32 message.toLowerCase();33
34 if (message == "ciao" )35 Ciao.write("xmpp", USER, "Hello, i'm Arduino :-) ");36 else if ( message == "led on") {37 digitalWrite(LED, HIGH);38 Ciao.writeResponse("xmpp", id, "LED ON");39 }40 else if ( message == "led off") {41 digitalWrite(LED, LOW);42 Ciao.writeResponse("xmpp", id, "LED OFF");43 }44 else45 Ciao.write("xmpp", USER, "Sorry i don't understand :-( ");46 }47}
Ciao.begin()
Initializes the Ciao communication.
1Ciao.begin();2
3Returns4None
1#include <Ciao.h>2
3int ctrl=0;4void setup()5{6 Ciao.begin(); //Start the serial connection with the computer7 //to view the result open the serial monitor8 pinMode(9,OUTPUT);9}10
11void loop() // run over and over again12{13 //getting the voltage reading from the temperature sensor14 int readingTemp = analogRead(A0);15 // converting readingTemp to voltage16 float voltage = readingTemp * 4.56;17 voltage /= 1024;18 // now print out the temperature19 float temperatureC = (voltage - 0.5) * 100 ;20 int readingLum = analogRead(A2);21
22 analogWrite(9,map(readingLum,0,1023,0,255));23
24 if (ctrl>=10){25 Ciao.write("mqtt","iot-2/evt/status/fmt/json","{\"d\": {\"temperature\":"+String(temperatureC)+",\"luminosity\":"+String(readingLum)+"}}");26 ctrl=0;27 }28 ctrl++;29 delay(100);30}
Ciao.read()
The read function is usually used to receive data from the specified connector. It returns a CiaoData object. It accepts three optional parameters that could be used by the connector to customize and process the read request.
1read(connector [, param 1] [, param 2] [, param 3])2
3Returns4The requested data
1CiaoData data =Ciao.read("restserver");
Ciao.write()
The write function is usually used to send data outside the mcu through the specified connector. It returns a CiaoData object. It accepts three optional parameters that could be used by the connector to customize and process the write request.
1write(connector [, param 1] [, param 2] [, param 3])2
3Returns4None
1Ciao.write("file","button.txt","Hello!","w");
Ciao.writeResponse()
The writeResponse function is used to send a response to a specific connector request. The request is identified by the id. The id is part of CiaoData object coming from a call to read or write.
1writeResponse(connector, id [, param 1] [, param 2] [, param 3])2
3Returns4None
1CiaoData data = Ciao.read("restserver");2
3if(!data.isEmpty()){4 String id = data.get(0);5 String request = data.get(2);6 Ciao.writeResponse("restserver", id,"Request received: "+ request);7 }
Ciao.get()
The get function returns a string used to extract data from the CiaoData object. CiaoData could contains more than one information and all of these information are accessible through the index parameter. Data and information extracted and the index number depends on how the specified connector is implemented. See Connectors to know the meaning of each index.
1data.get(index);2
3Returns4The data at the selected index
1if(data.isError()){2 String id = data.get(0);3 String error = data.get(2);4 Serial.println("Error:" + error);5 }
Ciao.isError()
The isError function enables the user to check if the CiaoData object contain an error code. Returns true if the operation failed or false if not. If the operation failed, the error message is available at index #2 through the get function.
1data.isError()2
3Returns4True if an error is detected, false otherwise
1if(data.isError()){2 String id = data.get(0);3 String error = data.get(2);4 Serial.println("Error:" + error);5}
Ciao.isEmpty()
The isEmpty function enables the user to check if the CiaoData object is empty. Returns true if the operation isn’t yet completed by the connector, or false if the operation is completed and data is available.
1data.isEmpty();2
3Returns4True in case of empty data, false otherwise
1if(data.isError()){2 String id = data.get(0);3 String error = data.get(2);4 Serial.println("Error:" + error);5 }
Ciao.splitString()
The splitString function enables the user to manage the MCU command sent by the connector. The function accepts up four parameters, the first is the serial command for the MCU, the second parameter is the character that should be used to split the serial command, while the third and fourth parameter are respectively, the array of strings used to split the serial command received and the size of the array itself .
1data.get(string, divisor, array, size);2
3Returns4The data at the selected index
1#include<ciao.h>2
3void setup() {4 Ciao.begin();5 Serial.begin(57600);6 }7
8void loop() {9 CiaoData data = Ciao.read("xmpp");10 String id = data.get(0);11 String sender = data.get(1);12 String message = data.get(2);13 String command[3];14 splitString(message,"/",command,3);15 Serial.println("command type: "+command[0])16 //output is digital Serial.println("pin: "+command[1])17 //output is 13 Serial.println("pin value: "+command[2]))18 //output is 119 }