What sloppy code looks like in process

I never said I was a clean software code writer.

I write code like I draw — tracing and [re]sketching until I get a good feel for the drawing technique.

These lines of code are my “doodles”:

/* Read two one ultrasonic sensors and two PIR sensors, control five LEDs and two servos
Based on code by
David A. Mellis, Tom Igoe,
Kimmo Karvinen and Tero Karvinen
Updated by Joe Saavedra, 2010
http://BotBook.com
*/
/*****************************************************************************/
//    Function: If the sensor detects movement in its detecting range,
//              the LED is turned on. Otherwise, the LED is turned off.
//  Hardware: Grove – PIR Motion Sensor, Grove – LED
//    Arduino IDE: Arduino-1.0
//    Author:     Frankie.Chu
//    Date:      Jan 21,2013
//    Version: v1.0
//    by http://www.seeedstudio.com
//      Modified by: RadioShack Corporation
//      Date: July 18, 2013
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
/*******************************************************************************/
/*macro definitions of PIR motion sensor pins and LED pins*/
#define PIR_MOTION_SENSOR_LEFT 2//Use pin 2 to receive the signal from the left PIR module
#define PIR_MOTION_SENSOR_RT 5//Use pin 5 to receive the signal from the right PIR module
#define LED_LEFT    6//the LED is connected to D6 of Arduino
#define LED_RT    9//the LED is connected to D9 of Arduino
// Number Two: Sweep
// by BARRAGAN
// For more information on this circuit, go to http://www.oomlout.com/oom.php/products/ardx/circ-04

/*#define trigPin 12 // from forum.arduino.cc
#define echoPin 13 // from forum.arduino.cc*/
#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
Servo myservo2;  // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position

//const int leftPing = 3;
const int rightPing = 12;

//const int leftPIRLed = 6;
//const int leftUSLed1 = 7;
const int rightUSLed1 = 8;
//const int rightPIRLed = 9;
//const int leftUSLed2 = 10;
//const int leftUSLed3 = 11;
const int rightUSLed2 = 11;
const int rightUSLed3 = 3;

const int closeD = 10; // cm; maximum closest distance – 0 to 10 cm range
const int midD = 20; // cm; maximum hand distance – 10 to 20 cm range
const int farD = 30; // cm; maximum farthest distance – 20 to 30 cm range

void setup()
{
myservo1.attach(10);  // attaches the servo 1 on pin 10 to the servo object
myservo2.attach(4);  // attaches the servo 2 on pin 4 to the servo object
pinsInit();

Serial.begin(9600);
//  pinMode(leftPIRLed, OUTPUT);
//  pinMode(leftUSLed1, OUTPUT);
//  pinMode(leftUSLed2, OUTPUT);
//  pinMode(leftUSLed3, OUTPUT);
//  pinMode(rightPIRLed, OUTPUT);
pinMode(rightUSLed1, OUTPUT);
pinMode(rightUSLed2, OUTPUT);
pinMode(rightUSLed3, OUTPUT);

//pinMode(trigPin, OUTPUT); //from forum.arduino.cc
//pinMode(echoPin, INPUT); //from forum.arduino.cc
}

void loop()
{
if(isPeopleDetectedLeft())//if the left PIR sensor detects movement, turn on LED.
turnOnLEDLeft();
else//if the left PIR sensor does not detect movement, do not turn on LED.
turnOffLEDLeft();
if(isPeopleDetectedRt())//if the right PIR sensor detects movement, turn on LED.
turnOnLEDRt();
else//if the right PIR sensor does not detect movement, do not turn on LED.
turnOffLEDRt();
//  ping(leftPing, leftUSLed1, leftUSLed2, leftUSLed3);
ping(rightPing, rightUSLed1, rightUSLed2, rightUSLed3);
//  delay(500);
/*int duration, distance,pos=0,i;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2)/29.1;
Serial.print(distance);
Serial.println(” cm”);
//if(distance<15)
if(rightPing<5)
{
myservo.write(90);
}
else{
myservo.write(0);
}
delay(10);*/

/*    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
{                                  // in steps of 1 degree
myservo.write(pos);              // tell servo to go to position in variable ‘pos’
delay(15);                       // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
{
myservo.write(pos);              // tell servo to go to position in variable ‘pos’
delay(15);                       // waits 15ms for the servo to reach the position
}*/
}

