Skip to content

Instantly share code, notes, and snippets.

@tizza555
Created November 13, 2023 18:18
Show Gist options
  • Save tizza555/c0bb1f378216c2cfb9d62a3b0adb3f68 to your computer and use it in GitHub Desktop.
Save tizza555/c0bb1f378216c2cfb9d62a3b0adb3f68 to your computer and use it in GitHub Desktop.
Shoulder Mounted Light Sensor
// ODRADEK by Tyler Jorge
// Created on November 6th, 2023
// DIGF-3011, Advanced Wearables, Kate Hartman
// OCAD University
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library
// SeveralThingsAtTheSameTime
// by Robin2, forum.arduino.cc
// https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158
#include <Servo.h>
#include <Adafruit_NeoPixel.h>
#define PIN 9 // pin for the Photovoltaic Sensor
#define NUMPIXELS 12 // number of pixels for the NeoPixel ring
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Servo threeservo; // define the three arm servos as "threeservo"
Servo spinservo; // define the 360 degree servo as "spinservo"
int pos = 0; // initial position of servos
unsigned long previousMillis = 0;
const long delayInterval = 550; // Increase delayInterval for smoother movements
const long pauseInterval = 4000; // Delay after moving between 15 and 85 degrees
const int lowLightThreshold = 100; // Adjust this threshold based on environment
const int numReadings = 10; // Number of readings to average
int lightReadings[numReadings]; // Array to store readings
int readingIndex = 0; // Index for the current reading
void setup() {
Serial.begin(9600); // begin serial
threeservo.attach(11); // three servo motors attached to pin 11
spinservo.attach(10); // 360 degree servo attached to pin 10
pixels.begin(); // initialize neopixels
// Initialize the array with initial readings
for (int i = 0; i < numReadings; i++) {
lightReadings[i] = analogRead(A1);
}
}
void loop() {
// Update the array with the latest reading
lightReadings[readingIndex] = analogRead(A1);
readingIndex = (readingIndex + 1) % numReadings;
// Calculate the average of the readings
int lightValue = 0;
for (int i = 0; i < numReadings; i++) {
lightValue += lightReadings[i];
}
lightValue /= numReadings;
lightValue = map(lightValue, 0, 1023, 0, 180); // maps analog sensor readings to servo angle
Serial.println(lightValue); // print photovoltaic sensor readings in serial monitor
pixels.clear(); // clear pixels
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(255, 0, 0)); // set pixel colour to red
}
pixels.show(); // show pixels (blink)
if (lightValue > 120) { // if LDR reads light value above 120:
moveServo(threeservo, lightValue, 15, 85); // flap arms between 15 and 85 degress
moveSpinServo(spinservo, lightValue); // spin the 360 degree servo by lightvalue
} else {
threeservo.write(90); // three arms remain locked at 90 degrees
spinservo.write(0); // disc servo remains at 0 degrees
pos = 0;
}
}
void moveServo(Servo &servo, int lightValue, int startPos, int endPos) {
unsigned long currentMillis = millis();
static bool isPaused = false;
if (currentMillis - previousMillis >= delayInterval && !isPaused) {
if (lightValue > lowLightThreshold) {
previousMillis = currentMillis;
if (pos <= endPos) {
servo.write(pos);
pos++;
} else if (pos >= startPos) {
servo.write(pos);
pos--;
} else {
pos = startPos;
isPaused = true;
}
} else {
isPaused = true;
}
}
if (isPaused && currentMillis - previousMillis >= pauseInterval) {
isPaused = false;
pos = startPos;
}
}
void moveSpinServo(Servo &servo, int lightValue) {
if (lightValue > lowLightThreshold) {
int angle = map(lightValue, 0, 180, 0, 180); // determines what angle to write the disc servo at, based on lightvalue recieved from LDR
servo.write(angle);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment