I’ve been wrestling with getting a single servo motor to work in my project for a couple of days now.
If I set it up on a nano by itself, it functions the way I’m expecting it to. When I put it in the system with the other components, the servo will sit and chatter back and forth for a few cycles then goes quiet. After that it doesn’t respond to anything. If I cycle the power to the servo, it’s just a rinse & repeat situation.
I have cobbled together code from several sample sketches and tried to tailor it to my needs. If there are code conflicts, then it’s in the deep end of the pool and I’m still swimming in the shallow end. Any advice/help will be greatly appreciated as well as any suggestions for improvement (Like I said it’s been “cobbled together”). This is my first Arduino project, so I’m braced for a stern critique. I wasn't sure about the category, even though my project is low voltage it looked like the best fit. I took it literally when the forum said to 'post all your code and your circuit - so if this is more than required, I'll post less next time round.
StandingStoneCircuitLayout.pdf (523.5 KB)
#include <FastLED.h>
#include <Servo.h>
//Servo Definitions
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
FASTLED_USING_NAMESPACE
// Light strip Init
#define DATA_PIN 5
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS 57
#define BRIGHTNESS 96
#define FRAMES_PER_SECOND 120
CRGB leds[NUM_LEDS];
//RCWL Variable initialization
int Sensor = A1; //RCWL-0516 Input
int SFXTrig = A0; //Trigger the sound card
int SensorVal = 0; //RCWL-0516 Sensor Value
int LoopCheck = 0; //Looping detection delay
int LightTrig = 0; //Trigger for the LED strips
int firstPass = 1; //the first time through the loop will set this to zero
int LightTog = 1; //irritating message removal
int MonitorTog = 1; //irritating message removal
int LoopMax = 148800; //should be a 3 minute delay
int ServoTrig = 0; //Only trigger the servo once
//Crystal Variable Init
int LED = 7; //LED output on Pin D7
int CrystalTrig = 4; //Looking for a magnet activation on D4
int CrystalVal = 0; //Value of the Reed Switch
int CrystalAct = 0; //Disable the scan once the crystal has been placed
void setup() {
//Status Panel
Serial.begin(57600);
delay(1000); //give it a second to setup the Serial Monitor Window
Serial.println("Standing Stone Functionality is initializing");
Serial.println(" **Monitoring functions will sleep for 3 minutes after reset");
// Setup the LED Strip
delay(1000); // 1 second delay for recovery
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS); // set master brightness control
Serial.println(" [1] LED Strip has been setup");
// Setup the Servo motor
myservo.attach(9); // attaches the servo on pin 9 to the servo object
delay(250);
myservo.write(pos); // Zero the servo
Serial.println(" [2] Servo Object Created,atached and Zeroed");
delay(1000);
// Setup the Reed Switch and its LED
pinMode(LED, OUTPUT);
pinMode(CrystalTrig, INPUT);
Serial.println(" [3] Crystal Sensor has been Configured");
// Setup Sound Board and Motion Sensor Pin Modes
pinMode(SFXTrig, OUTPUT);
pinMode(SFXTrig, LOW);
Serial.println(" [4] SFX Board has been Configured");
pinMode(Sensor, INPUT);
Serial.println(" [5] Motion Sensor has been Configured");
}
// List of patterns to cycle through. But there is only one pattern right now
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { Cylon };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
void loop() {
// first pass through here, turn off the Lights
if (firstPass == 1 ) {
Serial.println(" [6] Turning the light Strip Off.");
firstPass = 0;
for(int dot = 0; dot < NUM_LEDS; dot++) {
leds[dot] = CRGB::Black;
FastLED.show();
}
}
// Sense movement and activate the sound card
CrystalVal = digitalRead(CrystalTrig); // Read the Crystal
SensorVal = analogRead(Sensor); //Read the RCWL-0516 Value
// Check to see if we should turn on the Servo
//Serial.println((String)" Crystal Activation flag was "+CrystalAct);
//Serial.println((String)" Crystal Sensor Value was "+CrystalVal);
if (CrystalAct == 0) {
if (CrystalVal == 0) { CrysLock(); }
}
// End of Servo Check
// DeBounce the activity scan
LoopCheck ++;
if(LoopCheck == LoopMax){
if (MonitorTog == 1 ) {
Serial.println(" [7] The Stone is now Actively Monitoring for motion");
MonitorTog = 0;
}
}
if(LoopCheck > LoopMax-1) {
if (SensorVal >= 500) {
Serial.println("----------------------");
Serial.println("**Movement was detected**");
Serial.println((String)" Sensor Value was "+SensorVal);
analogWrite(SFXTrig,0);
delay(250);
analogWrite(SFXTrig,255);
delay(250);
Serial.println(" SFX Board Activated");
Serial.println(" ");
LightTrig = 1;
LoopCheck = 0;
Serial.println(" Resetting the LoopCheck Variable");
Serial.println(" and turning on the LED lights, then");
Serial.println(" Sleeping for 5 minutes");
Serial.println("----------------------");
}
}
// End of DeBounce
//Active Light cycle: Someone has triggered the stone.
if (LightTrig == 1) {
if(LightTog == 1) {
LightTog = 0;
Serial.println("The LED lights have been Activated");
Serial.println("----------------------");
}
// Call the current pattern function once, updating the 'leds' array
gPatterns[gCurrentPatternNumber]();
FastLED.show();
FastLED.delay(1000/FRAMES_PER_SECOND);
// do some periodic updates
EVERY_N_MILLISECONDS( 5 ) { gHue++; } // slowly cycle the "base color" through the rainbow
EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
// time out the lights
if (LoopCheck > LoopMax-1) {
LightTrig = 0;
LightTog = 1;
Serial.println(" Time is up - No one actived the Crystl during this event");
Serial.println(" Light Trigger was just reset");
Serial.println(" Turning the lights off now.");
Serial.println(" I'm just watching for movement now");
for(int dot = 0; dot < NUM_LEDS; dot++) {
leds[dot] = CRGB::Black;
FastLED.show();
}
}
}
}
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void nextPattern(){
// add one to the current pattern number, and wrap around at the end
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}
void Cylon(){
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy( leds, NUM_LEDS, 20);
int pos = beatsin16( 13, 0, NUM_LEDS-1 );
leds[pos] += CHSV( gHue, 255, 192);
}
void CrysLock() {
digitalWrite(LED, HIGH);
Serial.println("----------------------");
Serial.println("Crystal Event Detected");
Serial.println(" ** UNLOCK Drawer Mech **");
for (pos = 0; pos <= 90; pos += 1) {
myservo.write(pos);
delay(10);
}
delay(250);
Serial.println(" ** Re-LOCK Drawer Mech **");
for (pos = 90; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(10);
}
Serial.println(" Servo Controller was returned to LOCKed Position");
delay(2000);
CrystalAct = 1;
digitalWrite(LED, LOW);
Serial.println(" Crystal Event Monitor has been deactivated");
Serial.println(" Return to IDLE Scanning(Lights and Sound only)");
}