void pinsInit()
{
pinMode(PIR_MOTION_SENSOR_LEFT, INPUT);
pinMode(LED_LEFT,OUTPUT);
pinMode(PIR_MOTION_SENSOR_RT, INPUT);
pinMode(LED_RT,OUTPUT);

}
void turnOnLEDLeft()
{
digitalWrite(LED_LEFT,HIGH);
myservo2.write(180);
}
void turnOffLEDLeft()
{
digitalWrite(LED_LEFT,LOW);
myservo2.write(90);
}
void turnOnLEDRt()
{
digitalWrite(LED_RT,HIGH);
myservo2.write(0);
}
void turnOffLEDRt()
{
digitalWrite(LED_RT,LOW);
myservo2.write(90);
}
/***************************************************************/
/*Function: Detect whether there is movement in the PIR sensor’s detecting range*/
/*Return:-boolean, true is movement is detected.*/
boolean isPeopleDetectedLeft()
{
int sensorValue = digitalRead(PIR_MOTION_SENSOR_LEFT);
if(sensorValue == HIGH)//if the sensor value is HIGH?
{
return true;//yes,return true
}
else
{
return false;//no,return false
}
}
boolean isPeopleDetectedRt()
{
int sensorValue = digitalRead(PIR_MOTION_SENSOR_RT);
if(sensorValue == HIGH)//if the sensor value is HIGH?
{
return true;//yes,return true
}
else
{
return false;//no,return false
}
}
boolean ping(int pingPin, int ledPin1, int ledPin2, int ledPin3)
{
int d = getDistance(pingPin); // cm
boolean pinActivated1 = false;
boolean pinActivated2 = false;
boolean pinActivated3 = false;
if (d < closeD) {
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
myservo1.write(180);
pinActivated1 = true;
pinActivated2 = false;
pinActivated3 = false;
} else {
if (d < midD) {
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, LOW);
myservo1.write(90);
pinActivated1 = false;
pinActivated2 = true;
pinActivated3 = false;
}
else {
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, HIGH);
myservo1.write(0);
pinActivated1 = false;
pinActivated2 = false;
pinActivated3 = true;
}
}
return pinActivated1, pinActivated2, pinActivated3;
}

int getDistance(int pingPin)
{
long duration, inches, cm;

pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);

pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);

inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print(“in, “);
Serial.print(cm);
Serial.print(“cm”);
Serial.println();
return(cm); // You could also return inches
}

long microsecondsToInches(long microseconds)
{
return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29 / 2;
}

 

Today’s Arduino programming lesson

The last update on my Arduino-based yard art sculpture showed the addition of a servo to a circuit with eight LEDs.

Today, I want to figure out if I can set the servo and LEDs to activate only after a PIR (passive infrared) motion sensor has been triggered.

The PIR motion sensor I’ll use for this experiment is sold through Radio Shack (product number 276-135) and available online at Parallax, Inc.  (product number 555-28027, rev B).

Via info at Parallax, here’s how to wire the sensor to your Arduino (note: I’m using digital port 12, not 2 as shown):

PIR-6

The question for me is how complex/sophisticated do I want the code for the yard art sculpture to be?  For example, let’s look at two code samples, a simple one and one that’s more sophisticated.

First, the simple code from here:

/*
 * PIR sensor tester
 */

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare sensor as input

  Serial.begin(9600);
}

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
  } else {
    digitalWrite(ledPin, LOW); // turn LED OFF
    if (pirState == HIGH){
      // we have just turned of
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}

And now, the more sophisticated code from here:

/* 
 * //////////////////////////////////////////////////
 * //making sense of the Parallax PIR sensor's output
 * //////////////////////////////////////////////////
 *
 * Switches a LED according to the state of the sensors output pin.
 * Determines the beginning and end of continuous motion sequences.
 *
 * @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
 * @date:   3. September 2006 
 *
 * kr1 (cleft) 2006 
 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/
 *
 *
 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 
 * (http://www.parallax.com/detail.asp?product_id=555-28027)
 *
 * The sensor's output pin goes to HIGH if motion is present.
 * However, even if motion is present it goes to LOW from time to time, 
 * which might give the impression no motion is present. 
 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 
 * assuming continuous motion is present during these phases.
 *  
 */

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000;  

boolean lockLow = true;
boolean takeLowTime;  

int pirPin = 3;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop(){

     if(digitalRead(pirPin) == HIGH){
       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         delay(50);
         }         
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){       
       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;                        
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           delay(50);
           }
       }
  }

Conclusion?

So, what do you think?  Should I go with the first or second code sample for the yard art sculpture?

I’ll get input from you — the loyal, happy reader — and let everyone else know what you said.  Then, I’ll show you what I did and if it differs from you, I’ll try your suggestions and show the world the results.

Until next time!