Saturday, February 8, 2014

Current configuration brief wrap-up

OK, it's time to wrap up the SMS monitor based on arduino for the time being as I work on the internet-based version, which I am documenting in a separate blog.

The arduino is a Uno costing around $30.00

The GPRS/GSM modem board is a SIM900 gprs/gsm shield from  http://store.linksprite.com/, and cost $39.00.

The SIM card is a gophone card with pay as you go and I have a text plan that costs $10.00 per month for 1000 text messages.

I built the temperature and A/C power interfaces on an Arduino prototyping board. It connects to two 10K NTC temperature sensitive resistors for outside and inside temperature measurements. These connect to Arduino analog inputs 0 and 1. It connects via an opto isolator to a small cube-type 5V USB A/C power supply like those used for iPhone and MP3 charging, which supplies 5 V when A/C power is on and zero when off. This connects to Arduino digital input pin 3. A/C power is indicated by an led connected to pin 5.

The protoboard schematic is:

Power is supplied by a single USB cable that splits to provide power to the SIM900 GSM board, which requires more power than the Arduino board can supply, via a barrel connector and a standard USB B connector to Arduino. 

Here are some photos, invarious stages of undress:





And code:

//  Name

//       tweet_house_status_sec_hp
//
//  Description
//
//    Sketch to measure two temperatures and report via SMS both periodically and 
//    when changes greater than some threshold are observed.
//
//    Hardware needed:
//
//    Arduino (Uno, professional, etc.)
//    SIM900 gsm/gprs shield and activated sim card.
//
// Author: John Zouck
// Initial release date: November 24, 2013
//
#include <SIM900gsm.h>
#include <SoftwareSerial.h>
#include <gsm_timer_sec.h>
#include <thermistor.h>
#include <counts_last_period.h>
#include <Time.h>
#include <EEPROM.h>

static int house_power = 3;     // House power reported on pin 3
static int power_led = 5;       // Power led indicator is pin 5
static SoftwareSerial gprs(7,8);

#define TWEET_PERIOD_MINUTES 240   // 4 hours max per tweet
#define DELTA_TEMP 4.0             // delta temp to cause report: degrees F
#define TEMP_CHECK_TIME_SEC  2   // check temps and power every 2 seconds
#define TMIN_REPORT_TIME_MINUTES 1  // Report no more than once every 1 minutes.
#define SMS_CHECK_PERIOD_SECONDS 15
#define SMS_REPLY_TEST_DIVISOR  1


static gsm_timer_sec tcheck;
static gsm_timer_sec treport;
static gsm_timer_sec tchecksms;
// Last sampled temperature values.
static  float temp0;
static  float temp1;
// Calibraton factors, put in EEPROM.
static  float delta_temp0 = 0.0;
static  float delta_temp1 = 0.0;
static  int hp_last = 0;

static counts_last_period clp( 30 * 60 * 1000); // Limit to 10 SMS per 30 minutes

static char *buildtstr( unsigned long t, char *str);
static void checksms( float t1, float t2, char *reply );
static char *build_report( float t1, float t2, int hp, char *str);
static int report_temps( char *str);
static int calibrate( char *sms, char *sender);
static int rcals( float *cf1, float *cf2);
static int wcals( float *cf1, float *cf2);
static char *build_cal_report( float ct1, float ct2, char *str);

// Noise reduction for analog inputs via averaging values

static int analog_average( int ch, int n ) {
  int i;
  int sum = 0;
  for (i = 0; i < n; i++ ) {
    sum += analogRead( ch );
    delay (1);
  }
  return sum/n;
}

// The following #define is used so we can test without
// actually sending any messages.
#define GSM_SMS_ENABLE

