Skip to content

Instantly share code, notes, and snippets.

@tomasero
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save tomasero/af28515df4f0902eda09 to your computer and use it in GitHub Desktop.

Select an option

Save tomasero/af28515df4f0902eda09 to your computer and use it in GitHub Desktop.

Revisions

  1. tomasero revised this gist Jun 11, 2015. 1 changed file with 115 additions and 21 deletions.
    136 changes: 115 additions & 21 deletions ultrasound.ino
    Original file line number Diff line number Diff line change
    @@ -1,43 +1,137 @@
    #define APP_VERSION 1.0

    double distance = 0;
    double echo = 0;
    int ultraSoundSignal = D0; // Ultrasound signal pin
    // This #include statement was automatically added by the Spark IDE.
    #include "elapsedMillis/elapsedMillis.h"

    #define APP_VERSION 1.1

    long distance = 0;
    long echo = 0;
    const int trigPin = D0;
    const int echoPin = D1;
    const int led = D7;
    bool active = FALSE;
    bool prevActive = active;
    int readings = 0;
    int readingIndex = 0;
    double avgDistance;
    String distances = "";

    // Elapsed Millis Stuff
    unsigned int publishInterval = 2000; // Every 2000 ms (2 seconds)
    unsigned int refractoryPeriod = 10000;
    elapsedMillis pTimeElapsed; //declare global if you don't want it reset every time loop runs
    elapsedMillis rTimeElapsed;


    void setup() {
    pinMode(ultraSoundSignal,OUTPUT);
    pinMode(trigPin, OUTPUT);
    // pinMode(echoPin, INPUT);
    pinMode(led, OUTPUT);
    Spark.publish("status", "{ status: \"started up! "+String(APP_VERSION)+"\"}", 60, PRIVATE );
    rTimeElapsed = 0;
    pTimeElapsed = 0;
    Spark.variable("distance", &distance, DOUBLE);
    Spark.function("activation", activation);
    }

    void loop() {
    updateDistance();
    if (active) {
    digitalWrite(led, HIGH);
    updateDistance();
    } else {
    digitalWrite(led, LOW);
    }
    delay(100);
    }

    int activation(String state) {
    Spark.publish("status", "{ Sensor Activation: " + state +"}");

    pTimeElapsed = 0;
    rTimeElapsed = refractoryPeriod;
    readings = 0;
    readingIndex = 0;
    distances = "";

    if (state == "on") {
    active = TRUE;
    } else {
    active = FALSE;
    }
    return 1;
    }

    void updateDistance() {
    Spark.publish("status", "{ status: updateDistance}", 60, PRIVATE );
    pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output
    digitalWrite(ultraSoundSignal, LOW); // Send low pulse
    pinMode(trigPin, OUTPUT);
    digitalWrite(trigPin, LOW); // Send low pulse
    delayMicroseconds(2); // Wait for 2 microseconds
    digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
    digitalWrite(trigPin, HIGH); // Send high pulse
    delayMicroseconds(5); // Wait for 5 microseconds
    digitalWrite(ultraSoundSignal, LOW); // Holdoff
    pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
    digitalWrite(ultraSoundSignal, HIGH); // Turn on pullup resistor
    digitalWrite(trigPin, LOW); // Holdoff

    // please note that pulseIn has a 1sec timeout, which may
    // not be desirable. Depending on your sensor specs, you
    // can likely bound the time like this -- marcmerlin
    // echo = pulseIn(ultraSoundSignal, HIGH, 38000)
    echo = pulseIn(ultraSoundSignal, HIGH); //Listen for echo
    distance = (echo / 58.138);// * .39; //convert to CM then to inches
    pinMode(trigPin, INPUT);
    // echo = pulseIn(echoPin, HIGH); //Listen for echo
    echo = pulseIn(trigPin, HIGH); //Listen for echo
    distance = microsecondsToCentimeters(echo);
    // distance = round(distance);
    Spark.publish("distance", "Outside: " + String(distance));
    if (distance <= 100) {
    Spark.publish("distance", String(distance)); //it just posts one time? why?
    // Spark.publish("distance", "Outside: " + String(distance));


    if (readingIndex < 20) {
    distances += ", " + String(distance);
    if (distance <= 15) {
    readings++;
    }
    avgDistance += distance;
    readingIndex++;
    } else {
    avgDistance = avgDistance/20;
    publishDistance(readings, avgDistance);
    readings = 0;
    readingIndex = 0;
    avgDistance = 0;
    distances = "";
    }
    // if (distance <= 100 && !detected) {
    // Spark.publish("distance", "near");
    // Spark.publish("distance", String(distance));
    // detected = 1;

    // }
    }

    void publishDistance(int readings, double avgDistance) {
    String state;
    // if (readings >= 10) {
    if (avgDistance < 100) {
    state = "near";
    // if (rTimeElapsed < refractoryPeriod) {
    // return;
    // }
    } else {
    state = "far";
    }
    if (pTimeElapsed > publishInterval) {
    // Spark.publish("status", "{ Num of Positives: " + String(readings) +"}");
    // Spark.publish("status", "{ Distances: " + distances +"}");
    Spark.publish("status", "{ Average distance: " + String(avgDistance) +"}");;
    rTimeElapsed = 0;
    pTimeElapsed = 0;
    Spark.publish("distance", state);
    }
    }

    double pulseIn(uint16_t pin, uint8_t state) {
    long microsecondsToCentimeters(long microseconds) {
    // The speed of sound is 340 m/s or 29 microseconds per centimeter.
    // The ping travels out and back, so to find the distance of the
    // object we take half of the distance travelled.
    return microseconds / 29 / 2;
    }

    unsigned long pulseIn(uint16_t pin, uint8_t state) {

    GPIO_TypeDef* portMask = (PIN_MAP[pin].gpio_peripheral); // Cache the target's peripheral mask to speed up the loops.
    uint16_t pinMask = (PIN_MAP[pin].gpio_pin); // Cache the target's GPIO pin mask to speed up the loops.
  2. tomasero created this gist Jun 9, 2015.
    65 changes: 65 additions & 0 deletions ultrasound.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    #define APP_VERSION 1.0

    double distance = 0;
    double echo = 0;
    int ultraSoundSignal = D0; // Ultrasound signal pin

    void setup() {
    pinMode(ultraSoundSignal,OUTPUT);
    Spark.publish("status", "{ status: \"started up! "+String(APP_VERSION)+"\"}", 60, PRIVATE );
    Spark.variable("distance", &distance, DOUBLE);
    }

    void loop() {
    updateDistance();
    }

    void updateDistance() {
    Spark.publish("status", "{ status: updateDistance}", 60, PRIVATE );
    pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output
    digitalWrite(ultraSoundSignal, LOW); // Send low pulse
    delayMicroseconds(2); // Wait for 2 microseconds
    digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
    delayMicroseconds(5); // Wait for 5 microseconds
    digitalWrite(ultraSoundSignal, LOW); // Holdoff
    pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
    digitalWrite(ultraSoundSignal, HIGH); // Turn on pullup resistor
    // please note that pulseIn has a 1sec timeout, which may
    // not be desirable. Depending on your sensor specs, you
    // can likely bound the time like this -- marcmerlin
    // echo = pulseIn(ultraSoundSignal, HIGH, 38000)
    echo = pulseIn(ultraSoundSignal, HIGH); //Listen for echo
    distance = (echo / 58.138);// * .39; //convert to CM then to inches
    // distance = round(distance);
    Spark.publish("distance", "Outside: " + String(distance));
    if (distance <= 100) {
    Spark.publish("distance", String(distance)); //it just posts one time? why?
    }
    }

    double pulseIn(uint16_t pin, uint8_t state) {

    GPIO_TypeDef* portMask = (PIN_MAP[pin].gpio_peripheral); // Cache the target's peripheral mask to speed up the loops.
    uint16_t pinMask = (PIN_MAP[pin].gpio_pin); // Cache the target's GPIO pin mask to speed up the loops.
    unsigned long pulseCount = 0; // Initialize the pulseCount variable now to save time.
    unsigned long loopCount = 0; // Initialize the loopCount variable now to save time.
    unsigned long loopMax = 20000000; // Roughly just under 10 seconds timeout to maintain the Spark Cloud connection.

    // Wait for the pin to enter target state while keeping track of the timeout.
    while (GPIO_ReadInputDataBit(portMask, pinMask) != state) {
    if (loopCount++ == loopMax) {
    return 0;
    }
    }

    // Iterate the pulseCount variable each time through the loop to measure the pulse length; we also still keep track of the timeout.
    while (GPIO_ReadInputDataBit(portMask, pinMask) == state) {
    if (loopCount++ == loopMax) {
    return 0;
    }
    pulseCount++;
    }

    // Return the pulse time in microseconds by multiplying the pulseCount variable with the time it takes to run once through the loop.
    return pulseCount * 0.405; // Calculated the pulseCount++ loop to be about 0.405uS in length.
    }