POSIX
calls and a Python script and create an alarm for unread Gmail emails in your inbox.A Little Bit of History
The Intel Makers Community
https://communities.intel.com/community/makers
.http://forum.arduino.cc/
.Installing the Arduino IDE for Intel Galileo
-
The Arduino web site at
http://arduino.cc/en/main/software
.
-
The Intel web site at
https://communities.intel.com/docs/DOC-22226
.
-
Windows: Just unzip the zip file using 7-zip, preferably to C:\. Open the folder that’s extracted and execute the
arduino.exe
file. -
Linux 32/64 bits: Extract the tarball zipped file to a new directory and execute the
./arduino
. Use the following command with the appropriate file name:
tgz file: tar –xvzf <
filename
>.tgz
-
MacOSX : Drag and drop the file into the
/Applications
folder to install the IDE. Launch it by double-clicking Arduino in theApplications
folder.
-
Windows: Never use Winzip! You should use the 7-zip tools (see
http://www.7-zip.org/
) because the cross-compiler used for Quark has long path names and several sub-directories. Winzip cannot handle these path names, which causes errors during the extraction. -
When zip fails in Linux: If you are a Linux developer and the unzip command fails to extract the package, you can install 7-zip with the command
sudo apt-get install p7zip-
full
for Ubuntu and Debian distributions or you can download the command-line tool fromhttp://www.7-zip.org/download.html
Connecting Intel Galileo
-
Check Figure 3-2 (left) if you have a Intel Galileo Generation 1. Always connect the 5V power supply (1) before the USB cable on client port (2) to avoid hardware damages.
-
Check Figure 3-2 (right) if you have a Intel Galileo Generation 2. Always connect the power supply (1) before the USB cable on client port (2) to avoid hardware damages. Remember, the Intel Galileo Gen 2 power supply must be between 7V and 12V DC. You cannot use 5V DC.
-
Always keep the power supply connected to Intel Galileo when transferring sketches or updating the firmware of your board. Developers are tempted to use the USB Client Port because it can boot the board and run the sketches but the 5V power supply is really recommended to keep connected in all occasions and to avoid hardware instability.
Installing the Drivers and the Arduino IDE
https://communities.intel.com/docs/DOC-22226
) for the latest instructions on how to install the serial driver and Arduino IDE. For your convenience, a version of the steps is provided here as well.Installing the Arduino IDE
Installing the IDE on Windows
http://www.7-zip.org
. This web site contains the installers for downloading. It is very simple to install; just follow the recommendations on the site. You then simply extract the zip file on any directory using the 7-zip tool.C:\
, but this is wrong. You are free to install anywhere.Installing the IDE on Linux
tar -zxvf arduino-1.5.3-linux32.tar.gz
tar -zxvf arduino-1.5.3-linux64.tar.gz
sudo apt-get remove modemmanager
./arduino
sudo arduino
sudo chmod 755 /dev/ttACM[X]
[X]
is the number of port enumerated in your machine, such as /dev/ttyACM0
.Installing the IDE on MacOS
Applications
folder on your Mac.Installing the Drivers
The Common Step to Install the Driver
Installing the Driver on Windows
hardware/arduino/x86/tools
directory. This allows the proper driver file called linux-cdc-acm.inf
to be installed.Installing the Driver on Linux
ls /dev/ttyACM*
ttyACM0
or any other ttyACM[X]
, where [X]
represents an integer number. If you cannot see a serial port, follow these steps:
KERNEL=="ttyACM[0-9]*", MODE="0666"
udev
service with the following command:sudo service udev restart
Installing the Driver on MacOS
Understanding the Arduino IDE
Number | Description |
---|---|
1 | Area code where you develop the code. |
2 | Notification bar informing you if the code was saved and whether the compilation was successful. |
3 | Console message with details of compilation, file transfer messages, and error messages. |
4 5 6 7 8 9 10 | Informs the line number of the cursor in the editor.
Verify icon: compile the code. Transfer icon: compile the code and transfer to Intel Galileo. Open a new sketch. Open a sketch. Save the edited sketch. Open the serial debug console. |
Checking the Port and Board Selected
-
Windows: The ports are named with the COM prefix, followed by an integer number, such as
COM5
. -
Linux: The ports are named with the
ttyACM
prefix, followed by an integer number, such asttyACM0
. -
MacOS: The ports are named with the
/dev/cu.usbmodem
prefix, followed by a sequence of numbers and/or alphabetic characters, such as/dev/cu.usbmodem0001
or/dev/cu.usbmodemfd021
.
/dev/tty
, because although these ports have the same nomenclature used on Linux machines, they are not the right ones.What Is a Sketch?
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led =
13
;
// the setup routine runs once when you press reset:
void
setup()
{
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void
loop()
{
digitalWrite(led, HIGH);
// turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW);
// turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
setup()
and loop()
.setup()
function is executed one time, and this function establishes the initial setup of your hardware, including the pin directions, the speed of the serial ports, device initializations, and so on.loop()
function is cyclic, which means it works like an infinite loop. It is on this function that you control your hardware.-
There is an LED connected to pin number 13.
-
In the
setup()
function, the pin is configured asOUTPUT
by thepinMode()
function. -
In the
loop()
function, theLED
will be turnedON
for one second and then turnedOFF
for one second again. The LED is turned on and off when thedigitalWrite()
function sets the pin toHIGH
andLOW
, respectively and the delay of one second is set by thedelay()
function, which received the number of milliseconds as an argument.
Compiling and Running the Sketch
"
Done compiling
"
in the area represented by the number 2 in Figure 3-3."Done uploading"
message in the notification bar and the "Transfer complete"
message in the console message area. These messages are represented by the numbers 2 and 3, respectively, in Figure 3-4.BATT
terminal, as shown in Figure 3-7.
Persisted and Not Persisted Sketches
Persisted Sketches and Long Time to Start
Debugging with Serial Console and Serial Communication
Serial
; however, if you need to communicate with external devices like XBee shields, you should use the 0 and 1 pins to connect to such devices. The communication in this case is done by a different object but with same class methods, called Serial1
. Arduino Uno uses the Serial
object to establish communication with the 0 and 1 pins, so if you are porting some sketch code created for Arduino Uno as the serial interface, you need to change the object from Serial
to Serial1
.Serial
object methods used to establish a communication and transmit messages: begin()
, print()
, println()
, available()
, and read()
.Serial.begin(int speed)
speed
argument indicates baud rate. The values typically are 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, and 115200.Serial
object for debugging messages, this argument is irrelevant because the communication with Serial
object is always 115200 bauds. If you set it to a different speed like 9600 bauds, the communication will still be 115200.Serial1
, which uses pins 0 and 1, speed really does have an effect in the communication because this object was created to communicate with external devices.Serial.print(data)
data
argument through the serial port. The data
argument might be a string, an integer, a char, a byte, a long, or any other standard type supported in the Arduino reference.Serial.println(data)
Serial.print()
method except a carrier and return is added to the end of the data message.Serial.available( )
Serial.read( )
available()
method.Serial
objects and how to invoke the serial console terminal.Printing Debug Messages and Using the Serial Console
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
// put your setup code here, to run once:
Serial.begin
(9600); // does not matter for this object
delay(3000);
}
void loop() {
// transmitting something from Galileo to IDE
Serial.println("Hi there!! type something and press SEND button!!! ");
delay(1000);
// if the developer sent something from IDE to Galileo
while (
Serial.available())
{
// get the new byte:
char inChar = (char)
Serial.read();
// add it to the inputString:
inputString += inChar;
if (inChar ==
'\n'
) {
stringComplete = true;
}
}
if (stringComplete == true) {
Serial.print
("\nCOOL!! RECEIVED YOUR MESSAGE: ");
Serial.println
(inputString);
inputString = "";
stringComplete=false;
}
}
"\n"
character, it is necessary to change the list box in the right-bottom corner to Both NL & CR. That means both newline and carriage return characters.Understanding the serialtest.ino Code
setup()
function, the serial object is initiated with 9600 bauds by Serial.begin()
. This is irrelevant as explained before because the communication is always 115200 bauds for Serial
.setup()
, there is a delay of three seconds to give you time to access the serial monitor. For Intel Galileo, if you are creating sketches that immediately print something, it is recommended that you add a small delay; otherwise, you can miss some messages (Galileo is faster than you).loop()
function, there is a message being printed by Serial.println()
followed by Serial.available()
that will always return false if you do not type anything in the text box and press the Send button in the serial console.Serial.available()
will return true. Each character of your message will be read by Serial.read()
and accumulated in the variable inputString
until the newline character (\n
) is encountered (this character is automatically added when you press the Send button or press Enter).Serial.print()
in the while
loop block contained by Serial.available()
.Serial.print()
and Serial.println()
that asks to the user to transmit something is added to the end of the loop()
function. There is a delay of 1000ms (1 second) initiated by the delay()
function to avoid multiples messages running in the serial console.The Arduino Language Reference and APIs
-
Structure:
loop()
andsetup()
-
Digital I/0:
pinMode()
anddigitalWrite()
-
Time:
delay()
-
Communication:
Serial.begin()
,Serial.print()
,Serial.println()
,Serial.available()
, andSerial.read()
http://arduino.cc/en/Reference/HomePage
, as shown in Figure 3-9.
Structure
setup()
and loop()
. Even if your sketch doesn’t need these functions, you should at least keep them empty in your sketch to avoid compilations. Each of these items is discussed next.setup( )
loop( )
Digital I/O
pinMode(int pin, int mode)
setup()
function and sets the “pin” that means the pin number to a specific “mode,” which can be INPUT
, OUTPUT
, or INPUT_PULLUP
.mode
is INPUT
, the pin
is used as INPUT
; for example, to read the state of a button.mode
is OUTPUT
, the pin
is used as OUTPUT
; for example, to turn on/off an LED.mode
is set to INPUT_PULLUP
and the pullup resistor is around 20k ohms, that means if you use a pulldown resistor the logic will be inverted. If no pulldown resistor is used, the reading still will be 1
if you have 5 to 3.3V or 0
if it’s connected to the ground.digitalWrite(int pin, int state)
pin
state according to the state
argument that’s passed, which can be HIGH
or LOW
. It works only if pin
was set as OUTPUT
by the pinMode()
function.int digitalRead(int pin)
pin
number and returns HIGH
or LOW
(both are integers).Analog I/O
int analogRead(int pin)
pin
that can assume the values A0 to A5, according to the six analog ports supported by Intel Galileo. The value returned is an integer between 0 and 1023 and refers to the scale of 0 to 5V, respectively. Intel Galileo has 12-bit maximum resolution in the ADC. Figure 3-10 shows the analog ports on the Intel Galileo board.
analogWrite(int pin, int value)—PWM
pin
argument specifies which PIN must generate the PWM with a duty cycle set by value
.3
, 5
, 6
, 9
, 10
, and 11
. You also can easily identify such pins because there is a small tilde (∼
) in front of the pins that support PWM, as shown in Figure 3-11.value
must be an integer between 0 and 255, and this range is proportional to the percentage of 0% to 100% of the duty cycle to be generated. Thus, if the value is 0, the duty cycle is zero. 127 will generate a PWM with 50% of duty cycle and 255 a duty cycle with 100%.Time
long millis( )
long micros( )
delay(int milliseconds)
milliseconds
.delayMicroseconds(int microseconds)
microseconds
argument.Running Some Examples
Fade Example
pinMode()
function to set pin 9 to OUTPUT
. It also shows how to generate a PWM to simulate a fading effect. The code varies the duty cycle applied in a pin port connect to an LED, which changes the intensity of the LED.Fade Materials list
Number | Description |
---|---|
1 | LED |
1 | 220 ohm resistor |
1 | Breadboard |
n | Hook-up wires (assorted) |
Fade Schematics
Fade Code
/*
Fade
This example shows how to fade an LED on pin 9
using the analogWrite() function.
This example code is in the public domain.
*/
int led = 9; // the pin that the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
// wait for 30 milliseconds to see the dimming effect
delay(30)
;
}
Running the Fade Sketch
setup()
is executed only once. It sets pin 9 to OUTPUT
through the pinMode()
function. In the loop()
function, analogWrite()
generates a PWM with a duty cycle of 0 stored in the brightness
variable. The duty cycle increases by five, as defined by the variable fadeAmount
, until it reaches 255. At this point, the duty cycle reduces by five again until it reaches 0. The logic then starts increasing the duty cycle again. This logic will create a PWM varying the duty cycle, causing a diming effect.ON
and OFF
.Button Example
digitalRead()
function to read the state of a working input method. It uses digitalWrite()
to turn on an LED. Note that this example uses an LED on pin 13, which means you do not need to connect an LED to pin 13 because pin 13 is connected to the LED built in to the Intel Galileo, as shown in Figure 3-7. However, if you connect an LED to pin 13 similar as you connected on pin 2 in the fade example , you will see two LEDs working at same time you push the button or switch. In other words, you will see the built-in and the external LED having the same effect. The 10k ohm resistor is used to limit the current and then the button is opened. This prevents a short circuit between the 5V and the GND in the board.pinMode()
function is used to set the pins to OUTPUT
and INPUT
.Button Materials List
Number | Description |
---|---|
1 1 | 10k ohm resistor Pushbutton or switch |
1 | Breadboard |
n | Hook-up wires (assorted) |
Button Schematics
Button Code
/*
Button
Turns on and off a light emitting diode(LED) connected to digital
pin 13, when pressing a pushbutton attached to pin 2.
* LED attached from pin 13 to ground
* pushbutton attached to pin 2 from +5V
* 10K resistor attached to pin 2 from ground
* Note: on most Arduinos there is already an LED on the board
attached to pin 13.
created 2005
modified 30 Aug 2011
by Tom Igoe
This example code is in the public domain.
*/
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop(){
// read the state of the pushbutton value:
buttonState =
digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH)
{
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
Running the Button Sketch
setup()
function is called once you’ve set pin 13 to OUTPUT
and pin 2 to INPUT
through pinMode()
.loop()
function, the variable buttonState
receives the current state of the switch or pushbutton. When you press the button, digitalRead()
returns HIGH
and buttonState
saves this value and the digitalWrite()
function sets pin 13 (LED) to HIGH
, thus turning ON
the built-in LED.digitalRead()
returns LOW
and the buttonState
variable saves this value. Then the digitalWrite()
function sets pin 13 (LED) to LOW
, turning OFF
the built-in LED.ReadAnalogVoltage Example
analogRead()
function to convert the voltage over a potentiometer to a digital reading.Serial
object discussed previously to print the value read in the serial console terminal.ReadAnalogVoltage Materials List
Number | Description |
---|---|
1 1 | Potentiometer (any!) Breadboard |
n | Hook-up wires (assorted) |
ReadAnalogVoltage Schematics
The ReadAnalogVoltage Code
ReadAnalogVoltage
example./*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue =
analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(voltage);
}
Running the ReadAnalogVoltage Sketch
loop()
function that the analogRead()
command reads the analog port A0
and the variable sensor value saves it.analogRead()
was discussed previously, that the return value was between 0 and 1023. In this case, 0 means 0V and 1023 means 5V in the port A. This conversion is being done by the voltage variable that’s printed in the serial console terminal by Serial.println()
.The Debounce Example
millis()
function to add logic based on time. It determines whether a button was pressed after a period of time, in order to avoid interpreting multiples presses. This is called debounce.Debounce Materials List
Debounce Schematics
Debounce Code
/* Listing 3-5 Debounce.ino.
Debounce
Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's
a minimum delay between toggles to debounce the circuit (i.e. to ignore
noise).
The circuit:
* LED attached from pin 13 to ground
* pushbutton attached from pin 2 to +5V
* 10K resistor attached from pin 2 to ground
* Note: On most Arduino boards, there is already an LED on the board
connected to pin 13, so you don't need any extra components for this example.
created 21 November 2006
by David A. Mellis
modified 30 Aug 2011
by Limor Fried
modified 28 Dec 2012
by Mike Walters
This example code is in the public domain.
*/
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0 // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED:
digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
}
Running the Debounce Sketch
setup()
function sets pin 2 to INPUT
because the button or switch should be connected to this pin. Pin 13 (the internal built-in LED) is set to OUTPUT
.loop()
function reads the button state through digitalRead()
and the variable reading assumes the value. If the button state differs from the last read, the lastDebounceTime
variable assumes the current millis()
. Then the loop
function keeps running and reading the button states, but when the debounceDelay
interval is reached after the first button pressing, the state is checked again. If the code detects that the user was still pressing the button, the LED state is changed.Updating the Firmware Using the IDE
dediprog
and the manual procedure to upload the firmware to the board, which was discussed in the Chapter 2, there is a third option involving IDE and it is much simpler.Updating the Firmware with Different Firmware
https://communities.intel.com/docs/DOC-22226
) and then download the file with the .cap
extension to the following locations:
-
Windows: .../Arduino<IDE VERSION>/hardware/tools/x86/bin/
-
Linux: .../Arduino<IDE VERSION>/hardware/tools/
-
MacOS: Arduino.app/Contents/Resources/Java/hardware/tools/x86/bin/
.cap
file to one of these locations, make sure you delete or change the extension of the old .cap
file because only one cap file can be present in this location.Troubleshooting the Drivers
Serial Communication Issues with IDE on Windows
C:\galileo-arduino-1.5.3/hardware/arduino/x86/tools/izmir/clupload_win.sh: line 40: /dev/ttyS8: No such file or directory
cmd.exe
). If you are using Windows 7, you must start the Command Prompt as the administrator. According to Figure 3-18, click in the Start icon (1) and type cmd
, as shown in the figure (2). Don’t press Enter. As soon you type cmd
, you will see the cmd.exe
file available in Programs, as shown in Figure 3-18 (3).set devmgr_show_nonpresent_devices=1
and start devmgmt.msc
. See Figure 3-19.IDE Problems with Virtual Machines and 64-Bit Linux
Warning Messages with 64-Bit Linux
/ibus/bus is not root
, try starting the IDE using gksudo ./arduino
instead of sudo ./arduino
. To install the gksudo
, use the sudo apt-get install gksu
command.Problems with VMware
/dev/ttySx
where x
is the port number. There is a bug in VMware if the comm port is automatically recognized and selected without any manual intervention. If that happens, disconnect the port as shown in Figure 3-24 and then reconnect it.
Problems with Oracle Virtual Box
Communicating Sketches with Linux Native Programs
POSIX
libraries can be used to establish communication as any other regular program in Linux OS.POSIX
. Considering Python is being used you should have an SD card image because SPI images are very tiny and do not contain additional software like Python. Additional examples are covered in future chapters.is.Additionalfuture Project Example: Unread Email Alarm with Python and POSIX Functions
POSIX
APIs to create a timer that asynchronously calls a function handler every 10 seconds. When this function handler is executed, it calls a Python script that counts the number of emails unread in a Gmail account. If the number of emails increased, an LED is ON
, which informs you that there is new email in the inbox.Materials List
Number | Description |
---|---|
1 | LED |
1 | 220 ohm resistor |
1 | Breadboard |
n | Hook-up wires (assorted) |
Quantity | Components |
---|---|
1 | Intel Centrino Wireless-N 135 or Ethernet cable |
2 | Dual band antennas 350mm cable 2118060-1 TE Connectivity (only if WiFi) |
1 1 n 1 | LED 220 ohm resistor Hook-up wires (assorted) Breadboard |
The Schematics
The PythonP Code
emailCounter.
py
and it accepts two arguments wherein the first argument is your Gmail’s username or email and the second argument is your password.python email.counter <your username or email> <your password>
# based in the discussion in:
# by manoel.c.ramon@intel.com
import imaplib
import sys
obj = imaplib.IMAP4_SSL('imap.gmail.com','993')
obj.login(sys.argv[1],sys.argv[2])
obj.select()
obj.search(None,'UnSeen')
print len(obj.search(None,'UnSeen')[1][0].split())
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
// the led
int led = 2; // the built-in LED
// emails counters
int current_emails_counter = -1;
int last_emails_counter = -1;
// add here your credentials
String gmailUserName=""; // email or password
String gmailPassword=""; // your password
String script_name = "python /home/root/emailCounter.py ";
// this function calls a Python script to read the number of emails not read
int
processEmailCounter
()
{
char cmd_rsp[8]; // This buffer will containg the script response
FILE *fpipe;
String command = script_name;
command += gmailUserName;
command += " ";
command += gmailPassword;
// buffer to be used with popen
char cmd_char[300];
// clear message buffer
memset((void *)cmd_char, sizeof(cmd_char), 0);
// convert the message to char array
command.toCharArray(cmd_char, sizeof(cmd_char), 0);
if ( !(fpipe = (FILE*)popen((char *)cmd_char,"r")) )
{ // If fpipe is NULL
Serial.println("Problems with pipe");
}
else
{
while ( fgets( cmd_rsp, sizeof(cmd_rsp), fpipe)) {}
pclose(fpipe);
// let's print the serial result
Serial.println(cmd_rsp);
return atoi(cmd_rsp);
}
return -1;
}
// this is my time handler...
void
timerHandler
(int signum)
{
current_emails_counter = processEmailCounter();
if (last_emails_counter == -1)
{
last_emails_counter = current_emails_counter;
Serial.println("I am ready to check now... ");
}
if (current_emails_counter != last_emails_counter)
{
// turn on the LED
digitalWrite(led, HIGH);
}
}
int setAlarm ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timerHandler;
sigaction (SIGVTALRM, &sa, NULL);
// Configure the timer to expire after 1 seconds
timer.it_value.tv_sec
= 1;
timer.it_value.tv_usec = 0;
// ... and every 10 seconds after that
timer.it_interval.tv_sec
= 10;
timer.it_interval.tv_usec = 0;
// Start a virtual timer. Counter while sketch runs
setitimer (ITIMER_VIRTUAL,
&
timer, NULL);
}
void setup() {
// only a small delay to allow you press CTRL+SHIT+M
// and see the Serial Monitor
delay(3000);
// set the alarm
setAlarm();
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
}
Preparing the Project to Run
/home/root/emailCounter.py
. Otherwise, you have to change the sketch code to the path you want.// add your credentials here
String gmailUserName=""; // email or password
String gmailPassword=""; // your password
Running the Code
ON
.Reviewing the Code
setup()
function has a delay of three seconds in order to allow you to start the serial console and catch the first debug messages printed by Serial.print()
and Serial.println()
. The setup()
function also initializes the timer setting by calling the setAlarm()
function. It sets pin 2 to OUTPUT
through pinMode()
because the LED must be connected to this pin and then turns off the LED by having digitalWrite()
pass LOW
.setAlarm()
function creates a timer using setitimer()
, which in turn calls a function handler called timerHandler()
in one second, as soon the sketch runs, and then every 10 seconds after that. With the regular Arduino reference you could control the seconds passed in the loop() function using millis(); however, using the POSIX
functions is much easier. The timer that’s created is the ITIMER_VIRTUAL
type, which means the function handler is called only while the sketch is running.setitimer()
works, visit this link:
http://unixhelp.ed.ac.uk/CGI/man-cgi?setitimer+2
.timerHandler()
is called, it calls the processEmailCounter()
function, which is responsible for executing the emailCounter.py
Python script. This script receives your credentials and returns the number of unread emails in your Gmail inbox. The sketch receives the response using the popen()
function (ANSI C) and receives the number of emails in a char
array, which is converted to an integer format using atoi()
.timerHandler()
uses two variables called current_emails_counter
and last_emails_counter
. They determine if the number of unread email increased according to the processEmailCounter()
function. If there was an increase, the LED connected to pin 2 is set to HIGH
by digitalWire()
.loop()
:void loop() {
// put your main code here, to run repeatedly:
}
POSIX
calls provided by the Linux libraries. Note that a few functions from the Arduino reference were used: pinMode()
and digitalWrite()
.
Summary
POSIX
functions and how to interface with Python scripts.