void setup() {
  char str[100];
  unsigned long t;
  int rply;
  uint8_t tm[6];   // 0-5: yy mm dd hh mi ss

  gprs.begin(9600); // Slow down output from modem so we can keep up...

  Serial.begin(115200);

  SIM900poweron( gprs);
  Serial.println("Modem power on and sim card registered.");


  // Set Time package time from Modem BBU clock once
  // Use time package functions from now on so we
  // don't have to query modem each time we want time.

  // Get time and date from modem bbu clock once:

  rply = SIM900date_sec( gprs, &t, str, 95, tm);

  // Set time and date in software clock.
  // Args are: hh, mi, ss, dd, mm, yy
  // i.e. for 18:21:00 on November 23, 2013:
  //    setTime( 18, 21, 0, 23, 11, 13);

  setTime( tm[3], tm[4], tm[5], tm[2], tm[1], tm[0]);

  switch (timeStatus()) {
  case timeSet:
    Serial.print("Program tweet_house_status_sec started at time = ");
    Serial.println( buildtstr(now(), str));
    break;
  case timeNotSet: 
  case timeNeedsSync:
  default: 
    Serial.println("Time not synced.");
  }

  strcat( str, ": tweet_house_status_sec program startup.");
  // Erase all SMS
  //rply = SIM900eraseall( gprs, 0);
  pinMode( house_power, INPUT);
  pinMode( power_led, OUTPUT);
#ifdef GSM_SMS_ENABLE
  rply = SIM900tweet( gprs, str );
#endif

  // Read cal factors from EEPROM
  rcals( &delta_temp0, &delta_temp1);
  // Print cal factors
  Serial.println("EEPROM cal factors 1 and 2: ");
  Serial.println(delta_temp0, 4);
  Serial.println(delta_temp1, 4);

  tcheck.start(TEMP_CHECK_TIME_SEC); // seconds between temperature checks
  treport.start( TWEET_PERIOD_MINUTES * 60 ); // report period if no delta temp detected.
  tchecksms.start( SMS_CHECK_PERIOD_SECONDS/SMS_REPLY_TEST_DIVISOR);  // Period to check for new SMS
}


void loop () {
  float temp0_c;
  float temp1_c;
  int cnt;
  static float lt0 = -50.0;
  static float lt1 = -50.0;
  char report_s[76];
  int hp;
  
  // Read house power pin
  hp = digitalRead( house_power );
  if ( hp == 0 ) {
      digitalWrite( power_led, LOW);
  } else {
      digitalWrite( power_led, HIGH);
  }
  
  if ( tcheck.check()) {
    temp0 = thermistor_tempf (analog_average(0, 10)); // get value
    temp1 = thermistor_tempf (analog_average(1, 10)); // get value
    temp0_c = delta_temp0 + temp0;
    temp1_c = delta_temp1 + temp1;

    build_report( temp0_c, temp1_c, hp, report_s);

    if ( (abs( temp0_c - lt0 ) > DELTA_TEMP  || abs( temp1_c - lt1) > DELTA_TEMP ||
      treport.check() || hp != hp_last) && !clp.check( millis()) ) {

      hp_last = hp;
        Serial.println( report_s );

#ifdef GSM_SMS_ENABLE
      report_temps( report_s);
#endif

      lt0 = temp0_c;
      lt1 = temp1_c;
      treport.start( TWEET_PERIOD_MINUTES * 60);
    }
    tcheck.start( TEMP_CHECK_TIME_SEC );
  }

  if ( tchecksms.check() ) {
    checksms(report_s);
    tchecksms.start( SMS_CHECK_PERIOD_SECONDS / SMS_REPLY_TEST_DIVISOR);
  }
}

// See if there are any SMS messages waiting. Reply with "reply"
// argument and erase SMS if so.

static void checksms( char *reply ) {
  int cnt;
  int rply;
  int smslist[31];
  char sms[200];
  char calreport[70];

  Serial.print("In checksms(), freeRam: ");
  Serial.println( freeRam() );

  cnt = SIM900getsmsixl( gprs, smslist, 32, 10000);
  if ( cnt > 0 ) 
  {
    char sender[20];
    for ( int i = 0; i < cnt; i++) {
      SIM900getsms( gprs, smslist[i], sms, 190, 5000);
      //Serial.println(sms);
      SIM900getsender( sms, sender ); 
      if ( calibrate( sms, sender) ) {
        build_cal_report( delta_temp0, delta_temp1, calreport);
#ifdef GSM_SMS_ENABLE
          SIM900sendsms( gprs, calreport, sender);
#endif
      } 
      else {
        // Reply, but not to twitter (40404)
        if ( NULL == strstr( sender, "40404") ) {
          Serial.print("Replying to sender: ");
          Serial.println( sender);
#ifdef GSM_SMS_ENABLE
          SIM900sendsms( gprs, reply, sender);
#endif
        }
      }
    }

#ifdef GSM_SMS_ENABLE
    SIM900eraseall( gprs, 0);
#endif

  }

// Calibrate therms t1 and t2 by sending SMS with text "CALT1=xx.x" or
// "CALT2=yy.y" where xx.x and yy.y are actual temperatures, like 32.0 if
// therm is in ice bath at 32 degrees.

static int calibrate( char *sms, char *sender) {
  float ct1;
  char *calt1;
  float ct2;
  char *calt2;
  int calrcvd = 0;

  //Serial.println("calibrate() called.");
  if ( NULL != (calt1 = strstr( sms, "CALT1=") )) {
    //Serial.print("Got a CALT1= SMS to calibrate temperature T1 is: ");
    ct1 = strtod( calt1 + 6, NULL);
    //Serial.println(ct1);
    delta_temp0 = ct1 - temp0;
    // Write to EEPROM
    wcals(&delta_temp0, &delta_temp1);
    calrcvd = 1;
  }
  if ( NULL != (calt2 = strstr( sms, "CALT2=") )) {
    //Serial.print("Got a CALT2= SMS to calibrate temperature T2 is: ");
    ct2 = strtod( calt2 + 6, NULL);
    //Serial.println(ct2);
    delta_temp1 = ct2 - temp1;
    // Write to EEPROM
    wcals(&delta_temp0, &delta_temp1);
    calrcvd = 1;
  }
  return calrcvd;
}
// Report temperatures via SMS
// Right now we just tweet to 40404. Later we might add sending
// SMS to a list of cell phones as well.

static int report_temps( char *str) {
  int rply;

  Serial.println("Tweeting: ");
  Serial.println(str);

  rply = SIM900tweet( gprs, str );
}

// Build string with leading time and date (current time) and
// temperatures t1 and t2, like:
//
//   "11/24/2013 12:03:52    48.3 F and    33.6 F."
//
// Need min. of 46 characters space in char array str points to.

static char *build_report( float t1, float t2, int hp, char *str) {
  char ts[15];
  unsigned long t;

  buildtstr( now(),str);
  dtostrf( t1, 7, 1, ts);
  strcat( str, ts );
  strcat( str, " F and ");
  dtostrf( t2, 7, 1, ts);
  strcat( str, ts );
  strcat( str, " F, Power: ");
  if ( hp ) {
     strcat( str, "ON");
  } else {
      strcat( str, "OFF");
  }  
  return str;
}

// Build string with leading time and date (current time) and
// calibration constants.
//   "11/24/2013 12:03:52    -1.2 F and    2.6 F."
//
// Need min. of 66 characters space in char array str points to.

static char *build_cal_report( float ct1, float ct2, char *str) {
  char ts[15];
  unsigned long t;

  buildtstr( now(),str);
  strcat( str, " Calibration consts: ");
  dtostrf( ct1, 7, 1, ts);
  strcat( str, ts );
  strcat( str, " F and ");
  dtostrf( ct2, 7, 1, ts);
  strcat( str, ts );
  strcat( str, " F.");
  return str;
}


// Build time string from time t.
// buildtstr( now(), str) returns:
//       "11/24/2013 12:03:52"


static char *buildtstr( unsigned long t, char *str) {
  sprintf( str, "%02d/%02d/%02d %02d:%02d:%02d ", month(t),
  day(t), year(t), hour(t), minute(t), second(t));
  return str;
}

static int wcals( float *cf1, float *cf2) {
  // write 4-byte floats to locations 0 and 4 in EEPROM
  for (int i = 0; i < 4; i++) {
    EEPROM.write(i, *((byte *) cf1 + i));
  }
  for (int i = 4; i < 8; i++) {
    EEPROM.write(i, *((byte *) cf2 + i - 4));
  }
}

static int rcals( float *cf1, float *cf2) {

  // read 4-byte float 0.0 from locations 0 and 4 in EEPROM
  for (int i = 0; i < 4; i++) {
    *((byte *) cf1 + i) = EEPROM.read(i);
  }
  for (int i = 4; i < 8; i++) {
    *((byte *) cf2 + i - 4) = EEPROM.read(i);
  }
  //Serial.println("EEPROM cal factors 1 and 2: ");
  //Serial.println(*cf1, 4);
  //Serial.println(*cf2, 4);
  //Serial.println("Done!");

}









Friday, December 13, 2013

More ideas for improvement

Change reporting criteria to capture temperature inflections, like when temp. starts declining after successive rises.

Monday, December 2, 2013

Some ideas for improvement

Now that we have a very satisfactory unit in terms of basic functionality, power, cost an reliability, it's time to add some functionality to make more home information available via SMS. This is the first of a number of posts aimed at keeping track of desirable improvements.

  • Add SD-card recording capability if Arduino memory will allow. Stack the SD shield I have now in NH.

  • Change to variable reporting period. More frequent if very cold, or hot outside. 

  • Add ability to change reporting period via SMS, from only some phone numbers.

  • Add ability to turn on or off bits, maybe connected to alternate thermostats so temps can be set remotely.


  • Add a/c electrical power monitoring and UPS backup. Since we are away a lot we need to know when power goes out so we can avoid food rotting in unpowered refrigerators. SInce the unit uses fairly low power a simple low-energy UPS could be used to keep it running while we measure a/c power using a small wall-wart and optical isolator and single digital input on Arduino.

  • Monitor furnace burner  and well pump operational cycles using a/c wiring taps of some sort. Acquire on off times over longer periods and report some sort of statistics, like total running time each day, average, min and max running times, and average time between cycles. Store info in EEPROM (1 kbyte max) to ride through possible power outages.

  • Keep temperature min/max/average for day.

Results of 1 week test run: best system yet!

We just got back from a trip over Thanksgiving during which I left the new monitor running. The latest version measures two temperatures using 10K NTC thermistors, reports them periodically via twitter, and responds to SMS messages it is sent by returning the two temperatures. SMS can be sent via email or cell phone, and will respond in either case via email or SMS depending on where the SMS came from.

Happily the unit performed flawlessly. I got twitter reports as expected and responses to SMS from my iPhone and emails. I had the unit set to tweet every 2 hours, or when the temperature changed more than 5 degrees F.

The unit is much less expensive, simpler, lower power and more reliable than either of my earlier Linux based approaches. The hardware cost is $39 for the SIM900 modem shield and $28.80 for the Arduino, plus $11.99 for the power adapter and $7.99 for the case. I built the 10K NTC temperature sensors my self at negligible cost.

Here's a screenshot of the order from http://store.linksprite.com/:



The SIM card is my old AT&T Gophone account SIM, for which I buy packages of 1000 SMS for $9.99/month. At 30 SMS/day hat is more than enough for experimenting. If I built another for the condo I could probably use the cheaper Arduino pro.

Bottom line is the unit cost total of about $89 for the (unpackaged) hardware and $9.99/month cell service. That's a lot lower monthly cost than a unit that requires an internet connection, at least for moderate data usage packages.

Interestingly, my cell phone SIM from Black Wireless, an AT&T distributor of pay as you go service, worked from the cruise ship, which provided cell service at sea for the same $0.05 per SMS and voice minute (although I did not try to make voice calls.)

Here's a twitter page:



Wednesday, November 13, 2013

Arduino Standard Library and Example Trees in Ubuntu

Example code is found in:   /usr/share/doc/arduino-core/examples

Official Library code is found in:     /usr/share/arduino/libraries

Libraries


/usr/share/arduino
├── arduinopc.jar
├── examples -> ../doc/arduino-core/examples
├── hardware
├── libraries
│   ├── EEPROM
│   │   ├── EEPROM.cpp
│   │   ├── EEPROM.h
│   │   ├── examples
│   │   │   ├── eeprom_clear
│   │   │   │   └── eeprom_clear.ino
│   │   │   ├── eeprom_read
│   │   │   │   └── eeprom_read.ino
│   │   │   └── eeprom_write
│   │   │       └── eeprom_write.ino
│   │   └── keywords.txt
│   ├── Esplora
│   │   ├── Esplora.cpp
│   │   ├── Esplora.h
│   │   ├── examples
│   │   │   ├── EsploraKart
│   │   │   │   └── EsploraKart.ino
│   │   │   ├── EsploraLedShow
│   │   │   │   └── EsploraLedShow.ino
│   │   │   ├── EsploraLedShow2
│   │   │   │   └── EsploraLedShow2.ino
│   │   │   ├── EsploraMusic
│   │   │   │   └── EsploraMusic.ino
│   │   │   ├── EsploraRemote
│   │   │   │   └── EsploraRemote.ino
│   │   │   └── EsploraTable
│   │   │       └── EsploraTable.ino
│   │   └── keywords.txt
│   ├── Ethernet
│   │   ├── Dhcp.cpp
│   │   ├── Dhcp.h
│   │   ├── Dns.cpp
│   │   ├── Dns.h
│   │   ├── EthernetClient.cpp
│   │   ├── EthernetClient.h
│   │   ├── Ethernet.cpp
│   │   ├── Ethernet.h
│   │   ├── EthernetServer.cpp
│   │   ├── EthernetServer.h
│   │   ├── EthernetUdp.cpp
│   │   ├── EthernetUdp.h
│   │   ├── examples
│   │   │   ├── BarometricPressureWebServer
│   │   │   │   └── BarometricPressureWebServer.ino
│   │   │   ├── ChatServer
│   │   │   │   └── ChatServer.ino
│   │   │   ├── DhcpAddressPrinter
│   │   │   │   └── DhcpAddressPrinter.ino
│   │   │   ├── DhcpChatServer
│   │   │   │   └── DhcpChatServer.ino
│   │   │   ├── DnsWebClient
│   │   │   │   └── DnsWebClient.ino
│   │   │   ├── PachubeClient
│   │   │   │   └── PachubeClient.ino
│   │   │   ├── PachubeClientString
│   │   │   │   └── PachubeClientString.ino
│   │   │   ├── TelnetClient
│   │   │   │   └── TelnetClient.ino
│   │   │   ├── TwitterClient
│   │   │   │   └── TwitterClient.ino
│   │   │   ├── UdpNtpClient
│   │   │   │   └── UdpNtpClient.ino
│   │   │   ├── UDPSendReceiveString
│   │   │   │   └── UDPSendReceiveString.ino
│   │   │   ├── WebClient
│   │   │   │   └── WebClient.ino
│   │   │   ├── WebClientRepeating
│   │   │   │   └── WebClientRepeating.ino
│   │   │   └── WebServer
│   │   │       └── WebServer.ino
│   │   ├── keywords.txt
│   │   ├── util.h
│   │   └── utility
│   │       ├── socket.cpp
│   │       ├── socket.h
│   │       ├── w5100.cpp
│   │       └── w5100.h
│   ├── Firmata
│   │   ├── Boards.h
│   │   ├── examples
│   │   │   ├── AllInputsFirmata
│   │   │   │   └── AllInputsFirmata.ino
│   │   │   ├── AnalogFirmata
│   │   │   │   └── AnalogFirmata.ino
│   │   │   ├── EchoString
│   │   │   │   └── EchoString.ino
│   │   │   ├── I2CFirmata
│   │   │   │   └── I2CFirmata.ino
│   │   │   ├── OldStandardFirmata
│   │   │   │   └── OldStandardFirmata.ino
│   │   │   ├── ServoFirmata
│   │   │   │   └── ServoFirmata.ino
│   │   │   ├── SimpleAnalogFirmata
│   │   │   │   └── SimpleAnalogFirmata.ino
│   │   │   ├── SimpleDigitalFirmata
│   │   │   │   └── SimpleDigitalFirmata.ino
│   │   │   └── StandardFirmata
│   │   │       └── StandardFirmata.ino
│   │   ├── Firmata.cpp
│   │   ├── Firmata.h
│   │   ├── keywords.txt
│   │   └── TODO.txt
│   ├── LiquidCrystal
│   │   ├── examples
│   │   │   ├── Autoscroll
│   │   │   │   └── Autoscroll.ino
│   │   │   ├── Blink
│   │   │   │   └── Blink.ino
│   │   │   ├── Cursor
│   │   │   │   └── Cursor.ino
│   │   │   ├── CustomCharacter
│   │   │   │   └── CustomCharacter.ino
│   │   │   ├── Display
│   │   │   │   └── Display.ino
│   │   │   ├── HelloWorld
│   │   │   │   └── HelloWorld.ino
│   │   │   ├── Scroll
│   │   │   │   └── Scroll.ino
│   │   │   ├── SerialDisplay
│   │   │   │   └── SerialDisplay.ino
│   │   │   ├── setCursor
│   │   │   │   └── setCursor.ino
│   │   │   └── TextDirection
│   │   │       └── TextDirection.ino
│   │   ├── keywords.txt
│   │   ├── LiquidCrystal.cpp
│   │   └── LiquidCrystal.h
│   ├── SD
│   │   ├── examples
│   │   │   ├── CardInfo
│   │   │   │   └── CardInfo.ino
│   │   │   ├── Datalogger
│   │   │   │   └── Datalogger.ino
│   │   │   ├── DumpFile
│   │   │   │   └── DumpFile.ino
│   │   │   ├── Files
│   │   │   │   └── Files.ino
│   │   │   ├── listfiles
│   │   │   │   └── listfiles.ino
│   │   │   └── ReadWrite
│   │   │       └── ReadWrite.ino
│   │   ├── File.cpp
│   │   ├── keywords.txt
│   │   ├── README.txt
│   │   ├── SD.cpp
│   │   ├── SD.h
│   │   └── utility
│   │       ├── FatStructs.h
│   │       ├── Sd2Card.cpp
│   │       ├── Sd2Card.h
│   │       ├── Sd2PinMap.h
│   │       ├── SdFat.h
│   │       ├── SdFatmainpage.h
│   │       ├── SdFatUtil.h
│   │       ├── SdFile.cpp
│   │       ├── SdInfo.h
│   │       └── SdVolume.cpp
│   ├── Servo
│   │   ├── examples
│   │   │   ├── Knob
│   │   │   │   └── Knob.ino
│   │   │   └── Sweep
│   │   │       └── Sweep.ino
│   │   ├── keywords.txt
│   │   ├── Servo.cpp
│   │   └── Servo.h
│   ├── SoftwareSerial
│   │   ├── examples
│   │   │   ├── SoftwareSerialExample
│   │   │   │   └── SoftwareSerialExample.ino
│   │   │   └── TwoPortReceive
│   │   │       └── TwoPortReceive.ino
│   │   ├── keywords.txt
│   │   ├── SoftwareSerial.cpp
│   │   └── SoftwareSerial.h
│   ├── SPI
│   │   ├── examples
│   │   │   ├── BarometricPressureSensor
│   │   │   │   ├── BarometricPressureSensor
│   │   │   │   │   └── BarometricPressureSensor.ino
│   │   │   │   └── BarometricPressureSensor.ino
│   │   │   └── DigitalPotControl
│   │   │       └── DigitalPotControl.ino
│   │   ├── keywords.txt
│   │   ├── SPI.cpp
│   │   └── SPI.h
│   ├── Stepper
│   │   ├── examples
│   │   │   ├── MotorKnob
│   │   │   │   └── MotorKnob.ino
│   │   │   ├── stepper_oneRevolution
│   │   │   │   └── stepper_oneRevolution.ino
│   │   │   ├── stepper_oneStepAtATime
│   │   │   │   └── stepper_oneStepAtATime.ino
│   │   │   └── stepper_speedControl
│   │   │       └── stepper_speedControl.ino
│   │   ├── keywords.txt
│   │   ├── Stepper.cpp
│   │   └── Stepper.h
│   ├── WiFi
│   │   ├── examples
│   │   │   ├── ConnectNoEncryption
│   │   │   │   └── ConnectNoEncryption.ino
│   │   │   ├── ConnectWithWEP
│   │   │   │   └── ConnectWithWEP.ino
│   │   │   ├── ConnectWithWPA
│   │   │   │   └── ConnectWithWPA.ino
│   │   │   ├── ScanNetworks
│   │   │   │   └── ScanNetworks.ino
│   │   │   ├── SimpleWebServerWiFi
│   │   │   │   └── SimpleWebServerWiFi.ino
│   │   │   ├── WifiChatServer
│   │   │   │   └── WifiChatServer.ino
│   │   │   ├── WifiPachubeClient
│   │   │   │   └── WifiPachubeClient.ino
│   │   │   ├── WifiPachubeClientString
│   │   │   │   └── WifiPachubeClientString.ino
│   │   │   ├── WifiTwitterClient
│   │   │   │   └── WifiTwitterClient.ino
│   │   │   ├── WifiWebClient
│   │   │   │   └── WifiWebClient.ino
│   │   │   ├── WifiWebClientRepeating
│   │   │   │   └── WifiWebClientRepeating.ino
│   │   │   └── WifiWebServer
│   │   │       └── WifiWebServer.ino
│   │   ├── keywords.txt
│   │   ├── utility
│   │   │   ├── debug.h
│   │   │   ├── server_drv.cpp
│   │   │   ├── server_drv.h
│   │   │   ├── socket.c
│   │   │   ├── socket.h
│   │   │   ├── spi_drv.cpp
│   │   │   ├── spi_drv.h
│   │   │   ├── wifi_drv.cpp
│   │   │   ├── wifi_drv.h
│   │   │   ├── wifi_spi.h
│   │   │   ├── wl_definitions.h
│   │   │   └── wl_types.h
│   │   ├── WiFiClient.cpp
│   │   ├── WiFiClient.h
│   │   ├── WiFi.cpp
│   │   ├── WiFi.h
│   │   ├── WiFiServer.cpp
│   │   └── WiFiServer.h
│   └── Wire
│       ├── examples
│       │   ├── digital_potentiometer
│       │   │   └── digital_potentiometer.ino
│       │   ├── master_reader
│       │   │   └── master_reader.ino
│       │   ├── master_writer
│       │   │   └── master_writer.ino
│       │   ├── SFRRanger_reader
│       │   │   └── SFRRanger_reader.ino
│       │   ├── slave_receiver
│       │   │   └── slave_receiver.ino
│       │   └── slave_sender
│       │       └── slave_sender.ino
│       ├── keywords.txt
│       ├── utility
│       │   ├── twi.c
│       │   └── twi.h
│       ├── Wire.cpp
│       └── Wire.h
├── reference -> ../doc/arduino-core/reference
└── tools
    ├── howto.txt
    └── Mangler
        └── src
            └── Mangler.java

141 directories, 325 files



Examples



/usr/share/doc/arduino-core/examples
├── 01.Basics
│   ├── AnalogReadSerial
│   │   └── AnalogReadSerial.ino
│   ├── BareMinimum
│   │   └── BareMinimum.ino
│   ├── Blink
│   │   └── Blink.ino
│   ├── DigitalReadSerial
│   │   └── DigitalReadSerial.ino
│   ├── Fade
│   │   └── Fade.ino
│   └── ReadAnalogVoltage
│       └── ReadAnalogVoltage.ino
├── 02.Digital
│   ├── BlinkWithoutDelay
│   │   └── BlinkWithoutDelay.ino
│   ├── Button
│   │   └── Button.ino
│   ├── Debounce
│   │   └── Debounce.ino
│   ├── DigitalIputPullup
│   │   └── DigitalIputPullup.ino
│   ├── StateChangeDetection
│   │   └── StateChangeDetection.ino
│   ├── toneKeyboard
│   │   ├── pitches.h
│   │   └── toneKeyboard.ino
│   ├── toneMelody
│   │   ├── pitches.h
│   │   └── toneMelody.ino
│   ├── toneMultiple
│   │   ├── pitches.h
│   │   └── toneMultiple.ino
│   └── tonePitchFollower
│       └── tonePitchFollower.ino
├── 03.Analog
│   ├── AnalogInOutSerial
│   │   └── AnalogInOutSerial.ino
│   ├── AnalogInput
│   │   └── AnalogInput.ino
│   ├── AnalogWriteMega
│   │   └── AnalogWriteMega.ino
│   ├── Calibration
│   │   └── Calibration.ino
│   ├── Fading
│   │   └── Fading.ino
│   └── Smoothing
│       └── Smoothing.ino
├── 04.Communication
│   ├── ASCIITable
│   │   └── ASCIITable.ino
│   ├── Dimmer
│   │   └── Dimmer.ino
│   ├── Graph
│   │   └── Graph.ino
│   ├── MIDI
│   │   └── Midi.ino
│   ├── MultiSerialMega
│   │   └── MultiSerialMega.ino
│   ├── PhysicalPixel
│   │   └── PhysicalPixel.ino
│   ├── ReadASCIIString
│   │   └── ReadASCIIString.ino
│   ├── SerialCallResponse
│   │   └── SerialCallResponse.ino
│   ├── SerialCallResponseASCII
│   │   └── SerialCallResponseASCII.ino
│   ├── SerialEvent
│   │   └── SerialEvent.ino
│   └── VirtualColorMixer
│       └── VirtualColorMixer.ino
├── 05.Control
│   ├── Arrays
│   │   └── Arrays.ino
│   ├── ForLoopIteration
│   │   └── ForLoopIteration.ino
│   ├── IfStatementConditional
│   │   └── IfStatementConditional.ino
│   ├── switchCase
│   │   └── switchCase.ino
│   ├── switchCase2
│   │   └── switchCase2.ino
│   └── WhileStatementConditional
│       └── WhileStatementConditional.ino
├── 06.Sensors
│   ├── ADXL3xx
│   │   └── ADXL3xx.ino
│   ├── Knock
│   │   └── Knock.ino
│   ├── Memsic2125
│   │   └── Memsic2125.ino
│   └── Ping
│       └── Ping.ino
├── 07.Display
│   ├── barGraph
│   │   └── barGraph.ino
│   └── RowColumnScanning
│       └── RowColumnScanning.ino
├── 08.Strings
│   ├── CharacterAnalysis
│   │   └── CharacterAnalysis.ino
│   ├── StringAdditionOperator
│   │   └── StringAdditionOperator.ino
│   ├── StringAppendOperator
│   │   └── StringAppendOperator.ino
│   ├── StringCaseChanges
│   │   └── StringCaseChanges.ino
│   ├── StringCharacters
│   │   └── StringCharacters.ino
│   ├── StringComparisonOperators
│   │   └── StringComparisonOperators.ino
│   ├── StringConstructors
│   │   └── StringConstructors.ino
│   ├── StringIndexOf
│   │   └── StringIndexOf.ino
│   ├── StringLength
│   │   └── StringLength.ino
│   ├── StringLengthTrim
│   │   └── StringLengthTrim.ino
│   ├── StringReplace
│   │   └── StringReplace.ino
│   ├── StringStartsWithEndsWith
│   │   └── StringStartsWithEndsWith.ino
│   ├── StringSubstring
│   │   └── StringSubstring.ino
│   ├── StringToInt
│   │   └── StringToInt.ino
│   └── StringToIntRGB
│       └── StringToIntRGB.ino
├── 09.USB
│   ├── Keyboard
│   │   ├── KeyboardLogout
│   │   │   └── KeyboardLogout.ino
│   │   ├── KeyboardMessage
│   │   │   └── KeyboardMessage.ino
│   │   ├── KeyboardReprogram
│   │   │   └── KeyboardReprogram.ino
│   │   └── KeyboardSerial
│   │       └── KeyboardSerial.ino
│   ├── KeyboardAndMouseControl
│   │   └── KeyboardAndMouseControl.ino
│   └── Mouse
│       ├── ButtonMouseControl
│       │   └── ButtonMouseControl.ino
│       └── JoystickMouseControl
│           └── JoystickMouseControl.ino
├── 10.StarterKit
│   ├── p02_SpaceshipInterface
│   │   └── p02_SpaceshipInterface.ino
│   ├── p03_LoveOMeter
│   │   └── p03_LoveOMeter.ino
│   ├── p04_ColorMixingLamp
│   │   └── p04_ColorMixingLamp.ino
│   ├── p05_ServoMoodIndicator
│   │   └── p05_ServoMoodIndicator.ino
│   ├── p06_LightTheremin
│   │   └── p06_LightTheremin.ino
│   ├── p07_Keyboard
│   │   └── p07_Keyboard.ino
│   ├── p08_DigitalHourglass
│   │   └── p08_DigitalHourglass.ino
│   ├── p09_MotorizedPinwheel
│   │   └── p09_MotorizedPinwheel.ino
│   ├── p10_Zoetrope
│   │   └── p10_Zoetrope.ino
│   ├── p11_CrystalBall
│   │   └── p11_CrystalBall.ino
│   ├── p12_KnockLock
│   │   └── p12_KnockLock.ino
│   ├── p13_TouchSensorLamp
│   │   └── p13_TouchSensorLamp.ino
│   ├── p14_TweakTheArduinoLogo
│   │   └── p14_TweakTheArduinoLogo.ino
│   └── p15_HackingButtons
│       └── p15_HackingButtons.ino
└── ArduinoISP
    └── ArduinoISP.ino

93 directories, 84 files